From 546376b7fede83cd77dd6688ed0749a414c90a8b Mon Sep 17 00:00:00 2001 From: msweet Date: Fri, 10 May 2013 18:56:23 +0000 Subject: [PATCH] Import cups.org releases git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/tags/release-1.1.1@4306 a1ca3aef-8c08-0410-bb20-df032aa958be --- CHANGES.txt | 610 + CREDITS.txt | 26 + LICENSE.html | 895 + Makedefs.in | 163 + Makefile | 128 + README.txt | 266 + backend/Makefile | 141 + backend/betest.c | 85 + backend/ipp.c | 721 + backend/lpd.c | 442 + backend/parallel.c | 563 + backend/serial.c | 705 + backend/socket.c | 281 + backend/usb.c | 370 + berkeley/Makefile | 105 + berkeley/lpc.c | 466 + berkeley/lpq.c | 501 + berkeley/lpr.c | 352 + berkeley/lprm.c | 221 + cgi-bin/Makefile | 119 + cgi-bin/admin.c | 1491 + cgi-bin/cgi.h | 87 + cgi-bin/classes.c | 301 + cgi-bin/html.c | 89 + cgi-bin/ipp-var.c | 257 + cgi-bin/ipp-var.h | 55 + cgi-bin/jobs.c | 139 + cgi-bin/printers.c | 301 + cgi-bin/template.c | 455 + cgi-bin/var.c | 656 + conf/Makefile | 73 + conf/classes.conf | 89 + conf/client.conf | 50 + conf/cupsd.conf | 542 + conf/mime.convs | 64 + conf/mime.types | 127 + conf/printcap | 2 + conf/printers.conf | 96 + config.h.in | 127 + configure.in | 483 + cups.dsw | 128 + cups.list | 507 + cups.sh.in | 114 + cups.spec | 113 + cups/Makefile | 166 + cups/cups.dsp | 180 + cups/cups.h | 148 + cups/cups_C.h | 132 + cups/debug.h | 57 + cups/dest.c | 504 + cups/emit.c | 305 + cups/http.c | 1665 + cups/http.h | 325 + cups/ipp.c | 1701 + cups/ipp.h | 361 + cups/language.c | 402 + cups/language.h | 222 + cups/mark.c | 437 + cups/md5.c | 392 + cups/md5.h | 94 + cups/md5passwd.c | 148 + cups/options.c | 384 + cups/page.c | 189 + cups/ppd.c | 1904 + cups/ppd.h | 241 + cups/snprintf.c | 287 + cups/string.c | 125 + cups/string.h | 94 + cups/testhttp.c | 109 + cups/testmime.dsp | 102 + cups/testppd.c | 187 + cups/testppd.dsp | 102 + cups/usersys.c | 201 + cups/util.c | 1500 + data/HPGLprolog | 37 + data/Makefile | 103 + data/classified | 259 + data/confidential | 259 + data/cups.pam | 2 + data/iso-8859-1 | 251 + data/iso-8859-10 | 251 + data/iso-8859-13 | 251 + data/iso-8859-14 | 251 + data/iso-8859-15 | 251 + data/iso-8859-2 | 253 + data/iso-8859-3 | 244 + data/iso-8859-4 | 251 + data/iso-8859-5 | 251 + data/iso-8859-6 | 206 + data/iso-8859-7 | 246 + data/iso-8859-8 | 214 + data/iso-8859-9 | 251 + data/psglyphs | 1051 + data/secret | 259 + data/standard | 259 + data/testprint.ps | 505 + data/topsecret | 259 + data/unclassified | 259 + data/utf-8 | 38 + data/windows-1250 | 254 + data/windows-1251 | 258 + data/windows-1252 | 254 + data/windows-1253 | 243 + data/windows-1254 | 252 + data/windows-1255 | 236 + data/windows-1256 | 259 + data/windows-1257 | 247 + data/windows-1258 | 250 + data/windows-874 | 228 + doc/Makefile | 225 + doc/cmp.html | 680 + doc/cmp.pdf | 830 + doc/cmp.shtml | 595 + doc/cups.css | 4 + doc/cupsdoc.css | 9 + doc/documentation.html | 77 + doc/figures.sc | Bin 0 -> 51728 bytes doc/glossary.shtml | 73 + doc/idd.html | 1094 + doc/idd.pdf | 936 + doc/idd.shtml | 1429 + doc/images/accept-jobs.gif | Bin 0 -> 259 bytes doc/images/add-class.gif | Bin 0 -> 242 bytes doc/images/add-printer.gif | Bin 0 -> 252 bytes doc/images/cancel-job.gif | Bin 0 -> 248 bytes doc/images/cancel-jobs.gif | Bin 0 -> 255 bytes doc/images/cancel.gif | Bin 0 -> 210 bytes doc/images/classes.gif | Bin 0 -> 591 bytes doc/images/config-printer.gif | Bin 0 -> 296 bytes doc/images/continue.gif | Bin 0 -> 224 bytes doc/images/cups-bar.gif | Bin 0 -> 1242 bytes doc/images/cups-block-diagram.gif | Bin 0 -> 11637 bytes doc/images/cups-large.gif | Bin 0 -> 7457 bytes doc/images/cups-medium.gif | Bin 0 -> 3163 bytes doc/images/cups-small.gif | Bin 0 -> 1266 bytes doc/images/delete-class.gif | Bin 0 -> 259 bytes doc/images/delete-printer.gif | Bin 0 -> 267 bytes doc/images/draft.gif | Bin 0 -> 926 bytes doc/images/hold-job.gif | Bin 0 -> 228 bytes doc/images/left.gif | Bin 0 -> 110 bytes doc/images/logo.gif | Bin 0 -> 1958 bytes doc/images/manage-classes.gif | Bin 0 -> 289 bytes doc/images/manage-jobs.gif | Bin 0 -> 266 bytes doc/images/manage-printers.gif | Bin 0 -> 296 bytes doc/images/modify-class.gif | Bin 0 -> 267 bytes doc/images/modify-printer.gif | Bin 0 -> 277 bytes doc/images/navbar.gif | Bin 0 -> 2869 bytes doc/images/navbar.xcf.gz | Bin 0 -> 4253 bytes doc/images/print-test-page.gif | Bin 0 -> 288 bytes doc/images/printer-idle.gif | Bin 0 -> 706 bytes doc/images/printer-processing.gif | Bin 0 -> 805 bytes doc/images/printer-stopped.gif | Bin 0 -> 794 bytes doc/images/reject-jobs.gif | Bin 0 -> 252 bytes doc/images/release-job.gif | Bin 0 -> 255 bytes doc/images/restart-job.gif | Bin 0 -> 249 bytes doc/images/right.gif | Bin 0 -> 145 bytes doc/images/show-active.gif | Bin 0 -> 303 bytes doc/images/show-completed.gif | Bin 0 -> 337 bytes doc/images/start-class.gif | Bin 0 -> 238 bytes doc/images/start-printer.gif | Bin 0 -> 255 bytes doc/images/stop-class.gif | Bin 0 -> 245 bytes doc/images/stop-printer.gif | Bin 0 -> 252 bytes doc/index.html | 36 + doc/ipp.html | 1409 + doc/ipp.pdf | 1432 + doc/ipp.shtml | 1891 + doc/overview.html | 500 + doc/overview.pdf | Bin 0 -> 33962 bytes doc/printing-overview.shtml | 125 + doc/references.shtml | 42 + doc/sam.html | 4238 +++ doc/sam.pdf | 3294 ++ doc/sam.shtml | 3890 ++ doc/sdd.html | 590 + doc/sdd.pdf | 1024 + doc/sdd.shtml | 550 + doc/spm.html | 7254 ++++ doc/spm.pdf | 9570 +++++ doc/spm.shtml | 8051 ++++ doc/ssr.html | 270 + doc/ssr.pdf | Bin 0 -> 29096 bytes doc/ssr.shtml | 167 + doc/stp.html | 174 + doc/stp.pdf | Bin 0 -> 25064 bytes doc/stp.shtml | 47 + doc/sum.html | 1643 + doc/sum.pdf | 1299 + doc/sum.shtml | 878 + doc/svd.html | 297 + doc/svd.pdf | 546 + doc/svd.shtml | 212 + doc/system-overview.shtml | 19 + filter/Makefile | 207 + filter/common.c | 255 + filter/common.h | 67 + filter/form-main.c | 60 + filter/form-ps.c | 47 + filter/form-tree.c | 622 + filter/form.h | 175 + filter/hpgl-attr.c | 446 + filter/hpgl-char.c | 500 + filter/hpgl-config.c | 638 + filter/hpgl-input.c | 232 + filter/hpgl-main.c | 255 + filter/hpgl-polygon.c | 380 + filter/hpgl-prolog.c | 407 + filter/hpgl-vector.c | 731 + filter/hpgltops.h | 232 + filter/image-bmp.c | 499 + filter/image-colorspace.c | 882 + filter/image-gif.c | 644 + filter/image-jpeg.c | 194 + filter/image-photocd.c | 323 + filter/image-pix.c | 223 + filter/image-png.c | 250 + filter/image-pnm.c | 288 + filter/image-sgi.c | 267 + filter/image-sgi.h | 94 + filter/image-sgilib.c | 857 + filter/image-sun.c | 377 + filter/image-tiff.c | 1631 + filter/image-zoom.c | 310 + filter/image.c | 800 + filter/image.h | 231 + filter/imagetops.c | 685 + filter/imagetoraster.c | 4260 +++ filter/pstops.c | 912 + filter/raster.c | 252 + filter/raster.h | 233 + filter/rastertoepson.c | 955 + filter/rastertohp.c | 566 + filter/textcommon.c | 748 + filter/textcommon.h | 93 + filter/texttops.c | 1274 + fonts/AvantGarde-Book | Bin 0 -> 34871 bytes fonts/AvantGarde-BookOblique | Bin 0 -> 35156 bytes fonts/AvantGarde-Demi | Bin 0 -> 36354 bytes fonts/AvantGarde-DemiOblique | Bin 0 -> 36128 bytes fonts/Bookman-Demi | Bin 0 -> 44768 bytes fonts/Bookman-DemiItalic | Bin 0 -> 44950 bytes fonts/Bookman-Light | Bin 0 -> 44934 bytes fonts/Bookman-LightItalic | Bin 0 -> 44162 bytes fonts/Charter-Bold | Bin 0 -> 33799 bytes fonts/Charter-BoldItalic | Bin 0 -> 35229 bytes fonts/Charter-Italic | Bin 0 -> 35118 bytes fonts/Charter-Roman | Bin 0 -> 34869 bytes fonts/Courier | Bin 0 -> 45758 bytes fonts/Courier-Bold | Bin 0 -> 50493 bytes fonts/Courier-BoldOblique | Bin 0 -> 51527 bytes fonts/Courier-Oblique | Bin 0 -> 44404 bytes fonts/Helvetica | Bin 0 -> 36026 bytes fonts/Helvetica-Bold | Bin 0 -> 35941 bytes fonts/Helvetica-BoldOblique | Bin 0 -> 39013 bytes fonts/Helvetica-Narrow | Bin 0 -> 36615 bytes fonts/Helvetica-Narrow-Bold | Bin 0 -> 37240 bytes fonts/Helvetica-Narrow-BoldOblique | Bin 0 -> 38310 bytes fonts/Helvetica-Narrow-Oblique | Bin 0 -> 37247 bytes fonts/Helvetica-Oblique | Bin 0 -> 38314 bytes fonts/Makefile | 75 + fonts/NewCenturySchlbk-Bold | Bin 0 -> 48864 bytes fonts/NewCenturySchlbk-BoldItalic | Bin 0 -> 47083 bytes fonts/NewCenturySchlbk-Italic | Bin 0 -> 45832 bytes fonts/NewCenturySchlbk-Roman | Bin 0 -> 46830 bytes fonts/Palatino-Bold | Bin 0 -> 52406 bytes fonts/Palatino-BoldItalic | Bin 0 -> 51285 bytes fonts/Palatino-Italic | Bin 0 -> 50022 bytes fonts/Palatino-Roman | Bin 0 -> 52665 bytes fonts/Symbol | Bin 0 -> 33709 bytes fonts/Times-Bold | Bin 0 -> 44729 bytes fonts/Times-BoldItalic | Bin 0 -> 44656 bytes fonts/Times-Italic | Bin 0 -> 45458 bytes fonts/Times-Roman | Bin 0 -> 46026 bytes fonts/Utopia-Bold | Bin 0 -> 36580 bytes fonts/Utopia-BoldItalic | Bin 0 -> 37836 bytes fonts/Utopia-Italic | Bin 0 -> 37599 bytes fonts/Utopia-Regular | Bin 0 -> 36350 bytes fonts/ZapfChancery-MediumItalic | Bin 0 -> 49289 bytes fonts/ZapfDingbats | Bin 0 -> 45955 bytes locale/C/cups_C | 132 + locale/Makefile | 80 + locale/de/cups_de | 133 + locale/en/cups_en | 132 + locale/es/cups_es | 132 + locale/fr/cups_fr | 132 + locale/it/cups_it | 132 + locale/locale.txt | 32 + locale/translate.c | 259 + man/Makefile | 103 + man/accept.man | 58 + man/backend.man | 109 + man/classes.conf.man | 72 + man/cups-lpd.man | 58 + man/cups-polld.man | 46 + man/cupsd.conf.man | 246 + man/cupsd.man | 51 + man/enable.man | 65 + man/filter.man | 116 + man/lp.man | 112 + man/lpadmin.man | 125 + man/lpc.man | 80 + man/lpinfo.man | 56 + man/lpmove.man | 50 + man/lpoptions.man | 99 + man/lpq.man | 53 + man/lpr.man | 97 + man/lprm.man | 52 + man/lpstat.man | 126 + man/mime.convs.man | 54 + man/mime.types.man | 98 + man/printers.conf.man | 73 + pdftops/Array.cxx | 51 + pdftops/Array.h | 53 + pdftops/CMapInfo.h | 31364 ++++++++++++++++ pdftops/COPYING | 339 + pdftops/Catalog.cxx | 284 + pdftops/Catalog.h | 69 + pdftops/CompactFontInfo.h | 464 + pdftops/Dict.cxx | 88 + pdftops/Dict.h | 69 + pdftops/Error.cxx | 49 + pdftops/Error.h | 26 + pdftops/FontEncoding.cxx | 143 + pdftops/FontEncoding.h | 64 + pdftops/FontFile.cxx | 1620 + pdftops/FontFile.h | 117 + pdftops/FontInfo.h | 2068 + pdftops/GString.cxx | 196 + pdftops/GString.h | 92 + pdftops/Gfx.cxx | 1588 + pdftops/Gfx.h | 216 + pdftops/GfxFont.cxx | 887 + pdftops/GfxFont.h | 234 + pdftops/GfxState.cxx | 971 + pdftops/GfxState.h | 473 + pdftops/ImageOutputDev.cxx | 155 + pdftops/ImageOutputDev.h | 67 + pdftops/Lexer.cxx | 453 + pdftops/Lexer.h | 72 + pdftops/Link.cxx | 609 + pdftops/Link.h | 313 + pdftops/Makefile | 128 + pdftops/Object.cxx | 220 + pdftops/Object.h | 299 + pdftops/OutputDev.cxx | 85 + pdftops/OutputDev.h | 131 + pdftops/PDFDoc.cxx | 169 + pdftops/PDFDoc.h | 107 + pdftops/PSOutputDev.cxx | 1177 + pdftops/PSOutputDev.h | 160 + pdftops/Page.cxx | 211 + pdftops/Page.h | 111 + pdftops/Params.cxx | 87 + pdftops/Params.h | 40 + pdftops/Parser.cxx | 161 + pdftops/Parser.h | 51 + pdftops/README | 348 + pdftops/StdFontInfo.h | 546 + pdftops/Stream-CCITT.h | 459 + pdftops/Stream.cxx | 3332 ++ pdftops/Stream.h | 715 + pdftops/XRef.cxx | 443 + pdftops/XRef.h | 84 + pdftops/config.h | 46 + pdftops/configure.in | 203 + pdftops/gfile.cxx | 522 + pdftops/gfile.h | 115 + pdftops/gmem.c | 203 + pdftops/gmem.h | 53 + pdftops/gmempp.cxx | 23 + pdftops/gtypes.h | 29 + pdftops/parseargs.c | 190 + pdftops/parseargs.h | 71 + pdftops/pdftops.cxx | 144 + ppd/Makefile | 56 + ppd/deskjet.ppd | 196 + ppd/epson24.ppd | 128 + ppd/epson9.ppd | 126 + ppd/laserjet.ppd | 199 + ppd/stcolor.ppd | 132 + ppd/stphoto.ppd | 132 + pstoraster/Fontmap | 98 + pstoraster/Makefile | 427 + pstoraster/bfont.h | 76 + pstoraster/bseq.h | 66 + pstoraster/btoken.h | 41 + pstoraster/ctype_.h | 37 + pstoraster/dirent_.h | 60 + pstoraster/dstack.h | 236 + pstoraster/errno_.h | 42 + pstoraster/errors.h | 148 + pstoraster/estack.h | 139 + pstoraster/files.h | 157 + pstoraster/fname.h | 54 + pstoraster/gconf.h | 43 + pstoraster/gconfig.c | 127 + pstoraster/gconfig.h | 243 + pstoraster/gconfig_.h | 5 + pstoraster/gconfigv.h | 4 + pstoraster/gdebug.h | 132 + pstoraster/gdev8bcm.h | 78 + pstoraster/gdevabuf.c | 404 + pstoraster/gdevbbox.c | 1069 + pstoraster/gdevbbox.h | 100 + pstoraster/gdevcmap.h | 74 + pstoraster/gdevcups.c | 2518 ++ pstoraster/gdevdbit.c | 706 + pstoraster/gdevddrw.c | 635 + pstoraster/gdevdflt.c | 270 + pstoraster/gdevdgbr.c | 586 + pstoraster/gdevhit.c | 98 + pstoraster/gdevht.h | 51 + pstoraster/gdevm1.c | 759 + pstoraster/gdevm16.c | 168 + pstoraster/gdevm2.c | 259 + pstoraster/gdevm24.c | 526 + pstoraster/gdevm32.c | 249 + pstoraster/gdevm4.c | 319 + pstoraster/gdevm8.c | 247 + pstoraster/gdevmem.c | 498 + pstoraster/gdevmem.h | 233 + pstoraster/gdevmgr.h | 127 + pstoraster/gdevmpla.c | 200 + pstoraster/gdevmrop.h | 97 + pstoraster/gdevnfwd.c | 797 + pstoraster/gdevpccm.h | 44 + pstoraster/gdevpcfb.h | 209 + pstoraster/gdevpcl.h | 52 + pstoraster/gdevpipe.c | 72 + pstoraster/gdevpm.h | 46 + pstoraster/gdevprn.c | 837 + pstoraster/gdevprn.h | 560 + pstoraster/gdevprna.h | 190 + pstoraster/gdevps.c | 1151 + pstoraster/gdevpsde.c | 282 + pstoraster/gdevpsdf.c | 514 + pstoraster/gdevpsdf.h | 292 + pstoraster/gdevpsdi.c | 349 + pstoraster/gdevpsdp.c | 705 + pstoraster/gdevpsds.c | 470 + pstoraster/gdevpsds.h | 110 + pstoraster/gdevpstr.h | 90 + pstoraster/gdevpxen.h | 269 + pstoraster/gdevpxop.h | 114 + pstoraster/gdevvec.c | 905 + pstoraster/gdevvec.h | 349 + pstoraster/genarch.c | 163 + pstoraster/ghost.h | 34 + pstoraster/gp.h | 233 + pstoraster/gp_getnv.c | 60 + pstoraster/gp_nofb.c | 58 + pstoraster/gp_nsync.c | 120 + pstoraster/gp_unifn.c | 61 + pstoraster/gp_unifs.c | 440 + pstoraster/gp_unix.c | 173 + pstoraster/gpcheck.h | 65 + pstoraster/gpgetenv.h | 50 + pstoraster/gpsync.h | 81 + pstoraster/gs_btokn.ps | 313 + pstoraster/gs_ccfnt.ps | 100 + pstoraster/gs_cff.ps | 614 + pstoraster/gs_cidfn.ps | 466 + pstoraster/gs_cmap.ps | 256 + pstoraster/gs_cmdl.ps | 188 + pstoraster/gs_dbt_e.ps | 67 + pstoraster/gs_diskf.ps | 232 + pstoraster/gs_dpnxt.ps | 120 + pstoraster/gs_dps.ps | 205 + pstoraster/gs_dps1.ps | 147 + pstoraster/gs_dps2.ps | 200 + pstoraster/gs_epsf.ps | 67 + pstoraster/gs_fform.ps | 100 + pstoraster/gs_fonts.ps | 934 + pstoraster/gs_init.ps | 1521 + pstoraster/gs_iso_e.ps | 74 + pstoraster/gs_kanji.ps | 166 + pstoraster/gs_ksb_e.ps | 72 + pstoraster/gs_lev2.ps | 717 + pstoraster/gs_ll3.ps | 387 + pstoraster/gs_mex_e.ps | 72 + pstoraster/gs_mro_e.ps | 65 + pstoraster/gs_pfile.ps | 135 + pstoraster/gs_res.ps | 726 + pstoraster/gs_setpd.ps | 708 + pstoraster/gs_statd.ps | 296 + pstoraster/gs_std_e.ps | 81 + pstoraster/gs_sym_e.ps | 91 + pstoraster/gs_ttf.ps | 694 + pstoraster/gs_typ32.ps | 134 + pstoraster/gs_typ42.ps | 52 + pstoraster/gs_type1.ps | 145 + pstoraster/gs_wan_e.ps | 52 + pstoraster/gs_wl1_e.ps | 74 + pstoraster/gs_wl2_e.ps | 74 + pstoraster/gs_wl5_e.ps | 74 + pstoraster/gsalloc.c | 1621 + pstoraster/gsalloc.h | 87 + pstoraster/gsalpha.c | 48 + pstoraster/gsalpha.h | 41 + pstoraster/gsalphac.h | 71 + pstoraster/gsargs.c | 225 + pstoraster/gsargs.h | 89 + pstoraster/gsbitmap.h | 193 + pstoraster/gsbitops.c | 666 + pstoraster/gsbitops.h | 222 + pstoraster/gsbittab.c | 144 + pstoraster/gsbittab.h | 83 + pstoraster/gsccode.h | 72 + pstoraster/gsccolor.h | 58 + pstoraster/gscdefs.c | 78 + pstoraster/gscdefs.h | 81 + pstoraster/gscdevn.c | 184 + pstoraster/gschar.c | 1492 + pstoraster/gschar.h | 130 + pstoraster/gschar0.c | 407 + pstoraster/gscie.c | 1357 + pstoraster/gscie.h | 688 + pstoraster/gsclipsr.c | 45 + pstoraster/gsclipsr.h | 34 + pstoraster/gscolor.c | 357 + pstoraster/gscolor.h | 43 + pstoraster/gscolor1.c | 271 + pstoraster/gscolor1.h | 47 + pstoraster/gscolor2.c | 455 + pstoraster/gscolor2.h | 106 + pstoraster/gscolor3.c | 70 + pstoraster/gscolor3.h | 41 + pstoraster/gscompt.h | 59 + pstoraster/gscoord.c | 507 + pstoraster/gscoord.h | 55 + pstoraster/gscparam.c | 480 + pstoraster/gscpixel.c | 89 + pstoraster/gscpixel.h | 34 + pstoraster/gscpm.h | 39 + pstoraster/gscrd.c | 350 + pstoraster/gscrd.h | 75 + pstoraster/gscrdp.c | 629 + pstoraster/gscrdp.h | 104 + pstoraster/gscrypt1.h | 56 + pstoraster/gscscie.c | 374 + pstoraster/gscsel.h | 44 + pstoraster/gscsepnm.h | 54 + pstoraster/gscsepr.c | 352 + pstoraster/gscsepr.h | 74 + pstoraster/gscspace.c | 237 + pstoraster/gscspace.h | 400 + pstoraster/gsdcolor.h | 332 + pstoraster/gsdevice.c | 570 + pstoraster/gsdevice.h | 103 + pstoraster/gsdevmem.c | 236 + pstoraster/gsdll.h | 145 + pstoraster/gsdparam.c | 782 + pstoraster/gsdpnext.h | 34 + pstoraster/gsdps.h | 40 + pstoraster/gsdps1.c | 242 + pstoraster/gsdsrc.c | 121 + pstoraster/gsdsrc.h | 133 + pstoraster/gserror.h | 42 + pstoraster/gserrors.h | 56 + pstoraster/gsexit.h | 41 + pstoraster/gsfcmap.c | 167 + pstoraster/gsfcmap.h | 69 + pstoraster/gsflip.h | 46 + pstoraster/gsfont.c | 558 + pstoraster/gsfont.h | 87 + pstoraster/gsfont0.c | 136 + pstoraster/gsfunc.c | 78 + pstoraster/gsfunc.h | 136 + pstoraster/gsfunc0.c | 347 + pstoraster/gsfunc0.h | 66 + pstoraster/gsfunc3.c | 361 + pstoraster/gsfunc3.h | 114 + pstoraster/gsgc.h | 91 + pstoraster/gshsb.c | 171 + pstoraster/gshsb.h | 33 + pstoraster/gsht.c | 651 + pstoraster/gsht.h | 78 + pstoraster/gsht1.c | 449 + pstoraster/gsht1.h | 60 + pstoraster/gshtscr.c | 574 + pstoraster/gshtx.h | 158 + pstoraster/gsimage.c | 326 + pstoraster/gsimage.h | 84 + pstoraster/gsimpath.c | 191 + pstoraster/gsinit.c | 79 + pstoraster/gsio.h | 66 + pstoraster/gsiodev.c | 318 + pstoraster/gsiparam.h | 289 + pstoraster/gsiparm2.h | 63 + pstoraster/gsiparm3.h | 67 + pstoraster/gsiparm4.h | 59 + pstoraster/gsjconf.h | 81 + pstoraster/gsjmorec.h | 59 + pstoraster/gslib.h | 44 + pstoraster/gsline.c | 340 + pstoraster/gsline.h | 75 + pstoraster/gslparam.h | 52 + pstoraster/gsmalloc.c | 398 + pstoraster/gsmalloc.h | 78 + pstoraster/gsmatrix.c | 455 + pstoraster/gsmatrix.h | 80 + pstoraster/gsmdebug.h | 54 + pstoraster/gsmemlok.h | 64 + pstoraster/gsmemory.c | 196 + pstoraster/gsmemory.h | 277 + pstoraster/gsmemraw.h | 181 + pstoraster/gsmisc.c | 942 + pstoraster/gsnorop.c | 119 + pstoraster/gspaint.c | 356 + pstoraster/gspaint.h | 38 + pstoraster/gsparam.c | 382 + pstoraster/gsparam.h | 505 + pstoraster/gsparams.c | 417 + pstoraster/gsparams.h | 77 + pstoraster/gspath.c | 518 + pstoraster/gspath.h | 98 + pstoraster/gspath1.c | 480 + pstoraster/gspath2.h | 40 + pstoraster/gspcolor.c | 958 + pstoraster/gspcolor.h | 87 + pstoraster/gspenum.h | 40 + pstoraster/gspmdrv.h | 40 + pstoraster/gsptype1.h | 143 + pstoraster/gsptype2.h | 52 + pstoraster/gsrect.h | 61 + pstoraster/gsrefct.h | 148 + pstoraster/gsrop.h | 46 + pstoraster/gsropc.h | 60 + pstoraster/gsropt.h | 195 + pstoraster/gsshade.c | 451 + pstoraster/gsshade.h | 255 + pstoraster/gsstate.c | 1025 + pstoraster/gsstate.h | 81 + pstoraster/gsstruct.h | 970 + pstoraster/gstext.c | 344 + pstoraster/gstext.h | 231 + pstoraster/gstrap.c | 190 + pstoraster/gstrap.h | 81 + pstoraster/gstype1.c | 562 + pstoraster/gstype1.h | 265 + pstoraster/gstype2.c | 772 + pstoraster/gstype42.c | 481 + pstoraster/gstypes.h | 86 + pstoraster/gsuid.h | 78 + pstoraster/gsutil.c | 285 + pstoraster/gsutil.h | 67 + pstoraster/gsxfont.h | 45 + pstoraster/gx.h | 52 + pstoraster/gxacpath.c | 479 + pstoraster/gxalloc.h | 403 + pstoraster/gxalpha.h | 74 + pstoraster/gxarith.h | 84 + pstoraster/gxband.h | 70 + pstoraster/gxbcache.c | 153 + pstoraster/gxbcache.h | 130 + pstoraster/gxbitfmt.h | 195 + pstoraster/gxbitmap.h | 133 + pstoraster/gxbitops.h | 142 + pstoraster/gxccache.c | 456 + pstoraster/gxccman.c | 797 + pstoraster/gxchar.h | 190 + pstoraster/gxcht.c | 710 + pstoraster/gxcindex.h | 91 + pstoraster/gxclbits.c | 740 + pstoraster/gxcldev.h | 708 + pstoraster/gxclimag.c | 1316 + pstoraster/gxclio.h | 104 + pstoraster/gxclip.c | 582 + pstoraster/gxclip.h | 75 + pstoraster/gxclip2.c | 306 + pstoraster/gxclip2.h | 55 + pstoraster/gxclipm.c | 309 + pstoraster/gxclipm.h | 35 + pstoraster/gxclist.c | 728 + pstoraster/gxclist.h | 311 + pstoraster/gxclmem.c | 1147 + pstoraster/gxclmem.h | 155 + pstoraster/gxclpage.c | 127 + pstoraster/gxclpage.h | 63 + pstoraster/gxclpath.c | 1198 + pstoraster/gxclpath.h | 207 + pstoraster/gxclrast.c | 2331 ++ pstoraster/gxclread.c | 517 + pstoraster/gxclrect.c | 656 + pstoraster/gxclutil.c | 616 + pstoraster/gxclzlib.c | 76 + pstoraster/gxcmap.c | 890 + pstoraster/gxcmap.h | 101 + pstoraster/gxcolor2.h | 98 + pstoraster/gxcomp.h | 113 + pstoraster/gxcoord.h | 44 + pstoraster/gxcpath.c | 962 + pstoraster/gxcpath.h | 134 + pstoraster/gxcspace.h | 237 + pstoraster/gxctable.c | 146 + pstoraster/gxctable.h | 70 + pstoraster/gxcvalue.h | 48 + pstoraster/gxdcconv.c | 162 + pstoraster/gxdcconv.h | 43 + pstoraster/gxdcolor.c | 339 + pstoraster/gxdcolor.h | 199 + pstoraster/gxdda.h | 158 + pstoraster/gxdevcli.h | 877 + pstoraster/gxdevice.h | 453 + pstoraster/gxdevmem.h | 170 + pstoraster/gxdevrop.h | 35 + pstoraster/gxdht.h | 272 + pstoraster/gxdither.c | 502 + pstoraster/gxdither.h | 76 + pstoraster/gxfarith.h | 144 + pstoraster/gxfcache.h | 270 + pstoraster/gxfcmap.h | 101 + pstoraster/gxfill.c | 1543 + pstoraster/gxfixed.h | 248 + pstoraster/gxfmap.h | 105 + pstoraster/gxfont.h | 224 + pstoraster/gxfont0.h | 81 + pstoraster/gxfont1.h | 158 + pstoraster/gxfont42.h | 72 + pstoraster/gxfrac.h | 98 + pstoraster/gxftype.h | 57 + pstoraster/gxfunc.h | 56 + pstoraster/gxgetbit.h | 101 + pstoraster/gxhint1.c | 275 + pstoraster/gxhint2.c | 397 + pstoraster/gxhint3.c | 560 + pstoraster/gxht.c | 532 + pstoraster/gxht.h | 222 + pstoraster/gxhttile.h | 54 + pstoraster/gxhttype.h | 45 + pstoraster/gxi12bit.c | 300 + pstoraster/gxicolor.c | 307 + pstoraster/gxidata.c | 255 + pstoraster/gxifast.c | 716 + pstoraster/gxiinit.c | 921 + pstoraster/gximage.h | 283 + pstoraster/gximage3.c | 429 + pstoraster/gximage4.c | 297 + pstoraster/gximono.c | 586 + pstoraster/gxiodev.h | 190 + pstoraster/gxiparam.h | 172 + pstoraster/gxiscale.c | 256 + pstoraster/gxistate.h | 251 + pstoraster/gxline.h | 81 + pstoraster/gxlum.h | 50 + pstoraster/gxmatrix.h | 83 + pstoraster/gxmclip.c | 116 + pstoraster/gxmclip.h | 111 + pstoraster/gxobj.h | 230 + pstoraster/gxop1.h | 81 + pstoraster/gxp1fill.c | 374 + pstoraster/gxp1fill.h | 40 + pstoraster/gxpageq.h | 192 + pstoraster/gxpaint.c | 81 + pstoraster/gxpaint.h | 125 + pstoraster/gxpath.c | 829 + pstoraster/gxpath.h | 317 + pstoraster/gxpath2.c | 487 + pstoraster/gxpcache.h | 61 + pstoraster/gxpcmap.c | 666 + pstoraster/gxpcolor.h | 138 + pstoraster/gxpcopy.c | 824 + pstoraster/gxpdash.c | 189 + pstoraster/gxpflat.c | 455 + pstoraster/gxropc.h | 53 + pstoraster/gxsample.c | 211 + pstoraster/gxsample.h | 87 + pstoraster/gxshade.c | 348 + pstoraster/gxshade.h | 247 + pstoraster/gxshade1.c | 527 + pstoraster/gxshade4.c | 285 + pstoraster/gxshade4.h | 58 + pstoraster/gxshade6.c | 566 + pstoraster/gxstate.h | 86 + pstoraster/gxstroke.c | 1319 + pstoraster/gxsync.h | 81 + pstoraster/gxtext.h | 121 + pstoraster/gxtmap.h | 58 + pstoraster/gxtype1.c | 518 + pstoraster/gxtype1.h | 346 + pstoraster/gxxfont.h | 180 + pstoraster/gzacpath.h | 60 + pstoraster/gzcpath.h | 106 + pstoraster/gzht.h | 203 + pstoraster/gzline.h | 41 + pstoraster/gzpath.h | 385 + pstoraster/gzstate.h | 137 + pstoraster/ialloc.c | 314 + pstoraster/ialloc.h | 125 + pstoraster/iastate.h | 35 + pstoraster/iastruct.h | 34 + pstoraster/ibnum.c | 222 + pstoraster/ibnum.h | 71 + pstoraster/iccinit0.c | 31 + pstoraster/ichar.h | 72 + pstoraster/icharout.h | 59 + pstoraster/icie.h | 96 + pstoraster/icolor.h | 54 + pstoraster/iconfig.c | 74 + pstoraster/icontext.c | 275 + pstoraster/icontext.h | 59 + pstoraster/icsmap.h | 45 + pstoraster/icstate.h | 74 + pstoraster/idebug.c | 299 + pstoraster/idebug.h | 48 + pstoraster/idict.c | 780 + pstoraster/idict.h | 268 + pstoraster/idictdef.h | 128 + pstoraster/idparam.c | 371 + pstoraster/idparam.h | 90 + pstoraster/idstack.c | 249 + pstoraster/idstack.h | 125 + pstoraster/iestack.h | 56 + pstoraster/ifilter.h | 89 + pstoraster/ifont.h | 97 + pstoraster/ifunc.h | 58 + pstoraster/igc.c | 1316 + pstoraster/igc.h | 102 + pstoraster/igcref.c | 680 + pstoraster/igcstr.c | 393 + pstoraster/igcstr.h | 41 + pstoraster/igstate.h | 181 + pstoraster/iht.h | 37 + pstoraster/iimage.h | 46 + pstoraster/iimage2.h | 50 + pstoraster/iinit.c | 511 + pstoraster/ilevel.h | 39 + pstoraster/ilocate.c | 439 + pstoraster/imain.c | 664 + pstoraster/imain.h | 276 + pstoraster/imainarg.c | 849 + pstoraster/imainarg.h | 54 + pstoraster/imemory.h | 99 + pstoraster/iminst.h | 92 + pstoraster/iname.c | 637 + pstoraster/iname.h | 105 + pstoraster/inamedef.h | 230 + pstoraster/inames.h | 114 + pstoraster/interp.c | 1554 + pstoraster/interp.h | 95 + pstoraster/iostack.h | 45 + pstoraster/ipacked.h | 136 + pstoraster/iparam.c | 1080 + pstoraster/iparam.h | 118 + pstoraster/iparray.h | 42 + pstoraster/ireclaim.c | 163 + pstoraster/iref.h | 437 + pstoraster/isave.c | 1068 + pstoraster/isave.h | 133 + pstoraster/iscan.c | 1131 + pstoraster/iscan.h | 161 + pstoraster/iscanbin.c | 768 + pstoraster/iscannum.c | 398 + pstoraster/iscannum.h | 36 + pstoraster/isstate.h | 46 + pstoraster/istack.c | 588 + pstoraster/istack.h | 256 + pstoraster/istream.h | 43 + pstoraster/istruct.h | 98 + pstoraster/iutil.c | 676 + pstoraster/iutil.h | 121 + pstoraster/iutil2.c | 154 + pstoraster/iutil2.h | 56 + pstoraster/ivmspace.h | 111 + pstoraster/main.h | 101 + pstoraster/malloc_.h | 63 + pstoraster/math_.h | 97 + pstoraster/memory_.h | 107 + pstoraster/opcheck.h | 86 + pstoraster/opdef.h | 164 + pstoraster/oper.h | 108 + pstoraster/opextern.h | 115 + pstoraster/ostack.h | 94 + pstoraster/pipe_.h | 42 + pstoraster/pstoraster.c | 232 + pstoraster/sa85x.h | 51 + pstoraster/sbcp.c | 259 + pstoraster/sbhc.c | 291 + pstoraster/sbhc.h | 98 + pstoraster/sbtx.h | 45 + pstoraster/sbwbs.c | 535 + pstoraster/sbwbs.h | 78 + pstoraster/scanchar.h | 75 + pstoraster/scantab.c | 112 + pstoraster/scf.h | 213 + pstoraster/scfd.c | 809 + pstoraster/scfdtab.c | 942 + pstoraster/scfe.c | 536 + pstoraster/scfetab.c | 170 + pstoraster/scfparam.c | 99 + pstoraster/scfx.h | 132 + pstoraster/scommon.h | 173 + pstoraster/sdcparam.c | 630 + pstoraster/sdcparam.h | 57 + pstoraster/sdct.h | 121 + pstoraster/sdctc.c | 55 + pstoraster/sdctd.c | 303 + pstoraster/sdcte.c | 203 + pstoraster/sddparam.c | 83 + pstoraster/sdeparam.c | 328 + pstoraster/seexec.c | 192 + pstoraster/sfilter.h | 139 + pstoraster/sfilter1.c | 301 + pstoraster/sfilter2.c | 339 + pstoraster/sfxstdio.c | 269 + pstoraster/shc.c | 74 + pstoraster/shc.h | 254 + pstoraster/shcgen.c | 491 + pstoraster/shcgen.h | 60 + pstoraster/siscale.c | 498 + pstoraster/siscale.h | 148 + pstoraster/sjpeg.h | 80 + pstoraster/sjpegc.c | 305 + pstoraster/sjpegd.c | 100 + pstoraster/sjpege.c | 129 + pstoraster/sjpegerr.c | 102 + pstoraster/slzwc.c | 50 + pstoraster/slzwce.c | 167 + pstoraster/slzwd.c | 372 + pstoraster/slzwx.h | 80 + pstoraster/smtf.c | 184 + pstoraster/smtf.h | 49 + pstoraster/spcxd.c | 75 + pstoraster/spcxx.h | 35 + pstoraster/spdiff.c | 334 + pstoraster/spdiffx.h | 55 + pstoraster/spngp.c | 364 + pstoraster/spngpx.h | 61 + pstoraster/srld.c | 133 + pstoraster/srle.c | 203 + pstoraster/srlx.h | 77 + pstoraster/sstring.c | 464 + pstoraster/sstring.h | 79 + pstoraster/stat_.h | 62 + pstoraster/std.h | 261 + pstoraster/stdio_.h | 74 + pstoraster/stdpre.h | 413 + pstoraster/store.h | 250 + pstoraster/stream.c | 911 + pstoraster/stream.h | 334 + pstoraster/strimpl.h | 154 + pstoraster/string_.h | 59 + pstoraster/szlibc.c | 140 + pstoraster/szlibd.c | 115 + pstoraster/szlibe.c | 112 + pstoraster/szlibx.h | 64 + pstoraster/szlibxx.h | 73 + pstoraster/time_.h | 70 + pstoraster/vmsmath.h | 49 + pstoraster/zarith.c | 373 + pstoraster/zarray.c | 131 + pstoraster/zbseq.c | 136 + pstoraster/zcfont.c | 164 + pstoraster/zchar.c | 710 + pstoraster/zchar1.c | 763 + pstoraster/zchar2.c | 228 + pstoraster/zchar32.c | 217 + pstoraster/zchar42.c | 184 + pstoraster/zcharout.c | 241 + pstoraster/zcid.c | 102 + pstoraster/zcie.c | 731 + pstoraster/zcolor.c | 241 + pstoraster/zcolor1.c | 247 + pstoraster/zcolor2.c | 191 + pstoraster/zcontrol.c | 897 + pstoraster/zcrd.c | 438 + pstoraster/zcsdevn.c | 119 + pstoraster/zcsindex.c | 239 + pstoraster/zcspixel.c | 73 + pstoraster/zcssepr.c | 186 + pstoraster/zdevcal.c | 79 + pstoraster/zdevice.c | 445 + pstoraster/zdevice2.c | 373 + pstoraster/zdict.c | 515 + pstoraster/zdps1.c | 459 + pstoraster/zfbcp.c | 99 + pstoraster/zfcmap.c | 355 + pstoraster/zfdctd.c | 110 + pstoraster/zfdcte.c | 157 + pstoraster/zfdecode.c | 363 + pstoraster/zfile.c | 915 + pstoraster/zfileio.c | 842 + pstoraster/zfilter.c | 418 + pstoraster/zfilter2.c | 165 + pstoraster/zfilterx.c | 336 + pstoraster/zfname.c | 116 + pstoraster/zfont.c | 471 + pstoraster/zfont0.c | 346 + pstoraster/zfont1.c | 291 + pstoraster/zfont2.c | 553 + pstoraster/zfont32.c | 79 + pstoraster/zfont42.c | 189 + pstoraster/zfproc.c | 363 + pstoraster/zfreuse.c | 206 + pstoraster/zfunc.c | 235 + pstoraster/zfunc0.c | 113 + pstoraster/zfunc3.c | 136 + pstoraster/zfzlib.c | 105 + pstoraster/zgeneric.c | 528 + pstoraster/zgstate.c | 450 + pstoraster/zhsb.c | 68 + pstoraster/zht.c | 265 + pstoraster/zht1.c | 156 + pstoraster/zht2.c | 357 + pstoraster/zimage.c | 490 + pstoraster/zimage2.c | 158 + pstoraster/zimage3.c | 139 + pstoraster/ziodev.c | 475 + pstoraster/ziodev2.c | 148 + pstoraster/zmath.c | 277 + pstoraster/zmatrix.c | 358 + pstoraster/zmedia2.c | 472 + pstoraster/zmisc.c | 345 + pstoraster/zmisc1.c | 157 + pstoraster/zmisc2.c | 322 + pstoraster/zmisc3.c | 129 + pstoraster/zpacked.c | 258 + pstoraster/zpaint.c | 92 + pstoraster/zpath.c | 205 + pstoraster/zpath1.c | 279 + pstoraster/zpcolor.c | 264 + pstoraster/zrelbit.c | 342 + pstoraster/zshade.c | 599 + pstoraster/zstack.c | 295 + pstoraster/zstring.c | 172 + pstoraster/zsysvm.c | 164 + pstoraster/ztoken.c | 241 + pstoraster/ztrap.c | 72 + pstoraster/ztype.c | 510 + pstoraster/zupath.c | 673 + pstoraster/zusparam.c | 655 + pstoraster/zvmem.c | 404 + pstoraster/zvmem2.c | 153 + scheduler/Makefile | 149 + scheduler/auth.c | 904 + scheduler/auth.h | 117 + scheduler/banners.c | 217 + scheduler/banners.h | 58 + scheduler/cert.c | 250 + scheduler/cert.h | 60 + scheduler/classes.c | 553 + scheduler/classes.h | 43 + scheduler/client.c | 1785 + scheduler/client.h | 98 + scheduler/conf.c | 1399 + scheduler/conf.h | 121 + scheduler/cups-lpd.c | 1097 + scheduler/cups-polld.c | 308 + scheduler/cups.pam | 2 + scheduler/cupsd.dsp | 173 + scheduler/cupsd.h | 175 + scheduler/devices.c | 470 + scheduler/dirsvc.c | 790 + scheduler/dirsvc.h | 96 + scheduler/filter.c | 301 + scheduler/ipp.c | 5011 +++ scheduler/job.c | 2572 ++ scheduler/job.h | 91 + scheduler/listen.c | 142 + scheduler/log.c | 464 + scheduler/main.c | 617 + scheduler/mime.c | 553 + scheduler/mime.h | 139 + scheduler/ppds.c | 641 + scheduler/printers.c | 1415 + scheduler/printers.h | 84 + scheduler/testmime.c | 199 + scheduler/testspeed.c | 126 + scheduler/type.c | 1065 + standards/draft-ietf-ipp-collection-02.txt | 1666 + ...-ietf-ipp-finishings-fold-trim-bale-00.txt | 585 + ...aft-ietf-ipp-implementers-guide-v11-01.txt | 4929 +++ standards/draft-ietf-ipp-indp-00.txt | 2170 ++ standards/draft-ietf-ipp-indp-method-00.txt | 729 + .../draft-ietf-ipp-job-printer-set-ops-02.txt | 3342 ++ .../draft-ietf-ipp-ldap-printer-schema-01.txt | 1403 + standards/draft-ietf-ipp-model-v11-07.txt | 13015 +++++++ standards/draft-ietf-ipp-not-04.txt | 5 + .../draft-ietf-ipp-not-http-delivery-00.txt | 743 + standards/draft-ietf-ipp-not-over-snmp-02.txt | 1770 + standards/draft-ietf-ipp-not-spec-02.txt | 4560 +++ standards/draft-ietf-ipp-notify-mailto-00.txt | 1043 + standards/draft-ietf-ipp-notify-poll-00.txt | 1034 + standards/draft-ietf-ipp-ops-set2-00.txt | 3100 ++ standards/draft-ietf-ipp-protocol-v11-06.txt | 2577 ++ standards/rfc1179.txt | 787 + standards/rfc1321.txt | 1179 + standards/rfc2246.txt | 4483 +++ standards/rfc2396.txt | 2243 ++ standards/rfc2487.txt | 451 + standards/rfc2565.txt | 2075 + standards/rfc2566.txt | 9691 +++++ standards/rfc2567.txt | 2411 ++ standards/rfc2568.txt | 563 + standards/rfc2569.txt | 1571 + standards/rfc2595.txt | 843 + standards/rfc2616.txt | 9859 +++++ standards/rfc2617.txt | 1907 + standards/rfc2639.txt | 3587 ++ standards/rfc2712.txt | 395 + standards/rfc2817.txt | 731 + standards/rfc2818.txt | 395 + systemv/Makefile | 181 + systemv/accept.c | 293 + systemv/cancel.c | 236 + systemv/lp.c | 352 + systemv/lpadmin.c | 1470 + systemv/lpinfo.c | 430 + systemv/lpmove.c | 215 + systemv/lpoptions.c | 308 + systemv/lppasswd.c | 417 + systemv/lpstat.c | 1644 + templates/Makefile | 102 + templates/add-class.tmpl | 33 + templates/add-printer.tmpl | 33 + templates/admin-op.tmpl | 1 + templates/admin.tmpl | 57 + templates/choose-device.tmpl | 32 + templates/choose-make.tmpl | 35 + templates/choose-members.tmpl | 30 + templates/choose-model.tmpl | 35 + templates/choose-serial.tmpl | 55 + templates/choose-uri.tmpl | 41 + templates/class-added.tmpl | 2 + templates/class-confirm.tmpl | 6 + templates/class-deleted.tmpl | 1 + templates/class-modified.tmpl | 2 + templates/classes.tmpl | 50 + templates/config-printer.tmpl | 6 + templates/config-printer2.tmpl | 2 + templates/error.tmpl | 3 + templates/header.tmpl | 20 + templates/job-cancel.tmpl | 1 + templates/job-hold.tmpl | 1 + templates/job-release.tmpl | 1 + templates/job-restart.tmpl | 1 + templates/jobs.tmpl | 55 + templates/modify-class.tmpl | 34 + templates/modify-printer.tmpl | 36 + templates/option-boolean.tmpl | 7 + templates/option-header.tmpl | 8 + templates/option-pickmany.tmpl | 7 + templates/option-pickone.tmpl | 7 + templates/option-trailer.tmpl | 8 + templates/printer-accept.tmpl | 1 + templates/printer-added.tmpl | 2 + templates/printer-configured.tmpl | 2 + templates/printer-confirm.tmpl | 6 + templates/printer-deleted.tmpl | 1 + templates/printer-modified.tmpl | 2 + templates/printer-reject.tmpl | 1 + templates/printer-start.tmpl | 2 + templates/printer-stop.tmpl | 2 + templates/printers.tmpl | 56 + templates/test-page.tmpl | 2 + templates/trailer.tmpl | 7 + test/Makefile | 63 + test/create-job-format.test | 56 + test/create-job-sheets.test | 55 + test/create-job-timeout.test | 55 + test/create-job.test | 54 + test/get-job-attributes.test | 80 + test/get-job-attributes2.test | 28 + test/get-printer-attributes.test | 44 + test/ipptest.c | 754 + test/print-job-hold.test | 33 + test/print-job.test | 32 + visualc/config.h | 114 + 1167 files changed, 465561 insertions(+) create mode 100644 CHANGES.txt create mode 100644 CREDITS.txt create mode 100644 LICENSE.html create mode 100644 Makedefs.in create mode 100644 Makefile create mode 100644 README.txt create mode 100644 backend/Makefile create mode 100644 backend/betest.c create mode 100644 backend/ipp.c create mode 100644 backend/lpd.c create mode 100644 backend/parallel.c create mode 100644 backend/serial.c create mode 100644 backend/socket.c create mode 100644 backend/usb.c create mode 100644 berkeley/Makefile create mode 100644 berkeley/lpc.c create mode 100644 berkeley/lpq.c create mode 100644 berkeley/lpr.c create mode 100644 berkeley/lprm.c create mode 100644 cgi-bin/Makefile create mode 100644 cgi-bin/admin.c create mode 100644 cgi-bin/cgi.h create mode 100644 cgi-bin/classes.c create mode 100644 cgi-bin/html.c create mode 100644 cgi-bin/ipp-var.c create mode 100644 cgi-bin/ipp-var.h create mode 100644 cgi-bin/jobs.c create mode 100644 cgi-bin/printers.c create mode 100644 cgi-bin/template.c create mode 100644 cgi-bin/var.c create mode 100644 conf/Makefile create mode 100644 conf/classes.conf create mode 100644 conf/client.conf create mode 100644 conf/cupsd.conf create mode 100644 conf/mime.convs create mode 100644 conf/mime.types create mode 100644 conf/printcap create mode 100644 conf/printers.conf create mode 100644 config.h.in create mode 100644 configure.in create mode 100644 cups.dsw create mode 100644 cups.list create mode 100755 cups.sh.in create mode 100644 cups.spec create mode 100644 cups/Makefile create mode 100644 cups/cups.dsp create mode 100644 cups/cups.h create mode 100644 cups/cups_C.h create mode 100644 cups/debug.h create mode 100644 cups/dest.c create mode 100644 cups/emit.c create mode 100644 cups/http.c create mode 100644 cups/http.h create mode 100644 cups/ipp.c create mode 100644 cups/ipp.h create mode 100644 cups/language.c create mode 100644 cups/language.h create mode 100644 cups/mark.c create mode 100644 cups/md5.c create mode 100644 cups/md5.h create mode 100644 cups/md5passwd.c create mode 100644 cups/options.c create mode 100644 cups/page.c create mode 100644 cups/ppd.c create mode 100644 cups/ppd.h create mode 100644 cups/snprintf.c create mode 100644 cups/string.c create mode 100644 cups/string.h create mode 100644 cups/testhttp.c create mode 100644 cups/testmime.dsp create mode 100644 cups/testppd.c create mode 100644 cups/testppd.dsp create mode 100644 cups/usersys.c create mode 100644 cups/util.c create mode 100644 data/HPGLprolog create mode 100644 data/Makefile create mode 100644 data/classified create mode 100644 data/confidential create mode 100644 data/cups.pam create mode 100644 data/iso-8859-1 create mode 100644 data/iso-8859-10 create mode 100644 data/iso-8859-13 create mode 100644 data/iso-8859-14 create mode 100644 data/iso-8859-15 create mode 100644 data/iso-8859-2 create mode 100644 data/iso-8859-3 create mode 100644 data/iso-8859-4 create mode 100644 data/iso-8859-5 create mode 100644 data/iso-8859-6 create mode 100644 data/iso-8859-7 create mode 100644 data/iso-8859-8 create mode 100644 data/iso-8859-9 create mode 100644 data/psglyphs create mode 100644 data/secret create mode 100644 data/standard create mode 100644 data/testprint.ps create mode 100644 data/topsecret create mode 100644 data/unclassified create mode 100644 data/utf-8 create mode 100644 data/windows-1250 create mode 100644 data/windows-1251 create mode 100644 data/windows-1252 create mode 100644 data/windows-1253 create mode 100644 data/windows-1254 create mode 100644 data/windows-1255 create mode 100644 data/windows-1256 create mode 100644 data/windows-1257 create mode 100644 data/windows-1258 create mode 100644 data/windows-874 create mode 100644 doc/Makefile create mode 100644 doc/cmp.html create mode 100644 doc/cmp.pdf create mode 100644 doc/cmp.shtml create mode 100644 doc/cups.css create mode 100644 doc/cupsdoc.css create mode 100644 doc/documentation.html create mode 100644 doc/figures.sc create mode 100644 doc/glossary.shtml create mode 100644 doc/idd.html create mode 100644 doc/idd.pdf create mode 100644 doc/idd.shtml create mode 100644 doc/images/accept-jobs.gif create mode 100644 doc/images/add-class.gif create mode 100644 doc/images/add-printer.gif create mode 100644 doc/images/cancel-job.gif create mode 100644 doc/images/cancel-jobs.gif create mode 100644 doc/images/cancel.gif create mode 100644 doc/images/classes.gif create mode 100644 doc/images/config-printer.gif create mode 100644 doc/images/continue.gif create mode 100644 doc/images/cups-bar.gif create mode 100644 doc/images/cups-block-diagram.gif create mode 100644 doc/images/cups-large.gif create mode 100644 doc/images/cups-medium.gif create mode 100644 doc/images/cups-small.gif create mode 100644 doc/images/delete-class.gif create mode 100644 doc/images/delete-printer.gif create mode 100644 doc/images/draft.gif create mode 100644 doc/images/hold-job.gif create mode 100644 doc/images/left.gif create mode 100644 doc/images/logo.gif create mode 100644 doc/images/manage-classes.gif create mode 100644 doc/images/manage-jobs.gif create mode 100644 doc/images/manage-printers.gif create mode 100644 doc/images/modify-class.gif create mode 100644 doc/images/modify-printer.gif create mode 100644 doc/images/navbar.gif create mode 100644 doc/images/navbar.xcf.gz create mode 100644 doc/images/print-test-page.gif create mode 100644 doc/images/printer-idle.gif create mode 100644 doc/images/printer-processing.gif create mode 100644 doc/images/printer-stopped.gif create mode 100644 doc/images/reject-jobs.gif create mode 100644 doc/images/release-job.gif create mode 100644 doc/images/restart-job.gif create mode 100644 doc/images/right.gif create mode 100644 doc/images/show-active.gif create mode 100644 doc/images/show-completed.gif create mode 100644 doc/images/start-class.gif create mode 100644 doc/images/start-printer.gif create mode 100644 doc/images/stop-class.gif create mode 100644 doc/images/stop-printer.gif create mode 100644 doc/index.html create mode 100644 doc/ipp.html create mode 100644 doc/ipp.pdf create mode 100644 doc/ipp.shtml create mode 100644 doc/overview.html create mode 100644 doc/overview.pdf create mode 100644 doc/printing-overview.shtml create mode 100644 doc/references.shtml create mode 100644 doc/sam.html create mode 100644 doc/sam.pdf create mode 100644 doc/sam.shtml create mode 100644 doc/sdd.html create mode 100644 doc/sdd.pdf create mode 100644 doc/sdd.shtml create mode 100644 doc/spm.html create mode 100644 doc/spm.pdf create mode 100644 doc/spm.shtml create mode 100644 doc/ssr.html create mode 100644 doc/ssr.pdf create mode 100644 doc/ssr.shtml create mode 100644 doc/stp.html create mode 100644 doc/stp.pdf create mode 100644 doc/stp.shtml create mode 100644 doc/sum.html create mode 100644 doc/sum.pdf create mode 100644 doc/sum.shtml create mode 100644 doc/svd.html create mode 100644 doc/svd.pdf create mode 100644 doc/svd.shtml create mode 100644 doc/system-overview.shtml create mode 100644 filter/Makefile create mode 100644 filter/common.c create mode 100644 filter/common.h create mode 100644 filter/form-main.c create mode 100644 filter/form-ps.c create mode 100644 filter/form-tree.c create mode 100644 filter/form.h create mode 100644 filter/hpgl-attr.c create mode 100644 filter/hpgl-char.c create mode 100644 filter/hpgl-config.c create mode 100644 filter/hpgl-input.c create mode 100644 filter/hpgl-main.c create mode 100644 filter/hpgl-polygon.c create mode 100644 filter/hpgl-prolog.c create mode 100644 filter/hpgl-vector.c create mode 100644 filter/hpgltops.h create mode 100644 filter/image-bmp.c create mode 100644 filter/image-colorspace.c create mode 100644 filter/image-gif.c create mode 100644 filter/image-jpeg.c create mode 100644 filter/image-photocd.c create mode 100644 filter/image-pix.c create mode 100644 filter/image-png.c create mode 100644 filter/image-pnm.c create mode 100644 filter/image-sgi.c create mode 100644 filter/image-sgi.h create mode 100644 filter/image-sgilib.c create mode 100644 filter/image-sun.c create mode 100644 filter/image-tiff.c create mode 100644 filter/image-zoom.c create mode 100644 filter/image.c create mode 100644 filter/image.h create mode 100644 filter/imagetops.c create mode 100644 filter/imagetoraster.c create mode 100644 filter/pstops.c create mode 100644 filter/raster.c create mode 100644 filter/raster.h create mode 100644 filter/rastertoepson.c create mode 100644 filter/rastertohp.c create mode 100644 filter/textcommon.c create mode 100644 filter/textcommon.h create mode 100644 filter/texttops.c create mode 100644 fonts/AvantGarde-Book create mode 100644 fonts/AvantGarde-BookOblique create mode 100644 fonts/AvantGarde-Demi create mode 100644 fonts/AvantGarde-DemiOblique create mode 100644 fonts/Bookman-Demi create mode 100644 fonts/Bookman-DemiItalic create mode 100644 fonts/Bookman-Light create mode 100644 fonts/Bookman-LightItalic create mode 100644 fonts/Charter-Bold create mode 100644 fonts/Charter-BoldItalic create mode 100644 fonts/Charter-Italic create mode 100644 fonts/Charter-Roman create mode 100644 fonts/Courier create mode 100644 fonts/Courier-Bold create mode 100644 fonts/Courier-BoldOblique create mode 100644 fonts/Courier-Oblique create mode 100644 fonts/Helvetica create mode 100644 fonts/Helvetica-Bold create mode 100644 fonts/Helvetica-BoldOblique create mode 100644 fonts/Helvetica-Narrow create mode 100644 fonts/Helvetica-Narrow-Bold create mode 100644 fonts/Helvetica-Narrow-BoldOblique create mode 100644 fonts/Helvetica-Narrow-Oblique create mode 100644 fonts/Helvetica-Oblique create mode 100644 fonts/Makefile create mode 100644 fonts/NewCenturySchlbk-Bold create mode 100644 fonts/NewCenturySchlbk-BoldItalic create mode 100644 fonts/NewCenturySchlbk-Italic create mode 100644 fonts/NewCenturySchlbk-Roman create mode 100644 fonts/Palatino-Bold create mode 100644 fonts/Palatino-BoldItalic create mode 100644 fonts/Palatino-Italic create mode 100644 fonts/Palatino-Roman create mode 100644 fonts/Symbol create mode 100644 fonts/Times-Bold create mode 100644 fonts/Times-BoldItalic create mode 100644 fonts/Times-Italic create mode 100644 fonts/Times-Roman create mode 100644 fonts/Utopia-Bold create mode 100644 fonts/Utopia-BoldItalic create mode 100644 fonts/Utopia-Italic create mode 100644 fonts/Utopia-Regular create mode 100644 fonts/ZapfChancery-MediumItalic create mode 100644 fonts/ZapfDingbats create mode 100644 locale/C/cups_C create mode 100644 locale/Makefile create mode 100644 locale/de/cups_de create mode 100644 locale/en/cups_en create mode 100644 locale/es/cups_es create mode 100644 locale/fr/cups_fr create mode 100644 locale/it/cups_it create mode 100644 locale/locale.txt create mode 100644 locale/translate.c create mode 100644 man/Makefile create mode 100644 man/accept.man create mode 100644 man/backend.man create mode 100644 man/classes.conf.man create mode 100644 man/cups-lpd.man create mode 100644 man/cups-polld.man create mode 100644 man/cupsd.conf.man create mode 100644 man/cupsd.man create mode 100644 man/enable.man create mode 100644 man/filter.man create mode 100644 man/lp.man create mode 100644 man/lpadmin.man create mode 100644 man/lpc.man create mode 100644 man/lpinfo.man create mode 100644 man/lpmove.man create mode 100644 man/lpoptions.man create mode 100644 man/lpq.man create mode 100644 man/lpr.man create mode 100644 man/lprm.man create mode 100644 man/lpstat.man create mode 100644 man/mime.convs.man create mode 100644 man/mime.types.man create mode 100644 man/printers.conf.man create mode 100644 pdftops/Array.cxx create mode 100644 pdftops/Array.h create mode 100644 pdftops/CMapInfo.h create mode 100644 pdftops/COPYING create mode 100644 pdftops/Catalog.cxx create mode 100644 pdftops/Catalog.h create mode 100644 pdftops/CompactFontInfo.h create mode 100644 pdftops/Dict.cxx create mode 100644 pdftops/Dict.h create mode 100644 pdftops/Error.cxx create mode 100644 pdftops/Error.h create mode 100644 pdftops/FontEncoding.cxx create mode 100644 pdftops/FontEncoding.h create mode 100644 pdftops/FontFile.cxx create mode 100644 pdftops/FontFile.h create mode 100644 pdftops/FontInfo.h create mode 100644 pdftops/GString.cxx create mode 100644 pdftops/GString.h create mode 100644 pdftops/Gfx.cxx create mode 100644 pdftops/Gfx.h create mode 100644 pdftops/GfxFont.cxx create mode 100644 pdftops/GfxFont.h create mode 100644 pdftops/GfxState.cxx create mode 100644 pdftops/GfxState.h create mode 100644 pdftops/ImageOutputDev.cxx create mode 100644 pdftops/ImageOutputDev.h create mode 100644 pdftops/Lexer.cxx create mode 100644 pdftops/Lexer.h create mode 100644 pdftops/Link.cxx create mode 100644 pdftops/Link.h create mode 100644 pdftops/Makefile create mode 100644 pdftops/Object.cxx create mode 100644 pdftops/Object.h create mode 100644 pdftops/OutputDev.cxx create mode 100644 pdftops/OutputDev.h create mode 100644 pdftops/PDFDoc.cxx create mode 100644 pdftops/PDFDoc.h create mode 100644 pdftops/PSOutputDev.cxx create mode 100644 pdftops/PSOutputDev.h create mode 100644 pdftops/Page.cxx create mode 100644 pdftops/Page.h create mode 100644 pdftops/Params.cxx create mode 100644 pdftops/Params.h create mode 100644 pdftops/Parser.cxx create mode 100644 pdftops/Parser.h create mode 100644 pdftops/README create mode 100644 pdftops/StdFontInfo.h create mode 100644 pdftops/Stream-CCITT.h create mode 100644 pdftops/Stream.cxx create mode 100644 pdftops/Stream.h create mode 100644 pdftops/XRef.cxx create mode 100644 pdftops/XRef.h create mode 100644 pdftops/config.h create mode 100644 pdftops/configure.in create mode 100644 pdftops/gfile.cxx create mode 100644 pdftops/gfile.h create mode 100644 pdftops/gmem.c create mode 100644 pdftops/gmem.h create mode 100644 pdftops/gmempp.cxx create mode 100644 pdftops/gtypes.h create mode 100644 pdftops/parseargs.c create mode 100644 pdftops/parseargs.h create mode 100644 pdftops/pdftops.cxx create mode 100644 ppd/Makefile create mode 100644 ppd/deskjet.ppd create mode 100644 ppd/epson24.ppd create mode 100644 ppd/epson9.ppd create mode 100644 ppd/laserjet.ppd create mode 100644 ppd/stcolor.ppd create mode 100644 ppd/stphoto.ppd create mode 100644 pstoraster/Fontmap create mode 100644 pstoraster/Makefile create mode 100644 pstoraster/bfont.h create mode 100644 pstoraster/bseq.h create mode 100644 pstoraster/btoken.h create mode 100644 pstoraster/ctype_.h create mode 100644 pstoraster/dirent_.h create mode 100644 pstoraster/dstack.h create mode 100644 pstoraster/errno_.h create mode 100644 pstoraster/errors.h create mode 100644 pstoraster/estack.h create mode 100644 pstoraster/files.h create mode 100644 pstoraster/fname.h create mode 100644 pstoraster/gconf.h create mode 100644 pstoraster/gconfig.c create mode 100644 pstoraster/gconfig.h create mode 100644 pstoraster/gconfig_.h create mode 100644 pstoraster/gconfigv.h create mode 100644 pstoraster/gdebug.h create mode 100644 pstoraster/gdev8bcm.h create mode 100644 pstoraster/gdevabuf.c create mode 100644 pstoraster/gdevbbox.c create mode 100644 pstoraster/gdevbbox.h create mode 100644 pstoraster/gdevcmap.h create mode 100644 pstoraster/gdevcups.c create mode 100644 pstoraster/gdevdbit.c create mode 100644 pstoraster/gdevddrw.c create mode 100644 pstoraster/gdevdflt.c create mode 100644 pstoraster/gdevdgbr.c create mode 100644 pstoraster/gdevhit.c create mode 100644 pstoraster/gdevht.h create mode 100644 pstoraster/gdevm1.c create mode 100644 pstoraster/gdevm16.c create mode 100644 pstoraster/gdevm2.c create mode 100644 pstoraster/gdevm24.c create mode 100644 pstoraster/gdevm32.c create mode 100644 pstoraster/gdevm4.c create mode 100644 pstoraster/gdevm8.c create mode 100644 pstoraster/gdevmem.c create mode 100644 pstoraster/gdevmem.h create mode 100644 pstoraster/gdevmgr.h create mode 100644 pstoraster/gdevmpla.c create mode 100644 pstoraster/gdevmrop.h create mode 100644 pstoraster/gdevnfwd.c create mode 100644 pstoraster/gdevpccm.h create mode 100644 pstoraster/gdevpcfb.h create mode 100644 pstoraster/gdevpcl.h create mode 100644 pstoraster/gdevpipe.c create mode 100644 pstoraster/gdevpm.h create mode 100644 pstoraster/gdevprn.c create mode 100644 pstoraster/gdevprn.h create mode 100644 pstoraster/gdevprna.h create mode 100644 pstoraster/gdevps.c create mode 100644 pstoraster/gdevpsde.c create mode 100644 pstoraster/gdevpsdf.c create mode 100644 pstoraster/gdevpsdf.h create mode 100644 pstoraster/gdevpsdi.c create mode 100644 pstoraster/gdevpsdp.c create mode 100644 pstoraster/gdevpsds.c create mode 100644 pstoraster/gdevpsds.h create mode 100644 pstoraster/gdevpstr.h create mode 100644 pstoraster/gdevpxen.h create mode 100644 pstoraster/gdevpxop.h create mode 100644 pstoraster/gdevvec.c create mode 100644 pstoraster/gdevvec.h create mode 100644 pstoraster/genarch.c create mode 100644 pstoraster/ghost.h create mode 100644 pstoraster/gp.h create mode 100644 pstoraster/gp_getnv.c create mode 100644 pstoraster/gp_nofb.c create mode 100644 pstoraster/gp_nsync.c create mode 100644 pstoraster/gp_unifn.c create mode 100644 pstoraster/gp_unifs.c create mode 100644 pstoraster/gp_unix.c create mode 100644 pstoraster/gpcheck.h create mode 100644 pstoraster/gpgetenv.h create mode 100644 pstoraster/gpsync.h create mode 100644 pstoraster/gs_btokn.ps create mode 100644 pstoraster/gs_ccfnt.ps create mode 100644 pstoraster/gs_cff.ps create mode 100644 pstoraster/gs_cidfn.ps create mode 100644 pstoraster/gs_cmap.ps create mode 100644 pstoraster/gs_cmdl.ps create mode 100644 pstoraster/gs_dbt_e.ps create mode 100644 pstoraster/gs_diskf.ps create mode 100644 pstoraster/gs_dpnxt.ps create mode 100644 pstoraster/gs_dps.ps create mode 100644 pstoraster/gs_dps1.ps create mode 100644 pstoraster/gs_dps2.ps create mode 100644 pstoraster/gs_epsf.ps create mode 100644 pstoraster/gs_fform.ps create mode 100644 pstoraster/gs_fonts.ps create mode 100644 pstoraster/gs_init.ps create mode 100644 pstoraster/gs_iso_e.ps create mode 100644 pstoraster/gs_kanji.ps create mode 100644 pstoraster/gs_ksb_e.ps create mode 100644 pstoraster/gs_lev2.ps create mode 100644 pstoraster/gs_ll3.ps create mode 100644 pstoraster/gs_mex_e.ps create mode 100644 pstoraster/gs_mro_e.ps create mode 100644 pstoraster/gs_pfile.ps create mode 100644 pstoraster/gs_res.ps create mode 100644 pstoraster/gs_setpd.ps create mode 100644 pstoraster/gs_statd.ps create mode 100644 pstoraster/gs_std_e.ps create mode 100644 pstoraster/gs_sym_e.ps create mode 100644 pstoraster/gs_ttf.ps create mode 100644 pstoraster/gs_typ32.ps create mode 100644 pstoraster/gs_typ42.ps create mode 100644 pstoraster/gs_type1.ps create mode 100644 pstoraster/gs_wan_e.ps create mode 100644 pstoraster/gs_wl1_e.ps create mode 100644 pstoraster/gs_wl2_e.ps create mode 100644 pstoraster/gs_wl5_e.ps create mode 100644 pstoraster/gsalloc.c create mode 100644 pstoraster/gsalloc.h create mode 100644 pstoraster/gsalpha.c create mode 100644 pstoraster/gsalpha.h create mode 100644 pstoraster/gsalphac.h create mode 100644 pstoraster/gsargs.c create mode 100644 pstoraster/gsargs.h create mode 100644 pstoraster/gsbitmap.h create mode 100644 pstoraster/gsbitops.c create mode 100644 pstoraster/gsbitops.h create mode 100644 pstoraster/gsbittab.c create mode 100644 pstoraster/gsbittab.h create mode 100644 pstoraster/gsccode.h create mode 100644 pstoraster/gsccolor.h create mode 100644 pstoraster/gscdefs.c create mode 100644 pstoraster/gscdefs.h create mode 100644 pstoraster/gscdevn.c create mode 100644 pstoraster/gschar.c create mode 100644 pstoraster/gschar.h create mode 100644 pstoraster/gschar0.c create mode 100644 pstoraster/gscie.c create mode 100644 pstoraster/gscie.h create mode 100644 pstoraster/gsclipsr.c create mode 100644 pstoraster/gsclipsr.h create mode 100644 pstoraster/gscolor.c create mode 100644 pstoraster/gscolor.h create mode 100644 pstoraster/gscolor1.c create mode 100644 pstoraster/gscolor1.h create mode 100644 pstoraster/gscolor2.c create mode 100644 pstoraster/gscolor2.h create mode 100644 pstoraster/gscolor3.c create mode 100644 pstoraster/gscolor3.h create mode 100644 pstoraster/gscompt.h create mode 100644 pstoraster/gscoord.c create mode 100644 pstoraster/gscoord.h create mode 100644 pstoraster/gscparam.c create mode 100644 pstoraster/gscpixel.c create mode 100644 pstoraster/gscpixel.h create mode 100644 pstoraster/gscpm.h create mode 100644 pstoraster/gscrd.c create mode 100644 pstoraster/gscrd.h create mode 100644 pstoraster/gscrdp.c create mode 100644 pstoraster/gscrdp.h create mode 100644 pstoraster/gscrypt1.h create mode 100644 pstoraster/gscscie.c create mode 100644 pstoraster/gscsel.h create mode 100644 pstoraster/gscsepnm.h create mode 100644 pstoraster/gscsepr.c create mode 100644 pstoraster/gscsepr.h create mode 100644 pstoraster/gscspace.c create mode 100644 pstoraster/gscspace.h create mode 100644 pstoraster/gsdcolor.h create mode 100644 pstoraster/gsdevice.c create mode 100644 pstoraster/gsdevice.h create mode 100644 pstoraster/gsdevmem.c create mode 100644 pstoraster/gsdll.h create mode 100644 pstoraster/gsdparam.c create mode 100644 pstoraster/gsdpnext.h create mode 100644 pstoraster/gsdps.h create mode 100644 pstoraster/gsdps1.c create mode 100644 pstoraster/gsdsrc.c create mode 100644 pstoraster/gsdsrc.h create mode 100644 pstoraster/gserror.h create mode 100644 pstoraster/gserrors.h create mode 100644 pstoraster/gsexit.h create mode 100644 pstoraster/gsfcmap.c create mode 100644 pstoraster/gsfcmap.h create mode 100644 pstoraster/gsflip.h create mode 100644 pstoraster/gsfont.c create mode 100644 pstoraster/gsfont.h create mode 100644 pstoraster/gsfont0.c create mode 100644 pstoraster/gsfunc.c create mode 100644 pstoraster/gsfunc.h create mode 100644 pstoraster/gsfunc0.c create mode 100644 pstoraster/gsfunc0.h create mode 100644 pstoraster/gsfunc3.c create mode 100644 pstoraster/gsfunc3.h create mode 100644 pstoraster/gsgc.h create mode 100644 pstoraster/gshsb.c create mode 100644 pstoraster/gshsb.h create mode 100644 pstoraster/gsht.c create mode 100644 pstoraster/gsht.h create mode 100644 pstoraster/gsht1.c create mode 100644 pstoraster/gsht1.h create mode 100644 pstoraster/gshtscr.c create mode 100644 pstoraster/gshtx.h create mode 100644 pstoraster/gsimage.c create mode 100644 pstoraster/gsimage.h create mode 100644 pstoraster/gsimpath.c create mode 100644 pstoraster/gsinit.c create mode 100644 pstoraster/gsio.h create mode 100644 pstoraster/gsiodev.c create mode 100644 pstoraster/gsiparam.h create mode 100644 pstoraster/gsiparm2.h create mode 100644 pstoraster/gsiparm3.h create mode 100644 pstoraster/gsiparm4.h create mode 100644 pstoraster/gsjconf.h create mode 100644 pstoraster/gsjmorec.h create mode 100644 pstoraster/gslib.h create mode 100644 pstoraster/gsline.c create mode 100644 pstoraster/gsline.h create mode 100644 pstoraster/gslparam.h create mode 100644 pstoraster/gsmalloc.c create mode 100644 pstoraster/gsmalloc.h create mode 100644 pstoraster/gsmatrix.c create mode 100644 pstoraster/gsmatrix.h create mode 100644 pstoraster/gsmdebug.h create mode 100644 pstoraster/gsmemlok.h create mode 100644 pstoraster/gsmemory.c create mode 100644 pstoraster/gsmemory.h create mode 100644 pstoraster/gsmemraw.h create mode 100644 pstoraster/gsmisc.c create mode 100644 pstoraster/gsnorop.c create mode 100644 pstoraster/gspaint.c create mode 100644 pstoraster/gspaint.h create mode 100644 pstoraster/gsparam.c create mode 100644 pstoraster/gsparam.h create mode 100644 pstoraster/gsparams.c create mode 100644 pstoraster/gsparams.h create mode 100644 pstoraster/gspath.c create mode 100644 pstoraster/gspath.h create mode 100644 pstoraster/gspath1.c create mode 100644 pstoraster/gspath2.h create mode 100644 pstoraster/gspcolor.c create mode 100644 pstoraster/gspcolor.h create mode 100644 pstoraster/gspenum.h create mode 100644 pstoraster/gspmdrv.h create mode 100644 pstoraster/gsptype1.h create mode 100644 pstoraster/gsptype2.h create mode 100644 pstoraster/gsrect.h create mode 100644 pstoraster/gsrefct.h create mode 100644 pstoraster/gsrop.h create mode 100644 pstoraster/gsropc.h create mode 100644 pstoraster/gsropt.h create mode 100644 pstoraster/gsshade.c create mode 100644 pstoraster/gsshade.h create mode 100644 pstoraster/gsstate.c create mode 100644 pstoraster/gsstate.h create mode 100644 pstoraster/gsstruct.h create mode 100644 pstoraster/gstext.c create mode 100644 pstoraster/gstext.h create mode 100644 pstoraster/gstrap.c create mode 100644 pstoraster/gstrap.h create mode 100644 pstoraster/gstype1.c create mode 100644 pstoraster/gstype1.h create mode 100644 pstoraster/gstype2.c create mode 100644 pstoraster/gstype42.c create mode 100644 pstoraster/gstypes.h create mode 100644 pstoraster/gsuid.h create mode 100644 pstoraster/gsutil.c create mode 100644 pstoraster/gsutil.h create mode 100644 pstoraster/gsxfont.h create mode 100644 pstoraster/gx.h create mode 100644 pstoraster/gxacpath.c create mode 100644 pstoraster/gxalloc.h create mode 100644 pstoraster/gxalpha.h create mode 100644 pstoraster/gxarith.h create mode 100644 pstoraster/gxband.h create mode 100644 pstoraster/gxbcache.c create mode 100644 pstoraster/gxbcache.h create mode 100644 pstoraster/gxbitfmt.h create mode 100644 pstoraster/gxbitmap.h create mode 100644 pstoraster/gxbitops.h create mode 100644 pstoraster/gxccache.c create mode 100644 pstoraster/gxccman.c create mode 100644 pstoraster/gxchar.h create mode 100644 pstoraster/gxcht.c create mode 100644 pstoraster/gxcindex.h create mode 100644 pstoraster/gxclbits.c create mode 100644 pstoraster/gxcldev.h create mode 100644 pstoraster/gxclimag.c create mode 100644 pstoraster/gxclio.h create mode 100644 pstoraster/gxclip.c create mode 100644 pstoraster/gxclip.h create mode 100644 pstoraster/gxclip2.c create mode 100644 pstoraster/gxclip2.h create mode 100644 pstoraster/gxclipm.c create mode 100644 pstoraster/gxclipm.h create mode 100644 pstoraster/gxclist.c create mode 100644 pstoraster/gxclist.h create mode 100644 pstoraster/gxclmem.c create mode 100644 pstoraster/gxclmem.h create mode 100644 pstoraster/gxclpage.c create mode 100644 pstoraster/gxclpage.h create mode 100644 pstoraster/gxclpath.c create mode 100644 pstoraster/gxclpath.h create mode 100644 pstoraster/gxclrast.c create mode 100644 pstoraster/gxclread.c create mode 100644 pstoraster/gxclrect.c create mode 100644 pstoraster/gxclutil.c create mode 100644 pstoraster/gxclzlib.c create mode 100644 pstoraster/gxcmap.c create mode 100644 pstoraster/gxcmap.h create mode 100644 pstoraster/gxcolor2.h create mode 100644 pstoraster/gxcomp.h create mode 100644 pstoraster/gxcoord.h create mode 100644 pstoraster/gxcpath.c create mode 100644 pstoraster/gxcpath.h create mode 100644 pstoraster/gxcspace.h create mode 100644 pstoraster/gxctable.c create mode 100644 pstoraster/gxctable.h create mode 100644 pstoraster/gxcvalue.h create mode 100644 pstoraster/gxdcconv.c create mode 100644 pstoraster/gxdcconv.h create mode 100644 pstoraster/gxdcolor.c create mode 100644 pstoraster/gxdcolor.h create mode 100644 pstoraster/gxdda.h create mode 100644 pstoraster/gxdevcli.h create mode 100644 pstoraster/gxdevice.h create mode 100644 pstoraster/gxdevmem.h create mode 100644 pstoraster/gxdevrop.h create mode 100644 pstoraster/gxdht.h create mode 100644 pstoraster/gxdither.c create mode 100644 pstoraster/gxdither.h create mode 100644 pstoraster/gxfarith.h create mode 100644 pstoraster/gxfcache.h create mode 100644 pstoraster/gxfcmap.h create mode 100644 pstoraster/gxfill.c create mode 100644 pstoraster/gxfixed.h create mode 100644 pstoraster/gxfmap.h create mode 100644 pstoraster/gxfont.h create mode 100644 pstoraster/gxfont0.h create mode 100644 pstoraster/gxfont1.h create mode 100644 pstoraster/gxfont42.h create mode 100644 pstoraster/gxfrac.h create mode 100644 pstoraster/gxftype.h create mode 100644 pstoraster/gxfunc.h create mode 100644 pstoraster/gxgetbit.h create mode 100644 pstoraster/gxhint1.c create mode 100644 pstoraster/gxhint2.c create mode 100644 pstoraster/gxhint3.c create mode 100644 pstoraster/gxht.c create mode 100644 pstoraster/gxht.h create mode 100644 pstoraster/gxhttile.h create mode 100644 pstoraster/gxhttype.h create mode 100644 pstoraster/gxi12bit.c create mode 100644 pstoraster/gxicolor.c create mode 100644 pstoraster/gxidata.c create mode 100644 pstoraster/gxifast.c create mode 100644 pstoraster/gxiinit.c create mode 100644 pstoraster/gximage.h create mode 100644 pstoraster/gximage3.c create mode 100644 pstoraster/gximage4.c create mode 100644 pstoraster/gximono.c create mode 100644 pstoraster/gxiodev.h create mode 100644 pstoraster/gxiparam.h create mode 100644 pstoraster/gxiscale.c create mode 100644 pstoraster/gxistate.h create mode 100644 pstoraster/gxline.h create mode 100644 pstoraster/gxlum.h create mode 100644 pstoraster/gxmatrix.h create mode 100644 pstoraster/gxmclip.c create mode 100644 pstoraster/gxmclip.h create mode 100644 pstoraster/gxobj.h create mode 100644 pstoraster/gxop1.h create mode 100644 pstoraster/gxp1fill.c create mode 100644 pstoraster/gxp1fill.h create mode 100644 pstoraster/gxpageq.h create mode 100644 pstoraster/gxpaint.c create mode 100644 pstoraster/gxpaint.h create mode 100644 pstoraster/gxpath.c create mode 100644 pstoraster/gxpath.h create mode 100644 pstoraster/gxpath2.c create mode 100644 pstoraster/gxpcache.h create mode 100644 pstoraster/gxpcmap.c create mode 100644 pstoraster/gxpcolor.h create mode 100644 pstoraster/gxpcopy.c create mode 100644 pstoraster/gxpdash.c create mode 100644 pstoraster/gxpflat.c create mode 100644 pstoraster/gxropc.h create mode 100644 pstoraster/gxsample.c create mode 100644 pstoraster/gxsample.h create mode 100644 pstoraster/gxshade.c create mode 100644 pstoraster/gxshade.h create mode 100644 pstoraster/gxshade1.c create mode 100644 pstoraster/gxshade4.c create mode 100644 pstoraster/gxshade4.h create mode 100644 pstoraster/gxshade6.c create mode 100644 pstoraster/gxstate.h create mode 100644 pstoraster/gxstroke.c create mode 100644 pstoraster/gxsync.h create mode 100644 pstoraster/gxtext.h create mode 100644 pstoraster/gxtmap.h create mode 100644 pstoraster/gxtype1.c create mode 100644 pstoraster/gxtype1.h create mode 100644 pstoraster/gxxfont.h create mode 100644 pstoraster/gzacpath.h create mode 100644 pstoraster/gzcpath.h create mode 100644 pstoraster/gzht.h create mode 100644 pstoraster/gzline.h create mode 100644 pstoraster/gzpath.h create mode 100644 pstoraster/gzstate.h create mode 100644 pstoraster/ialloc.c create mode 100644 pstoraster/ialloc.h create mode 100644 pstoraster/iastate.h create mode 100644 pstoraster/iastruct.h create mode 100644 pstoraster/ibnum.c create mode 100644 pstoraster/ibnum.h create mode 100644 pstoraster/iccinit0.c create mode 100644 pstoraster/ichar.h create mode 100644 pstoraster/icharout.h create mode 100644 pstoraster/icie.h create mode 100644 pstoraster/icolor.h create mode 100644 pstoraster/iconfig.c create mode 100644 pstoraster/icontext.c create mode 100644 pstoraster/icontext.h create mode 100644 pstoraster/icsmap.h create mode 100644 pstoraster/icstate.h create mode 100644 pstoraster/idebug.c create mode 100644 pstoraster/idebug.h create mode 100644 pstoraster/idict.c create mode 100644 pstoraster/idict.h create mode 100644 pstoraster/idictdef.h create mode 100644 pstoraster/idparam.c create mode 100644 pstoraster/idparam.h create mode 100644 pstoraster/idstack.c create mode 100644 pstoraster/idstack.h create mode 100644 pstoraster/iestack.h create mode 100644 pstoraster/ifilter.h create mode 100644 pstoraster/ifont.h create mode 100644 pstoraster/ifunc.h create mode 100644 pstoraster/igc.c create mode 100644 pstoraster/igc.h create mode 100644 pstoraster/igcref.c create mode 100644 pstoraster/igcstr.c create mode 100644 pstoraster/igcstr.h create mode 100644 pstoraster/igstate.h create mode 100644 pstoraster/iht.h create mode 100644 pstoraster/iimage.h create mode 100644 pstoraster/iimage2.h create mode 100644 pstoraster/iinit.c create mode 100644 pstoraster/ilevel.h create mode 100644 pstoraster/ilocate.c create mode 100644 pstoraster/imain.c create mode 100644 pstoraster/imain.h create mode 100644 pstoraster/imainarg.c create mode 100644 pstoraster/imainarg.h create mode 100644 pstoraster/imemory.h create mode 100644 pstoraster/iminst.h create mode 100644 pstoraster/iname.c create mode 100644 pstoraster/iname.h create mode 100644 pstoraster/inamedef.h create mode 100644 pstoraster/inames.h create mode 100644 pstoraster/interp.c create mode 100644 pstoraster/interp.h create mode 100644 pstoraster/iostack.h create mode 100644 pstoraster/ipacked.h create mode 100644 pstoraster/iparam.c create mode 100644 pstoraster/iparam.h create mode 100644 pstoraster/iparray.h create mode 100644 pstoraster/ireclaim.c create mode 100644 pstoraster/iref.h create mode 100644 pstoraster/isave.c create mode 100644 pstoraster/isave.h create mode 100644 pstoraster/iscan.c create mode 100644 pstoraster/iscan.h create mode 100644 pstoraster/iscanbin.c create mode 100644 pstoraster/iscannum.c create mode 100644 pstoraster/iscannum.h create mode 100644 pstoraster/isstate.h create mode 100644 pstoraster/istack.c create mode 100644 pstoraster/istack.h create mode 100644 pstoraster/istream.h create mode 100644 pstoraster/istruct.h create mode 100644 pstoraster/iutil.c create mode 100644 pstoraster/iutil.h create mode 100644 pstoraster/iutil2.c create mode 100644 pstoraster/iutil2.h create mode 100644 pstoraster/ivmspace.h create mode 100644 pstoraster/main.h create mode 100644 pstoraster/malloc_.h create mode 100644 pstoraster/math_.h create mode 100644 pstoraster/memory_.h create mode 100644 pstoraster/opcheck.h create mode 100644 pstoraster/opdef.h create mode 100644 pstoraster/oper.h create mode 100644 pstoraster/opextern.h create mode 100644 pstoraster/ostack.h create mode 100644 pstoraster/pipe_.h create mode 100644 pstoraster/pstoraster.c create mode 100644 pstoraster/sa85x.h create mode 100644 pstoraster/sbcp.c create mode 100644 pstoraster/sbhc.c create mode 100644 pstoraster/sbhc.h create mode 100644 pstoraster/sbtx.h create mode 100644 pstoraster/sbwbs.c create mode 100644 pstoraster/sbwbs.h create mode 100644 pstoraster/scanchar.h create mode 100644 pstoraster/scantab.c create mode 100644 pstoraster/scf.h create mode 100644 pstoraster/scfd.c create mode 100644 pstoraster/scfdtab.c create mode 100644 pstoraster/scfe.c create mode 100644 pstoraster/scfetab.c create mode 100644 pstoraster/scfparam.c create mode 100644 pstoraster/scfx.h create mode 100644 pstoraster/scommon.h create mode 100644 pstoraster/sdcparam.c create mode 100644 pstoraster/sdcparam.h create mode 100644 pstoraster/sdct.h create mode 100644 pstoraster/sdctc.c create mode 100644 pstoraster/sdctd.c create mode 100644 pstoraster/sdcte.c create mode 100644 pstoraster/sddparam.c create mode 100644 pstoraster/sdeparam.c create mode 100644 pstoraster/seexec.c create mode 100644 pstoraster/sfilter.h create mode 100644 pstoraster/sfilter1.c create mode 100644 pstoraster/sfilter2.c create mode 100644 pstoraster/sfxstdio.c create mode 100644 pstoraster/shc.c create mode 100644 pstoraster/shc.h create mode 100644 pstoraster/shcgen.c create mode 100644 pstoraster/shcgen.h create mode 100644 pstoraster/siscale.c create mode 100644 pstoraster/siscale.h create mode 100644 pstoraster/sjpeg.h create mode 100644 pstoraster/sjpegc.c create mode 100644 pstoraster/sjpegd.c create mode 100644 pstoraster/sjpege.c create mode 100644 pstoraster/sjpegerr.c create mode 100644 pstoraster/slzwc.c create mode 100644 pstoraster/slzwce.c create mode 100644 pstoraster/slzwd.c create mode 100644 pstoraster/slzwx.h create mode 100644 pstoraster/smtf.c create mode 100644 pstoraster/smtf.h create mode 100644 pstoraster/spcxd.c create mode 100644 pstoraster/spcxx.h create mode 100644 pstoraster/spdiff.c create mode 100644 pstoraster/spdiffx.h create mode 100644 pstoraster/spngp.c create mode 100644 pstoraster/spngpx.h create mode 100644 pstoraster/srld.c create mode 100644 pstoraster/srle.c create mode 100644 pstoraster/srlx.h create mode 100644 pstoraster/sstring.c create mode 100644 pstoraster/sstring.h create mode 100644 pstoraster/stat_.h create mode 100644 pstoraster/std.h create mode 100644 pstoraster/stdio_.h create mode 100644 pstoraster/stdpre.h create mode 100644 pstoraster/store.h create mode 100644 pstoraster/stream.c create mode 100644 pstoraster/stream.h create mode 100644 pstoraster/strimpl.h create mode 100644 pstoraster/string_.h create mode 100644 pstoraster/szlibc.c create mode 100644 pstoraster/szlibd.c create mode 100644 pstoraster/szlibe.c create mode 100644 pstoraster/szlibx.h create mode 100644 pstoraster/szlibxx.h create mode 100644 pstoraster/time_.h create mode 100644 pstoraster/vmsmath.h create mode 100644 pstoraster/zarith.c create mode 100644 pstoraster/zarray.c create mode 100644 pstoraster/zbseq.c create mode 100644 pstoraster/zcfont.c create mode 100644 pstoraster/zchar.c create mode 100644 pstoraster/zchar1.c create mode 100644 pstoraster/zchar2.c create mode 100644 pstoraster/zchar32.c create mode 100644 pstoraster/zchar42.c create mode 100644 pstoraster/zcharout.c create mode 100644 pstoraster/zcid.c create mode 100644 pstoraster/zcie.c create mode 100644 pstoraster/zcolor.c create mode 100644 pstoraster/zcolor1.c create mode 100644 pstoraster/zcolor2.c create mode 100644 pstoraster/zcontrol.c create mode 100644 pstoraster/zcrd.c create mode 100644 pstoraster/zcsdevn.c create mode 100644 pstoraster/zcsindex.c create mode 100644 pstoraster/zcspixel.c create mode 100644 pstoraster/zcssepr.c create mode 100644 pstoraster/zdevcal.c create mode 100644 pstoraster/zdevice.c create mode 100644 pstoraster/zdevice2.c create mode 100644 pstoraster/zdict.c create mode 100644 pstoraster/zdps1.c create mode 100644 pstoraster/zfbcp.c create mode 100644 pstoraster/zfcmap.c create mode 100644 pstoraster/zfdctd.c create mode 100644 pstoraster/zfdcte.c create mode 100644 pstoraster/zfdecode.c create mode 100644 pstoraster/zfile.c create mode 100644 pstoraster/zfileio.c create mode 100644 pstoraster/zfilter.c create mode 100644 pstoraster/zfilter2.c create mode 100644 pstoraster/zfilterx.c create mode 100644 pstoraster/zfname.c create mode 100644 pstoraster/zfont.c create mode 100644 pstoraster/zfont0.c create mode 100644 pstoraster/zfont1.c create mode 100644 pstoraster/zfont2.c create mode 100644 pstoraster/zfont32.c create mode 100644 pstoraster/zfont42.c create mode 100644 pstoraster/zfproc.c create mode 100644 pstoraster/zfreuse.c create mode 100644 pstoraster/zfunc.c create mode 100644 pstoraster/zfunc0.c create mode 100644 pstoraster/zfunc3.c create mode 100644 pstoraster/zfzlib.c create mode 100644 pstoraster/zgeneric.c create mode 100644 pstoraster/zgstate.c create mode 100644 pstoraster/zhsb.c create mode 100644 pstoraster/zht.c create mode 100644 pstoraster/zht1.c create mode 100644 pstoraster/zht2.c create mode 100644 pstoraster/zimage.c create mode 100644 pstoraster/zimage2.c create mode 100644 pstoraster/zimage3.c create mode 100644 pstoraster/ziodev.c create mode 100644 pstoraster/ziodev2.c create mode 100644 pstoraster/zmath.c create mode 100644 pstoraster/zmatrix.c create mode 100644 pstoraster/zmedia2.c create mode 100644 pstoraster/zmisc.c create mode 100644 pstoraster/zmisc1.c create mode 100644 pstoraster/zmisc2.c create mode 100644 pstoraster/zmisc3.c create mode 100644 pstoraster/zpacked.c create mode 100644 pstoraster/zpaint.c create mode 100644 pstoraster/zpath.c create mode 100644 pstoraster/zpath1.c create mode 100644 pstoraster/zpcolor.c create mode 100644 pstoraster/zrelbit.c create mode 100644 pstoraster/zshade.c create mode 100644 pstoraster/zstack.c create mode 100644 pstoraster/zstring.c create mode 100644 pstoraster/zsysvm.c create mode 100644 pstoraster/ztoken.c create mode 100644 pstoraster/ztrap.c create mode 100644 pstoraster/ztype.c create mode 100644 pstoraster/zupath.c create mode 100644 pstoraster/zusparam.c create mode 100644 pstoraster/zvmem.c create mode 100644 pstoraster/zvmem2.c create mode 100644 scheduler/Makefile create mode 100644 scheduler/auth.c create mode 100644 scheduler/auth.h create mode 100644 scheduler/banners.c create mode 100644 scheduler/banners.h create mode 100644 scheduler/cert.c create mode 100644 scheduler/cert.h create mode 100644 scheduler/classes.c create mode 100644 scheduler/classes.h create mode 100644 scheduler/client.c create mode 100644 scheduler/client.h create mode 100644 scheduler/conf.c create mode 100644 scheduler/conf.h create mode 100644 scheduler/cups-lpd.c create mode 100644 scheduler/cups-polld.c create mode 100644 scheduler/cups.pam create mode 100644 scheduler/cupsd.dsp create mode 100644 scheduler/cupsd.h create mode 100644 scheduler/devices.c create mode 100644 scheduler/dirsvc.c create mode 100644 scheduler/dirsvc.h create mode 100644 scheduler/filter.c create mode 100644 scheduler/ipp.c create mode 100644 scheduler/job.c create mode 100644 scheduler/job.h create mode 100644 scheduler/listen.c create mode 100644 scheduler/log.c create mode 100644 scheduler/main.c create mode 100644 scheduler/mime.c create mode 100644 scheduler/mime.h create mode 100644 scheduler/ppds.c create mode 100644 scheduler/printers.c create mode 100644 scheduler/printers.h create mode 100644 scheduler/testmime.c create mode 100644 scheduler/testspeed.c create mode 100644 scheduler/type.c create mode 100644 standards/draft-ietf-ipp-collection-02.txt create mode 100644 standards/draft-ietf-ipp-finishings-fold-trim-bale-00.txt create mode 100644 standards/draft-ietf-ipp-implementers-guide-v11-01.txt create mode 100644 standards/draft-ietf-ipp-indp-00.txt create mode 100644 standards/draft-ietf-ipp-indp-method-00.txt create mode 100644 standards/draft-ietf-ipp-job-printer-set-ops-02.txt create mode 100644 standards/draft-ietf-ipp-ldap-printer-schema-01.txt create mode 100644 standards/draft-ietf-ipp-model-v11-07.txt create mode 100644 standards/draft-ietf-ipp-not-04.txt create mode 100644 standards/draft-ietf-ipp-not-http-delivery-00.txt create mode 100644 standards/draft-ietf-ipp-not-over-snmp-02.txt create mode 100644 standards/draft-ietf-ipp-not-spec-02.txt create mode 100644 standards/draft-ietf-ipp-notify-mailto-00.txt create mode 100644 standards/draft-ietf-ipp-notify-poll-00.txt create mode 100644 standards/draft-ietf-ipp-ops-set2-00.txt create mode 100644 standards/draft-ietf-ipp-protocol-v11-06.txt create mode 100644 standards/rfc1179.txt create mode 100644 standards/rfc1321.txt create mode 100644 standards/rfc2246.txt create mode 100644 standards/rfc2396.txt create mode 100644 standards/rfc2487.txt create mode 100644 standards/rfc2565.txt create mode 100644 standards/rfc2566.txt create mode 100644 standards/rfc2567.txt create mode 100644 standards/rfc2568.txt create mode 100644 standards/rfc2569.txt create mode 100644 standards/rfc2595.txt create mode 100644 standards/rfc2616.txt create mode 100644 standards/rfc2617.txt create mode 100644 standards/rfc2639.txt create mode 100644 standards/rfc2712.txt create mode 100644 standards/rfc2817.txt create mode 100644 standards/rfc2818.txt create mode 100644 systemv/Makefile create mode 100644 systemv/accept.c create mode 100644 systemv/cancel.c create mode 100644 systemv/lp.c create mode 100644 systemv/lpadmin.c create mode 100644 systemv/lpinfo.c create mode 100644 systemv/lpmove.c create mode 100644 systemv/lpoptions.c create mode 100644 systemv/lppasswd.c create mode 100644 systemv/lpstat.c create mode 100644 templates/Makefile create mode 100644 templates/add-class.tmpl create mode 100644 templates/add-printer.tmpl create mode 100644 templates/admin-op.tmpl create mode 100644 templates/admin.tmpl create mode 100644 templates/choose-device.tmpl create mode 100644 templates/choose-make.tmpl create mode 100644 templates/choose-members.tmpl create mode 100644 templates/choose-model.tmpl create mode 100644 templates/choose-serial.tmpl create mode 100644 templates/choose-uri.tmpl create mode 100644 templates/class-added.tmpl create mode 100644 templates/class-confirm.tmpl create mode 100644 templates/class-deleted.tmpl create mode 100644 templates/class-modified.tmpl create mode 100644 templates/classes.tmpl create mode 100644 templates/config-printer.tmpl create mode 100644 templates/config-printer2.tmpl create mode 100644 templates/error.tmpl create mode 100644 templates/header.tmpl create mode 100644 templates/job-cancel.tmpl create mode 100644 templates/job-hold.tmpl create mode 100644 templates/job-release.tmpl create mode 100644 templates/job-restart.tmpl create mode 100644 templates/jobs.tmpl create mode 100644 templates/modify-class.tmpl create mode 100644 templates/modify-printer.tmpl create mode 100644 templates/option-boolean.tmpl create mode 100644 templates/option-header.tmpl create mode 100644 templates/option-pickmany.tmpl create mode 100644 templates/option-pickone.tmpl create mode 100644 templates/option-trailer.tmpl create mode 100644 templates/printer-accept.tmpl create mode 100644 templates/printer-added.tmpl create mode 100644 templates/printer-configured.tmpl create mode 100644 templates/printer-confirm.tmpl create mode 100644 templates/printer-deleted.tmpl create mode 100644 templates/printer-modified.tmpl create mode 100644 templates/printer-reject.tmpl create mode 100644 templates/printer-start.tmpl create mode 100644 templates/printer-stop.tmpl create mode 100644 templates/printers.tmpl create mode 100644 templates/test-page.tmpl create mode 100644 templates/trailer.tmpl create mode 100644 test/Makefile create mode 100644 test/create-job-format.test create mode 100644 test/create-job-sheets.test create mode 100644 test/create-job-timeout.test create mode 100644 test/create-job.test create mode 100644 test/get-job-attributes.test create mode 100644 test/get-job-attributes2.test create mode 100644 test/get-printer-attributes.test create mode 100644 test/ipptest.c create mode 100644 test/print-job-hold.test create mode 100644 test/print-job.test create mode 100644 visualc/config.h diff --git a/CHANGES.txt b/CHANGES.txt new file mode 100644 index 0000000000..47e14d22fa --- /dev/null +++ b/CHANGES.txt @@ -0,0 +1,610 @@ +CHANGES.txt - 07/21/2000 +------------------------ + +CHANGES IN CUPS v1.1.1 + + - The pstoraster Makefile still referenced one of the + old PDF filter files. + - The filter Makefile used INSTALL_DATA instead of + INSTALL_LIB to install the CUPS image library. + - The administration CGI didn't work properly with + network devices. + - The BrowseACL variable was not updated after the + cupsd.conf file was loaded. + - The lpd mini-daemon didn't support printer instances. + - Now use a default umask of 077 for child processes. + - Now put temp files in /var/spool/cups/tmp for child + processes and the root user, unless TMPDIR or TempDir + is defined otherwise. + - cupsGetPPD() no longer uses easy-to-guess filenames. + - The CUPS-Delete-Class and CUPS-Delete-Printer + operations now save classes.conf file as needed. + - The lppasswd command wouldn't add a user. + - The ppdOpen() function could cause a segfault if a + 0-length PPD file was read. + - The image filters were not handling images with + different X and Y resolutions properly. + - The imagetoraster filter defaulted to RGB output + instead of black output like pstoraster. + - The pstops filter didn't handle binary data properly. + - The pstops filter didn't handle copies properly for + PS files lacking DSC comments. + - The pstops filter now appends %%EOF to the end of + documents if they don't have it. + - The cupsGetPPD() function didn't work with remote + printers lacking the @server in the name. + - The configure script didn't work right when only + --prefix was specified. + - The ppdEmit() code now wraps all printer commands so + that buggy PostScript printers will still print a file + after receiving an option that isn't available. + - Fixed the DeskJet margin bug, and disabled 600dpi + color mode until it can be fixed. + - The cupsAddDest() function didn't sort instances + correctly in all cases. + - The time-at-xyz attributes now expand to the date and + time in banner files. + + +CHANGES IN CUPS v1.1 + + - Documentation updates. + - Configuration script updates. + - Didn't map charset and language value strings to lowercase + and _ to - as required by SLP and IPP. + - ppdLoadXYZ() didn't add the list of available fonts to the + ppd_file_t structure. + - The text filter common code was freeing the PPD file data + before it was used. + - The text filter now embeds missing fonts. + - The CGI interface now maps local access to the server to + the localhost address. + - The HP-GL/2 filter didn't use the specified (or default) + color ranges, resulting in strange colors. + - The HP-GL/2 filter didn't default to no input window, which + caused unnecessary clipping of plots. + - Integrated Xpdf's pdftops filter into CUPS, which is a + lightweight and reliable replacement for Ghostscript's + PDF support. + - Removed all PDF support from Ghostscript. + - Updated HP driver to set top margin; this seems to fix + the offset problem seen on HP DeskJet printers. + - Fixed dependencies on the ZLIB and JPEG libraries in + pstoraster. + - The lpr command wasn't using the lpoptions defined by + the user. + - The lpr command would segfault if the CUPS server was + not running. + - The top-level makefile was not installing the CUPS + initialization script. It now does so if it sees there + is an init.d directory in /sbin, /etc/rc.d, or /etc. + - "lpstat -v all" didn't work. + - pstoraster would crash on some platforms doing the + setpagedevice operator. + - The web administration interface now allows you to set + the default banner pages. + - Images can now be positioned on the page using the new + "position" option. + - The AccessLog, ErrorLog, and PageLog directives now + support "%s" to insert the server name. + - Added a new BrowseShortNames directive to allow for + short remote printer names ("printer" instead of + "printer@server") when possible. + - The scheduler could crash if given an invalid PPD file + with no PageSize attributes. + - Updated the serial, parallel, and usb backends to do + multiple writes and ignore ioctl() errors as needed; + this should fix problems with serial printing on old + serial drivers and with the UltraSPARC parallel port + driver under Solaris 2.7. + - Now propagate LD_LIBRARY_PATH to child processes from + cupsd. + - New DataDir directive for installing in alternate + locations. + - New CUPS_SERVERROOT and CUPS_DATADIR environment + variables to specify installation directories as + needed. + - Queued remote jobs recreate remote printers as needed + when the scheduler is started. + - Deleting a printer also purges all jobs on that + printer. + - Old job and control files that don't belong to a + printer are automatically deleted. + - Wasn't updating time-at-processing and + time-at-completed attributes in job. + - Didn't send required multiple-operation-time-out + attribute in response to a get-printer-attributes + request. + - cups-lpd now supports options set with lpoptions. + - The job-hold-until attribute is now provided with all + jobs. For jobs that are not currently held the value + is "no-hold". + - The scheduler was not sending "unknown" values in IPP + responses. + - The lpoptions command now accumulates options from + previous runs rather than replacing all options for a + printer. + - The IPP backend now switches to IPP/1.0 if a 1.1 + request fails. + - The lpadmin and admin.cgi programs now validate new + printer and class names. + - The access_log file now includes the number of IPP bytes + received in a POST request. + + +CHANGES IN CUPS v1.1b5 + + - Documentation updates. + - The pstoraster filter didn't compile without the JPEG library. + - The cupsd server didn't support the HTTP OPTIONS request + method. + - Dropped the "CLOSE" method supported by the cupsd server. + (not defined in HTTP specification) + - Makefile/configure script fixes. + - Missing the job-restart template. + - Added IPP test suite for testing. + - Missing IPP documentation from binary distributions. + - Fixed multiple-document handling code when last-document + not specified. + - Added more checks to IPP requests to prevent bad requests + from getting through. + - Not all of the Ghostscript error output was being sent to + stderr. + - The PostScript filter now added PJL commands to set the + job name and display string, if supported. + - The scheduler would crash if the browse socket could not + be bound. Now disables browsing if port 631 (reserved for + IPP) is being used by a misbehaving daemon. + - The USB backend now looks for the older Linux 2.2.x USB + printer device filenames as well as the newer ones. + - The IPP backend now uses the UTF-8 charset exclusively, + since apparently only CUPS handles more than US-ASCII and + UTF-8... + - Wasn't quoting ( in PostScript banners... + - Send-document requests with no document-format attribute + could cause cupsd to crash. + - Old jobs in the spool directory might cause cupsd to + crash. + - CUPS now supports all of the recommended job-hold-until + keywords as well as name values of the form "HH:MM" and + "HH:MM:SS". + - Added placeholder pointer for TLS encryption to the HTTP + connection structure. + - Fixed the "fast poll" bug reported by DISA - the + status pipe wasn't being closed for multi-file jobs. + - Revamped put_params code in pstoraster to fix bitmap + allocation bug with FrameMaker output. + - Ripped out filename, etc. code from pstoraster as it + is a potential security hole. + - Added support for RIP_CACHE environment variable in the + new pstoraster. + - Fixed USB device filenames for Linux; now support new + pre-2.4 devices (/dev/usb/lp#) and 2.2 devices + (/dev/usblp#) + - Fixed accept-jobs crash with classes. + - Didn't include dot-matrix EPSON drivers in previous + release. + + +CHANGES IN CUPS v1.1b4 + + - Documentation updates. + - Many makefile and configuration script fixes (should + now compile better under *BSD.) + - The MediaPosition attribute was being mishandled by + GhostScript, causing the RIP to fail whenever a paper + tray was selected. + - The scheduler now logs the final line of log information + from a filter, even if it doesn't end with a newline; this + primarily affects GhostScript error output. + - The scheduler was saving implicit classes, so after a few + restarts you'll end up with AnyPrinter, AnyAnyPrinter, etc. + - The JPEG autodetection didn't work with some JPEG files that + came from digital cameras (JPEG but not JFIF); the new + magic types should work with all images that the JPEG library + can handle. + - Fixed a bug in the new contains() MIME type rule that could + cause cupsd to crash. + - Switched to using strtol() in the MIME type code so that you + can use hex, octal, or decimal constants as desired in the + mime.types file. + - Banner files are now treated as templates, allowing any type + of file to be used as a banner. + - Added a 30-second timeout to backend device reports so that a + hung backend will not prevent the scheduler from starting. + - Backends are once again terminated when jobs are stopped; the + CUPS-supplied backends will stay alive until the downstream + filters have had a chance to clear out old page data. + - The charset lookup in the CUPS localization support was wrong + (iso8859-x instead of iso-8859-x) + - Changed the "cpNNNN" code page files to "windows-NNNN" to match + the IANA registrations. + - New PostScript banner pages. + - Added Windows BMP and Alias PIX image file support to the image + filter. + - The PNG reading coded didn't free all of its buffers. + - Added Digest authentication support to the client and server + code. + - Added Solaris options to System V commands. + - Now support the output-bin job template attribute. + - Now log the job-billing attribute in the page_log file, and + keep track of the total number of pages in the + job-media-sheets-completed attribute. + - The penwidth option is now in micrometers to support more + accurate width specification. + - The image filters now support interlaced and transparent PNG + files. + - Didn't handle Keep-Alive for HTTP/1.0 clients. + - The BrowsePoll support didn't handle when BrowseInterval + was set to 0 (now uses 30 seconds if BrowseInterval is 0) + - The DeskJet driver now supports 600 DPI color for printers + that support it. + - New lpinfo and lpmove commands. + - The lpq command now supports the Digital UNIX output format. + - The LPD mini-daemon now supports all required LPD operations. + - Implemented timeouts for multi-file documents. + - New cupsPrintFiles() function in the CUPS API library to + print multiple files using create-job and send-document + requests (1 job ID for multiple files) + - The lp command now sends multiple files as a single job, + matching the behavior of the System V command. + - The "cancel -a" command now purges job history files. + + +CHANGES IN CUPS v1.1b3 + + - Documentation updates. + - The startup script redirected stderr before stdout, + which caused problems with some versions of Bourne + shell and Bash. + - Fixed a bug in the scheduler's PPD language reading + code. + - Fixed a bug in the scheduler's check for the + manufacturer in the PPD. + - The pstoraster filter didn't allow some input and + output attributes to be set. + - Added banner page support. + - Added missing PAM configuration file. + - Configuration script fixes for Linux and *BSD. + - The log file code was using the wrong sign for the + timezone offset. + - The default printcap file is now empty (no printcap + file is generated). + - The scheduler did not start jobs destined for remote + printers when they became available. + - The scheduler now sends jobs to remote printers + immediately. (when sending jobs to a class, the remote + printer is only used when it becomes available) + - The scheduler now supports printing of banner pages + via the job-sheets attribute (banner files go in + /usr/share/cups/banners) + - The cupsd process now forks itself into the background + (override with -f) + - Added several *BSD enhancements. + - Added UNSUPPORTED libtool option to configuration + script to allow the use of libtool. Note that this is + UNSUPPORTED by us, but added by request of the *BSD + folks. + - The parallel, serial, and usb backends now retry the + opening of their ports. This allows multiple print + queues to be associated with a single physical port, + and will allow CUPS to support several types of + parallel port auto-switches in the near future. + - Set-Job-Attributes now supports adding, changing, and + deleting job template attributes, and no longer allows + job-printer-uri to be set (see CUPS-Move-Job) + - Added CUPS-Move-Job operation to support moving of jobs. + - The CGI template functionality now supports multiple + languages (still only have templates for English) + - The CUPS-Get-Printers and CUPS-Get-Classes operations + now support filtering as defined in the IDD. + - The Get-Jobs, CUPS-Get-Printers, and CUPS-Get-Classes + operations no longer limit themselves to 1000 jobs, + printers, or classes (believe it or not, this is + needed for some sites) + - The web interfaces now support language-specific + templates. + - The web admin interface now supports class management. + - The web admin interface now shows a list of + manufacturers before selecting the PPD/driver for a + specific printer. + - The web admin interface now supports configuration of + the default printer options in the PPD file. + - The web interface now uses printer/class + authentication for the test page instead of admin + authentication. + - Updated the RPM spec file for the current release. + - Updated language support for Windows code pages. + - 8-bit character set files can now use multiple fonts + (needed for Arabic, Greek, Hebrew, etc.) + - Added basic right-to-left text support in the text + filter. + - The POSIX locale now uses ISO-8859-1 instead of + US-ASCII. + - Fixed PDF printing problems. + - Fixed PostScript RIP page device dictionary elements + that weren't getting passed in cups_get_params(). + - Added a new "contains" rule for the magic file typing. + - The "printable" rule now accepts characters from 128 to 255 + (needed for Microsoft character sets) + - Added support for ~/.cupsrc as well as /etc/cups/client.conf + so that the default server can be configured on a per-user + basis without environment variables. + - Added LPD mini-daemon to support incoming LPD jobs. + + +CHANGES IN CUPS v1.1b2 + + - Documentation updates. + - The lp command didn't always load the user-defined + destinations, preventing it from seeing the default + printer. + - Many configure script and makefile fixes. + - The Microsoft code page files were missing from the + distribution. + - Added a workaround for the HP IPP client (which is sending + an invalid printer-uri in requests) + - Fixed the encoding of text-with-language and name-with-language + to match the IPP spec. + - Added support for unknown value tags in the IPP routines + (previously they would be ignored) + - Integrated GNU GhostScript 5.50 into the pstoraster filter. + - Client hostname resolution was broken on little-endian + machines. + - Now look at client.conf file for client's default server + and printer. + - The cupsServer() function did not close the client.conf file + if it contained a ServerName directive. + - Added BrowseAllow, BrowseDeny, BrowseOrder, BrowsePoll, and + BrowseRelay directives. + - BrowseInterval 0 disables advertising of local printers, but + still receives information on remote printers. + - New browse polling daemon (for polling servers on different + networks) + - New PPD cache file for faster startup times with large numbers + of PPD files. + - The Host: field was incorrectly required for HTTP/1.0 clients. + - New set-job-attributes operation now supported. + - The mime_load_types() and mime_load_convs() functions did not + close their input files. + + +CHANGES IN CUPS v1.1b1 + + - NEW web-based administration interface. + - NEW EPSON printer drivers. + - NEW user-defined printers and options. + - NEW persistent jobs and job history + - NEW IPP/1.1 support + - NEW template-based web interfaces. + - NEW CUPS-get-devices and CUPS-get-ppds operations. + - NEW support for create-job and send-file operations. + - NEW certificate-based authentication for local + administration. + - NEW USB backend. + - The lpr command now produces human-readable error messages. + - The lpq command now produces BSD standard format output + instead of OSF/1 output. This should resolve the SAMBA + print queue problems that have been reported. + - The IPP backend did not always detect when the "raw" option + was being used. + - The "lpstat -p" command would stop after the first active + printer. + - The "lpstat -v" command would stop before the first remote + printer. + + +CHANGES IN CUPS v1.0.5 + + - The HP-GL/2 filter did not correctly set the pen color + for pens other than #1. + - The scheduler would only accept 26 simultaneous jobs + under some OS releases (mkstemp() limitation.) It now + handles up to 2^32 simultaneous jobs. + - The PostScript filter loaded the printer's PPD file + twice. + - The PAM authentication code now uses pam_strerror() to + provide a textual error message in the error_log file. + - The scheduler now copies PPD and interface script + files instead of moving them; this fixes installations + with a separate requests directory. + - The PostScript RIP did not generate correct 6-color + output. + - Several filters were marking PPD options twice when + they didn't need to. + - The scheduler did not save the printer or class state + after an accept-jobs or reject-jobs operation. + - The cupsGetDefault() function now ignores the PRINTER + environment variable if it is set to "lp". + - New ippErrorString() function to get textual error + messages. + - Better error reporting in the System V commands. + - The lpadmin and lpstat commands always tried to + connect to the default server. + - The text filter didn't load the charset files from the + correct location. + - Wasn't sending a WWW-Authenticate: field to HTTP + clients when authentication was required. + - httpSeparate() didn't always set the default port + number for known methods. + - The HP-GL/2 filter now looks for "PSwidth,length" + instead of (the correct) "PSlength,width" as + documented by HP. It appears that many major CAD + applications are broken and this change allows the + auto-rotation to work with them. + - The IPP "printer-resolution" option was not being + translated. + - The charset files did not include the Microsoft + "standard" characters from 128 to 159 (unused by the + ISO-8859-x charsets) + - The scheduler was chunking the Content-Type field from + CGI programs; this problem was most noticeable with + Microsoft Internet Explorer 5. + - By popular demand, the printers, jobs, and classes + CGIs no longer force a reload of the page every 10/30 + seconds. + - The scheduler incorrectly required that the IPP client + provide a document-format attribute for the + validate-job operation. + - Clients that sent bad IPP requests without the + required attributes-natural-language and + attributes-charset attributes would crash the + scheduler. + + +CHANGES IN CUPS v1.0.4 + + - Documentation updates. + - Jobs would get stuck in the queue and wouldn't print + until you enabled the queue. + - The lp and lpr commands now catch SIGHUP and SIGINTR. + - The lp and lpr commands now use sigaction or sigset + when available. + - CUPS library updates for WIN32/OS-2 + + +CHANGES IN CUPS v1.0.3 + + - Documentation updates. + - The lpq man page was missing. + - The configure script was not properly detecting the + image libraries. + - The top-level makefile was calling "make" instead of + "$(MAKE)". + - PostScript filter fixes for number-up, OutputOrder, + and %Trailer. + - The imagetops filter didn't end the base-85 encoding + properly if the image data was not a multiple of 4 + bytes in length. + - The imagetoraster filter didn't generate good banded + RGB or CMY data (was dividing the line width by 4 + instead of 3...) + - The imagetoraster filter now records the bounding + box of the image on the page. + - The CUPS image library cache code wasn't working as + designed; images larger than the maximum RIP cache + would eventually thrash using the same cache tile. + - The CUPS image library TIFF loading code didn't + handle unknown resolution units properly; the fixed + code uses a default resolution of 128 PPI. + - cupsGetClasses() and cupsGetPrinters() did not free + existing strings if they ran out of memory. + - The scheduler logs incorrectly contained 3 digits for + the timezone offset instead of 4. + - The scheduler now does a lookup for the default user + and group ID; the previous hardcoded values caused + problems with the LPD backend. + - The cancel-job operation now allows any user in the + system group to cancel any job. + - The cancel-job operation stopped the print queue if + the job was being printed. + - Now only stop printers if the backend fails. If the + filter fails then the failure is noted in the + error_log and printing continues with the next file in + the queue. + - Now log whether a filter fails because of a signal + or because it returned a non-zero exit status. + - The root user now always passes the system group test. + - Printers with an interface script and remote printers + and classes didn't have a printer-make-and-model + attribute. + - Added logging of lost/timed-out remote printers. + - The HP-GL/2 filter was scaling the pen width twice. + - Updated the HP-GL/2 filter to use a single SP (Set + Pen) procedure. This makes the output smaller and is + more appropriate since the filter keeps track of the + pen states already. + - The scheduler didn't handle passwords with spaces. + - The IPP backend now does multiple copies and retries + if the destination server requires it (e.g. HP + JetDirect.) + - The disable command didn't implement the "-c" option + (cancel all jobs.) + - Changed the CMYK generation function for the image file + and PostScript RIPs. + - The lp command didn't support the "-h" option as + documented. + - The AppSocket, IPP, and LPD backends now retry on all + network errors. This should prevent stopped queues + caused by a printer being disconnected from the + network or powered off. + - The scheduler now restarts a job if the corresponding + printer is modified. + - The image RIPs now rotate the image if needed to fit + on the page. + + +CHANGES IN CUPS v1.0.2 + + - The HP-GL/2 filter didn't always scale the output + correctly. + - The HP-GL/2 filter now supports changing the page size + automatically when the "fitplot" option is not used. + - The cancel-job operation was expecting a resource name + of the form "/job/#" instead of "/jobs/#"; this + prevented the cancel and lprm commands from working. + - The backends didn't log pages when files were printed + using the "-oraw" option. + - The authorization code did not work with the Slackware + long shadow password package because its crypt() can + return NULL. + - The chunking code didn't work for reading the response + of a POST request. + - cupsGetPPD() now does authentication as needed. + - The N-up code in the PostScript filter didn't work + with some printers (grestoreall would restore the + default blank page and device settings). + - The N-up code in the PostScript filter didn't scale + the pages to fit within the imageable area of the + page. + - Wasn't doing an fchown() on the request files. This + caused problems when the default root account group + and CUPS group were not the same. + + +CHANGES IN CUPS v1.0.1 + + - Documentation updates. + - Fixed a bunch of possible buffer-overflow conditions. + - The scheduler now supports authentication using PAM. + - Updated the Italian message file. + - httpEncode64() didn't add an extra "=" if there was + only one byte in the last three-byte group. + - Now drop any trailing character set from the locale + string (e.g. "en_US.ISO_8859-1" becomes "en_US") + - Fixed "timezone" vs "tm_gmtoff" usage for BSD-based + operating systems. + - Updated IPP security so that "get" operations can be + done from any resource name; this allows the CGIs to + work with printer authentication enabled so long as + authentication isn't turned on for the whole "site". + - The IPP code didn't properly handle the "unsupported" + group; this caused problems with the HP JetDirect since + it doesn't seem to support the "copies" attribute. + - The HTTP chunking code was missing a CR LF pair at the + end of a 0-length chunk. + - The httpSeparate() function didn't handle embedded + usernames and passwords in the URI properly. + - Doing "lpadmin -p printer -E" didn't restart printing + if there were pending jobs. + - The cancel-job operation now requires either a + requesting-user-name attribute or an authenticated + username. + - The add-printer code did not report errors if the + interface script or PPD file could not be renamed. + - Request files are now created without world read + permissions. + - Added a cupsLastError() function to the CUPS API to + retrieve the IPP error code from the last request. + - Options are now case-insensitive. + - The lpq command now provides 10 characters for the + username instead of the original (Berkeley standard) + 7. + - The cancel command needed a local CUPS server to work + (or the appropriate ServerName in cupsd.conf) + - The cancel and lprm commands didn't report the IPP + error if the job could not be cancelled. + - The lp and lpr commands didn't intercept SIGTERM to + remove temporary files when printing from stdin. + - The lp and lpr commands didn't report the IPP error if + the job could not be printed. diff --git a/CREDITS.txt b/CREDITS.txt new file mode 100644 index 0000000000..71bad14862 --- /dev/null +++ b/CREDITS.txt @@ -0,0 +1,26 @@ +CREDITS.txt - 01/27/2000 +------------------------ + +Few projects are completed by one person, and CUPS is no exception. We'd +like to thank the following individuals for their contributions: + + Nathaniel Barbour - Lots of testing and feedback. + N. Becker - setsid(). + Jean-Eric Cuendet - GhostScript filters for CUPS. + Van Dang - HTTP and IPP policeman. + Dr. ZP Han - setgid()/setuid(). + Guy Harris - *BSD shared libraries and lots of other fixes. + Wang Jian - CUPS RPM corrections. + Roderick Johnstone - Beta tester of the millenium. + Sergey V. Kovalyov - ESP Print Pro and CUPS beta tester. + Mark Lawrence - Microsoft interoperability testing. + Jason McMullan - Original CUPS RPM distributions. + Wes Morgan - *BSD fixes. + Ulrich Oldendorf - German locale. + Petter Reinholdtsen - HP-UX compiler stuff. + Stuart Stevens - HP JetDirect IPP information. + Kiko - Bug fixes. + L. Peter Deutsch - MD5 code. + +If I've missed someone, please let me know by sending an email to +"mike@easysw.com". diff --git a/LICENSE.html b/LICENSE.html new file mode 100644 index 0000000000..ad7fc21cd0 --- /dev/null +++ b/LICENSE.html @@ -0,0 +1,895 @@ + + + Software License Agreement - Common UNIX Printing System + + + + +

Common UNIX Printing System License Agreement

+ +

Copyright 1997-2000 by Easy Software Products
+44141 AIRPORT VIEW DR STE 204
+HOLLYWOOD, MARYLAND 20636-3111 USA
+
+Voice: +1.301.373.9603
+Email: cups-info@cups.org
+WWW: http://www.cups.org + +

Introduction

+ +

The Common UNIX Printing SystemTM, ("CUPSTM"), +is provided under the GNU General Public License ("GPL") and GNU +Library General Public License ("LGPL"), Version 2. A copy of these +licenses follow this introduction. + +

The GNU LGPL applies to the CUPS API library, located in the "cups" +subdirectory of the CUPS source distribution and in the +"/usr/include/cups" directory and "libcups.a", "libcups.sl", or +"libcups.so" files in the binary distributions. + +

The GNU GPL applies to the remainder of the CUPS distribution, +including the "pstoraster" filter which is based upon GNU Ghostscript +5.50 and the "pdftops" filter which is based upon Xpdf 0.90. + +

For those not familiar with the GNU GPL, the license basically +allows you to: + +

+ +

What this license does not allow you to do is make changes or +add features to CUPS and then sell a binary distribution without source +code. You must provide source for any new drivers, changes, or +additions to the software, and all code must be provided under the GPL +or LGPL as appropriate. + +

The GNU LGPL relaxes the "link-to" restriction, allowing you to +develop applications that use the CUPS API library under other licenses +and/or conditions as appropriate for your application. + +

Trademarks

+ +

Easy Software Products has trademarked the Common UNIX Printing +System, CUPS, and CUPS logo. These names and logos may be used freely +in any direct port or binary distribution of CUPS. To use them in +derivative products, please contract Easy Software Products for written +permission. Our intention is to protect the value of these trademarks and +ensure that any derivative product meets the same high-quality +standards as the original. + +

Binary Distribution Rights

+ +

Easy Software Products also sells rights to the CUPS source code +under a binary distribution license for vendors that are unable to +release source code for their drivers, additions, and modifications to +CUPS under the GNU GPL and LGPL. For information please contact us at +the address shown above. + +

The Common UNIX Printing System provides a "pstoraster" filter that +utilizes the GNU GhostScript 5.50 core to convert PostScript files into +a stream of raster images. For binary distribution licensing of this +software, please contact: + +

+Miles Jones
+Director of Marketing
+Artifex Software Inc.
+454 Las Gallinas Ave., Suite 108
+San Rafael, CA 94903 USA
+Voice: +1.415.492.9861
+Fax: +1.415.492.9862
+EMail: info@arsoft.com +
+ +

The "pdftops" filter is based on the Xpdf 0.90 software. For binary +distribution licensing of this software, please contact: + +

+Derek B. Noonburg
+Email: derekn@foolabs.com
+WWW: http://www.foolabs.com/xpdf/ +
+ +

Support

+ +

Easy Software Products sells software support for CUPS as well as a +commercial printing product based on CUPS called ESP Print Pro. You can +find out more at our web site: + +

+ + +

GNU GENERAL PUBLIC LICENSE

+ +

Version 2, June 1991 + +

+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+
+
+

Preamble

+ +

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + +

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + +

For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + +

We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + +

Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + +

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + +

The precise terms and conditions for copying, distribution and +modification follow. + +

GNU GENERAL PUBLIC LICENSE
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+ +
    + +
  1. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +

    Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + +

  2. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +

    You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +

  3. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +
      + +
    1. You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. + +
    2. You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any +part thereof, to be licensed as a whole at no charge to all third +parties under the terms of this License. + +
    3. if the modified program normally reads commands interactively +when run, you must cause it, when started running for such +interactive use in the most ordinary way, to print or display an +announcement including an appropriate copyright notice and a +notice that there is no warranty (or else, saying that you provide +a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this +License. (Exception: if the Program itself is interactive but +does not normally print such an announcement, your work based on +the Program is not required to print an announcement.) + +
    + +

    These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +

    Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +

    In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +

  4. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + +
      + +
    1. Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, + +
    2. Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your +cost of physically performing source distribution, a complete +machine-readable copy of the corresponding source code, to be +distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, + +
    3. Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form with such +an offer, in accord with Subsection b above.) + +
    + +

    The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +

    If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + +

  5. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + +
  6. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + +
  7. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +
  8. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +

    If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +

    It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +

    This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +

  9. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + +
  10. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +

    Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + +

  11. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + +
+ +

NO WARRANTY

+ +
    + +
  1. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + +
  2. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + +
+ +

END OF TERMS AND CONDITIONS

+ + +

GNU LIBRARY GENERAL PUBLIC LICENSE

+ +

Version 2, June 1991 + +

+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+ +

Preamble

+ +

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + +

This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + +

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + +

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + +

For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + +

Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + +

Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + +

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + +

Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + +

The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + +

Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + +

However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + +

The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + +

Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + +

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+ +

0. +This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + +

A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + +

The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + +

"Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + +

Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + +

1. +You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + +

You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + +

2. +You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + +

    + +
  1. The modified work must itself be a software library. + +

    +

  2. You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + +

    +

  3. You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + +

    +

  4. If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + +

    (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +

+ +

These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +

Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +

In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + +

3. +You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + +

Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + +

This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + +

4. +You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + +

If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + +

5. +A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + +

However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + +

When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + +

If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + +

Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + +

6. +As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + +

You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + +

    + +
  1. Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + +

    +

  2. Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + +

    +

  3. If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + +

    +

  4. Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + +
+ +

For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + +

It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + +

7. +You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + +

    + +
  1. Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + +

    +

  2. Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + +
+ +

8. +You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + +

9. +You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + +

10. +Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + +

11. +If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +

If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +

It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +

This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + +

12. +If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + +

13. +The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +

Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + +

14. +If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + +

NO WARRANTY + +

15. +BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + +

16. +IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + +

END OF TERMS AND CONDITIONS

+ + + diff --git a/Makedefs.in b/Makedefs.in new file mode 100644 index 0000000000..45a8676083 --- /dev/null +++ b/Makedefs.in @@ -0,0 +1,163 @@ +# +# "$Id$" +# +# Common makefile definitions for the Common UNIX Printing System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +# +# Programs... +# + +AR = @AR@ +AWK = @AWK@ +CC = @LIBTOOL@ @CC@ +CHMOD = @CHMOD@ +CP = @CP@ +CXX = @LIBTOOL@ @CXX@ +DSO = @DSO@ +HTMLDOC = @HTMLDOC@ +LIBTOOL = @LIBTOOL@ +LN = /bin/ln -sf +MKDIR = @MKDIR@ -p +MV = @MV@ +NROFF = @NROFF@ +RANLIB = @RANLIB@ +RM = @RM@ -f +SED = @SED@ +SHELL = /bin/sh + +# +# Installation programs... +# + +INSTALL_BIN = $(LIBTOOL) $(CP) +INSTALL_DATA = $(CP) +INSTALL_LIB = $(LIBTOOL) $(CP) +INSTALL_MAN = $(CP) +INSTALL_SCRIPT = $(CP) +INSTALL_SYSV = @INSTALL_SYSV@ + +# +# Libraries... +# + +LIBCUPS = @LIBCUPS@ +LIBCUPSIMAGE = @LIBCUPSIMAGE@ +LIBJPEG = @LIBJPEG@ +LIBPNG = @LIBPNG@ +LIBTIFF = @LIBTIFF@ +LIBZ = @LIBZ@ + +# +# Program options... +# +# OPTIM defines the common compiler optimization/debugging options. +# OPTIONS defines other compile-time options (currently only -dDEBUG for +# extra debug info) +# + +ARFLAGS = crvs +CFLAGS = @CFLAGS@ $(OPTIM) -I.. $(OPTIONS) +CXXFLAGS = @CXXFLAGS@ $(OPTIM) -I.. $(OPTIONS) +DSOLIBS = @DSOLIBS@ +IMGLIBS = @IMGLIBS@ -lm +LDFLAGS = @LDFLAGS@ $(OPTIM) +LINKCUPS = @LINKCUPS@ +LINKCUPSIMAGE = @LINKCUPSIMAGE@ +LIBS = $(LINKCUPS) $(NETLIBS) @LIBS@ +NETLIBS = @NETLIBS@ +OPTIM = @OPTIM@ +OPTIONS = + +# +# Directories... +# +# The first section uses the GNU names (which are *extremely* +# difficult to find in a makefile because they are lowercase...) +# We have to define these first because autoconf uses ${prefix} +# and ${exec_prefix} for most of the other directories... +# +# This is immediately followed by definition in ALL CAPS for the +# needed directories... +# + +bindir = @bindir@ +datadir = @datadir@ +exec_prefix = @exec_prefix@ +includedir = @includedir@ +infodir = @infodir@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +oldincludedir = @oldincludedir@ +prefix = @prefix@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +top_srcdir = @top_srcdir@ + +BINDIR = @bindir@ +DATADIR = @CUPS_DATADIR@ +DOCDIR = @CUPS_DOCROOT@ +ESP_ROOT = @ESP_ROOT@ +INCLUDEDIR = $(includedir) +LIBDIR = $(libdir) +LOCALEDIR = @CUPS_LOCALEDIR@ +LOGDIR = @CUPS_LOGDIR@ +MANDIR = @mandir@ +PAMDIR = @PAMDIR@ +REQUESTS = @CUPS_REQUESTS@ +SBINDIR = @sbindir@ +SERVERBIN = @CUPS_SERVERBIN@ +SERVERROOT = @CUPS_SERVERROOT@ + +CAT1EXT = @CAT1EXT@ +CAT5EXT = @CAT5EXT@ +CAT8EXT = @CAT8EXT@ + +# +# Rules... +# + +.SILENT: +.SUFFIXES: .a .c .cxx .h .man .o .0 .1 .5 .8 .z +.c.o: + echo Compiling $<... + $(CC) $(CFLAGS) -c $< +.cxx.o: + echo Compiling $<... + $(CXX) $(CXXFLAGS) -c $< +.man.0 .man.1 .man.5 .man.8: + echo Formatting $<... + $(RM) $@ + $(NROFF) -man $< >$@ +.man.z: + echo Formatting $<... + $(RM) $@ t.z + $(NROFF) -man $< >t + pack -f t + $(MV) t.z $@ + +# +# End of "$Id$" +# diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..e7241edb42 --- /dev/null +++ b/Makefile @@ -0,0 +1,128 @@ +# +# "$Id$" +# +# Top-level Makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include Makedefs + +# +# Directories to make... +# + +DIRS = cups backend berkeley cgi-bin doc filter man pdftops pstoraster \ + scheduler systemv + +# +# Make all targets... +# + +all: + for dir in $(DIRS); do\ + echo Making all in $$dir... ;\ + (cd $$dir ; $(MAKE) $(MFLAGS)) || exit 1;\ + done + +# +# Remove object and target files... +# + +clean: + for dir in $(DIRS); do\ + echo Cleaning in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) clean) || exit 1;\ + done + +# +# Install object and target files... +# + +install: + for dir in $(DIRS); do\ + echo Installing in $$dir... ;\ + (cd $$dir; $(MAKE) $(MFLAGS) install) || exit 1;\ + done + echo Installing in conf... + (cd conf; $(MAKE) $(MFLAGS) install) + echo Installing in data... + (cd data; $(MAKE) $(MFLAGS) install) + echo Installing in fonts... + (cd fonts; $(MAKE) $(MFLAGS) install) + (cd fonts; $(MAKE) $(MFLAGS) install) + echo Installing in locale... + echo Installing in ppd... + (cd ppd; $(MAKE) $(MFLAGS) install) + echo Installing in templates... + (cd templates; $(MAKE) $(MFLAGS) install) + echo Installing startup script... + if test -d $(prefix)/sbin/init.d; then \ + $(INSTALL_SCRIPT) cups.sh $(prefix)/sbin/init.d/cups; \ + $(CHMOD) ugo+rx $(prefix)/sbin/init.d/cups; \ + ln -s ../init.d/cups $(prefix)/sbin/rc0.d/K000cups; \ + ln -s ../init.d/cups $(prefix)/sbin/rc2.d/S999cups; \ + fi + if test -d $(prefix)/etc/rc.d/init.d; then \ + $(INSTALL_SCRIPT) cups.sh $(prefix)/etc/rc.d/init.d/cups; \ + $(CHMOD) ugo+rx $(prefix)/etc/rc.d/cups; \ + ln -s ../init.d/cups $(prefix)/etc/rc.d/rc0.d/K00cups; \ + ln -s ../init.d/cups $(prefix)/etc/rc.d/rc2.d/S99cups; \ + fi + if test -d $(prefix)/etc/init.d; then \ + $(INSTALL_SCRIPT) cups.sh $(prefix)/etc/init.d/cups; \ + $(CHMOD) ugo+rx $(prefix)/etc/init.d/cups; \ + ln -s ../init.d/cups $(prefix)/etc/rc0.d/K00cups; \ + ln -s ../init.d/cups $(prefix)/etc/rc2.d/S99cups; \ + fi + +# +# Make software distributions using EPM (http://www.easysw.com/epm)... +# + +EPMFLAGS = -v \ + BINDIR=$(BINDIR) DATADIR=$(DATADIR) \ + DOCDIR=$(DOCDIR) ESP_ROOT=$(ESP_ROOT) \ + INCLUDEDIR=$(INCLUDEDIR) LIBDIR=$(LIBDIR) \ + LOCALEDIR=$(LOCALEDIR) LOGDIR=$(LOGDIR) \ + MANDIR=$(MANDIR) PAMDIR=$(PAMDIR) \ + REQUESTS=$(REQUESTS) SBINDIR=$(SBINDIR) \ + SERVERBIN=$(SERVERBIN) SERVERROOT=$(SERVERROOT) + +epm: + epm $(EPMFLAGS) cups + +rpm: + epm $(EPMFLAGS) -f rpm cups + +deb: + epm $(EPMFLAGS) -f deb cups + +depot: + epm $(EPMFLAGS) -f depot cups + +pkg: + epm $(EPMFLAGS) -f pkg cups + +tardist: + epm $(EPMFLAGS) -f tardist cups + +# +# End of "$Id$". +# diff --git a/README.txt b/README.txt new file mode 100644 index 0000000000..ce3df5bfb3 --- /dev/null +++ b/README.txt @@ -0,0 +1,266 @@ +README - CUPS v1.1.1 - 07/21/2000 +--------------------------------- + +INTRODUCTION + +CUPS provides a portable printing layer for UNIX(r)-based operating +systems. It has been developed by Easy Software Products to promote a +standard printing solution for all UNIX vendors and users. CUPS +provides the System V and Berkeley command-line interfaces. + +CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX. + +CUPS also includes a customized version of GNU Ghostscript (currently +based off GNU Ghostscript 5.50) and an image file RIP that are used to +support non-PostScript printers. Sample drivers for HP and EPSON +printers are included that use these filters. + +Drivers for over 2300 printers are provided with our ESP Print Pro +software, available at: + + http://www.easysw.com/printpro + +CUPS is licensed under the GNU General Public License and GNU Library +General Public License. Please contact Easy Software Products for +commercial support and "binary distribution" rights. + + +SYSTEM REQUIREMENTS + +Binary distributions require a minimum of 10MB of free disk space. We +do not recommend using CUPS on a workstation with less than 32MB of RAM +or a PC with less than 16MB of RAM. + +If you are installing from source you'll need ANSI-compliant C and C++ +compilers and optionally one or more image file support libraries. +Complete source installation instructions can be found in the CUPS +System Administrator's Manual in the files "doc/sam.html" or +"doc/sam.pdf". + + +SOFTWARE REQUIREMENTS + +The following operating system software is required to install one of +the binary distributions from Easy Software Products: + + - Digital UNIX (aka OSF1 aka Compaq Tru64 UNIX) 4.0 or higher + - HP-UX 10.20 or higher + - IRIX 5.3 or higher + - Linux 2.0 with glibc2 or higher + - Solaris 2.5 or higher (SPARC or Intel) + + +INSTALLING "PORTABLE" CUPS DISTRIBUTIONS + +We are currently distributing "portable" CUPS binary distributions in +TAR format with installation and removal scripts generated by our ESP +Package Manager (EPM) software, which is available from: + + http://www.easysw.com/epm + +WARNING: Installing CUPS will overwrite your existing printing system. +Backup files are made by the installation script and restored by the +removal script, so if you experience problems you should be able to +remove the CUPS software to restore your previous configuration. +However, Easy Software Products makes no warranty for this and will not +be liable for any lost revenues, etc. + +To install the CUPS software you will need to be logged in as root +(doing an "su" is good enough). Once you are the root user, run the +installation script with: + + ./cups.install ENTER + +After asking you a few yes/no questions the CUPS software will be +installed and the scheduler will be started automatically. + + +INSTALLING HOST-SPECIFIC (RPM, DEBIAN, ETC.) DISTRIBUTIONS + +The host-specific distributions use the operating system software +installation tools. To install a host-specific distribution please +consult the CUPS Software Administrators Manual or your operating +system documentation. + + +READING THE DOCUMENTATION + +Once you have installed the software you can access the documentation +(and a bunch of other stuff) on-line at: + + http://localhost:631 + +If you're having trouble getting that far, the documentation is located +in the "/usr/share/doc/cups" directory in the binary distributions, and +under the "doc" directory in the source archives. + +Please read the documentation before asking questions. + + +SETTING UP PRINTER QUEUES USING YOUR WEB BROWSER + +CUPS 1.1 includes a new web-based administration tool that allows you +to manage printers, classes, and jobs on your server. To access the +printer administration tools open the following URL in your browser: + + http://localhost:631/admin + +You will be asked for the administration password (root or any other +user in the sys/system/root group on your system) and then shown a +menu of available functions. + +DO NOT use the hostname for your machine - it will not work with the +default CUPS configuration. To enable administration access on other +addresses, consult the CUPS Software Administrators Manual. + + +SETTING UP PRINTER QUEUES FROM THE COMMAND-LINE + +CUPS works best with PPD (PostScript Printer Description) files. In a +pinch you can also use System V style printer interface scripts. + +Six sample PPD files are provided with this distribution that utilize +the PostScript and image file RIPs and the sample EPSON and HP printer +drivers. To add the sample DeskJet driver to the system for a printer +connected to the parallel port, use one of the following commands: + + Digital UNIX: + + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp0 -E + + HP-UX: + + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/c2t0d0_lp -E + + IRIX: + + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/plp -E + + Linux: + + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp0 -E + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp1 -E + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/lp2 -E + + Solaris: + + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/bpp0 -E + /usr/lib/lpadmin -p DeskJet -m deskjet.ppd -v parallel:/dev/ecpp0 -E + +Similarly, for the other sample drivers you can use: + + Driver PPD File + -------------------------- ------------ + HP DeskJet Series deskjet.ppd + HP LaserJet Series laserjet.ppd + EPSON Stylus Color Series stcolor.ppd + EPSON Stylus Photo Series stphoto.ppd + EPSON 9-pin Series epson9.ppd + EPSON 24-pin Series epson24.ppd + +These sample drivers provide basic printing capabilities, but generally +do not exercise the full potential of the printers or CUPS. For +commercial printer drivers check out our ESP Print Pro software at: + + http://www.easysw.com/printpro + + +PRINTING FILES + +CUPS provides both the System V "lp" and Berkeley "lpr" commands for +printing: + + lp filename + lpr filename + +Both the "lp" and "lpr" commands support printing options for the +driver: + + lp -omedia=A4 -oresolution=600dpi filename + lpr -omedia=A4 -oresolution=600dpi filename + +CUPS recognizes many types of images files as well as PDF, PostScript, +HP-GL/2, and text files, so you can print those files directly rather +than through an application. + +If you have an application that generates output specifically for your +printer then you need to use the "-oraw" or "-l" options: + + lp -oraw filename + lpr -l filename + +This will prevent the filters from misinterpreting your print file. + + +REPORTING PROBLEMS + +If you have problems, READ THE DOCUMENTATION FIRST! If the +documentation does not solve your problems please send an email to +cups-support@cups.org. Include your operating system and version, +compiler and version, and any errors or problems you've run into. The +/var/log/error_log file should also be sent, as it often helps to +determine the cause of your problem. + +If you are running a version of Linux, be sure to provide the Linux +distribution you have, too. + +Please note that the "cups-support@cups.org" email address goes to the +CUPS developers; they are busy people, so your email may go unanswered +for days or weeks. Commercial support (with a guaranteed response +time) is available from Easy Software Products. + + +OTHER RESOURCES + +See the CUPS web site at "http://www.cups.org" for other site links. + +You can subscribe to the CUPS mailing list by sending a message +containing "subscribe cups" to majordomo@cups.org. This list is +provided to discuss problems, questions, and improvements to the CUPS +software. New releases of CUPS are announced to this list as well. + + +LEGAL STUFF + +CUPS is Copyright 1993-2000 by Easy Software Products. CUPS, the CUPS +logo, and the Common UNIX Printing System are the trademark property of +Easy Software Products. + +The MD5 Digest code is Copyright 1999 Aladdin Enterprises. + +The PostScript RIP software (pstoraster) is based on the GNU +Ghostscript 5.50 core, Copyright 1986-1998 by Aladdin Enterprises. + +The PDF filter (pdftops) is based on the Xpdf 0.90 software, Copyright +1996-1999 by Derek B. Noonburg. + +This software is based in part on the work of the Independent JPEG +Group. + +CUPS is provided under the terms of the GNU General Public License and +GNU Library General Public License. This program is distributed in the +hope that it will be useful, but WITHOUT ANY WARRANTY; without even the +implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR +PURPOSE. See the "LICENSE.html", "LICENSE.txt", or "cups.license" files +for more information. + +For commercial licensing information, please contact: + + Attn: CUPS Licensing Information + Easy Software Products + 44141 Airport View Drive, Suite 204 + Hollywood, Maryland 20636-3111 USA + + Voice: +1.301.373.9603 + Email: cups-info@cups.org + WWW: http://www.cups.org + +Note that commercial licensors may also require a license from Artifex +Software Inc. which handles commercial licensing of the Ghostscript +software, and from Derek B. Noonburg who developed the Xpdf software +used to print PDF files. diff --git a/backend/Makefile b/backend/Makefile new file mode 100644 index 0000000000..7cb23729ad --- /dev/null +++ b/backend/Makefile @@ -0,0 +1,141 @@ +# +# "$Id$" +# +# Backend makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +BACKENDS = ipp lpd parallel serial socket usb +TARGETS = betest $(BACKENDS) +OBJS = betest.o ipp.o lpd.o parallel.o serial.o socket.o usb.o + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) $(TARGETS) + + +# +# Install all targets... +# + +install: + -$(MKDIR) $(SERVERBIN)/backend + $(CHMOD) ugo+rx $(SERVERBIN) + $(CHMOD) ugo+rx $(SERVERBIN)/backend + $(INSTALL_BIN) $(BACKENDS) $(SERVERBIN)/backend + $(RM) $(SERVERBIN)/backend/http + $(LN) ipp $(SERVERBIN)/backend/http + + +# +# betest +# + +betest: betest.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o betest betest.o $(LIBS) + +betest.o: ../cups/string.h ../Makedefs + + +# +# ipp +# + +ipp: ipp.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o ipp ipp.o $(LIBS) + $(RM) http + $(LN) ipp http + +ipp.o: ../cups/cups.h ../Makedefs + + +# +# lpd +# + +lpd: lpd.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o lpd lpd.o $(LIBS) + +lpd.o: ../cups/cups.h ../Makedefs + + +# +# parallel +# + +parallel: parallel.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o parallel parallel.o $(LIBS) + +parallel.o: ../cups/cups.h ../Makedefs + + +# +# serial +# + +serial: serial.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o serial serial.o $(LIBS) + +serial.o: ../cups/cups.h ../Makedefs + + +# +# socket +# + +socket: socket.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o socket socket.o $(LIBS) + +socket.o: ../cups/cups.h ../Makedefs + + +# +# usb +# + +usb: usb.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o usb usb.o $(LIBS) + +usb.o: ../cups/cups.h ../Makedefs + + +# +# End of "$Id$". +# diff --git a/backend/betest.c b/backend/betest.c new file mode 100644 index 0000000000..8c68284e1e --- /dev/null +++ b/backend/betest.c @@ -0,0 +1,85 @@ +/* + * "$Id$" + * + * Backend test program for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Run the named backend. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include + + +/* + * 'main()' - Run the named backend. + * + * Usage: + * + * betest device-uri job-id user title copies options [file] + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments (7 or 8) */ + char *argv[]) /* I - Command-line arguments */ +{ + char backend[255]; /* Method in URI */ + + + if (argc < 7 || argc > 8) + { + fputs("Usage: betest device-uri job-id user title copies options [file]\n", + stderr); + return (1); + } + + /* + * Extract the method from the device-uri - that's the program we want to + * execute. + */ + + if (sscanf(argv[1], "%254[^:]", backend) != 1) + { + fputs("betest: Bad device-uri - no colon!\n", stderr); + return (1); + } + + /* + * Execute and return + */ + + execl(backend, argv[1], argv[2], argv[3], argv[4], argv[5], argv[6], argv[7], + NULL); + + return (1); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/ipp.c b/backend/ipp.c new file mode 100644 index 0000000000..24f1cf2962 --- /dev/null +++ b/backend/ipp.c @@ -0,0 +1,721 @@ +/* + * "$Id$" + * + * IPP backend for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Send a file to the printer or server. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * 'main()' - Send a file to the printer or server. + * + * Usage: + * + * printer-uri job-id user title copies options [file] + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + int n, n2; /* Attribute values */ + char *option, /* Name of option */ + *s; /* Pointer into option value */ + const char *val; /* Pointer to option value */ + int num_options; /* Number of printer options */ + cups_option_t *options; /* Printer options */ + char method[255], /* Method in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info */ + resource[1024], /* Resource info (printer name) */ + filename[1024]; /* File to print */ + int port; /* Port number (not used) */ + char password[255], /* Password info */ + uri[HTTP_MAX_URI];/* Updated URI without user/pass */ + http_status_t status; /* Status of HTTP job */ + ipp_status_t ipp_status; /* Status of IPP request */ + FILE *fp; /* File to print */ + http_t *http; /* HTTP connection */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *job_id; /* job-id attribute */ + ipp_attribute_t *copies_sup; /* copies-supported attribute */ + cups_lang_t *language; /* Default language */ + struct stat fileinfo; /* File statistics */ + size_t nbytes, /* Number of bytes written */ + tbytes; /* Total bytes written */ + char buffer[8192]; /* Output buffer */ + int copies; /* Number of copies remaining */ + const char *content_type; /* CONTENT_TYPE environment variable */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + int version; /* IPP version */ + + + if (argc == 1) + { + if ((s = strrchr(argv[0], '/')) != NULL) + s ++; + else + s = argv[0]; + + printf("network %s \"Unknown\" \"Internet Printing Protocol\"\n", s); + return (0); + } + else if (argc < 6 || argc > 7) + { + fprintf(stderr, "Usage: %s job-id user title copies options [file]\n", + argv[0]); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, copy stdin to a temporary file and print the temporary + * file. + */ + + if (argc == 6) + { + /* + * Copy stdin to a temporary file... + */ + + FILE *fp; /* Temporary file */ + char buffer[8192]; /* Buffer for copying */ + int bytes; /* Number of bytes read */ + + + if ((fp = fopen(cupsTempFile(filename, sizeof(filename)), "w")) == NULL) + { + perror("ERROR: unable to create temporary file"); + return (1); + } + + while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) + if (fwrite(buffer, 1, bytes, fp) < bytes) + { + perror("ERROR: unable to write to temporary file"); + fclose(fp); + unlink(filename); + return (1); + } + + fclose(fp); + } + else + { + strncpy(filename, argv[6], sizeof(filename) - 1); + filename[sizeof(filename) - 1] = '\0'; + } + + /* + * Open the print file... + */ + + if ((fp = fopen(filename, "rb")) == NULL) + { + perror("ERROR: Unable to open print file"); + return (1); + } + else + stat(filename, &fileinfo); + + /* + * Extract the hostname and printer name from the URI... + */ + + httpSeparate(argv[0], method, username, hostname, &port, resource); + + /* + * Try connecting to the remote server... + */ + + do + { + fprintf(stderr, "INFO: Connecting to %s...\n", hostname); + + if ((http = httpConnect(hostname, port)) == NULL) + { + if (errno == ECONNREFUSED) + { + fprintf(stderr, "INFO: Network host \'%s\' is busy; will retry in 30 seconds...", + hostname); + sleep(30); + } + else + { + perror("ERROR: Unable to connect to IPP host"); + sleep(30); + } + } + } + while (http == NULL); + + /* + * Build a URI for the printer and fill the standard IPP attributes for + * an IPP_PRINT_FILE request. We can't use the URI in argv[0] because it + * might contain username:password information... + */ + + snprintf(uri, sizeof(uri), "%s://%s:%d%s", method, hostname, port, resource); + + /* + * First validate the destination and see if the device supports multiple + * copies. We have to do this because some IPP servers (e.g. HP JetDirect) + * don't support the copies attribute... + */ + + language = cupsLangDefault(); + copies_sup = NULL; + version = 1; + + do + { + /* + * Build the IPP request... + */ + + request = ippNew(); + request->request.op.version[1] = version; + request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, "utf-8"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, + language != NULL ? language->language : "en"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Now fill in the HTTP request stuff... + */ + + httpClearFields(http); + httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); + if (username[0]) + { + httpEncode64(password, username); + httpSetField(http, HTTP_FIELD_AUTHORIZATION, password); + } + + sprintf(buffer, "%u", ippLength(request)); + httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, buffer); + + /* + * Do the request... + */ + + for (;;) + { + /* + * POST the request, retrying as needed... + */ + + if (httpPost(http, resource)) + { + fputs("INFO: Unable to POST get-printer-attributes request; retrying...\n", stderr); + sleep(10); + httpReconnect(http); + continue; + } + + fputs("INFO: POST successful, sending IPP request...\n", stderr); + + /* + * Send the IPP request... + */ + + request->state = IPP_IDLE; + + if (ippWrite(http, request) == IPP_ERROR) + { + fputs("ERROR: Unable to send IPP request!\n", stderr); + status = HTTP_ERROR; + break; + } + + fputs("INFO: IPP request sent, getting status...\n", stderr); + + /* + * Finally, check the status from the HTTP server... + */ + + while ((status = httpUpdate(http)) == HTTP_CONTINUE); + + if (status == HTTP_OK) + { + response = ippNew(); + ippRead(http, response); + + ipp_status = response->request.status.status_code; + + if (ipp_status > IPP_OK_CONFLICT) + { + if (ipp_status == IPP_PRINTER_BUSY || + ipp_status == IPP_SERVICE_UNAVAILABLE) + { + fputs("INFO: Printer busy; will retry in 10 seconds...\n", stderr); + sleep(10); + } + else if (ipp_status == IPP_BAD_REQUEST && version == 1) + { + /* + * Switch to IPP/1.0... + */ + + fputs("INFO: Printer does not support IPP/1.1, trying IPP/1.0...\n", stderr); + version = 0; + } + else + { + fprintf(stderr, "ERROR: Printer will not accept print file (%x)!\n", + ipp_status); + fprintf(stderr, "ERROR: %s\n", ippErrorString(ipp_status)); + status = HTTP_ERROR; + } + } + else if ((copies_sup = ippFindAttribute(response, "copies-supported", + IPP_TAG_RANGE)) != NULL) + { + /* + * Has the "copies-supported" attribute - does it have an upper + * bound > 1? + */ + + if (copies_sup->values[0].range.upper <= 1) + copies_sup = NULL; /* No */ + } + + ippDelete(response); + } + else + { + response = NULL; + + if (status == HTTP_ERROR) + { + fprintf(stderr, "WARNING: Did not receive the IPP response (%d)\n", + errno); + status = HTTP_OK; + ipp_status = IPP_PRINTER_BUSY; + } + else + { + fprintf(stderr, "ERROR: Validate request was not accepted (%d)!\n", + status); + ipp_status = IPP_FORBIDDEN; + } + } + + httpFlush(http); + + break; + } + + if (status != HTTP_OK) + { + if (fp != stdin) + fclose(fp); + + httpClose(http); + + return (1); + } + else if (ipp_status > IPP_OK_CONFLICT) + httpReconnect(http); + } + while (ipp_status > IPP_OK_CONFLICT); + + /* + * Now that we are "connected" to the port, ignore SIGTERM so that we + * can finish out any page data the driver sends (e.g. to eject the + * current page... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * See if the printer supports multiple copies... + */ + + if (copies_sup) + copies = 1; + else + copies = atoi(argv[4]); + + /* + * Then issue the print-job request... + */ + + while (copies > 0) + { + /* + * Build the IPP request... + */ + + request = ippNew(); + request->request.op.version[1] = version; + request->request.op.operation_id = IPP_PRINT_JOB; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, "utf-8"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, + language != NULL ? language->language : "en"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + fprintf(stderr, "DEBUG: printer-uri = \"%s\"\n", uri); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, argv[2]); + + fprintf(stderr, "DEBUG: requesting-user-name = \"%s\"\n", argv[2]); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, + argv[3]); + + fprintf(stderr, "DEBUG: job-name = \"%s\"\n", argv[3]); + + /* + * Handle options on the command-line... + */ + + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + + if (cupsGetOption("raw", num_options, options) || + ((content_type = getenv("CONTENT_TYPE")) != NULL && + strcasecmp(content_type, "application/vnd.cups-raw") == 0)) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", + NULL, "application/vnd.cups-raw"); + else if ((val = cupsGetOption("document-format", num_options, options)) != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", + NULL, val); + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", + NULL, "application/octet-stream"); + + if (copies_sup) + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "copies", atoi(argv[4])); + + for (i = 0; i < num_options; i ++) + { + /* + * Skip the "raw" option - handled above... + */ + + if (strcasecmp(options[i].name, "raw") == 0 || + strcasecmp(options[i].name, "document-format") == 0) + continue; + + /* + * See what the option value is; for compatibility with older interface + * scripts, we have to support single-argument options as well as + * option=value, option=low-high, and option=MxN. + */ + + option = options[i].name; + val = options[i].value; + + if (*val == '\0') + val = NULL; + + if (val != NULL) + { + if (strcasecmp(val, "true") == 0 || + strcasecmp(val, "on") == 0 || + strcasecmp(val, "yes") == 0) + { + /* + * Boolean value - true... + */ + + n = 1; + val = ""; + } + else if (strcasecmp(val, "false") == 0 || + strcasecmp(val, "off") == 0 || + strcasecmp(val, "no") == 0) + { + /* + * Boolean value - false... + */ + + n = 0; + val = ""; + } + + n = strtol(val, &s, 0); + } + else + { + if (strncasecmp(option, "no", 2) == 0) + { + option += 2; + n = 0; + } + else + n = 1; + + s = ""; + } + + if (*s != '\0' && *s != '-' && (*s != 'x' || s == val)) + /* + * String value(s)... + */ + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, option, NULL, val); + else if (val != NULL) + { + /* + * Numeric value, range, or resolution... + */ + + if (*s == '-') + { + n2 = strtol(s + 1, NULL, 0); + ippAddRange(request, IPP_TAG_JOB, option, n, n2); + } + else if (*s == 'x') + { + n2 = strtol(s + 1, &s, 0); + + if (strcasecmp(s, "dpc") == 0) + ippAddResolution(request, IPP_TAG_JOB, option, IPP_RES_PER_CM, n, n2); + else if (strcasecmp(s, "dpi") == 0) + ippAddResolution(request, IPP_TAG_JOB, option, IPP_RES_PER_INCH, n, n2); + else + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, option, NULL, val); + } + else + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, option, n); + } + else + /* + * Boolean value... + */ + ippAddBoolean(request, IPP_TAG_JOB, option, (char)n); + } + + /* + * Now fill in the HTTP request stuff... + */ + + httpClearFields(http); + httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); + if (username[0]) + { + httpEncode64(password, username); + httpSetField(http, HTTP_FIELD_AUTHORIZATION, password); + } + + sprintf(buffer, "%u", ippLength(request) + (size_t)fileinfo.st_size); + httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, buffer); + + /* + * Do the request... + */ + + for (;;) + { + /* + * POST the request, retrying as needed... + */ + + httpReconnect(http); + + if (httpPost(http, resource)) + { + fputs("INFO: Unable to POST print request; retrying...\n", stderr); + sleep(10); + continue; + } + + fputs("INFO: POST successful, sending IPP request...\n", stderr); + + /* + * Send the IPP request... + */ + + request->state = IPP_IDLE; + + if (ippWrite(http, request) == IPP_ERROR) + { + fputs("ERROR: Unable to send IPP request!\n", stderr); + status = HTTP_ERROR; + break; + } + + fputs("INFO: IPP request sent, sending print file...\n", stderr); + + /* + * Then send the file... + */ + + rewind(fp); + + tbytes = 0; + while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) + { + tbytes += nbytes; + fprintf(stderr, "INFO: Sending print file, %uk...\n", tbytes / 1024); + + if (httpWrite(http, buffer, nbytes) < nbytes) + { + perror("ERROR: Unable to send print file to printer"); + status = HTTP_ERROR; + break; + } + } + + fputs("INFO: Print file sent; checking status...\n", stderr); + + /* + * Finally, check the status from the HTTP server... + */ + + while ((status = httpUpdate(http)) == HTTP_CONTINUE); + + if (status == HTTP_OK) + { + response = ippNew(); + ippRead(http, response); + + if ((ipp_status = response->request.status.status_code) > IPP_OK_CONFLICT) + { + if (ipp_status == IPP_SERVICE_UNAVAILABLE || + ipp_status == IPP_PRINTER_BUSY) + { + fputs("INFO: Printer is busy; retrying print job...\n", stderr); + sleep(10); + } + else + { + fprintf(stderr, "ERROR: Print file was not accepted (%04x)!\n", + response->request.status.status_code); + fprintf(stderr, "ERROR: %s\n", ippErrorString(ipp_status)); + } + } + else if ((job_id = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL) + fputs("INFO: Print file accepted - job ID unknown.\n", stderr); + else + fprintf(stderr, "INFO: Print file accepted - job ID %d.\n", + job_id->values[0].integer); + } + else + { + response = NULL; + ipp_status = IPP_PRINTER_BUSY; + + if (status == HTTP_ERROR) + { + fprintf(stderr, "WARNING: Did not receive the IPP response (%d)\n", + errno); + status = HTTP_OK; + } + else + fprintf(stderr, "ERROR: Print request was not accepted (%d)!\n", status); + } + + httpFlush(http); + + break; + } + + if (request != NULL) + ippDelete(request); + if (response != NULL) + ippDelete(response); + + if (ipp_status <= IPP_OK_CONFLICT) + { + fprintf(stderr, "PAGE: 1 %d\n", copies_sup ? atoi(argv[4]) : 1); + copies --; + } + else if (ipp_status != IPP_SERVICE_UNAVAILABLE && + ipp_status != IPP_PRINTER_BUSY) + break; + } + + /* + * Free memory... + */ + + httpClose(http); + + /* + * Close and remove the temporary file if necessary... + */ + + fclose(fp); + + if (argc < 7) + unlink(filename); + + /* + * Return the queue status... + */ + + return (status != HTTP_OK); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/lpd.c b/backend/lpd.c new file mode 100644 index 0000000000..176790f53e --- /dev/null +++ b/backend/lpd.c @@ -0,0 +1,442 @@ +/* + * "$Id$" + * + * Line Printer Daemon backend for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Send a file to the printer or server. + * lpd_command() - Send an LPR command sequence and wait for a reply. + * lpd_queue() - Queue a file using the Line Printer Daemon protocol. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +# include +# include +# include +#endif /* WIN32 || __EMX__ */ + +extern int rresvport(int *port); /* Hello? No prototype for this... */ + + +/* + * Local functions... + */ + +static int lpd_command(int lpd_fd, char *format, ...); +static int lpd_queue(char *hostname, char *printer, char *filename, + char *user, int copies); + + +/* + * 'main()' - Send a file to the printer or server. + * + * Usage: + * + * printer-uri job-id user title copies options [file] + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + char method[255], /* Method in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info (not used) */ + resource[1024], /* Resource info (printer name) */ + filename[1024]; /* File to print */ + int port; /* Port number (not used) */ + int status; /* Status of LPD job */ + + + if (argc == 1) + { + puts("network lpd \"Unknown\" \"LPD/LPR Host or Printer\""); + return (0); + } + else if (argc < 6 || argc > 7) + { + fprintf(stderr, "Usage: %s job-id user title copies options [file]\n", + argv[0]); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, copy stdin to a temporary file and print the temporary + * file. + */ + + if (argc == 6) + { + /* + * Copy stdin to a temporary file... + */ + + FILE *fp; /* Temporary file */ + char buffer[8192]; /* Buffer for copying */ + int bytes; /* Number of bytes read */ + + + if ((fp = fopen(cupsTempFile(filename, sizeof(filename)), "w")) == NULL) + { + perror("ERROR: unable to create temporary file"); + return (1); + } + + while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) + if (fwrite(buffer, 1, bytes, fp) < bytes) + { + perror("ERROR: unable to write to temporary file"); + fclose(fp); + unlink(filename); + return (1); + } + + fclose(fp); + } + else + { + strncpy(filename, argv[6], sizeof(filename) - 1); + filename[sizeof(filename) - 1] = '\0'; + } + + /* + * Extract the hostname and printer name from the URI... + */ + + httpSeparate(argv[0], method, username, hostname, &port, resource); + + /* + * Queue the job... + */ + + if (argc > 6) + { + status = lpd_queue(hostname, resource + 1, filename, + argv[2] /* user */, atoi(argv[4]) /* copies */); + + if (!status) + fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4])); + } + else + status = lpd_queue(hostname, resource + 1, filename, + argv[2] /* user */, 1); + + /* + * Remove the temporary file if necessary... + */ + + if (argc < 7) + unlink(filename); + + /* + * Return the queue status... + */ + + return (status); +} + + +/* + * 'lpd_command()' - Send an LPR command sequence and wait for a reply. + */ + +static int /* O - Status of command */ +lpd_command(int fd, /* I - Socket connection to LPD host */ + char *format, /* I - printf()-style format string */ + ...) /* I - Additional args as necessary */ +{ + va_list ap; /* Argument pointer */ + char buf[1024]; /* Output buffer */ + int bytes; /* Number of bytes to output */ + char status; /* Status from command */ + + + /* + * Format the string... + */ + + va_start(ap, format); + bytes = vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + fprintf(stderr, "DEBUG: lpd_command %2.2x %s", buf[0], buf + 1); + + /* + * Send the command... + */ + + fprintf(stderr, "DEBUG: Sending command string (%d bytes)...\n", bytes); + + if (send(fd, buf, bytes, 0) < bytes) + return (-1); + + /* + * Read back the status from the command and return it... + */ + + fprintf(stderr, "DEBUG: Reading command status...\n"); + + if (recv(fd, &status, 1, 0) < 1) + return (-1); + + fprintf(stderr, "DEBUG: lpd_command returning %d\n", status); + + return (status); +} + + +/* + * 'lpd_queue()' - Queue a file using the Line Printer Daemon protocol. + */ + +static int /* O - Zero on success, non-zero on failure */ +lpd_queue(char *hostname, /* I - Host to connect to */ + char *printer, /* I - Printer/queue name */ + char *filename, /* I - File to print */ + char *user, /* I - Requesting user */ + int copies) /* I - Number of copies */ +{ + FILE *fp; /* Job file */ + char localhost[255]; /* Local host name */ + int error; /* Error number */ + struct stat filestats; /* File statistics */ + int port; /* LPD connection port */ + int fd; /* LPD socket */ + char control[10240], /* LPD control 'file' */ + *cptr; /* Pointer into control file string */ + char status; /* Status byte from command */ + struct sockaddr_in addr; /* Socket address */ + struct hostent *hostaddr; /* Host address */ + size_t nbytes, /* Number of bytes written */ + tbytes; /* Total bytes written */ + char buffer[8192]; /* Output buffer */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + /* + * First try to reserve a port for this connection... + */ + + if ((hostaddr = gethostbyname(hostname)) == NULL) + { + fprintf(stderr, "ERROR: Unable to locate printer \'%s\' - %s", + hostname, strerror(errno)); + return (1); + } + + fprintf(stderr, "INFO: Attempting to connect to host %s for printer %s\n", + hostname, printer); + + memset(&addr, 0, sizeof(addr)); + memcpy(&(addr.sin_addr), hostaddr->h_addr, hostaddr->h_length); + addr.sin_family = hostaddr->h_addrtype; + addr.sin_port = htons(515); /* LPD/printer service */ + + for (port = 732;;) + { + if ((fd = rresvport(&port)) < 0) + { + perror("ERROR: Unable to reserve port"); + sleep(30); + continue; + } + + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + error = errno; + close(fd); + fd = -1; + + if (error == ECONNREFUSED) + { + fprintf(stderr, "INFO: Network host \'%s\' is busy; will retry in 30 seconds...", + hostname); + sleep(30); + } + else if (error == EADDRINUSE) + { + port --; + if (port < 721) + port = 732; + } + else + { + perror("ERROR: Unable to connect to printer"); + sleep(30); + } + } + else + break; + } + + fprintf(stderr, "INFO: Connected on port %d...\n", port); + + /* + * Now that we are "connected" to the port, ignore SIGTERM so that we + * can finish out any page data the driver sends (e.g. to eject the + * current page... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Next, open the print file and figure out its size... + */ + + if (stat(filename, &filestats)) + { + perror("ERROR: unable to stat print file"); + return (1); + } + + if ((fp = fopen(filename, "rb")) == NULL) + { + perror("ERROR: unable to open print file for reading"); + return (1); + } + + /* + * Send a job header to the printer, specifying no banner page and + * literal output... + */ + + lpd_command(fd, "\002%s\n", printer); /* Receive print job(s) */ + + gethostname(localhost, sizeof(localhost)); + localhost[31] = '\0'; /* RFC 1179, Section 7.2 - host name < 32 chars */ + + snprintf(control, sizeof(control), "H%s\nP%s\n", localhost, user); + cptr = control + strlen(control); + + while (copies > 0) + { + + snprintf(cptr, sizeof(control) - (cptr - control), "ldfA%03d%s\n", + getpid() % 1000, localhost); + cptr += strlen(cptr); + copies --; + } + + snprintf(cptr, sizeof(control) - (cptr - control), + "UdfA%03d%s\nNdfA%03d%s\n", + getpid() % 1000, localhost, + getpid() % 1000, localhost); + + fprintf(stderr, "DEBUG: Control file is:\n%s", control); + + lpd_command(fd, "\002%d cfA%03.3d%s\n", strlen(control), getpid() % 1000, + localhost); + + fprintf(stderr, "INFO: Sending control file (%d bytes)\n", strlen(control)); + + if (send(fd, control, strlen(control) + 1, 0) < (strlen(control) + 1)) + { + perror("ERROR: Unable to write control file"); + status = 1; + } + else if (read(fd, &status, 1) < 1 || status != 0) + fprintf(stderr, "ERROR: Remote host did not accept control file (%d)\n", + status); + else + { + /* + * Send the print file... + */ + + fputs("INFO: Control file sent successfully\n", stderr); + + lpd_command(fd, "\003%u dfA%03.3d%s\n", (unsigned)filestats.st_size, + getpid() % 1000, localhost); + + fprintf(stderr, "INFO: Sending data file (%u bytes)\n", + (unsigned)filestats.st_size); + + tbytes = 0; + while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) + { + fprintf(stderr, "INFO: Spooling LPR job, %u%% complete...\n", + (unsigned)(100 * tbytes / filestats.st_size)); + + if (send(fd, buffer, nbytes, 0) < nbytes) + { + perror("ERROR: Unable to send print file to printer"); + break; + } + else + tbytes += nbytes; + } + + send(fd, "", 1, 0); + + if (tbytes < filestats.st_size) + status = 1; + else if (recv(fd, &status, 1, 0) < 1 || status != 0) + fprintf(stderr, "ERROR: Remote host did not accept data file (%d)\n", + status); + else + fputs("INFO: Data file sent successfully\n", stderr); + } + + /* + * Close the socket connection and input file and return... + */ + + close(fd); + fclose(fp); + + return (status); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/parallel.c b/backend/parallel.c new file mode 100644 index 0000000000..eefeaeeef6 --- /dev/null +++ b/backend/parallel.c @@ -0,0 +1,563 @@ +/* + * "$Id$" + * + * Parallel port backend for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Send a file to the specified parallel port. + * list_devices() - List all parallel devices. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include + +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +# include +# include +#endif /* WIN32 || __EMX__ */ + +#ifdef __sgi +# include +# ifndef INV_EPP_ECP_PLP +# define INV_EPP_ECP_PLP 6 /* From 6.3/6.4/6.5 sys/invent.h */ +# define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */ +# define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */ +# define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */ +# define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */ +# endif /* !INV_EPP_ECP_PLP */ +#endif /* __sgi */ + + +/* + * Local functions... + */ + +void list_devices(void); + + +/* + * 'main()' - Send a file to the specified parallel port. + * + * Usage: + * + * printer-uri job-id user title copies options [file] + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + char method[255], /* Method in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info (not used) */ + resource[1024], /* Resource info (device and options) */ + *options; /* Pointer to options */ + int port; /* Port number (not used) */ + FILE *fp; /* Print file */ + int copies; /* Number of copies to print */ + int fd; /* Parallel device */ + int wbytes; /* Number of bytes written */ + size_t nbytes, /* Number of bytes read */ + tbytes; /* Total number of bytes written */ + char buffer[8192], /* Output buffer */ + *bufptr; /* Pointer into buffer */ + struct termios opts; /* Parallel port options */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + if (argc == 1) + { + list_devices(); + return (0); + } + else if (argc < 6 || argc > 7) + { + fputs("Usage: parallel job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + { + fp = stdin; + copies = 1; + } + else + { + /* + * Try to open the print file... + */ + + if ((fp = fopen(argv[6], "rb")) == NULL) + { + perror("ERROR: unable to open print file"); + return (1); + } + + copies = atoi(argv[4]); + } + + /* + * Extract the device name and options from the URI... + */ + + httpSeparate(argv[0], method, username, hostname, &port, resource); + + /* + * See if there are any options... + */ + + if ((options = strchr(resource, '?')) != NULL) + { + /* + * Yup, terminate the device name string and move to the first + * character of the options... + */ + + *options++ = '\0'; + } + + /* + * Open the parallel port device... + */ + + do + { + if ((fd = open(resource, O_WRONLY | O_EXCL)) == -1) + { + if (errno == EBUSY) + { + fputs("INFO: Parallel port busy; will retry in 30 seconds...\n", stderr); + sleep(30); + } + else + { + perror("ERROR: Unable to open parallel port device file"); + return (1); + } + } + } + while (fd < 0); + + /* + * Set any options provided... + */ + + tcgetattr(fd, &opts); + + opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */ + + /**** No options supported yet ****/ + + tcsetattr(fd, TCSANOW, &opts); + + /* + * Now that we are "connected" to the port, ignore SIGTERM so that we + * can finish out any page data the driver sends (e.g. to eject the + * current page... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Finally, send the print file... + */ + + while (copies > 0) + { + copies --; + + if (fp != stdin) + { + fputs("PAGE: 1 1\n", stderr); + rewind(fp); + } + + tbytes = 0; + while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) + { + /* + * Write the print data to the printer... + */ + + tbytes += nbytes; + bufptr = buffer; + + while (nbytes > 0) + { + if ((wbytes = write(fd, bufptr, nbytes)) < 0) + if (errno == ENOTTY) + wbytes = write(fd, bufptr, nbytes); + + if (wbytes < 0) + { + perror("ERROR: Unable to send print file to printer"); + break; + } + + nbytes -= wbytes; + bufptr += wbytes; + } + + if (argc > 6) + fprintf(stderr, "INFO: Sending print file, %u bytes...\n", tbytes); + } + } + + /* + * Close the socket connection and input file and return... + */ + + close(fd); + if (fp != stdin) + fclose(fp); + + return (0); +} + + +/* + * 'list_devices()' - List all parallel devices. + */ + +void +list_devices(void) +{ + static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz"; + /* Funky hex numbering used for some devices */ + +#ifdef __linux + int i; /* Looping var */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + FILE *probe; /* /proc/parport/n/autoprobe file */ + char line[1024], /* Line from file */ + *delim, /* Delimiter in file */ + make[IPP_MAX_NAME], /* Make from file */ + model[IPP_MAX_NAME]; /* Model from file */ + + + for (i = 0; i < 4; i ++) + { + sprintf(device, "/proc/parport/%d/autoprobe", i); + if ((probe = fopen(device, "r")) != NULL) + { + memset(make, 0, sizeof(make)); + memset(model, 0, sizeof(model)); + strcpy(model, "Unknown"); + + while (fgets(line, sizeof(line), probe) != NULL) + { + /* + * Strip trailing ; and/or newline. + */ + + if ((delim = strrchr(line, ';')) != NULL) + *delim = '\0'; + else if ((delim = strrchr(line, '\n')) != NULL) + *delim = '\0'; + + /* + * Look for MODEL and MANUFACTURER lines... + */ + + if (strncmp(line, "MODEL:", 6) == 0 && + strncmp(line, "MODEL:Unknown", 13) != 0) + strncpy(model, line + 6, sizeof(model) - 1); + else if (strncmp(line, "MANUFACTURER:", 13) == 0 && + strncmp(line, "MANUFACTURER:Unknown", 20) != 0) + strncpy(make, line + 13, sizeof(make) - 1); + } + + fclose(probe); + + if (make[0]) + printf("direct parallel:/dev/lp%d \"%s %s\" \"Parallel Port #%d\"\n", + i, make, model, i + 1); + else + printf("direct parallel:/dev/lp%d \"%s\" \"Parallel Port #%d\"\n", + i, model, i + 1); + } + else + { + sprintf(device, "/dev/lp%d", i); + if ((fd = open(device, O_WRONLY)) >= 0) + { + close(fd); + printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); + } + else + { + sprintf(device, "/dev/par%d", i); + if ((fd = open(device, O_WRONLY)) >= 0) + { + close(fd); + printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); + } + } + } + } +#elif defined(__sgi) + int i, j, n; /* Looping vars */ + char device[255]; /* Device filename */ + inventory_t *inv; /* Hardware inventory info */ + + + /* + * IRIX maintains a hardware inventory of most devices... + */ + + setinvent(); + + while ((inv = getinvent()) != NULL) + { + if (inv->inv_class == INV_PARALLEL && + (inv->inv_type == INV_ONBOARD_PLP || + inv->inv_type == INV_EPP_ECP_PLP)) + { + /* + * Standard parallel port... + */ + + puts("direct parallel:/dev/plp \"Unknown\" \"Onboard Parallel Port\""); + } + else if (inv->inv_class == INV_PARALLEL && + inv->inv_type == INV_EPC_PLP) + { + /* + * EPC parallel port... + */ + + printf("direct parallel:/dev/plp%d \"Unknown\" \"Integral EPC parallel port, Ebus slot %d\"\n", + inv->inv_controller, inv->inv_controller); + } + } + + endinvent(); + + /* + * Central Data makes serial and parallel "servers" that can be + * connected in a number of ways. Look for ports... + */ + + for (i = 0; i < 10; i ++) + for (j = 0; j < 8; j ++) + for (n = 0; n < 32; n ++) + { + if (i == 8) /* EtherLite */ + sprintf(device, "/dev/lpn%d%c", j, funky_hex[n]); + else if (i == 9) /* PCI */ + sprintf(device, "/dev/lpp%d%c", j, funky_hex[n]); + else /* SCSI */ + sprintf(device, "/dev/lp%d%d%c", i, j, funky_hex[n]); + + if (access(device, 0) == 0) + { + if (i == 8) + printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n", + device, j, n); + else if (i == 9) + printf("direct parallel:%s \"Unknown\" \"Central Data PCI Parallel Port, ID %d, port %d\"\n", + device, j, n); + else + printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n", + device, i, j, n); + } + } +#elif defined(__sun) + int i, j, n; /* Looping vars */ + char device[255]; /* Device filename */ + + + /* + * Standard parallel ports... + */ + + for (i = 0; i < 10; i ++) + { + sprintf(device, "/dev/ecpp%d", i); + if (access(device, 0) == 0) + printf("direct parallel:%s \"Unknown\" \"Sun IEEE-1284 Parallel Port #%d\"\n", + device, i + 1); + } + + for (i = 0; i < 10; i ++) + { + sprintf(device, "/dev/bpp%d", i); + if (access(device, 0) == 0) + printf("direct parallel:%s \"Unknown\" \"Sun Standard Parallel Port #%d\"\n", + device, i + 1); + } + + for (i = 0; i < 3; i ++) + { + sprintf(device, "/dev/lp%d", i); + + if (access(device, 0) == 0) + printf("direct parallel:%s \"Unknown\" \"PC Parallel Port #%d\"\n", + device, i + 1); + } + + /* + * MAGMA parallel ports... + */ + + for (i = 0; i < 40; i ++) + { + sprintf(device, "/dev/pm%02d", i); + if (access(device, 0) == 0) + printf("direct parallel:%s \"Unknown\" \"MAGMA Parallel Board #%d Port #%d\"\n", + device, (i / 10) + 1, (i % 10) + 1); + } + + /* + * Central Data parallel ports... + */ + + for (i = 0; i < 9; i ++) + for (j = 0; j < 8; j ++) + for (n = 0; n < 32; n ++) + { + if (i == 8) /* EtherLite */ + sprintf(device, "/dev/sts/lpN%d%c", j, funky_hex[n]); + else + sprintf(device, "/dev/sts/lp%c%d%c", i + 'C', j, + funky_hex[n]); + + if (access(device, 0) == 0) + { + if (i == 8) + printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n", + device, j, n); + else + printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n", + device, i, j, n); + } + } +#elif defined(__hpux) + int i, j, n; /* Looping vars */ + char device[255]; /* Device filename */ + + + /* + * Standard parallel ports... + */ + + if (access("/dev/rlp", 0) == 0) + puts("direct parallel:/dev/rlp \"Unknown\" \"Standard Parallel Port (/dev/rlp)\""); + + for (i = 0; i < 7; i ++) + for (j = 0; j < 7; j ++) + { + sprintf(device, "/dev/c%dt%dd0_lp", i, j); + if (access(device, 0) == 0) + printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d,%d\"\n", i, j); + } + + /* + * Central Data parallel ports... + */ + + for (i = 0; i < 9; i ++) + for (j = 0; j < 8; j ++) + for (n = 0; n < 32; n ++) + { + if (i == 8) /* EtherLite */ + sprintf(device, "/dev/lpN%d%c", j, funky_hex[n]); + else + sprintf(device, "/dev/lp%c%d%c", i + 'C', j, + funky_hex[n]); + + if (access(device, 0) == 0) + { + if (i == 8) + printf("direct parallel:%s \"Unknown\" \"Central Data EtherLite Parallel Port, ID %d, port %d\"\n", + device, j, n); + else + printf("direct parallel:%s \"Unknown\" \"Central Data SCSI Parallel Port, logical bus %d, ID %d, port %d\"\n", + device, i, j, n); + } + } +#elif defined(__osf__) + int i; /* Looping var */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + + + for (i = 0; i < 3; i ++) + { + sprintf(device, "/dev/lp%d", i); + if ((fd = open(device, O_WRONLY)) >= 0) + { + close(fd); + printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); + } + } +#elif defined(FreeBSD) || defined(OpenBSD) || defined(NetBSD) + int i; /* Looping var */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + + + for (i = 0; i < 3; i ++) + { + sprintf(device, "/dev/lpt%d", i); + if ((fd = open(device, O_WRONLY)) >= 0) + { + close(fd); + printf("direct parallel:%s \"Unknown\" \"Parallel Port #%d\"\n", device, i + 1); + } + } +#endif +} + + +/* + * End of "$Id$". + */ diff --git a/backend/serial.c b/backend/serial.c new file mode 100644 index 0000000000..9d9e8a3f55 --- /dev/null +++ b/backend/serial.c @@ -0,0 +1,705 @@ +/* + * "$Id$" + * + * Serial port backend for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Send a file to the printer or server. + * list_devices() - List all serial devices. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include + +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +# include +# include +#endif /* WIN32 || __EMX__ */ + +#ifdef __sgi +# include +# ifndef INV_EPP_ECP_PLP +# define INV_EPP_ECP_PLP 6 /* From 6.3/6.4/6.5 sys/invent.h */ +# define INV_ASO_SERIAL 14 /* serial portion of SGI ASO board */ +# define INV_IOC3_DMA 16 /* DMA mode IOC3 serial */ +# define INV_IOC3_PIO 17 /* PIO mode IOC3 serial */ +# define INV_ISA_DMA 19 /* DMA mode ISA serial -- O2 */ +# endif /* !INV_EPP_ECP_PLP */ +#endif /* __sgi */ + + +/* + * Local functions... + */ + +void list_devices(void); + + +/* + * 'main()' - Send a file to the printer or server. + * + * Usage: + * + * printer-uri job-id user title copies options [file] + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + char method[255], /* Method in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info (not used) */ + resource[1024], /* Resource info (device and options) */ + *options, /* Pointer to options */ + name[255], /* Name of option */ + value[255], /* Value of option */ + *ptr; /* Pointer into name or value */ + int port; /* Port number (not used) */ + FILE *fp; /* Print file */ + int copies; /* Number of copies to print */ + int fd; /* Parallel device */ + int wbytes; /* Number of bytes written */ + size_t nbytes, /* Number of bytes read */ + tbytes; /* Total number of bytes written */ + char buffer[8192], /* Output buffer */ + *bufptr; /* Pointer into buffer */ + struct termios opts; /* Parallel port options */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + if (argc == 1) + { + list_devices(); + return (0); + } + else if (argc < 6 || argc > 7) + { + fputs("Usage: serial job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + { + fp = stdin; + copies = 1; + } + else + { + /* + * Try to open the print file... + */ + + if ((fp = fopen(argv[6], "rb")) == NULL) + { + perror("ERROR: unable to open print file"); + return (1); + } + + copies = atoi(argv[4]); + } + + /* + * Extract the device name and options from the URI... + */ + + httpSeparate(argv[0], method, username, hostname, &port, resource); + + /* + * See if there are any options... + */ + + if ((options = strchr(resource, '?')) != NULL) + { + /* + * Yup, terminate the device name string and move to the first + * character of the options... + */ + + *options++ = '\0'; + } + + /* + * Open the serial port device... + */ + + do + { + if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL)) == -1) + { + if (errno == EBUSY) + { + fputs("INFO: Serial port busy; will retry in 30 seconds...\n", stderr); + sleep(30); + } + else + { + perror("ERROR: Unable to open serial port device file"); + return (1); + } + } + } + while (fd < 0); + + /* + * Set any options provided... + */ + + tcgetattr(fd, &opts); + + opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */ + + if (options != NULL) + while (*options) + { + /* + * Get the name... + */ + + for (ptr = name; *options && *options != '=';) + *ptr++ = *options++; + *ptr = '\0'; + + if (*options == '=') + { + /* + * Get the value... + */ + + options ++; + + for (ptr = value; *options && *options != '+';) + *ptr++ = *options++; + *ptr = '\0'; + + if (*options == '+') + options ++; + } + else + value[0] = '\0'; + + /* + * Process the option... + */ + + if (strcasecmp(name, "baud") == 0) + { + /* + * Set the baud rate... + */ + +#if B19200 == 19200 + cfsetispeed(&opts, atoi(value)); + cfsetospeed(&opts, atoi(value)); +#else + switch (atoi(value)) + { + case 1200 : + cfsetispeed(&opts, B1200); + cfsetospeed(&opts, B1200); + break; + case 2400 : + cfsetispeed(&opts, B2400); + cfsetospeed(&opts, B2400); + break; + case 4800 : + cfsetispeed(&opts, B4800); + cfsetospeed(&opts, B4800); + break; + case 9600 : + cfsetispeed(&opts, B9600); + cfsetospeed(&opts, B9600); + break; + case 19200 : + cfsetispeed(&opts, B19200); + cfsetospeed(&opts, B19200); + break; + case 38400 : + cfsetispeed(&opts, B38400); + cfsetospeed(&opts, B38400); + break; + default : + fprintf(stderr, "WARNING: Unsupported baud rate %s!\n", value); + break; + } +#endif /* B19200 == 19200 */ + } + else if (strcasecmp(name, "bits") == 0) + { + /* + * Set number of data bits... + */ + + switch (atoi(value)) + { + case 7 : + opts.c_cflag &= ~CSIZE; + opts.c_cflag |= CS7; + opts.c_cflag |= PARENB; + opts.c_cflag &= ~PARODD; + break; + case 8 : + opts.c_cflag &= ~CSIZE; + opts.c_cflag |= CS8; + opts.c_cflag &= ~PARENB; + break; + } + } + else if (strcasecmp(name, "parity") == 0) + { + /* + * Set parity checking... + */ + + if (strcasecmp(value, "even") == 0) + { + opts.c_cflag |= PARENB; + opts.c_cflag &= ~PARODD; + } + else if (strcasecmp(value, "odd") == 0) + { + opts.c_cflag |= PARENB; + opts.c_cflag |= PARODD; + } + else if (strcasecmp(value, "none") == 0) + opts.c_cflag &= ~PARENB; + } + } + + tcsetattr(fd, TCSANOW, &opts); + + /* + * Now that we are "connected" to the port, ignore SIGTERM so that we + * can finish out any page data the driver sends (e.g. to eject the + * current page... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Finally, send the print file... + */ + + while (copies > 0) + { + copies --; + + if (fp != stdin) + { + fputs("PAGE: 1 1\n", stderr); + rewind(fp); + } + + tbytes = 0; + while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) + { + /* + * Write the print data to the printer... + */ + + tbytes += nbytes; + bufptr = buffer; + + while (nbytes > 0) + { + if ((wbytes = write(fd, bufptr, nbytes)) < 0) + if (errno == ENOTTY) + wbytes = write(fd, bufptr, nbytes); + + if (wbytes < 0) + { + perror("ERROR: Unable to send print file to printer"); + break; + } + + nbytes -= wbytes; + bufptr += wbytes; + } + + if (argc > 6) + fprintf(stderr, "INFO: Sending print file, %u bytes...\n", tbytes); + } + } + + /* + * Close the socket connection and input file and return... + */ + + close(fd); + if (fp != stdin) + fclose(fp); + + return (0); +} + + +/* + * 'list_devices()' - List all serial devices. + */ + +void +list_devices(void) +{ + static char *funky_hex = "0123456789abcdefghijklmnopqrstuvwxyz"; + /* Funky hex numbering used for some devices */ + +#ifdef __linux + int i; /* Looping var */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + + + for (i = 0; i < 4; i ++) + { + sprintf(device, "/dev/ttyS%d", i); + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { + close(fd); + printf("serial serial:%s?baud=115200 \"Unknown\" \"Serial Port #%d\"\n", + device, i + 1); + } + } +#elif defined(__sgi) + int i, j, n; /* Looping vars */ + char device[255]; /* Device filename */ + inventory_t *inv; /* Hardware inventory info */ + + + /* + * IRIX maintains a hardware inventory of most devices... + */ + + setinvent(); + + while ((inv = getinvent()) != NULL) + { + if (inv->inv_class == INV_SERIAL) + { + /* + * Some sort of serial port... + */ + + if (inv->inv_type == INV_CDSIO || inv->inv_type == INV_CDSIO_E) + { + /* + * CDSIO port... + */ + + for (n = 0; n < 6; n ++) + printf("serial serial:/dev/ttyd%d?baud=19200 \"Unknown\" \"CDSIO Board %d Serial Port #%d\"\n", + n + 5 + 8 * inv->inv_controller, inv->inv_controller, n + 1); + } + else if (inv->inv_type == INV_EPC_SERIAL) + { + /* + * Everest serial port... + */ + + if (inv->inv_unit == 0) + i = 1; + else + i = 41 + 4 * (int)inv->inv_controller; + + for (n = 0; n < (int)inv->inv_state; n ++) + printf("serial serial:/dev/ttyd%d?baud=19200 \"Unknown\" \"EPC Serial Port %d, Ebus slot %d\"\n", + n + i, n + 1, (int)inv->inv_controller); + } + else if (inv->inv_state > 1) + { + /* + * Standard serial port under IRIX 6.4 and earlier... + */ + + for (n = 0; n < (int)inv->inv_state; n ++) + printf("serial serial:/dev/ttyd%d?baud=19200 \"Unknown\" \"Onboard Serial Port %d\"\n", + n + (int)inv->inv_unit + 1, n + (int)inv->inv_unit + 1); + } + else + { + /* + * Standard serial port under IRIX 6.5 and beyond... + */ + + printf("serial serial:/dev/ttyd%d?baud=115200 \"Unknown\" \"Onboard Serial Port %d\"\n", + (int)inv->inv_controller, (int)inv->inv_controller); + } + } + } + + endinvent(); + + /* + * Central Data makes serial and parallel "servers" that can be + * connected in a number of ways. Look for ports... + */ + + for (i = 0; i < 10; i ++) + for (j = 0; j < 8; j ++) + for (n = 0; n < 32; n ++) + { + if (i == 8) /* EtherLite */ + sprintf(device, "/dev/ttydn%d%c", j, funky_hex[n]); + else if (i == 9) /* PCI */ + sprintf(device, "/dev/ttydp%d%c", j, funky_hex[n]); + else /* SCSI */ + sprintf(device, "/dev/ttyd%d%d%c", i, j, funky_hex[n]); + + if (access(device, 0) == 0) + { + if (i == 8) + printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n", + device, j, n); + else if (i == 9) + printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data PCI Serial Port, ID %d, port %d\"\n", + device, j, n); + else + printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n", + device, i, j, n); + } + } +#elif defined(__sun) + int i, j, n; /* Looping vars */ + char device[255]; /* Device filename */ + + + /* + * Standard serial ports... + */ + + for (i = 0; i < 26; i ++) + { + sprintf(device, "/dev/cua/%c", 'a' + i); + if (access(device, 0) == 0) + printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n", + device, i + 1); + } + + /* + * MAGMA serial ports... + */ + + for (i = 0; i < 40; i ++) + { + sprintf(device, "/dev/term/%02d", i); + if (access(device, 0) == 0) + printf("serial serial:%s?baud=38400 \"Unknown\" \"MAGMA Serial Board #%d Port #%d\"\n", + device, (i / 10) + 1, (i % 10) + 1); + } + + /* + * Central Data serial ports... + */ + + for (i = 0; i < 9; i ++) + for (j = 0; j < 8; j ++) + for (n = 0; n < 32; n ++) + { + if (i == 8) /* EtherLite */ + sprintf(device, "/dev/sts/ttyN%d%c", j, funky_hex[n]); + else + sprintf(device, "/dev/sts/tty%c%d%c", i + 'C', j, + funky_hex[n]); + + if (access(device, 0) == 0) + { + if (i == 8) + printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n", + device, j, n); + else + printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n", + device, i, j, n); + } + } +#elif defined(__hpux) + int i, j, n; /* Looping vars */ + char device[255]; /* Device filename */ + + + /* + * Standard serial ports... + */ + + for (i = 0; i < 10; i ++) + { + sprintf(device, "/dev/tty%dp0", i); + if (access(device, 0) == 0) + printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n", + device, i + 1); + } + + /* + * Central Data serial ports... + */ + + for (i = 0; i < 9; i ++) + for (j = 0; j < 8; j ++) + for (n = 0; n < 32; n ++) + { + if (i == 8) /* EtherLite */ + sprintf(device, "/dev/ttyN%d%c", j, funky_hex[n]); + else + sprintf(device, "/dev/tty%c%d%c", i + 'C', j, + funky_hex[n]); + + if (access(device, 0) == 0) + { + if (i == 8) + printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data EtherLite Serial Port, ID %d, port %d\"\n", + device, j, n); + else + printf("serial serial:%s?baud=38400 \"Unknown\" \"Central Data SCSI Serial Port, logical bus %d, ID %d, port %d\"\n", + device, i, j, n); + } + } +#elif defined(__osf__) + int i; /* Looping var */ + char device[255]; /* Device filename */ + + + /* + * Standard serial ports... + */ + + for (i = 0; i < 100; i ++) + { + sprintf(device, "/dev/tty%02d", i); + if (access(device, 0) == 0) + printf("serial serial:%s?baud=38400 \"Unknown\" \"Serial Port #%d\"\n", + device, i + 1); + } +#elif defined(FreeBSD) || defined(OpenBSD) || defined(NetBSD) + int i, j; /* Looping vars */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + + + /* + * SIO ports... + */ + + for (i = 0; i < 32; i ++) + { + sprintf(device, "/dev/ttyd%c", funky_hex[i]); + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { + close(fd); + printf("serial serial:%s?baud=115200 \"Unknown\" \"Standard Serial Port #%d\"\n", + device, i + 1); + } + } + + /* + * Cyclades ports... + */ + + for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */ + for (j = 0; j < 32; j ++) + { + sprintf(device, "/dev/ttyc%d%c", i, funky_hex[j]); + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { + close(fd); + printf("serial serial:%s?baud=115200 \"Unknown\" \"Cyclades #%d Serial Port #%d\"\n", + device, i, j + 1); + } + } + + /* + * Digiboard ports... + */ + + for (i = 0; i < 16; i ++) /* Should be up to 65536 boards... */ + for (j = 0; j < 32; j ++) + { + sprintf(device, "/dev/ttyD%d%c", i, funky_hex[j]); + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { + close(fd); + printf("serial serial:%s?baud=115200 \"Unknown\" \"Digiboard #%d Serial Port #%d\"\n", + device, i, j + 1); + } + } + + /* + * Stallion ports... + */ + + for (i = 0; i < 32; i ++) + { + sprintf(device, "/dev/ttyE%c", funky_hex[i]); + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { + close(fd); + printf("serial serial:%s?baud=115200 \"Unknown\" \"Stallion Serial Port #%d\"\n", + device, i + 1); + } + } + + /* + * SX ports... + */ + + for (i = 0; i < 128; i ++) + { + sprintf(device, "/dev/ttyA%d", i + 1); + if ((fd = open(device, O_WRONLY | O_NOCTTY | O_NDELAY)) >= 0) + { + close(fd); + printf("serial serial:%s?baud=115200 \"Unknown\" \"SX Serial Port #%d\"\n", + device, i + 1); + } + } +#endif +} + + +/* + * End of "$Id$". + */ diff --git a/backend/socket.c b/backend/socket.c new file mode 100644 index 0000000000..4a63870e71 --- /dev/null +++ b/backend/socket.c @@ -0,0 +1,281 @@ +/* + * "$Id$" + * + * AppSocket backend for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Send a file to the printer or server. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +# include +# include +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * 'main()' - Send a file to the printer or server. + * + * Usage: + * + * printer-uri job-id user title copies options [file] + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + char method[255], /* Method in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info (not used) */ + resource[1024]; /* Resource info (not used) */ + FILE *fp; /* Print file */ + int copies; /* Number of copies to print */ + int port; /* Port number */ + int fd; /* AppSocket */ + int error; /* Error code (if any) */ + struct sockaddr_in addr; /* Socket address */ + struct hostent *hostaddr; /* Host address */ + int wbytes; /* Number of bytes written */ + size_t nbytes, /* Number of bytes read */ + tbytes; /* Total number of bytes written */ + char buffer[8192], /* Output buffer */ + *bufptr; /* Pointer into buffer */ + struct timeval timeout; /* Timeout for select() */ + fd_set input; /* Input set for select() */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + if (argc == 1) + { + puts("network socket \"Unknown\" \"AppSocket/HP JetDirect\""); + return (0); + } + else if (argc < 6 || argc > 7) + { + fprintf(stderr, "Usage: %s job-id user title copies options [file]\n", + argv[0]); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + { + fp = stdin; + copies = 1; + } + else + { + /* + * Try to open the print file... + */ + + if ((fp = fopen(argv[6], "rb")) == NULL) + { + perror("ERROR: unable to open print file"); + return (1); + } + + copies = atoi(argv[4]); + } + + /* + * Extract the hostname and port number from the URI... + */ + + httpSeparate(argv[0], method, username, hostname, &port, resource); + + if (port == 0) + port = 9100; /* Default to HP JetDirect/Tektronix PhaserShare */ + + /* + * Then try to connect to the remote host... + */ + + if ((hostaddr = gethostbyname(hostname)) == NULL) + { + fprintf(stderr, "ERROR: Unable to locate printer \'%s\' - %s", + hostname, strerror(errno)); + return (1); + } + + fprintf(stderr, "INFO: Attempting to connect to host %s on port %d\n", + hostname, port); + + memset(&addr, 0, sizeof(addr)); + memcpy(&(addr.sin_addr), hostaddr->h_addr, hostaddr->h_length); + addr.sin_family = hostaddr->h_addrtype; + addr.sin_port = htons(port); + + while (copies > 0) + { + for (;;) + { + if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { + perror("ERROR: Unable to create socket"); + return (1); + } + + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) + { + error = errno; + close(fd); + fd = -1; + + if (error == ECONNREFUSED) + { + fprintf(stderr, "INFO: Network host \'%s\' is busy; will retry in 30 seconds...\n", + hostname); + sleep(30); + } + else + { + perror("ERROR: Unable to connect to printer"); + sleep(30); + } + } + else + break; + } + + /* + * Now that we are "connected" to the port, ignore SIGTERM so that we + * can finish out any page data the driver sends (e.g. to eject the + * current page... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Finally, send the print file... + */ + + copies --; + + if (fp != stdin) + { + fputs("PAGE: 1 1\n", stderr); + rewind(fp); + } + + fputs("INFO: Connected to host, sending print job...\n", stderr); + + tbytes = 0; + while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) + { + /* + * Write the print data to the printer... + */ + + tbytes += nbytes; + bufptr = buffer; + + while (nbytes > 0) + { + if ((wbytes = send(fd, bufptr, nbytes, 0)) < 0) + { + perror("ERROR: Unable to send print file to printer"); + break; + } + + nbytes -= wbytes; + bufptr += wbytes; + } + + /* + * Check for possible data coming back from the printer... + */ + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + FD_ZERO(&input); + FD_SET(fd, &input); + if (select(fd + 1, &input, NULL, NULL, &timeout) > 0) + { + /* + * Grab the data coming back and spit it out to stderr... + */ + + if ((nbytes = recv(fd, buffer, sizeof(buffer), 0)) > 0) + fprintf(stderr, "INFO: Received %u bytes of back-channel data!\n", + nbytes); + } + else if (argc > 6) + fprintf(stderr, "INFO: Sending print file, %u bytes...\n", tbytes); + } + + /* + * Close the socket connection... + */ + + close(fd); + } + + /* + * Close the input file and return... + */ + + if (fp != stdin) + fclose(fp); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/backend/usb.c b/backend/usb.c new file mode 100644 index 0000000000..b5e02abfa9 --- /dev/null +++ b/backend/usb.c @@ -0,0 +1,370 @@ +/* + * "$Id$" + * + * USB port backend for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Send a file to the specified USB port. + * list_devices() - List all USB devices. + */ + +/* + * Include necessary headers. + */ + +#include +#include +#include +#include +#include +#include + +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +# include +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * Local functions... + */ + +void list_devices(void); + + +/* + * 'main()' - Send a file to the specified USB port. + * + * Usage: + * + * printer-uri job-id user title copies options [file] + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments (6 or 7) */ + char *argv[]) /* I - Command-line arguments */ +{ + char method[255], /* Method in URI */ + hostname[1024], /* Hostname */ + username[255], /* Username info (not used) */ + resource[1024], /* Resource info (device and options) */ + *options; /* Pointer to options */ + int port; /* Port number (not used) */ + FILE *fp; /* Print file */ + int copies; /* Number of copies to print */ + int fd; /* Parallel device */ + int wbytes; /* Number of bytes written */ + size_t nbytes, /* Number of bytes read */ + tbytes; /* Total number of bytes written */ + char buffer[8192], /* Output buffer */ + *bufptr; /* Pointer into buffer */ + struct termios opts; /* Parallel port options */ +#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) + struct sigaction action; /* Actions for POSIX signals */ +#endif /* HAVE_SIGACTION && !HAVE_SIGSET */ + + + if (argc == 1) + { + list_devices(); + return (0); + } + else if (argc < 6 || argc > 7) + { + fputs("Usage: USB job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + { + fp = stdin; + copies = 1; + } + else + { + /* + * Try to open the print file... + */ + + if ((fp = fopen(argv[6], "rb")) == NULL) + { + perror("ERROR: unable to open print file"); + return (1); + } + + copies = atoi(argv[4]); + } + + /* + * Extract the device name and options from the URI... + */ + + httpSeparate(argv[0], method, username, hostname, &port, resource); + + /* + * See if there are any options... + */ + + if ((options = strchr(resource, '?')) != NULL) + { + /* + * Yup, terminate the device name string and move to the first + * character of the options... + */ + + *options++ = '\0'; + } + + /* + * Open the USB port device... + */ + + do + { + if ((fd = open(resource, O_WRONLY | O_EXCL)) == -1) + { + if (errno == EBUSY) + { + fputs("INFO: USB port busy; will retry in 30 seconds...\n", stderr); + sleep(30); + } + else + { + perror("ERROR: Unable to open USB port device file"); + return (1); + } + } + } + while (fd < 0); + + /* + * Set any options provided... + */ + + tcgetattr(fd, &opts); + + opts.c_lflag &= ~(ICANON | ECHO | ISIG); /* Raw mode */ + + /**** No options supported yet ****/ + + tcsetattr(fd, TCSANOW, &opts); + + /* + * Now that we are "connected" to the port, ignore SIGTERM so that we + * can finish out any page data the driver sends (e.g. to eject the + * current page... + */ + +#ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ + sigset(SIGTERM, SIG_IGN); +#elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + + sigemptyset(&action.sa_mask); + action.sa_handler = SIG_IGN; + sigaction(SIGTERM, &action, NULL); +#else + signal(SIGTERM, SIG_IGN); +#endif /* HAVE_SIGSET */ + + /* + * Finally, send the print file... + */ + + while (copies > 0) + { + copies --; + + if (fp != stdin) + { + fputs("PAGE: 1 1\n", stderr); + rewind(fp); + } + + tbytes = 0; + while ((nbytes = fread(buffer, 1, sizeof(buffer), fp)) > 0) + { + /* + * Write the print data to the printer... + */ + + tbytes += nbytes; + bufptr = buffer; + + while (nbytes > 0) + { + if ((wbytes = write(fd, bufptr, nbytes)) < 0) + if (errno == ENOTTY) + wbytes = write(fd, bufptr, nbytes); + + if (wbytes < 0) + { + perror("ERROR: Unable to send print file to printer"); + break; + } + + nbytes -= wbytes; + bufptr += wbytes; + } + + if (argc > 6) + fprintf(stderr, "INFO: Sending print file, %u bytes...\n", tbytes); + } + } + + /* + * Close the socket connection and input file and return... + */ + + close(fd); + if (fp != stdin) + fclose(fp); + + return (0); +} + + +/* + * 'list_devices()' - List all USB devices. + */ + +void +list_devices(void) +{ +#ifdef __linux + int i; /* Looping var */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + FILE *probe; /* /proc/parport/n/autoprobe file */ + char line[1024], /* Line from file */ + *delim, /* Delimiter in file */ + make[IPP_MAX_NAME], /* Make from file */ + model[IPP_MAX_NAME]; /* Model from file */ + + + if ((probe = fopen("/proc/bus/usb/devices", "r")) != NULL) + { + i = 0; + + memset(make, 0, sizeof(make)); + memset(model, 0, sizeof(model)); + + while (fgets(line, sizeof(line), probe) != NULL) + { + /* + * Strip trailing newline. + */ + + if ((delim = strrchr(line, '\n')) != NULL) + *delim = '\0'; + + /* + * See if it is a printer device ("P: ...") + */ + + if (strncmp(line, "S:", 2) == 0) + { + /* + * String attribute... + */ + + if (strncmp(line, "S: Manufacturer=", 17) == 0) + { + strncpy(make, line + 17, sizeof(make) - 1); + if (strcmp(make, "Hewlett-Packard") == 0) + strcpy(make, "HP"); + } + else if (strncmp(line, "S: Product=", 12) == 0) + strncpy(model, line + 12, sizeof(model) - 1); + } + else if (strncmp(line, "I:", 2) == 0 && + strstr(line, "Driver=printer") != NULL && + make[0] && model[0]) + { + /* + * We were processing a printer device; send the info out... + */ + + printf("direct usb:/dev/usb/lp%d \"%s %s\" \"USB Printer #%d\"\n", + i, make, model, i + 1); + + i ++; + + memset(make, 0, sizeof(make)); + memset(model, 0, sizeof(model)); + } + } + + fclose(probe); + } + else + { + for (i = 0; i < 8; i ++) + { + sprintf(device, "/dev/usb/lp%d", i); + if ((fd = open(device, O_WRONLY)) >= 0) + { + close(fd); + printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1); + } + + sprintf(device, "/dev/usblp%d", i); + if ((fd = open(device, O_WRONLY)) >= 0) + { + close(fd); + printf("direct usb:%s \"Unknown\" \"USB Printer #%d\"\n", device, i + 1); + } + } + } +#elif defined(__sgi) +#elif defined(__sun) +#elif defined(__hpux) +#elif defined(__osf) +#elif defined(FreeBSD) || defined(OpenBSD) || defined(NetBSD) + int i; /* Looping var */ + int fd; /* File descriptor */ + char device[255]; /* Device filename */ + + for (i = 0; i < 3; i ++) + { + sprintf(device, "/dev/ulpt%d", i); + if ((fd = open(device, O_WRONLY)) >= 0) + { + close(fd); + printf("direct usb:%s \"Unknown\" \"USB Port #%d\"\n", device, i + 1); + } + } +#endif +} + + +/* + * End of "$Id$". + */ diff --git a/berkeley/Makefile b/berkeley/Makefile new file mode 100644 index 0000000000..e56596172e --- /dev/null +++ b/berkeley/Makefile @@ -0,0 +1,105 @@ +# +# "$Id$" +# +# Berkeley commands makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +TARGETS = lpc lpq lpr lprm +OBJS = lpc.o lpq.o lpr.o lprm.o + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) $(TARGETS) + + +# +# Install all targets... +# + +install: + -$(MKDIR) $(BINDIR) + $(CHMOD) ugo+rx $(BINDIR) + $(INSTALL_BIN) lpq lpr lprm $(BINDIR) + -$(MKDIR) $(SBINDIR) + $(CHMOD) ugo+rx $(SBINDIR) + $(INSTALL_BIN) lpc $(SBINDIR) + + +# +# lpc +# + +lpc: lpc.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o lpc lpc.o $(LIBS) + +lpc.o: ../cups/cups.h ../Makedefs + + +# +# lpq +# + +lpq: lpq.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o lpq lpq.o $(LIBS) + +lpq.o: ../cups/cups.h ../Makedefs + + +# +# lpr +# + +lpr: lpr.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o lpr lpr.o $(LIBS) + +lpr.o: ../cups/cups.h ../Makedefs + + +# +# lprm +# + +lprm: lprm.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o lprm lprm.o $(LIBS) + +lprm.o: ../cups/cups.h ../Makedefs + + +# +# End of "$Id$". +# diff --git a/berkeley/lpc.c b/berkeley/lpc.c new file mode 100644 index 0000000000..c89b16dd93 --- /dev/null +++ b/berkeley/lpc.c @@ -0,0 +1,466 @@ +/* + * "$Id$" + * + * "lpc" command for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Parse options and commands. + * compare_strings() - Compare two command-line strings. + * do_command() - Do an lpc command... + * show_help() - Show help messages. + * show_status() - Show printers. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static int compare_strings(char *, char *, int); +static void do_command(http_t *, char *, char *); +static void show_help(char *); +static void show_status(http_t *, char *); + + +/* + * 'main()' - Parse options and commands. + */ + +int +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + http_t *http; /* Connection to server */ + char line[1024], /* Input line from user */ + *params; /* Pointer to parameters */ + + + /* + * Connect to the scheduler... + */ + + http = httpConnect(cupsServer(), ippPort()); + + if (argc > 1) + { + /* + * Process a single command on the command-line... + */ + + do_command(http, argv[1], argv[2]); + } + else + { + /* + * Do the command prompt thing... + */ + + printf("lpc> "); + while (fgets(line, sizeof(line), stdin) != NULL) + { + /* + * Strip the trailing newline... + */ + + line[strlen(line) - 1] = '\0'; + + /* + * Find any options in the string... + */ + + while (isspace(line[0])) + strcpy(line, line + 1); + + for (params = line; *params != '\0'; params ++) + if (isspace(*params)) + break; + + /* + * Remove whitespace between the command and parameters... + */ + + while (isspace(*params)) + *params++ = '\0'; + + /* + * The "quit" and "exit" commands exit; otherwise, process as needed... + */ + + if (compare_strings(line, "quit", 1) == 0 || + compare_strings(line, "exit", 2) == 0) + break; + + if (*params == '\0') + do_command(http, line, NULL); + else + do_command(http, line, params); + + /* + * Put another prompt out to the user... + */ + + printf("lpc> "); + } + } + + /* + * Close the connection to the server and return... + */ + + httpClose(http); + + return (0); +} + + +/* + * 'compare_strings()' - Compare two command-line strings. + */ + +static int /* O - -1 or 1 = no match, 0 = match */ +compare_strings(char *s, /* I - Command-line string */ + char *t, /* I - Option string */ + int tmin) /* I - Minimum number of unique chars in option */ +{ + int slen; /* Length of command-line string */ + + + slen = strlen(s); + if (slen < tmin) + return (-1); + else + return (strncmp(s, t, slen)); +} + + +/* + * 'do_command()' - Do an lpc command... + */ + +static void +do_command(http_t *http, /* I - HTTP connection to server */ + char *command, /* I - Command string */ + char *params) /* I - Parameters for command */ +{ + if (compare_strings(command, "status", 4) == 0) + show_status(http, params); + else if (compare_strings(command, "help", 1) == 0 || + strcmp(command, "?") == 0) + show_help(params); + else + puts("?Invalid command"); +} + + +/* + * 'show_help()' - Show help messages. + */ + +static void +show_help(char *command) /* I - Command to describe or NULL */ +{ + if (command == NULL) + { + puts("Commands may be abbreviated. Commands are:"); + puts(""); + puts("exit help quit status ?"); + } + else if (compare_strings(command, "help", 1) == 0 || + strcmp(command, "?") == 0) + puts("help\t\tget help on commands"); + else if (compare_strings(command, "status", 4) == 0) + puts("status\t\tshow status of daemon and queue"); + else + puts("?Invalid help command unknown"); +} + + +/* + * 'show_status()' - Show printers. + */ + +static void +show_status(http_t *http, /* I - HTTP connection to server */ + char *dests) /* I - Destinations */ +{ + ipp_t *request, /* IPP Request */ + *response, /* IPP Response */ + *jobs; /* IPP Get Jobs response */ + ipp_attribute_t *attr; /* Current attribute */ + cups_lang_t *language; /* Default language */ + char *printer, /* Printer name */ + *device; /* Device URI */ + ipp_pstate_t pstate; /* Printer state */ + int accepting; /* Is printer accepting jobs? */ + int jobcount; /* Count of current jobs */ + char *dptr, /* Pointer into destination list */ + *ptr; /* Pointer into printer name */ + int match; /* Non-zero if this job matches */ + char printer_uri[HTTP_MAX_URI]; + /* Printer URI */ + + + DEBUG_printf(("show_status(%08x, %08x)\n", http, dests)); + + if (http == NULL) + return; + + /* + * Build a CUPS_GET_PRINTERS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_GET_PRINTERS; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/printers/")) != NULL) + { + DEBUG_puts("show_status: request succeeded..."); + + /* + * Loop through the printers returned in the list and display + * their status... + */ + + for (attr = response->attrs; attr != NULL; attr = attr->next) + { + /* + * Skip leading attributes until we hit a job... + */ + + while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) + attr = attr->next; + + if (attr == NULL) + break; + + /* + * Pull the needed attributes from this job... + */ + + printer = NULL; + device = "file:/dev/null"; + pstate = IPP_PRINTER_IDLE; + jobcount = 0; + accepting = 1; + + while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) + { + if (strcmp(attr->name, "printer-name") == 0 && + attr->value_tag == IPP_TAG_NAME) + printer = attr->values[0].string.text; + + if (strcmp(attr->name, "device-uri") == 0 && + attr->value_tag == IPP_TAG_URI) + device = attr->values[0].string.text; + + if (strcmp(attr->name, "printer-state") == 0 && + attr->value_tag == IPP_TAG_ENUM) + pstate = (ipp_pstate_t)attr->values[0].integer; + + if (strcmp(attr->name, "printer-is-accepting-jobs") == 0 && + attr->value_tag == IPP_TAG_BOOLEAN) + accepting = attr->values[0].boolean; + + attr = attr->next; + } + + /* + * See if we have everything needed... + */ + + if (printer == NULL) + { + if (attr == NULL) + break; + else + continue; + } + + /* + * See if this is a printer we're interested in... + */ + + match = dests == NULL; + + if (dests != NULL) + { + for (dptr = dests; *dptr != '\0';) + { + /* + * Skip leading whitespace and commas... + */ + + while (isspace(*dptr) || *dptr == ',') + dptr ++; + + if (*dptr == '\0') + break; + + /* + * Compare names... + */ + + for (ptr = printer; + *ptr != '\0' && *dptr != '\0' && *ptr == *dptr; + ptr ++, dptr ++); + + if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr))) + { + match = 1; + break; + } + + /* + * Skip trailing junk... + */ + + while (!isspace(*dptr) && *dptr != '\0') + dptr ++; + while (isspace(*dptr) || *dptr == ',') + dptr ++; + + if (*dptr == '\0') + break; + } + } + + /* + * Display the printer entry if needed... + */ + + if (match) + { + /* + * If the printer state is "IPP_PRINTER_PROCESSING", then grab the + * current job for the printer. + */ + + if (pstate == IPP_PRINTER_PROCESSING) + { + /* + * Build an IPP_GET_JOBS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * limit + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_GET_JOBS; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, + cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, + language->language); + + snprintf(printer_uri, sizeof(printer_uri), + "ipp://localhost/printers/%s", printer); + attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, printer_uri); + + if ((jobs = cupsDoRequest(http, request, "/jobs/")) != NULL) + { + for (attr = jobs->attrs; attr != NULL; attr = attr->next) + if (strcmp(attr->name, "job-id") == 0) + jobcount ++; + + ippDelete(jobs); + } + } + + /* + * Display it... + */ + + printf("%s:\n", printer); + if (strncmp(device, "file:", 5) == 0) + printf("\tprinter is on device \'%s\' speed -1\n", device + 5); + else + { + /* + * Just show the method... + */ + + *strchr(device, ':') = '\0'; + printf("\tprinter is on device \'%s\' speed -1\n", device); + } + + printf("\tqueuing is %sabled\n", accepting ? "en" : "dis"); + printf("\tprinting is %sabled\n", + pstate == IPP_PRINTER_STOPPED ? "dis" : "en"); + if (jobcount == 0) + puts("\tno entries"); + else + printf("\t%d entries\n", jobcount); + puts("\tdaemon present"); + } + + if (attr == NULL) + break; + } + + ippDelete(response); + } +} + + +/* + * End of "$Id$". + */ diff --git a/berkeley/lpq.c b/berkeley/lpq.c new file mode 100644 index 0000000000..81ea233088 --- /dev/null +++ b/berkeley/lpq.c @@ -0,0 +1,501 @@ +/* + * "$Id$" + * + * "lpq" command for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Parse options and commands. + * show_jobs() - Show jobs. + * show_printer() - Show printer status. + */ + +/* + * Include necessary headers... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + + +/* + * Local functions... + */ + +static int show_jobs(http_t *, const char *, const char *, const int, + const int); +static void show_printer(http_t *, const char *); + + +/* + * 'main()' - Parse options and commands. + */ + +int +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + http_t *http; /* Connection to server */ + const char *dest, /* Desired printer */ + *user; /* Desired user */ + int id, /* Desired job ID */ + interval, /* Reporting interval */ + longstatus; /* Show file details */ + + /* + * Connect to the scheduler... + */ + + http = httpConnect(cupsServer(), ippPort()); + + /* + * Check for command-line options... + */ + + dest = cupsGetDefault(); + user = NULL; + id = 0; + interval = 0; + longstatus = 0; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '+') + interval = atoi(argv[i] + 1); + else if (argv[i][0] == '-') + { + switch (argv[i][1]) + { + case 'P' : /* Printer */ + if (argv[i][2]) + dest = argv[i] + 2; + else + { + i ++; + dest = argv[i]; + } + break; + + case 'l' : /* Long status */ + longstatus = 1; + break; + + default : + fputs("Usage: lpq [-P dest] [-l] [+interval]\n", stderr); + return (1); + } + } + else if (isdigit(argv[i][0])) + id = atoi(argv[i]); + else + user = argv[i]; + + /* + * Show the status in a loop... + */ + + for (;;) + { + if (dest) + show_printer(http, dest); + + i = show_jobs(http, dest, user, id, longstatus); + + if (i && interval) + { + fflush(stdout); + sleep(interval); + } + else + break; + } + + /* + * Close the connection to the server and return... + */ + + httpClose(http); + + return (0); +} + + +/* + * 'show_jobs()' - Show jobs. + */ + +static int /* O - Number of jobs in queue */ +show_jobs(http_t *http, /* I - HTTP connection to server */ + const char *dest, /* I - Destination */ + const char *user, /* I - User */ + const int id, /* I - Job ID */ + const int longstatus)/* I - 1 if long report desired */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + cups_lang_t *language; /* Default language */ + const char *jobdest, /* Pointer into job-printer-uri */ + *jobuser, /* Pointer to job-originating-user-name */ + *jobname; /* Pointer to job-name */ + ipp_jstate_t jobstate; /* job-state */ + int jobid, /* job-id */ + jobsize, /* job-k-octets */ +#ifdef __osf__ + jobpriority, /* job-priority */ +#endif /* __osf__ */ + jobcount, /* Number of jobs */ + jobcopies, /* Number of copies */ + rank; /* Rank of job */ + char resource[1024]; /* Resource string */ + char rankstr[255]; /* Rank string */ + char namestr[1024]; /* Job name string */ + static const char *ranks[10] =/* Ranking strings */ + { + "th", + "st", + "nd", + "rd", + "th", + "th", + "th", + "th", + "th", + "th" + }; + + + DEBUG_printf(("show_jobs(%08x, %08x, %08x, %d, %d)\n", http, dest, user, id, + longstatus)); + + if (http == NULL) + return (0); + + /* + * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires + * the following attributes: + * + * attributes-charset + * attributes-natural-language + * job-uri or printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + if (dest == NULL) + { + if (id) + sprintf(resource, "ipp://localhost/jobs/%d", id); + else + strcpy(resource, "ipp://localhost/jobs"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", + NULL, resource); + } + else + { + snprintf(resource, sizeof(resource), "ipp://localhost/printers/%s", dest); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, resource); + } + + if (user) + { + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, user); + ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); + } + + /* + * Do the request and get back a response... + */ + + jobcount = 0; + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + if (response->request.status.status_code > IPP_OK_CONFLICT) + { + fprintf(stderr, "lpq: get-jobs failed: %s\n", + ippErrorString(response->request.status.status_code)); + ippDelete(response); + return (0); + } + + rank = 1; + + /* + * Loop through the job list and display them... + */ + + for (attr = response->attrs; attr != NULL; attr = attr->next) + { + /* + * Skip leading attributes until we hit a job... + */ + + while (attr != NULL && attr->group_tag != IPP_TAG_JOB) + attr = attr->next; + + if (attr == NULL) + break; + + /* + * Pull the needed attributes from this job... + */ + + jobid = 0; + jobsize = 0; +#ifdef __osf__ + jobpriority = 50; +#endif /* __osf__ */ + jobstate = IPP_JOB_PENDING; + jobname = "untitled"; + jobuser = NULL; + jobdest = NULL; + jobcopies = 1; + + while (attr != NULL && attr->group_tag == IPP_TAG_JOB) + { + if (strcmp(attr->name, "job-id") == 0 && + attr->value_tag == IPP_TAG_INTEGER) + jobid = attr->values[0].integer; + + if (strcmp(attr->name, "job-k-octets") == 0 && + attr->value_tag == IPP_TAG_INTEGER) + jobsize = attr->values[0].integer * 1024; + +#ifdef __osf__ + if (strcmp(attr->name, "job-priority") == 0 && + attr->value_tag == IPP_TAG_INTEGER) + jobpriority = attr->values[0].integer; +#endif /* __osf__ */ + + if (strcmp(attr->name, "job-state") == 0 && + attr->value_tag == IPP_TAG_ENUM) + jobstate = (ipp_jstate_t)attr->values[0].integer; + + if (strcmp(attr->name, "job-printer-uri") == 0 && + attr->value_tag == IPP_TAG_URI) + if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL) + jobdest ++; + + if (strcmp(attr->name, "job-originating-user-name") == 0 && + attr->value_tag == IPP_TAG_NAME) + jobuser = attr->values[0].string.text; + + if (strcmp(attr->name, "job-name") == 0 && + attr->value_tag == IPP_TAG_NAME) + jobname = attr->values[0].string.text; + + if (strcmp(attr->name, "copies") == 0 && + attr->value_tag == IPP_TAG_INTEGER) + jobcopies = attr->values[0].integer; + + attr = attr->next; + } + + /* + * See if we have everything needed... + */ + + if (jobdest == NULL || jobid == 0) + { + if (attr == NULL) + break; + else + continue; + } + + if (!longstatus && jobcount == 0) +#ifdef __osf__ + puts("Rank Owner Pri Job Files Total Size"); +#else + puts("Rank Owner Job Files Total Size"); +#endif /* __osf__ */ + + jobcount ++; + + /* + * Display the job... + */ + + if (jobstate == IPP_JOB_PROCESSING) + strcpy(rankstr, "active"); + else + { + sprintf(rankstr, "%d%s", rank, ranks[rank % 10]); + rank ++; + } + + if (longstatus) + { + puts(""); + + if (jobcopies > 1) + snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies, + jobname); + else + { + strncpy(namestr, jobname, sizeof(namestr) - 1); + namestr[sizeof(namestr) - 1] = '\0'; + } + + printf("%s: %-31s [job %d localhost]\n", jobuser, rankstr, jobid); + printf(" %-31.31s %d bytes\n", namestr, jobsize); + } + else +#ifdef __osf__ + printf("%-6s %-10.10s %-4d %-10d %-27.27s %d bytes\n", rankstr, jobuser, + jobpriority, jobid, jobname, jobsize); +#else + printf("%-6s %-10.10s %-15d %-27.27s %d bytes\n", rankstr, jobuser, + jobid, jobname, jobsize); +#endif /* __osf */ + + if (attr == NULL) + break; + } + + ippDelete(response); + } + else + { + fprintf(stderr, "lpq: get-jobs failed: %s\n", ippErrorString(cupsLastError())); + return (0); + } + + if (jobcount == 0) + puts("no entries"); + + return (jobcount); +} + + +/* + * 'show_printer()' - Show printer status. + */ + +static void +show_printer(http_t *http, /* I - HTTP connection to server */ + const char *dest) /* I - Destination */ +{ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + cups_lang_t *language; /* Default language */ + ipp_pstate_t state; /* Printer state */ + char uri[HTTP_MAX_URI]; + /* Printer URI */ + + + if (http == NULL) + return; + + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + sprintf(uri, "ipp://localhost/printers/%s", dest); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, uri); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + if (response->request.status.status_code > IPP_OK_CONFLICT) + { + fprintf(stderr, "lpq: get-printer-attributes failed: %s\n", + ippErrorString(response->request.status.status_code)); + ippDelete(response); + return; + } + + if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) + state = (ipp_pstate_t)attr->values[0].integer; + else + state = IPP_PRINTER_STOPPED; + + switch (state) + { + case IPP_PRINTER_IDLE : + printf("%s is ready\n", dest); + break; + case IPP_PRINTER_PROCESSING : + printf("%s is ready and printing\n", dest); + break; + case IPP_PRINTER_STOPPED : + printf("%s is not ready\n", dest); + break; + } + + ippDelete(response); + } + else + fprintf(stderr, "lpq: get-printer-attributes failed: %s\n", + ippErrorString(cupsLastError())); +} + + +/* + * End of "$Id$". + */ diff --git a/berkeley/lpr.c b/berkeley/lpr.c new file mode 100644 index 0000000000..cbfad7e600 --- /dev/null +++ b/berkeley/lpr.c @@ -0,0 +1,352 @@ +/* + * "$Id$" + * + * "lpr" command for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Parse options and send files for printing. + * sighandler() - Signal catcher for when we print from stdin... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include + + +#ifndef WIN32 +# include + + +/* + * Local functions. + */ + +void sighandler(int); +#endif /* !WIN32 */ + + +/* + * Globals... + */ + +char tempfile[1024]; /* Temporary file for printing from stdin */ + + +/* + * 'main()' - Parse options and send files for printing. + */ + +int +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i, j; /* Looping var */ + int job_id; /* Job ID */ + char *printer, /* Destination printer or class */ + *instance; /* Instance */ + const char *title; /* Job title */ + int num_copies; /* Number of copies per file */ + int num_files; /* Number of files to print */ + const char *files[1000]; /* Files to print */ + int num_dests; /* Number of destinations */ + cups_dest_t *dests, /* Destinations */ + *dest; /* Selected destination */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ + int deletefile; /* Delete file after print? */ + char buffer[8192]; /* Copy buffer */ + FILE *temp; /* Temporary file pointer */ +#ifdef HAVE_SIGACTION + struct sigaction action; /* Signal action */ +#endif /* HAVE_SIGACTION */ + + + deletefile = 0; + printer = NULL; + num_dests = 0; + dests = NULL; + num_options = 0; + options = NULL; + num_files = 0; + title = NULL; + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-') + switch (argv[i][1]) + { + case 'i' : /* indent */ + case 'w' : /* width */ + if (argv[i][2] == '\0') + i ++; + case 'c' : /* CIFPLOT */ + case 'd' : /* DVI */ + case 'f' : /* FORTRAN */ + case 'g' : /* plot */ + case 'n' : /* Ditroff */ + case 't' : /* Troff */ + case 'v' : /* Raster image */ + fprintf(stderr, "Warning: \'%c\' format modifier not supported - output may not be correct!\n", + argv[i][1]); + break; + + case 'o' : /* Option */ + if (argv[i][2] != '\0') + num_options = cupsParseOptions(argv[i] + 2, num_options, &options); + else + { + i ++; + num_options = cupsParseOptions(argv[i], num_options, &options); + } + break; + + case 'l' : /* Literal/raw */ + num_options = cupsParseOptions("raw", num_options, &options); + break; + + case 'p' : /* Prettyprint */ + num_options = cupsParseOptions("prettyprint", num_options, &options); + break; + + case 'h' : /* Suppress burst page */ + case 's' : /* Don't use symlinks */ + break; + + case 'm' : /* Mail on completion */ + fputs("Warning: email notification is not supported!\n", stderr); + break; + + case 'r' : /* Remove file after printing */ + deletefile = 1; + break; + + case 'P' : /* Destination printer or class */ + if (argv[i][2] != '\0') + printer = argv[i] + 2; + else + { + i ++; + printer = argv[i]; + } + + if ((instance = strrchr(printer, '/')) != NULL) + *instance++ = '\0'; + + if (num_dests == 0) + num_dests = cupsGetDests(&dests); + + if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL) + { + for (j = 0; j < dest->num_options; j ++) + num_options = cupsAddOption(dest->options[j].name, + dest->options[j].value, + num_options, &options); + } + break; + + case '#' : /* Number of copies */ + if (argv[i][2] != '\0') + num_copies = atoi(argv[i] + 2); + else + { + i ++; + num_copies = atoi(argv[i]); + } + + if (num_copies < 1 || num_copies > 100) + { + fputs("lpr: Number copies must be between 1 and 100.\n", stderr); + return (1); + } + + sprintf(buffer, "%d", num_copies); + num_options = cupsAddOption("copies", buffer, num_options, &options); + break; + + case 'C' : /* Class */ + case 'J' : /* Job name */ + case 'T' : /* Title */ + if (argv[i][2] != '\0') + title = argv[i] + 2; + else + { + i ++; + title = argv[i]; + } + break; + + default : + fprintf(stderr, "lpr: Unknown option \'%c\'!\n", argv[i][1]); + return (1); + } + else if (num_files < 1000) + { + /* + * Print a file... + */ + + files[num_files] = argv[i]; + num_files ++; + + if (title == NULL) + { + if ((title = strrchr(argv[i], '/')) != NULL) + title ++; + else + title = argv[i]; + } + } + else + fprintf(stderr, "lpr: Too many files - \"%s\"\n", argv[i]); + /* + * See if we have any files to print; if not, print from stdin... + */ + + if (printer == NULL) + { + if (num_dests == 0) + num_dests = cupsGetDests(&dests); + + for (j = 0, dest = dests; j < num_dests; j ++, dest ++) + if (dest->is_default) + { + printer = dests[j].name; + + for (j = 0; j < dest->num_options; j ++) + num_options = cupsAddOption(dest->options[j].name, + dest->options[j].value, + num_options, &options); + break; + } + } + + if (printer == NULL) + { + fputs("lpr: error - no default destination available.\n", stderr); + return (1); + } + + if (num_files > 0) + { + job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options); + + if (deletefile) + { + /* + * Delete print files after printing... + */ + + for (i = 0; i < num_files; i ++) + unlink(files[i]); + } + } + else + { + num_files = 1; + +#ifndef WIN32 +# if defined(HAVE_SIGSET) + sigset(SIGHUP, sighandler); + sigset(SIGINT, sighandler); + sigset(SIGTERM, sighandler); +# elif defined(HAVE_SIGACTION) + memset(&action, 0, sizeof(action)); + action.sa_handler = sighandler; + + sigaction(SIGHUP, &action, NULL); + sigaction(SIGINT, &action, NULL); + sigaction(SIGTERM, &action, NULL); +# else + signal(SIGHUP, sighandler); + signal(SIGINT, sighandler); + signal(SIGTERM, sighandler); +# endif +#endif /* !WIN32 */ + + temp = fopen(cupsTempFile(tempfile, sizeof(tempfile)), "w"); + + if (temp == NULL) + { + fputs("lpr: unable to create temporary file.\n", stderr); + return (1); + } + + while ((i = fread(buffer, 1, sizeof(buffer), stdin)) > 0) + fwrite(buffer, 1, i, temp); + + i = ftell(temp); + fclose(temp); + + if (i == 0) + { + fputs("lpr: stdin is empty, so no job has been sent.\n", stderr); + return (1); + } + + if (title) + job_id = cupsPrintFile(printer, tempfile, title, num_options, options); + else + job_id = cupsPrintFile(printer, tempfile, "(stdin)", num_options, options); + + unlink(tempfile); + } + + if (job_id < 1) + { + fprintf(stderr, "lpr: unable to print file: %s\n", + ippErrorString(cupsLastError())); + return (1); + } + + return (0); +} + + +#ifndef WIN32 +/* + * 'sighandler()' - Signal catcher for when we print from stdin... + */ + +void +sighandler(int s) /* I - Signal number */ +{ + /* + * Remove the temporary file we're using to print from stdin... + */ + + unlink(tempfile); + + /* + * Exit... + */ + + exit(s); +} +#endif /* !WIN32 */ + + +/* + * End of "$Id$". + */ diff --git a/berkeley/lprm.c b/berkeley/lprm.c new file mode 100644 index 0000000000..4b931a683b --- /dev/null +++ b/berkeley/lprm.c @@ -0,0 +1,221 @@ +/* + * "$Id$" + * + * "lprm" command for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Parse options and cancel jobs. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include + +#include +#include + + +/* + * 'main()' - Parse options and cancel jobs. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + http_t *http; /* HTTP connection to server */ + int i; /* Looping var */ + int job_id; /* Job ID */ + const char *dest; /* Destination printer */ + char uri[1024]; /* Printer or job URI */ + ipp_t *request; /* IPP request */ + ipp_t *response; /* IPP response */ + ipp_op_t op; /* Operation */ + cups_lang_t *language; /* Language */ + + + /* + * Setup to cancel individual print jobs... + */ + + op = IPP_CANCEL_JOB; + job_id = 0; + dest = cupsGetDefault(); + response = NULL; + http = NULL; + + /* + * Open a connection to the server... + */ + + if ((http = httpConnect(cupsServer(), ippPort())) == NULL) + { + fputs("lprm: Unable to contact server!\n", stderr); + return (1); + } + + /* + * Process command-line arguments... + */ + + for (i = 1; i < argc; i ++) + if (argv[i][0] == '-' && argv[i][1] != '\0') + switch (argv[i][1]) + { + case 'P' : /* Cancel jobs on a printer */ + if (argv[i][2]) + dest = argv[i] + 2; + else + { + i ++; + dest = argv[i]; + } + break; + + default : + fprintf(stderr, "lprm: Unknown option \'%c\'!\n", argv[i][1]); + return (1); + } + else + { + /* + * Cancel a job or printer... + */ + + if (isdigit(argv[i][0])) + { + dest = NULL; + op = IPP_CANCEL_JOB; + job_id = atoi(argv[i]); + } + else if (strcmp(argv[i], "-") == 0) + { + /* + * Cancel all jobs + */ + + op = IPP_PURGE_JOBS; + } + else + job_id = 0; + + /* + * Build an IPP request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + job-id *or* job-uri + * [requesting-user-name] + */ + + request = ippNew(); + + request->request.op.operation_id = op; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + if (dest) + { + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", dest); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, uri); + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", + job_id); + } + else + { + sprintf(uri, "ipp://localhost/jobs/%d", job_id); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, + uri); + } + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, + "requesting-user-name", NULL, cupsUser()); + + /* + * Do the request and get back a response... + */ + + if (op == IPP_PURGE_JOBS) + response = cupsDoRequest(http, request, "/admin/"); + else + response = cupsDoRequest(http, request, "/jobs/"); + + if (response != NULL) + { + switch (response->request.status.status_code) + { + case IPP_NOT_FOUND : + fputs("lprm: Job or printer not found!\n", stderr); + break; + case IPP_NOT_AUTHORIZED : + fputs("lprm: Not authorized to lprm job(s)!\n", stderr); + break; + case IPP_FORBIDDEN : + fprintf(stderr, "lprm: You don't own job ID %d!\n", job_id); + break; + default : + if (response->request.status.status_code > IPP_OK_CONFLICT) + fputs("lprm: Unable to lprm job(s)!\n", stderr); + break; + } + + ippDelete(response); + } + else + { + fputs("lprm: Unable to cancel job(s)!\n", stderr); + return (1); + } + } + + /* + * If nothing has been cancelled yet, cancel the current job on the specified + * (or default) printer... + */ + + if (response == NULL) + if (!cupsCancelJob(dest, 0)) + { + fputs("lprm: Unable to cancel job(s)!\n", stderr); + return (1); + } + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/Makefile b/cgi-bin/Makefile new file mode 100644 index 0000000000..8eecaa55ea --- /dev/null +++ b/cgi-bin/Makefile @@ -0,0 +1,119 @@ +# +# "$Id$" +# +# CGI makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1997-1999 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +TARGETS = admin.cgi classes.cgi jobs.cgi printers.cgi +LIBOBJS = abort.o email.o html.o ipp-var.o template.o var.o +OBJS = $(LIBOBJS) admin.o classes.o jobs.o printers.o + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) libcgi.a $(TARGETS) + + +# +# Install all targets... +# + +install: + -$(MKDIR) $(SERVERBIN)/cgi-bin + $(CHMOD) ugo+rx $(SERVERBIN) + $(CHMOD) ugo+rx $(SERVERBIN)/cgi-bin + $(INSTALL_BIN) $(TARGETS) $(SERVERBIN)/cgi-bin + + +# +# libcgi.a +# + +libcgi.a: $(LIBOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + +$(LIBOBJS): cgi.h +ipp-var.o: ipp-var.h + + +# +# admin.cgi +# + +admin.cgi: admin.o ../Makedefs ../cups/$(LIBCUPS) libcgi.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ admin.o libcgi.a $(LIBS) + +admin.o: cgi.h ipp-var.h ../cups/cups.h ../cups/ipp.h ../cups/language.h + + +# +# classes.cgi +# + +classes.cgi: classes.o ../Makedefs ../cups/$(LIBCUPS) libcgi.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ classes.o libcgi.a $(LIBS) + +classes.o: cgi.h ipp-var.h ../cups/cups.h ../cups/ipp.h ../cups/language.h + + +# +# jobs.cgi +# + +jobs.cgi: jobs.o ../Makedefs ../cups/$(LIBCUPS) libcgi.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ jobs.o libcgi.a $(LIBS) + +jobs.o: cgi.h ipp-var.h ../cups/cups.h ../cups/ipp.h ../cups/language.h + + +# +# printers.cgi +# + +printers.cgi: printers.o ../Makedefs ../cups/$(LIBCUPS) libcgi.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ printers.o libcgi.a $(LIBS) + +printers.o: cgi.h ipp-var.h ../cups/cups.h ../cups/ipp.h ../cups/language.h + +$(OBJS): ../Makedefs + +# +# End of "$Id$". +# diff --git a/cgi-bin/admin.c b/cgi-bin/admin.c new file mode 100644 index 0000000000..38346e443c --- /dev/null +++ b/cgi-bin/admin.c @@ -0,0 +1,1491 @@ +/* + * "$Id$" + * + * Administration CGI for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry for CGI. + * do_am_class() - Add or modify a class. + * do_am_printer() - Add or modify a printer. + * do_config_printer() - Configure the default options for a printer. + * do_delete_class() - Delete a class... + * do_delete_printer() - Delete a printer... + * do_job_op() - Do a job operation. + * do_printer_op() - Do a printer operation. + * get_line() - Get a line that is terminated by a LF, CR, or CR LF. + */ + +/* + * Include necessary headers... + */ + +#include "ipp-var.h" +#include + + +/* + * Local functions... + */ + +static void do_am_class(http_t *http, cups_lang_t *language, int modify); +static void do_am_printer(http_t *http, cups_lang_t *language, int modify); +static void do_config_printer(http_t *http, cups_lang_t *language); +static void do_delete_class(http_t *http, cups_lang_t *language); +static void do_delete_printer(http_t *http, cups_lang_t *language); +static void do_job_op(http_t *http, cups_lang_t *language, ipp_op_t op); +static void do_printer_op(http_t *http, cups_lang_t *language, ipp_op_t op); +static char *get_line(char *buf, int length, FILE *fp); + + +/* + * 'main()' - Main entry for CGI. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + cups_lang_t *language; /* Language information */ + http_t *http; /* Connection to the server */ + const char *op; /* Operation name */ + + + /* + * Get the request language... + */ + + language = cupsLangDefault(); + + /* + * Send a standard header... + */ + + printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language)); + + cgiSetVariable("TITLE", "Admin"); + ippSetServerVersion(); + + cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG")); + + /* + * See if we have form data... + */ + + if (!cgiInitialize()) + { + /* + * Nope, send the administration menu... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "admin.tmpl", getenv("LANG")); + } + else if ((op = cgiGetVariable("OP")) != NULL) + { + /* + * Connect to the HTTP server... + */ + + http = httpConnect("localhost", ippPort()); + + /* + * Do the operation... + */ + + if (strcmp(op, "cancel-job") == 0) + do_job_op(http, language, IPP_CANCEL_JOB); + else if (strcmp(op, "hold-job") == 0) + do_job_op(http, language, IPP_HOLD_JOB); + else if (strcmp(op, "release-job") == 0) + do_job_op(http, language, IPP_RELEASE_JOB); + else if (strcmp(op, "restart-job") == 0) + do_job_op(http, language, IPP_RESTART_JOB); + else if (strcmp(op, "start-printer") == 0) + do_printer_op(http, language, IPP_RESUME_PRINTER); + else if (strcmp(op, "stop-printer") == 0) + do_printer_op(http, language, IPP_PAUSE_PRINTER); + else if (strcmp(op, "accept-jobs") == 0) + do_printer_op(http, language, CUPS_ACCEPT_JOBS); + else if (strcmp(op, "reject-jobs") == 0) + do_printer_op(http, language, CUPS_REJECT_JOBS); + else if (strcmp(op, "add-class") == 0) + do_am_class(http, language, 0); + else if (strcmp(op, "add-printer") == 0) + do_am_printer(http, language, 0); + else if (strcmp(op, "modify-class") == 0) + do_am_class(http, language, 1); + else if (strcmp(op, "modify-printer") == 0) + do_am_printer(http, language, 1); + else if (strcmp(op, "delete-class") == 0) + do_delete_class(http, language); + else if (strcmp(op, "delete-printer") == 0) + do_delete_printer(http, language); + else if (strcmp(op, "config-printer") == 0) + do_config_printer(http, language); + else + { + /* + * Bad operation code... Display an error... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "admin-op.tmpl", getenv("LANG")); + } + + /* + * Close the HTTP server connection... + */ + + httpClose(http); + } + else + { + /* + * Form data but no operation code... Display an error... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "admin-op.tmpl", getenv("LANG")); + } + + /* + * Send the standard trailer... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG")); + + /* + * Free the request language... + */ + + cupsLangFree(language); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * 'do_am_class()' - Add or modify a class. + */ + +static void +do_am_class(http_t *http, /* I - HTTP connection */ + cups_lang_t *language, /* I - Client's language */ + int modify) /* I - Modify the printer? */ +{ + int i, j; /* Looping vars */ + int element; /* Element number */ + int num_printers; /* Number of printers */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* member-uris attribute */ + ipp_status_t status; /* Request status */ + char uri[HTTP_MAX_URI]; /* Device or printer URI */ + const char *name, /* Pointer to class name */ + *ptr; /* Pointer to CGI variable */ + + + if (cgiGetVariable("PRINTER_LOCATION") == NULL) + { + if (modify) + { + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", + cgiGetVariable("PRINTER_NAME")); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + ippSetCGIVars(response, NULL, NULL); + ippDelete(response); + } + + /* + * Update the location and description of an existing printer... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "modify-class.tmpl", getenv("LANG")); + } + else + { + /* + * Get the name, location, and description for a new printer... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "add-class.tmpl", getenv("LANG")); + } + + return; + } + + name = cgiGetVariable("PRINTER_NAME"); + for (ptr = name; *ptr; ptr ++) + if (!isalnum(*ptr) && *ptr != '_') + break; + + if (*ptr || ptr == name) + { + cgiSetVariable("ERROR", "The class name may only contain letters, " + "numbers, and the underscore."); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + return; + } + + if (cgiGetVariable("MEMBER_URIS") == NULL) + { + /* + * Build a CUPS_GET_PRINTERS request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_GET_PRINTERS; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/printers"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + /* + * Create MEMBER_URIS and MEMBER_NAMES arrays... + */ + + for (element = 0, attr = response->attrs; + attr != NULL; + attr = attr->next) + if (attr->name && strcmp(attr->name, "printer-uri-supported") == 0) + { + cgiSetArray("MEMBER_URIS", element, attr->values[0].string.text); + element ++; + } + + for (element = 0, attr = response->attrs; + attr != NULL; + attr = attr->next) + if (attr->name && strcmp(attr->name, "printer-name") == 0) + { + cgiSetArray("MEMBER_NAMES", element, attr->values[0].string.text); + element ++; + } + + num_printers = cgiGetSize("MEMBER_URIS"); + + ippDelete(response); + } + else + num_printers = 0; + + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", + cgiGetVariable("PRINTER_NAME")); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) + { + /* + * Mark any current members in the class... + */ + + for (j = 0; j < num_printers; j ++) + cgiSetArray("MEMBER_SELECTED", j, ""); + + for (i = 0; i < attr->num_values; i ++) + for (j = 0; j < num_printers; j ++) + if (strcmp(attr->values[i].string.text, cgiGetArray("MEMBER_URIS", j)) == 0) + { + cgiSetArray("MEMBER_SELECTED", j, "SELECTED"); + break; + } + } + + ippDelete(response); + } + + /* + * Let the user choose... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "choose-members.tmpl", getenv("LANG")); + } + else + { + /* + * Build a CUPS_ADD_CLASS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * printer-location + * printer-info + * printer-is-accepting-jobs + * printer-state + * member-uris + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_ADD_CLASS; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", + cgiGetVariable("PRINTER_NAME")); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location", + NULL, cgiGetVariable("PRINTER_LOCATION")); + + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", + NULL, cgiGetVariable("PRINTER_INFO")); + + ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1); + + ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", + IPP_PRINTER_IDLE); + + if ((num_printers = cgiGetSize("MEMBER_URIS")) > 0) + { + attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", + num_printers, NULL, NULL); + for (i = 0; i < num_printers; i ++) + attr->values[i].string.text = strdup(cgiGetArray("MEMBER_URIS", i)); + } + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) + { + status = response->request.status.status_code; + ippDelete(response); + } + else + status = IPP_NOT_AUTHORIZED; + + if (status > IPP_OK_CONFLICT) + { + cgiSetVariable("ERROR", ippErrorString(status)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + } + else if (modify) + cgiCopyTemplateLang(stdout, TEMPLATES, "class-modified.tmpl", getenv("LANG")); + else + cgiCopyTemplateLang(stdout, TEMPLATES, "class-added.tmpl", getenv("LANG")); + } +} + + +/* + * 'do_am_printer()' - Add or modify a printer. + */ + +static void +do_am_printer(http_t *http, /* I - HTTP connection */ + cups_lang_t *language, /* I - Client's language */ + int modify) /* I - Modify the printer? */ +{ + int i; /* Looping var */ + int element; /* Element number */ + ipp_attribute_t *attr, /* Current attribute */ + *last; /* Last attribute */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_status_t status; /* Request status */ + const char *var; /* CGI variable */ + char uri[HTTP_MAX_URI], /* Device or printer URI */ + *uriptr; /* Pointer into URI */ + int maxrate; /* Maximum baud rate */ + char baudrate[255]; /* Baud rate string */ + const char *name, /* Pointer to class name */ + *ptr; /* Pointer to CGI variable */ + static int baudrates[] = /* Baud rates */ + { + 1200, + 2400, + 4800, + 9600, + 19200, + 38400, + 57600, + 115200, + 230400, + 460800 + }; + + + if (cgiGetVariable("PRINTER_LOCATION") == NULL) + { + if (modify) + { + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", + cgiGetVariable("PRINTER_NAME")); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + ippSetCGIVars(response, NULL, NULL); + ippDelete(response); + } + + /* + * Update the location and description of an existing printer... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "modify-printer.tmpl", getenv("LANG")); + } + else + { + /* + * Get the name, location, and description for a new printer... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "add-printer.tmpl", getenv("LANG")); + } + + return; + } + + name = cgiGetVariable("PRINTER_NAME"); + for (ptr = name; *ptr; ptr ++) + if (!isalnum(*ptr) && *ptr != '_') + break; + + if (*ptr || ptr == name) + { + cgiSetVariable("ERROR", "The printer name may only contain letters, " + "numbers, and the underscore."); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + return; + } + + if ((var = cgiGetVariable("DEVICE_URI")) == NULL) + { + /* + * Build a CUPS_GET_DEVICES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_GET_DEVICES; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/printers/"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + ippSetCGIVars(response, NULL, NULL); + ippDelete(response); + } + + /* + * Let the user choose... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "choose-device.tmpl", getenv("LANG")); + } + else if (strchr(var, '/') == NULL) + { + /* + * User needs to set the full URI... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "choose-uri.tmpl", getenv("LANG")); + } + else if (strncmp(var, "serial:", 7) == 0 && cgiGetVariable("BAUDRATE") == NULL) + { + /* + * Need baud rate, parity, etc. + */ + + if ((var = strchr(var, '?')) != NULL && + strncmp(var, "?baud=", 6) == 0) + maxrate = atoi(var + 6); + else + maxrate = 19200; + + for (i = 0; i < 10; i ++) + if (baudrates[i] > maxrate) + break; + else + { + sprintf(baudrate, "%d", baudrates[i]); + cgiSetArray("BAUDRATES", i, baudrate); + } + + cgiCopyTemplateLang(stdout, TEMPLATES, "choose-serial.tmpl", getenv("LANG")); + } + else if ((var = cgiGetVariable("PPD_NAME")) == NULL) + { + /* + * Build a CUPS_GET_PPDS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_GET_PPDS; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, "ipp://localhost/printers/"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + if ((var = cgiGetVariable("PPD_MAKE")) == NULL) + { + /* + * Let the user choose a make... + */ + + for (element = 0, attr = response->attrs, last = NULL; + attr != NULL; + attr = attr->next) + if (attr->name && strcmp(attr->name, "ppd-make") == 0) + if (last == NULL || + strcasecmp(last->values[0].string.text, + attr->values[0].string.text) != 0) + { + cgiSetArray("PPD_MAKE", element, attr->values[0].string.text); + element ++; + last = attr; + } + + cgiCopyTemplateLang(stdout, TEMPLATES, "choose-make.tmpl", + getenv("LANG")); + } + else + { + /* + * Let the user choose a model... + */ + + ippSetCGIVars(response, "ppd-make", var); + cgiCopyTemplateLang(stdout, TEMPLATES, "choose-model.tmpl", + getenv("LANG")); + } + + ippDelete(response); + } + + } + else + { + /* + * Build a CUPS_ADD_PRINTER request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * printer-location + * printer-info + * ppd-name + * device-uri + * printer-is-accepting-jobs + * printer-state + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_ADD_PRINTER; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", + cgiGetVariable("PRINTER_NAME")); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location", + NULL, cgiGetVariable("PRINTER_LOCATION")); + + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info", + NULL, cgiGetVariable("PRINTER_INFO")); + + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_NAME, "ppd-name", + NULL, cgiGetVariable("PPD_NAME")); + + strcpy(uri, cgiGetVariable("DEVICE_URI")); + if (strncmp(uri, "serial:", 7) == 0) + { + /* + * Update serial port URI to include baud rate, etc. + */ + + if ((uriptr = strchr(uri, '?')) == NULL) + uriptr = uri + strlen(uri); + + sprintf(uriptr, "?baud=%s+bits=%s+parity=%s+flow=%s", + cgiGetVariable("BAUDRATE"), cgiGetVariable("BITS"), + cgiGetVariable("PARITY"), cgiGetVariable("FLOW")); + } + + ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "device-uri", + NULL, uri); + + ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1); + + ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", + IPP_PRINTER_IDLE); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) + { + status = response->request.status.status_code; + ippDelete(response); + } + else + status = IPP_NOT_AUTHORIZED; + + if (status > IPP_OK_CONFLICT) + { + cgiSetVariable("ERROR", ippErrorString(status)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + } + else if (modify) + cgiCopyTemplateLang(stdout, TEMPLATES, "printer-modified.tmpl", getenv("LANG")); + else + cgiCopyTemplateLang(stdout, TEMPLATES, "printer-added.tmpl", getenv("LANG")); + } +} + + +/* + * 'do_config_printer()' - Configure the default options for a printer. + */ + +static void +do_config_printer(http_t *http, /* I - HTTP connection */ + cups_lang_t *language)/* I - Client's language */ +{ + int i, j, k; /* Looping vars */ + int have_options; /* Have options? */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* IPP attribute */ + char uri[HTTP_MAX_URI]; /* Job URI */ + const char *var; /* Variable value */ + const char *printer; /* Printer printer name */ + ipp_status_t status; /* Operation status... */ + const char *filename; /* PPD filename */ + char tempfile[1024]; /* Temporary filename */ + FILE *in, /* Input file */ + *out; /* Output file */ + char line[1024]; /* Line from PPD file */ + char keyword[1024], /* Keyword from Default line */ + *keyptr; /* Pointer into keyword... */ + ppd_file_t *ppd; /* PPD file */ + ppd_group_t *group; /* Option group */ + ppd_option_t *option; /* Option */ + + + /* + * Get the printer name... + */ + + if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL) + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer); + else + { + cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + return; + } + + /* + * Get the PPD file... + */ + + if ((filename = cupsGetPPD(printer)) == NULL) + { + cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + return; + } + + ppd = ppdOpenFile(filename); + + if (cgiGetVariable("job_sheets_start") != NULL || + cgiGetVariable("job_sheets_end") != NULL) + have_options = 1; + else + have_options = 0; + + for (i = ppd->num_groups, group = ppd->groups; + i > 0 && !have_options; + i --, group ++) + for (j = group->num_options, option = group->options; + j > 0; + j --, option ++) + if ((var = cgiGetVariable(option->keyword)) != NULL) + { + have_options = 1; + break; + } + + if (!have_options) + { + /* + * Show the options to the user... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "config-printer.tmpl", + getenv("LANG")); + + for (i = ppd->num_groups, group = ppd->groups; + i > 0; + i --, group ++) + { + cgiSetVariable("GROUP", group->text); + cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl", + getenv("LANG")); + + for (j = group->num_options, option = group->options; + j > 0; + j --, option ++) + { + if (strcmp(option->keyword, "PageRegion") == 0) + continue; + + cgiSetVariable("KEYWORD", option->keyword); + cgiSetVariable("KEYTEXT", option->text); + cgiSetVariable("DEFCHOICE", option->defchoice); + + cgiSetSize("CHOICES", option->num_choices); + cgiSetSize("TEXT", option->num_choices); + for (k = 0; k < option->num_choices; k ++) + { + cgiSetArray("CHOICES", k, option->choices[k].choice); + cgiSetArray("TEXT", k, option->choices[k].text); + } + + switch (option->ui) + { + case PPD_UI_BOOLEAN : + cgiCopyTemplateLang(stdout, TEMPLATES, "option-boolean.tmpl", + getenv("LANG")); + break; + case PPD_UI_PICKONE : + cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl", + getenv("LANG")); + break; + case PPD_UI_PICKMANY : + cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickmany.tmpl", + getenv("LANG")); + break; + } + } + + cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl", + getenv("LANG")); + } + + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the + * following attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", + cgiGetVariable("PRINTER_NAME")); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + if ((attr = ippFindAttribute(response, "job-sheets-supported", IPP_TAG_ZERO)) != NULL) + { + /* + * Add the job sheets options... + */ + + cgiSetVariable("GROUP", "Banners"); + cgiCopyTemplateLang(stdout, TEMPLATES, "option-header.tmpl", + getenv("LANG")); + + cgiSetSize("CHOICES", attr->num_values); + cgiSetSize("TEXT", attr->num_values); + for (k = 0; k < attr->num_values; k ++) + { + cgiSetArray("CHOICES", k, attr->values[k].string.text); + cgiSetArray("TEXT", k, attr->values[k].string.text); + } + + attr = ippFindAttribute(response, "job-sheets-default", IPP_TAG_ZERO); + + cgiSetVariable("KEYWORD", "job_sheets_start"); + cgiSetVariable("KEYTEXT", "Starting Banner"); + cgiSetVariable("DEFCHOICE", attr == NULL ? + "" : attr->values[0].string.text); + + cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl", + getenv("LANG")); + + cgiSetVariable("KEYWORD", "job_sheets_end"); + cgiSetVariable("KEYTEXT", "Ending Banner"); + cgiSetVariable("DEFCHOICE", attr == NULL && attr->num_values > 1 ? + "" : attr->values[1].string.text); + + cgiCopyTemplateLang(stdout, TEMPLATES, "option-pickone.tmpl", + getenv("LANG")); + + cgiCopyTemplateLang(stdout, TEMPLATES, "option-trailer.tmpl", + getenv("LANG")); + } + + ippDelete(response); + } + + cgiCopyTemplateLang(stdout, TEMPLATES, "config-printer2.tmpl", + getenv("LANG")); + } + else + { + /* + * Set default options... + */ + + cupsTempFile(tempfile, sizeof(tempfile)); + + in = fopen(filename, "rb"); + out = fopen(tempfile, "wb"); + + while (get_line(line, sizeof(line), in) != NULL) + { + if (strncmp(line, "*Default", 8) != 0) + fprintf(out, "%s\n", line); + else + { + /* + * Get default option name... + */ + + strcpy(keyword, line + 8); + + for (keyptr = keyword; *keyptr; keyptr ++) + if (*keyptr == ':' || isspace(*keyptr)) + break; + + *keyptr = '\0'; + + if (strcmp(keyword, "PageRegion") == 0) + var = cgiGetVariable("PageSize"); + else + var = cgiGetVariable(keyword); + + if (var != NULL) + fprintf(out, "*Default%s: %s\n", keyword, var); + else + fprintf(out, "%s\n", line); + } + } + + fclose(in); + fclose(out); + + /* + * Build a CUPS_ADD_PRINTER request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * job-sheets-default + * [ppd file] + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_ADD_PRINTER; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", + cgiGetVariable("PRINTER_NAME")); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_NAME, + "job-sheets-default", 2, NULL, NULL); + attr->values[0].string.text = strdup(cgiGetVariable("job_sheets_start")); + attr->values[1].string.text = strdup(cgiGetVariable("job_sheets_end")); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoFileRequest(http, request, "/admin/", tempfile)) != NULL) + { + status = response->request.status.status_code; + ippDelete(response); + } + else + status = IPP_NOT_AUTHORIZED; + + if (status > IPP_OK_CONFLICT) + { + cgiSetVariable("ERROR", ippErrorString(status)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + } + else + cgiCopyTemplateLang(stdout, TEMPLATES, "printer-configured.tmpl", getenv("LANG")); + + unlink(tempfile); + } + + unlink(filename); +} + + +/* + * 'do_delete_class()' - Delete a class... + */ + +static void +do_delete_class(http_t *http, /* I - HTTP connection */ + cups_lang_t *language) /* I - Client's language */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + char uri[HTTP_MAX_URI]; /* Job URI */ + const char *pclass; /* Printer class name */ + ipp_status_t status; /* Operation status... */ + + + if (cgiGetVariable("CONFIRM") == NULL) + { + cgiCopyTemplateLang(stdout, TEMPLATES, "class-confirm.tmpl", getenv("LANG")); + return; + } + + if ((pclass = cgiGetVariable("PRINTER_NAME")) != NULL) + snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass); + else + { + cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + return; + } + + /* + * Build a CUPS_DELETE_CLASS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_DELETE_CLASS; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) + { + status = response->request.status.status_code; + + ippDelete(response); + } + else + status = IPP_GONE; + + if (status > IPP_OK_CONFLICT) + { + cgiSetVariable("ERROR", ippErrorString(status)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + } + else + cgiCopyTemplateLang(stdout, TEMPLATES, "class-deleted.tmpl", getenv("LANG")); +} + + +/* + * 'do_delete_printer()' - Delete a printer... + */ + +static void +do_delete_printer(http_t *http, /* I - HTTP connection */ + cups_lang_t *language)/* I - Client's language */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + char uri[HTTP_MAX_URI]; /* Job URI */ + const char *printer; /* Printer printer name */ + ipp_status_t status; /* Operation status... */ + + + if (cgiGetVariable("CONFIRM") == NULL) + { + cgiCopyTemplateLang(stdout, TEMPLATES, "printer-confirm.tmpl", getenv("LANG")); + return; + } + + if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL) + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer); + else + { + cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + return; + } + + /* + * Build a CUPS_DELETE_PRINTER request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_DELETE_PRINTER; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) + { + status = response->request.status.status_code; + + ippDelete(response); + } + else + status = IPP_GONE; + + if (status > IPP_OK_CONFLICT) + { + cgiSetVariable("ERROR", ippErrorString(status)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + } + else + cgiCopyTemplateLang(stdout, TEMPLATES, "printer-deleted.tmpl", getenv("LANG")); +} + + +/* + * 'do_job_op()' - Do a job operation. + */ + +static void +do_job_op(http_t *http, /* I - HTTP connection */ + cups_lang_t *language, /* I - Client's language */ + ipp_op_t op) /* I - Operation to perform */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + char uri[HTTP_MAX_URI]; /* Job URI */ + const char *job; /* Job ID */ + const char *printer; /* Printer name (purge-jobs) */ + ipp_status_t status; /* Operation status... */ + + + if ((job = cgiGetVariable("JOB_ID")) != NULL) + snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%s", job); + else if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL) + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer); + else + { + cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + return; + } + + /* + * Build a job request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * job-uri or printer-uri (purge-jobs) + * requesting-user-name + */ + + request = ippNew(); + + request->request.op.operation_id = op; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + if (job) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", + NULL, uri); + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + if (getenv("REMOTE_USER") != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, getenv("REMOTE_USER")); + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, "root"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/jobs")) != NULL) + { + status = response->request.status.status_code; + + ippDelete(response); + } + else + status = IPP_GONE; + + if (status > IPP_OK_CONFLICT) + { + cgiSetVariable("ERROR", ippErrorString(status)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + } + else if (op == IPP_CANCEL_JOB) + cgiCopyTemplateLang(stdout, TEMPLATES, "job-cancel.tmpl", getenv("LANG")); + else if (op == IPP_HOLD_JOB) + cgiCopyTemplateLang(stdout, TEMPLATES, "job-hold.tmpl", getenv("LANG")); + else if (op == IPP_RELEASE_JOB) + cgiCopyTemplateLang(stdout, TEMPLATES, "job-release.tmpl", getenv("LANG")); + else if (op == IPP_RESTART_JOB) + cgiCopyTemplateLang(stdout, TEMPLATES, "job-restart.tmpl", getenv("LANG")); +} + + +/* + * 'do_printer_op()' - Do a printer operation. + */ + +static void +do_printer_op(http_t *http, /* I - HTTP connection */ + cups_lang_t *language, /* I - Client's language */ + ipp_op_t op) /* I - Operation to perform */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + char uri[HTTP_MAX_URI]; /* Printer URI */ + const char *printer; /* Printer name (purge-jobs) */ + ipp_status_t status; /* Operation status... */ + + + if ((printer = cgiGetVariable("PRINTER_NAME")) != NULL) + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer); + else + { + cgiSetVariable("ERROR", ippErrorString(IPP_NOT_FOUND)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + return; + } + + /* + * Build a printer request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = op; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/admin/")) != NULL) + { + status = response->request.status.status_code; + + ippDelete(response); + } + else + status = IPP_GONE; + + if (status > IPP_OK_CONFLICT) + { + cgiSetVariable("ERROR", ippErrorString(status)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + } + else if (op == IPP_PAUSE_PRINTER) + cgiCopyTemplateLang(stdout, TEMPLATES, "printer-stop.tmpl", getenv("LANG")); + else if (op == IPP_RESUME_PRINTER) + cgiCopyTemplateLang(stdout, TEMPLATES, "printer-start.tmpl", getenv("LANG")); + else if (op == CUPS_ACCEPT_JOBS) + cgiCopyTemplateLang(stdout, TEMPLATES, "printer-accept.tmpl", getenv("LANG")); + else if (op == CUPS_REJECT_JOBS) + cgiCopyTemplateLang(stdout, TEMPLATES, "printer-reject.tmpl", getenv("LANG")); +} + + +/* + * 'get_line()' - Get a line that is terminated by a LF, CR, or CR LF. + */ + +static char * /* O - Pointer to buf or NULL on EOF */ +get_line(char *buf, /* I - Line buffer */ + int length, /* I - Length of buffer */ + FILE *fp) /* I - File to read from */ +{ + char *bufptr; /* Pointer into buffer */ + int ch; /* Character from file */ + + + length --; + bufptr = buf; + + while ((ch = getc(fp)) != EOF) + { + if (ch == '\n') + break; + else if (ch == '\r') + { + /* + * Look for LF... + */ + + ch = getc(fp); + if (ch != '\n' && ch != EOF) + ungetc(ch, fp); + + break; + } + + *bufptr++ = ch; + length --; + if (length == 0) + break; + } + + *bufptr = '\0'; + + if (ch == EOF) + return (NULL); + else + return (buf); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/cgi.h b/cgi-bin/cgi.h new file mode 100644 index 0000000000..838bd87678 --- /dev/null +++ b/cgi-bin/cgi.h @@ -0,0 +1,87 @@ +/* + * "$Id$" + * + * CGI support library definitions. + * + * Copyright 1997-2000 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef _CGI_H_ +# define _CGI_H_ + +# include +# include +# include +# include + +# ifdef WIN32 +# include +# include +# include +# define strcasecmp(s,t) stricmp((s),(t)) +# define strncasecmp(s,t,n) strnicmp((s),(t),(n)) +# else +# include +# endif /* WIN32 */ + + +/* + * Prototypes... + */ + +extern int cgiInitialize(void); +extern void cgiAbort(const char *title, const char *stylesheet, + const char *format, ...); +extern int cgiCheckVariables(const char *names); +extern const char *cgiGetArray(const char *name, int element); +extern int cgiGetSize(const char *name); +extern void cgiSetSize(const char *name, int size); +extern const char *cgiGetVariable(const char *name); +extern void cgiSetArray(const char *name, int element, + const char *value); +extern void cgiSetVariable(const char *name, const char *value); +extern void cgiCopyTemplateFile(FILE *out, const char *tmpl); +extern void cgiCopyTemplateLang(FILE *out, const char *directory, + const char *tmpl, const char *lang); + +extern void cgiStartHTML(FILE *out, const char *author, + const char *stylesheet, + const char *keywords, + const char *description, + const char *title, ...); +extern void cgiEndHTML(FILE *out); + +extern FILE *cgiEMailOpen(const char *from, const char *to, + const char *cc, const char *subject, + int multipart); +extern void cgiEMailPart(FILE *mail, const char *type, + const char *charset, const char *encoding); +extern void cgiEMailClose(FILE *mail); + +extern char *cgiGetCookie(const char *name, char *buf, int buflen); +extern void cgiSetCookie(const char *name, const char *value, + const char *path, const char *domain, + time_t expires, int secure); + +# define cgiGetUser() getenv("REMOTE_USER") +# define cgiGetHost() (getenv("REMOTE_HOST") == NULL ? getenv("REMOTE_ADDR") : getenv("REMOTE_HOST")) + +#endif /* !_CGI_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/classes.c b/cgi-bin/classes.c new file mode 100644 index 0000000000..9e38f1294a --- /dev/null +++ b/cgi-bin/classes.c @@ -0,0 +1,301 @@ +/* + * "$Id$" + * + * Class status CGI for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry for CGI. + */ + +/* + * Include necessary headers... + */ + +#include "ipp-var.h" + + +/* + * 'main()' - Main entry for CGI. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + cups_lang_t *language; /* Language information */ + char *pclass; /* Printer class name */ + http_t *http; /* Connection to the server */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_status_t status; /* Operation status... */ + char uri[HTTP_MAX_URI]; + /* Printer URI */ + const char *which_jobs; /* Which jobs to show */ + const char *op; /* Operation to perform, if any */ + + + /* + * Get any form variables... + */ + + cgiInitialize(); + op = cgiGetVariable("OP"); + + /* + * Get the request language... + */ + + language = cupsLangDefault(); + + /* + * Connect to the HTTP server... + */ + + http = httpConnect("localhost", ippPort()); + + /* + * Tell the client to expect HTML... + */ + + printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language)); + + /* + * See if we need to show a list of printers or the status of a + * single printer... + */ + + ippSetServerVersion(); + + pclass = argv[0]; + if (strcmp(pclass, "/") == 0 || strcmp(pclass, "classes.cgi") == 0) + { + pclass = NULL; + cgiSetVariable("TITLE", cupsLangString(language, CUPS_MSG_CLASS)); + } + else + cgiSetVariable("TITLE", pclass); + + cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG")); + + if (op == NULL || strcasecmp(op, "print-test-page") != 0) + { + /* + * Get the class info... + */ + + request = ippNew(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + if (pclass == NULL) + { + /* + * Build a CUPS_GET_CLASSES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request->request.op.operation_id = CUPS_GET_CLASSES; + request->request.op.request_id = 1; + } + else + { + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; + request->request.op.request_id = 1; + + snprintf(uri, sizeof(uri), "ipp://%s/classes/%s", getenv("SERVER_NAME"), + pclass); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, + uri); + } + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + ippSetCGIVars(response, NULL, NULL); + ippDelete(response); + } + + /* + * Write the report... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "classes.tmpl", getenv("LANG")); + + /* + * Get jobs for the specified class if a class has been chosen... + */ + + if (pclass != NULL) + { + /* + * Build an IPP_GET_JOBS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + request->request.op.operation_id = IPP_GET_JOBS; + request->request.op.request_id = 1; + + snprintf(uri, sizeof(uri), "ipp://%s/classes/%s", getenv("SERVER_NAME"), + pclass); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, + uri); + + if ((which_jobs = cgiGetVariable("which_jobs")) != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", + NULL, which_jobs); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + ippSetCGIVars(response, NULL, NULL); + ippDelete(response); + + cgiCopyTemplateLang(stdout, TEMPLATES, "jobs.tmpl", getenv("LANG")); + } + } + } + else + { + /* + * Print a test page... + */ + + snprintf(uri, sizeof(uri), "ipp://localhost/classes/%s", pclass); + + /* + * Build an IPP_PRINT_JOB request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requesting-user-name + * document-format + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_PRINT_JOB; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + if (getenv("REMOTE_USER") != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, getenv("REMOTE_USER")); + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, "root"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", + NULL, "Test Page"); + + ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format", + NULL, "application/postscript"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoFileRequest(http, request, uri + 15, + CUPS_DATADIR "/data/testprint.ps")) != NULL) + { + status = response->request.status.status_code; + ippSetCGIVars(response, NULL, NULL); + + ippDelete(response); + } + else + status = IPP_GONE; + + cgiSetVariable("PRINTER_NAME", pclass); + + if (status > IPP_OK_CONFLICT) + { + cgiSetVariable("ERROR", ippErrorString(status)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + } + else + cgiCopyTemplateLang(stdout, TEMPLATES, "test-page.tmpl", getenv("LANG")); + } + + cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG")); + + /* + * Close the HTTP server connection... + */ + + httpClose(http); + cupsLangFree(language); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/html.c b/cgi-bin/html.c new file mode 100644 index 0000000000..c2b47c4c05 --- /dev/null +++ b/cgi-bin/html.c @@ -0,0 +1,89 @@ +/* + * "$Id$" + * + * CGI HTML functions. + * + * Copyright 1997-2000 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contents: + * + * cgiStartHTML() - Start an HTML document stream. + * cgiEndHTML() - End an HTML document stream. + */ + +#include "cgi.h" +#include + + +/* + * 'cgiStartHTML()' - Start an HTML document stream. + */ + +void +cgiStartHTML(FILE *out, /* I - Output file to use */ + const char *stylesheet, /* I - Stylesheet to use */ + const char *author, /* I - Author name */ + const char *keywords, /* I - Search keywords */ + const char *description, /* I - Description of document */ + const char *title, /* I - Title for page */ + ...) /* I - Any addition args for title */ +{ + va_list ap; /* Argument pointer */ + + + fputs("Content-type: text/html\n\n", out); + fputs("\n", out); + fputs("\n", out); + fputs("\n", out); + + fputs("\t\n", out); + va_start(ap, title); + vfprintf(out, title, ap); + va_end(ap); + fputs("\n", out); + + if (stylesheet) + fprintf(out, "\t\n", + stylesheet); + if (author) + fprintf(out, "\t\n", author); + if (keywords) + fprintf(out, "\t\n", keywords); + if (description) + fprintf(out, "\t\n", description); + + fputs("\n", out); + fputs("\n", out); +} + + +/* + * 'cgiEndHTML()' - End an HTML document stream. + */ + +void +cgiEndHTML(FILE *out) /* I - Output file to use */ +{ + fputs("\n", out); + fputs("\n", out); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/ipp-var.c b/cgi-bin/ipp-var.c new file mode 100644 index 0000000000..91615b3e0d --- /dev/null +++ b/cgi-bin/ipp-var.c @@ -0,0 +1,257 @@ +/* + * "$Id$" + * + * IPP variable routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ippSetServerVersion() - Set the server name and CUPS version... + * ippSetCGIVars() - Set CGI variables from an IPP response. + */ + +/* + * Include necessary headers... + */ + +#include "ipp-var.h" + + +/* + * 'ippGetTemplateDir()' - Get the templates directory... + */ + +char * /* O - Template directory */ +ippGetTemplateDir(void) +{ + const char *datadir; /* CUPS_DATADIR env var */ + static char templates[1024] = ""; /* Template directory */ + + + if (!templates[0]) + { + /* + * Build the template directory pathname... + */ + + if ((datadir = getenv("CUPS_DATADIR")) == NULL) + datadir = CUPS_DATADIR; + + snprintf(templates, sizeof(templates), "%s/templates", datadir); + } + + return (templates); +} + + +/* + * 'ippSetServerVersion()' - Set the server name and CUPS version... + */ + +void +ippSetServerVersion(void) +{ + cgiSetVariable("SERVER_NAME", getenv("SERVER_NAME")); + cgiSetVariable("REMOTE_USER", getenv("REMOTE_USER")); + cgiSetVariable("CUPS_VERSION", CUPS_SVERSION); +} + + +/* + * 'ippSetCGIVars()' - Set CGI variables from an IPP response. + */ + +void +ippSetCGIVars(ipp_t *response, /* I - Response data to be copied... */ + const char *filter_name, /* I - Filter name */ + const char *filter_value) /* I - Filter value */ +{ + int element; /* Element in CGI array */ + ipp_attribute_t *attr, /* Attribute in response... */ + *filter; /* Filtering attribute */ + int i; /* Looping var */ + char name[1024], /* Name of attribute */ + value[16384], /* Value(s) */ + *valptr; /* Pointer into value */ + char method[HTTP_MAX_URI], + username[HTTP_MAX_URI], + hostname[HTTP_MAX_URI], + resource[HTTP_MAX_URI], + uri[HTTP_MAX_URI]; + int port; /* URI data */ + char server[1024]; /* Name of server */ + + + ippSetServerVersion(); + + strcpy(server, cupsServer()); + + for (attr = response->attrs; + attr && attr->group_tag == IPP_TAG_OPERATION; + attr = attr->next); + + for (element = 0; attr != NULL; attr = attr->next, element ++) + { + /* + * Copy attributes to a separator... + */ + + if (filter_name) + { + for (filter = attr; + filter != NULL && filter->group_tag != IPP_TAG_ZERO; + filter = filter->next) + if (filter->name && strcmp(filter->name, filter_name) == 0 && + strcasecmp(filter->values[0].string.text, filter_value) == 0) + break; + + if (!filter) + return; + + if (filter->group_tag == IPP_TAG_ZERO) + { + attr = filter; + element --; + continue; + } + } + + for (; attr != NULL && attr->group_tag != IPP_TAG_ZERO; attr = attr->next) + { + /* + * Copy the attribute name, substituting "_" for "-"... + */ + + if (attr->name == NULL) + continue; + + for (i = 0; attr->name[i]; i ++) + if (attr->name[i] == '-') + name[i] = '_'; + else + name[i] = attr->name[i]; + + name[i] = '\0'; + + /* + * Copy values... + */ + + value[0] = '\0'; + valptr = value; + + for (i = 0; i < attr->num_values; i ++) + { + if (i) + strcat(valptr, ","); + + valptr += strlen(valptr); + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + sprintf(valptr, "%d", attr->values[i].integer); + break; + + case IPP_TAG_BOOLEAN : + sprintf(valptr, "%d", attr->values[i].boolean); + break; + + case IPP_TAG_NOVALUE : + strcat(valptr, "novalue"); + break; + + case IPP_TAG_RANGE : + sprintf(valptr, "%d-%d", attr->values[i].range.lower, + attr->values[i].range.upper); + break; + + case IPP_TAG_RESOLUTION : + sprintf(valptr, "%dx%d%s", attr->values[i].resolution.xres, + attr->values[i].resolution.yres, + attr->values[i].resolution.units == IPP_RES_PER_INCH ? + "dpi" : "dpc"); + break; + + case IPP_TAG_URI : + if (strchr(attr->values[i].string.text, ':') != NULL) + { + httpSeparate(attr->values[i].string.text, method, username, + hostname, &port, resource); + + if (strcmp(method, "ipp") == 0 || + strcmp(method, "http") == 0) + { + /* + * Map localhost access to localhost... + */ + + if (strcasecmp(hostname, server) == 0 && + (strcmp(getenv("REMOTE_HOST"), "127.0.0.1") == 0 || + strcmp(getenv("REMOTE_HOST"), "localhost") == 0)) + strcpy(hostname, "localhost"); + + /* + * Rewrite URI with HTTP address... + */ + + if (username[0]) + snprintf(uri, sizeof(uri), "http://%s@%s:%d%s", username, + hostname, port, resource); + else + snprintf(uri, sizeof(uri), "http://%s:%d%s", hostname, port, + resource); + + strcat(valptr, uri); + break; + } + } + + case IPP_TAG_STRING : + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + strcat(valptr, attr->values[i].string.text); + break; + + default : + break; /* anti-compiler-warning-code */ + } + } + + /* + * Add the element... + */ + + cgiSetArray(name, element, value); + } + + if (attr == NULL) + break; + } +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/ipp-var.h b/cgi-bin/ipp-var.h new file mode 100644 index 0000000000..4b60b49afa --- /dev/null +++ b/cgi-bin/ipp-var.h @@ -0,0 +1,55 @@ +/* + * "$Id$" + * + * IPP variable definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include "cgi.h" + + +/* + * Definitions... + */ + +#define TEMPLATES ippGetTemplateDir() + + +/* + * Prototype... + */ + +extern char *ippGetTemplateDir(void); +extern void ippSetServerVersion(void); +extern void ippSetCGIVars(ipp_t *, const char *, const char *); + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/jobs.c b/cgi-bin/jobs.c new file mode 100644 index 0000000000..3e6d4ab5d6 --- /dev/null +++ b/cgi-bin/jobs.c @@ -0,0 +1,139 @@ +/* + * "$Id$" + * + * Job status CGI for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry for CGI. + */ + +/* + * Include necessary headers... + */ + +#include "ipp-var.h" + + +/* + * 'main()' - Main entry for CGI. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + cups_lang_t *language; /* Language information */ + http_t *http; /* Connection to the server */ + const char *which_jobs; /* Which jobs to show */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + + + /* + * Get any form variables... + */ + + cgiInitialize(); + + /* + * Get the request language... + */ + + language = cupsLangDefault(); + + /* + * Connect to the HTTP server... + */ + + http = httpConnect("localhost", ippPort()); + + /* + * Tell the client to expect HTML... + */ + + printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language)); + + cgiSetVariable("TITLE", "Jobs"); + + ippSetServerVersion(); + + cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG")); + + /* + * Build an IPP_GET_JOBS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + request->request.op.operation_id = IPP_GET_JOBS; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, + "ipp://localhost/jobs"); + + if ((which_jobs = cgiGetVariable("which_jobs")) != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", + NULL, which_jobs); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + ippSetCGIVars(response, NULL, NULL); + ippDelete(response); + + cgiCopyTemplateLang(stdout, TEMPLATES, "jobs.tmpl", getenv("LANG")); + } + + cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG")); + + /* + * Close the HTTP server connection... + */ + + httpClose(http); + cupsLangFree(language); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/printers.c b/cgi-bin/printers.c new file mode 100644 index 0000000000..4c61acc343 --- /dev/null +++ b/cgi-bin/printers.c @@ -0,0 +1,301 @@ +/* + * "$Id$" + * + * Printer status CGI for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry for CGI. + */ + +/* + * Include necessary headers... + */ + +#include "ipp-var.h" + + +/* + * 'main()' - Main entry for CGI. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + cups_lang_t *language; /* Language information */ + char *printer; /* Printer name */ + http_t *http; /* Connection to the server */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_status_t status; /* Operation status... */ + char uri[HTTP_MAX_URI]; + /* Printer URI */ + const char *which_jobs; /* Which jobs to show */ + const char *op; /* Operation to perform, if any */ + + + /* + * Get any form variables... + */ + + cgiInitialize(); + op = cgiGetVariable("OP"); + + /* + * Get the request language... + */ + + language = cupsLangDefault(); + + /* + * Connect to the HTTP server... + */ + + http = httpConnect("localhost", ippPort()); + + /* + * Tell the client to expect HTML... + */ + + printf("Content-Type: text/html;charset=%s\n\n", cupsLangEncoding(language)); + + /* + * See if we need to show a list of printers or the status of a + * single printer... + */ + + ippSetServerVersion(); + + printer = argv[0]; + if (strcmp(printer, "/") == 0 || strcmp(printer, "printers.cgi") == 0) + { + printer = NULL; + cgiSetVariable("TITLE", cupsLangString(language, CUPS_MSG_PRINTER)); + } + else + cgiSetVariable("TITLE", printer); + + cgiCopyTemplateLang(stdout, TEMPLATES, "header.tmpl", getenv("LANG")); + + if (op == NULL || strcasecmp(op, "print-test-page") != 0) + { + /* + * Get the printer info... + */ + + request = ippNew(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + if (printer == NULL) + { + /* + * Build a CUPS_GET_PRINTERS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request->request.op.operation_id = CUPS_GET_PRINTERS; + request->request.op.request_id = 1; + } + else + { + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; + request->request.op.request_id = 1; + + snprintf(uri, sizeof(uri), "ipp://%s/printers/%s", getenv("SERVER_NAME"), + printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, + uri); + } + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + ippSetCGIVars(response, NULL, NULL); + ippDelete(response); + } + + /* + * Write the report... + */ + + cgiCopyTemplateLang(stdout, TEMPLATES, "printers.tmpl", getenv("LANG")); + + /* + * Get jobs for the specified printer if a printer has been chosen... + */ + + if (printer != NULL) + { + /* + * Build an IPP_GET_JOBS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + request->request.op.operation_id = IPP_GET_JOBS; + request->request.op.request_id = 1; + + snprintf(uri, sizeof(uri), "ipp://%s/printers/%s", getenv("SERVER_NAME"), + printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, + uri); + + if ((which_jobs = cgiGetVariable("which_jobs")) != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", + NULL, which_jobs); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(http, request, "/")) != NULL) + { + ippSetCGIVars(response, NULL, NULL); + ippDelete(response); + + cgiCopyTemplateLang(stdout, TEMPLATES, "jobs.tmpl", getenv("LANG")); + } + } + } + else + { + /* + * Print a test page... + */ + + snprintf(uri, sizeof(uri), "ipp://localhost/printers/%s", printer); + + /* + * Build an IPP_PRINT_JOB request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * requesting-user-name + * document-format + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_PRINT_JOB; + request->request.op.request_id = 1; + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + if (getenv("REMOTE_USER") != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, getenv("REMOTE_USER")); + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, "root"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", + NULL, "Test Page"); + + ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format", + NULL, "application/postscript"); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoFileRequest(http, request, uri + 15, + CUPS_DATADIR "/data/testprint.ps")) != NULL) + { + status = response->request.status.status_code; + ippSetCGIVars(response, NULL, NULL); + + ippDelete(response); + } + else + status = IPP_GONE; + + cgiSetVariable("PRINTER_NAME", printer); + + if (status > IPP_OK_CONFLICT) + { + cgiSetVariable("ERROR", ippErrorString(status)); + cgiCopyTemplateLang(stdout, TEMPLATES, "error.tmpl", getenv("LANG")); + } + else + cgiCopyTemplateLang(stdout, TEMPLATES, "test-page.tmpl", getenv("LANG")); + } + + cgiCopyTemplateLang(stdout, TEMPLATES, "trailer.tmpl", getenv("LANG")); + + /* + * Close the HTTP server connection... + */ + + httpClose(http); + cupsLangFree(language); + + /* + * Return with no errors... + */ + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/template.c b/cgi-bin/template.c new file mode 100644 index 0000000000..0d06cfed09 --- /dev/null +++ b/cgi-bin/template.c @@ -0,0 +1,455 @@ +/* + * "$Id$" + * + * CGI template function. + * + * Copyright 1997-2000 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contents: + * + * cgiCopyTemplateFile() - Copy a template file and replace all the + * '{variable}' strings with the variable value. + * cgiCopyTemplateLang() - Copy a template file using a language... + * cgi_copy() - Copy the template file, substituting as needed... + * cgi_puts() - Put a string to the output file, quoting as + * needed... + */ + +#include "cgi.h" + + +/* + * Local functions... + */ + +static void cgi_copy(FILE *out, FILE *in, int element, char term); +static void cgi_puts(const char *s, FILE *out); + + +/* + * 'cgiCopyTemplateFile()' - Copy a template file and replace all the + * '{variable}' strings with the variable value. + */ + +void +cgiCopyTemplateFile(FILE *out, /* I - Output file */ + const char *tmpl) /* I - Template file to read */ +{ + FILE *in; /* Input file */ + + + /* + * Open the template file... + */ + + if ((in = fopen(tmpl, "r")) == NULL) + return; + + /* + * Parse the file to the end... + */ + + cgi_copy(out, in, 0, 0); + + /* + * Close the template file and return... + */ + + fclose(in); +} + + +/* + * 'cgiCopyTemplateLang()' - Copy a template file using a language... + */ + +void +cgiCopyTemplateLang(FILE *out, /* I - Output file */ + const char *directory, /* I - Directory */ + const char *tmpl, /* I - Base filename */ + const char *lang) /* I - Language */ +{ + int i; /* Looping var */ + char filename[1024], /* Filename */ + locale[16]; /* Locale name */ + FILE *in; /* Input file */ + + + /* + * Convert the language to a locale name... + */ + + if (lang != NULL) + { + for (i = 0; lang[i] && i < 15; i ++) + if (isalnum(lang[i])) + locale[i] = tolower(lang[i]); + else + locale[i] = '_'; + + locale[i] = '\0'; + } + else + locale[0] = '\0'; + + /* + * See if we have a template file for this language... + */ + + sprintf(filename, "%s/%s/%s", directory, locale, tmpl); + if (access(filename, 0)) + { + locale[2] = '\0'; + + sprintf(filename, "%s/%s/%s", directory, locale, tmpl); + if (access(filename, 0)) + sprintf(filename, "%s/%s", directory, tmpl); + } + + /* + * Open the template file... + */ + + if ((in = fopen(filename, "r")) == NULL) + return; + + /* + * Parse the file to the end... + */ + + cgi_copy(out, in, 0, 0); + + /* + * Close the template file and return... + */ + + fclose(in); +} + + +/* + * 'cgi_copy()' - Copy the template file, substituting as needed... + */ + +static void +cgi_copy(FILE *out, /* I - Output file */ + FILE *in, /* I - Input file */ + int element, /* I - Element number (0 to N) */ + char term) /* I - Terminating character */ +{ + int ch; /* Character from file */ + char op; /* Operation */ + char name[255], /* Name of variable */ + *nameptr, /* Pointer into name */ + innername[255], /* Inner comparison name */ + *innerptr, /* Pointer into inner name */ + *s; /* String pointer */ + const char *value; /* Value of variable */ + const char *innerval; /* Inner value */ + char outval[1024], /* Output string */ + compare[1024]; /* Comparison string */ + int result; /* Result of comparison */ + + + /* + * Parse the file to the end... + */ + + while ((ch = getc(in)) != EOF) + if (ch == term) + break; + else if (ch == '{') + { + /* + * Get a variable name... + */ + + for (s = name; (ch = getc(in)) != EOF;) + if (strchr("}]<>=!", ch)) + break; + else if (s > name && ch == '?') + break; + else if (s < (name + sizeof(name) - 1)) + *s++ = ch; + + *s = '\0'; + + /* + * See if it has a value... + */ + + if (name[0] == '?') + { + /* + * Insert value only if it exists... + */ + + if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1])) + { + *nameptr++ = '\0'; + + if ((value = cgiGetArray(name + 1, atoi(nameptr) - 1)) != NULL) + strcpy(outval, value); + else + outval[0] = '\0'; + } + if ((value = cgiGetArray(name + 1, element)) != NULL) + strcpy(outval, value); + else + outval[0] = '\0'; + } + else if (name[0] == '#') + { + /* + * Insert count... + */ + + if (name[1]) + sprintf(outval, "%d", cgiGetSize(name + 1)); + else + sprintf(outval, "%d", element + 1); + } + else if (name[0] == '[') + { + /* + * Loop for # of elements... + */ + + int i; /* Looping var */ + long pos; /* File position */ + int count; /* Number of elements */ + + + if (isdigit(name[1])) + count = atoi(name + 1); + else + count = cgiGetSize(name + 1); + + pos = ftell(in); + + if (count > 0) + { + for (i = 0; i < count; i ++) + { + fseek(in, pos, SEEK_SET); + cgi_copy(out, in, i, '}'); + } + } + else + cgi_copy(NULL, in, 0, '}'); + + continue; + } + else + { + /* + * Insert variable or variable name (if element is NULL)... + */ + + if ((nameptr = strrchr(name, '-')) != NULL && isdigit(nameptr[1])) + { + *nameptr++ = '\0'; + if ((value = cgiGetArray(name, atoi(nameptr) - 1)) == NULL) + sprintf(outval, "{%s}", name); + else + strcpy(outval, value); + } + else if ((value = cgiGetArray(name, element)) == NULL) + sprintf(outval, "{%s}", name); + else + strcpy(outval, value); + } + + /* + * See if the terminating character requires another test... + */ + + if (ch == '}') + { + /* + * End of substitution... + */ + + if (out) + cgi_puts(outval, out); + + continue; + } + + /* + * OK, process one of the following checks: + * + * {name?exist:not-exist} Exists? + * {name=value?true:false} Equal + * {namevalue?true:false} Greater than + * {name!value?true:false} Not equal + */ + + if (ch == '?') + { + /* + * Test for existance... + */ + + result = cgiGetArray(name, element) != NULL && outval[0]; + } + else + { + /* + * Compare to a string... + */ + + op = ch; + + for (s = compare; (ch = getc(in)) != EOF;) + if (ch == '?') + break; + else if (ch == '#') + { + sprintf(s, "%d", element + 1); + s += strlen(s); + } + else if (ch == '{') + { + /* + * Grab the value of a variable... + */ + + innerptr = innername; + while ((ch = getc(in)) != EOF && ch != '}') + if (innerptr < (innername + sizeof(innername) - 1)) + *innerptr++ = ch; + *innerptr = '\0'; + + if (innername[0] == '#') + sprintf(s, "%d", cgiGetSize(innername + 1)); + else if ((innerptr = strrchr(innername, '-')) != NULL && + isdigit(innerptr[1])) + { + *innerptr++ = '\0'; + if ((innerval = cgiGetArray(innername, atoi(innerptr) - 1)) == NULL) + *s = '\0'; + else + strcpy(s, innerval); + } + else if (innername[0] == '?') + { + if ((innerval = cgiGetArray(innername + 1, element)) == NULL) + *s = '\0'; + else + strcpy(s, innerval); + } + else if ((innerval = cgiGetArray(innername, element)) == NULL) + sprintf(s, "{%s}", innername); + else + strcpy(s, innerval); + + s += strlen(s); + } + else if (ch == '\\') + *s++ = getc(in); + else + *s++ = ch; + + *s = '\0'; + + if (ch != '?') + return; + + /* + * Do the comparison... + */ + + switch (op) + { + case '<' : + result = strcasecmp(outval, compare) < 0; + break; + case '>' : + result = strcasecmp(outval, compare) > 0; + break; + case '=' : + result = strcasecmp(outval, compare) == 0; + break; + case '!' : + result = strcasecmp(outval, compare) != 0; + break; + default : + result = 1; + break; + } + } + + if (result) + { + /* + * Comparison true; output first part and ignore second... + */ + + cgi_copy(out, in, element, ':'); + cgi_copy(NULL, in, element, '}'); + } + else + { + /* + * Comparison false; ignore first part and output second... + */ + + cgi_copy(NULL, in, element, ':'); + cgi_copy(out, in, element, '}'); + } + } + else if (ch == '\\') /* Quoted char */ + { + if (out) + putc(getc(in), out); + else + getc(in); + } + else if (out) + putc(ch, out); +} + + +/* + * 'cgi_puts()' - Put a string to the output file, quoting as needed... + */ + +static void +cgi_puts(const char *s, + FILE *out) +{ + while (*s) + { + if (s[0] == '<' && s[1] != '/' && !isalpha(s[1])) + fputs("<", out); + else if (*s == '\"') + fputs(""", out); + else if (s[0] == '&' && isspace(s[1])) + fputs("&", out); + else + putc(*s, out); + + s ++; + } +} + + +/* + * End of "$Id$". + */ diff --git a/cgi-bin/var.c b/cgi-bin/var.c new file mode 100644 index 0000000000..b2ec5087e7 --- /dev/null +++ b/cgi-bin/var.c @@ -0,0 +1,656 @@ +/* + * "$Id$" + * + * CGI form variable and array functions. + * + * Copyright 1997-2000 by Easy Software Products. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * Contents: + * + * cgiInitialize() - Initialize the CGI variable "database"... + * cgiCheckVariables() - Check for the presence of "required" variables. + * cgiGetArray() - Get an element from a form array... + * cgiGetSize() - Get the size of a form array value. + * cgiGetVariable() - Get a CGI variable from the database... + * cgiSetArray() - Set array element N to the specified string. + * cgiSetVariable() - Set a CGI variable in the database... + * cgi_add_variable() - Add a form variable. + * cgi_compare_variables() - Compare two variables. + * cgi_find_variable() - Find a variable... + * cgi_initialize_get() - Initialize form variables using the GET method. + * cgi_initialize_post() - Initialize variables using the POST method. + * cgi_initialize_string() - Initialize form variables from a string. + * cgi_sort_variables() - Sort all form variables for faster lookup. + */ + +/*#define DEBUG*/ +#include "cgi.h" + + +/* + * Data structure to hold all the CGI form variables and arrays... + */ + +typedef struct +{ + const char *name; /* Name of variable */ + int nvalues, /* Number of values */ + avalues; /* Number of values allocated */ + const char **values; /* Value(s) of variable */ +} var_t; + + +/* + * Local globals... + */ + +static int form_count = 0, /* Form variable count */ + form_alloc = 0; /* Number of variables allocated */ +static var_t *form_vars = NULL; /* Form variables */ + + +/* + * Local functions... + */ + +static void cgi_add_variable(const char *name, int element, + const char *value); +static int cgi_compare_variables(const var_t *v1, const var_t *v2); +static var_t *cgi_find_variable(const char *name); +static int cgi_initialize_get(void); +static int cgi_initialize_post(void); +static int cgi_initialize_string(const char *data); +static void cgi_sort_variables(void); + + +/* + * 'cgiInitialize()' - Initialize the CGI variable "database"... + */ + +int /* O - Non-zero if there was form data */ +cgiInitialize(void) +{ + char *method; /* Form posting method */ + + +#ifdef DEBUG + setbuf(stdout, NULL); + puts("Content-type: text/plain\n"); +#endif /* DEBUG */ + + method = getenv("REQUEST_METHOD"); + + if (method == NULL) + return (0); + + if (strcasecmp(method, "GET") == 0) + return (cgi_initialize_get()); + else if (strcasecmp(method, "POST") == 0) + return (cgi_initialize_post()); + else + return (0); +} + + +/* + * 'cgiCheckVariables()' - Check for the presence of "required" variables. + * + * Names may be separated by spaces and/or commas. + */ + +int /* O - 1 if all variables present, 0 otherwise */ +cgiCheckVariables(const char *names) /* I - Variables to look for */ +{ + char name[255], /* Current variable name */ + *s; /* Pointer in string */ + const char *val; /* Value of variable */ + int element; /* Array element number */ + + + if (names == NULL) + return (1); + + while (*names != '\0') + { + while (*names == ' ' || *names == ',') + names ++; + + for (s = name; *names != '\0' && *names != ' ' && *names != ','; s ++, names ++) + *s = *names; + + *s = 0; + if (name[0] == '\0') + break; + + if ((s = strrchr(name, '-')) != NULL) + { + *s = '\0'; + element = atoi(s + 1) - 1; + val = cgiGetArray(name, element); + } + else + val = cgiGetVariable(name); + + if (val == NULL) + return (0); + + if (*val == '\0') + return (0); /* Can't be blank, either! */ + } + + return (1); +} + + +/* + * 'cgiGetArray()' - Get an element from a form array... + */ + +const char * /* O - Element value or NULL */ +cgiGetArray(const char *name, /* I - Name of array variable */ + int element) /* I - Element number (0 to N) */ +{ + var_t *var; /* Pointer to variable */ + + + if ((var = cgi_find_variable(name)) == NULL) + return (NULL); + + if (var->nvalues == 1) + return (var->values[0]); + + if (element < 0 || element >= var->nvalues) + return (NULL); + + return (var->values[element]); +} + + +/* + * 'cgiGetSize()' - Get the size of a form array value. + */ + +int /* O - Number of elements */ +cgiGetSize(const char *name) /* I - Name of variable */ +{ + var_t *var; /* Pointer to variable */ + + + if ((var = cgi_find_variable(name)) == NULL) + return (0); + + return (var->nvalues); +} + + +/* + * 'cgiGetVariable()' - Get a CGI variable from the database... + * + * Returns NULL if the variable doesn't exist... If the variable is an + * array of values, returns the last element... + */ + +const char * /* O - Value of variable */ +cgiGetVariable(const char *name)/* I - Name of variable */ +{ + const var_t *var; /* Returned variable */ + + + var = cgi_find_variable(name); + +#ifdef DEBUG + if (var == NULL) + printf("cgiGetVariable(\"%s\") is returning NULL...\n", name); + else + printf("cgiGetVariable(\"%s\") is returning \"%s\"...\n", name, + var->values[var->nvalues - 1]); +#endif /* DEBUG */ + + return ((var == NULL) ? NULL : var->values[var->nvalues - 1]); +} + + +/* + * 'cgiSetArray()' - Set array element N to the specified string. + * + * If the variable array is smaller than (element + 1), the intervening + * elements are set to NULL. + */ + +void +cgiSetArray(const char *name, /* I - Name of variable */ + int element, /* I - Element number (0 to N) */ + const char *value) /* I - Value of variable */ +{ + int i; /* Looping var */ + var_t *var; /* Returned variable */ + + + if (name == NULL || value == NULL || element < 0) + return; + + if ((var = cgi_find_variable(name)) == NULL) + { + cgi_add_variable(name, element, value); + cgi_sort_variables(); + } + else + { + if (element >= var->avalues) + { + var->avalues = element + 16; + var->values = (const char **)realloc((void *)(var->values), + sizeof(char *) * var->avalues); + } + + if (element >= var->nvalues) + { + for (i = var->nvalues; i < element; i ++) + var->values[i] = NULL; + + var->nvalues = element + 1; + } + else if (var->values[element]) + free((char *)var->values[element]); + + var->values[element] = strdup(value); + } +} + + +/* + * 'cgiSetSize()' - Set the array size. + */ + +void +cgiSetSize(const char *name, /* I - Name of variable */ + int size) /* I - Number of elements (0 to N) */ +{ + int i; /* Looping var */ + var_t *var; /* Returned variable */ + + + if (name == NULL || size < 0) + return; + + if ((var = cgi_find_variable(name)) == NULL) + return; + + if (size >= var->avalues) + { + var->avalues = size + 16; + var->values = (const char **)realloc((void *)(var->values), + sizeof(char *) * var->avalues); + } + + if (size > var->nvalues) + { + for (i = var->nvalues; i < size; i ++) + var->values[i] = NULL; + } + else if (size < var->nvalues) + { + for (i = size; i < var->nvalues; i ++) + if (var->values[i]) + free((void *)(var->values[i])); + } + + var->nvalues = size; +} + + +/* + * 'cgiSetVariable()' - Set a CGI variable in the database... + * + * If the variable is an array, this truncates the array to a single element. + */ + +void +cgiSetVariable(const char *name, /* I - Name of variable */ + const char *value) /* I - Value of variable */ +{ + int i; /* Looping var */ + var_t *var; /* Returned variable */ + + + if (name == NULL || value == NULL) + return; + + if ((var = cgi_find_variable(name)) == NULL) + { + cgi_add_variable(name, 0, value); + cgi_sort_variables(); + } + else + { + for (i = 0; i < var->nvalues; i ++) + if (var->values[i]) + free((char *)var->values[i]); + + var->values[0] = strdup(value); + var->nvalues = 1; + } +} + + +/* + * 'cgi_add_variable()' - Add a form variable. + */ + +static void +cgi_add_variable(const char *name, /* I - Variable name */ + int element, /* I - Array element number */ + const char *value) /* I - Variable value */ +{ + var_t *var; /* New variable */ + + + if (name == NULL || value == NULL) + return; + +#ifdef DEBUG + printf("Adding variable \'%s\' with value \'%s\'...\n", name, value); +#endif /* DEBUG */ + + if (form_count >= form_alloc) + { + if (form_alloc == 0) + form_vars = malloc(sizeof(var_t) * 16); + else + form_vars = realloc(form_vars, (form_alloc + 16) * sizeof(var_t)); + + form_alloc += 16; + } + + var = form_vars + form_count; + var->name = strdup(name); + var->nvalues = element + 1; + var->avalues = element + 1; + var->values = calloc(element + 1, sizeof(char *)); + var->values[element] = strdup(value); + + form_count ++; +} + + +/* + * 'cgi_compare_variables()' - Compare two variables. + */ + +static int /* O - Result of comparison */ +cgi_compare_variables(const var_t *v1, /* I - First variable */ + const var_t *v2) /* I - Second variable */ +{ + return (strcasecmp(v1->name, v2->name)); +} + + +/* + * 'cgi_find_variable()' - Find a variable... + */ + +static var_t * /* O - Variable pointer or NULL */ +cgi_find_variable(const char *name) /* I - Name of variable */ +{ + var_t key; /* Search key */ + + + if (form_count < 1 || name == NULL) + return (NULL); + + key.name = name; + + return ((var_t *)bsearch(&key, form_vars, form_count, sizeof(var_t), + (int (*)(const void *, const void *))cgi_compare_variables)); +} + + +/* + * 'cgi_initialize_get()' - Initialize form variables using the GET method. + */ + +static int /* O - 1 if form data read */ +cgi_initialize_get(void) +{ + char *data; /* Pointer to form data string */ + + +#ifdef DEBUG + puts("Initializing variables using GET method..."); +#endif /* DEBUG */ + + /* + * Check to see if there is anything for us to read... + */ + + data = getenv("QUERY_STRING"); + if (data == NULL || strlen(data) == 0) + return (0); + + /* + * Parse it out and return... + */ + + return (cgi_initialize_string(data)); +} + + +/* + * 'cgi_initialize_post()' - Initialize variables using the POST method. + */ + +static int /* O - 1 if form data was read */ +cgi_initialize_post(void) +{ + char *content_length, /* Length of input data (string) */ + *data; /* Pointer to form data string */ + int length, /* Length of input data */ + nbytes, /* Number of bytes read this read() */ + tbytes, /* Total number of bytes read */ + status; /* Return status */ + + +#ifdef DEBUG + puts("Initializing variables using POST method..."); +#endif /* DEBUG */ + + /* + * Check to see if there is anything for us to read... + */ + + content_length = getenv("CONTENT_LENGTH"); + if (content_length == NULL || atoi(content_length) == 0) + return (0); + + /* + * Get the length of the input stream and allocate a buffer for it... + */ + + length = atoi(content_length); + data = malloc(length + 1); + + /* + * Read the data into the buffer... + */ + + for (tbytes = 0; tbytes < length; tbytes += nbytes) + if ((nbytes = read(0, data + tbytes, length - tbytes)) < 0) + { + free(data); + return (0); + } + + data[length] = '\0'; + + /* + * Parse it out... + */ + + status = cgi_initialize_string(data); + + /* + * Free the data and return... + */ + + free(data); + + return (status); +} + + +/* + * 'cgi_initialize_string()' - Initialize form variables from a string. + */ + +static int +cgi_initialize_string(const char *data) /* I - Form data string */ +{ + int done; /* True if we're done reading a form variable */ + char *s, /* Pointer to current form string */ + ch, /* Temporary character */ + name[255], /* Name of form variable */ + value[65536]; /* Variable value... */ + + + /* + * Check input... + */ + + if (data == NULL) + return (0); + + /* + * Loop until we've read all the form data... + */ + + while (*data != '\0') + { + /* + * Get the variable name... + */ + + for (s = name; *data != '\0'; data ++, s ++) + if (*data == '=') + break; + else + *s = *data; + + *s = '\0'; + if (*data == '=') + data ++; + else + return (0); + + /* + * Read the variable value... + */ + + for (s = value, done = 0; !done && *data != '\0'; data ++, s ++) + switch (*data) + { + case '&' : /* End of data... */ + done = 1; + s --; + break; + + case '+' : /* Escaped space character */ + *s = ' '; + break; + + case '%' : /* Escaped control character */ + /* + * Read the hex code from stdin... + */ + + data ++; + ch = *data - '0'; + if (ch > 9) + ch -= 7; + *s = ch << 4; + + data ++; + ch = *data - '0'; + if (ch > 9) + ch -= 7; + *s |= ch; + break; + + default : /* Other characters come straight through */ + *s = *data; + break; + } + + *s = '\0'; /* nul terminate the string */ + + /* + * Remove trailing whitespace... + */ + + s --; + while (s >= value && *s == ' ') + *s-- = '\0'; + + /* + * Add the string to the variable "database"... + */ + + if ((s = strrchr(name, '-')) != NULL && isdigit(s[1])) + { + *s++ = '\0'; + cgiSetArray(name, atoi(s) - 1, value); + } + else if (cgiGetVariable(name) != NULL) + cgiSetArray(name, cgiGetSize(name), value); + else + cgiSetVariable(name, value); + } + + return (1); +} + + +/* + * 'cgi_sort_variables()' - Sort all form variables for faster lookup. + */ + +static void +cgi_sort_variables(void) +{ +#ifdef DEBUG + int i; + + + puts("Sorting variables..."); +#endif /* DEBUG */ + + if (form_count < 2) + return; + + qsort(form_vars, form_count, sizeof(var_t), + (int (*)(const void *, const void *))cgi_compare_variables); + +#ifdef DEBUG + puts("New variable list is:"); + for (i = 0; i < form_count; i ++) + printf("%s = %s\n", form_vars[i].name, form_vars[i].value); +#endif /* DEBUG */ +} + + +/* + * End of "$Id$". + */ diff --git a/conf/Makefile b/conf/Makefile new file mode 100644 index 0000000000..643e231439 --- /dev/null +++ b/conf/Makefile @@ -0,0 +1,73 @@ +# +# "$Id$" +# +# Configuration file makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1993-2000 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +# +# Config files... +# + +KEEP = classes.conf client.conf cupsd.conf printers.conf +REPLACE = mime.convs mime.types + + +# +# Make everything... +# + +all: + + +# +# Clean all config and object files... +# + +clean: + + +# +# Install files... +# + +install: + -$(MKDIR) $(SERVERROOT) + $(CHMOD) ugo+rx $(SERVERROOT) + for file in $(KEEP); do \ + if test -r $(SERVERROOT)/$$file ; then \ + $(INSTALL_DATA) $$file $(SERVERROOT)/$$file.N ; \ + else \ + $(INSTALL_DATA) $$file $(SERVERROOT) ; \ + fi ; \ + done + for file in $(REPLACE); do \ + if test -r $(SERVERROOT)/$$file ; then \ + $(MV) $(SERVERROOT)/$$file $(SERVERROOT)/$$file.O ; \ + fi ; \ + $(INSTALL_DATA) $$file $(SERVERROOT) ; \ + done + + +# +# End of "$Id$". +# diff --git a/conf/classes.conf b/conf/classes.conf new file mode 100644 index 0000000000..8819625b27 --- /dev/null +++ b/conf/classes.conf @@ -0,0 +1,89 @@ +# +# "$Id: classes.conf 1152 2000-06-22 18:25:29Z mike $" +# +# Sample class configuration file for the Common UNIX Printing System +# (CUPS) scheduler. +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +######################################################################## +# # +# This is a sample class configuration file. This file is included # +# from the main configuration file (cups.conf) and lists all of the # +# printer classes known to the system. # +# # +######################################################################## + +# +# Each class starts with a definition. Class names +# can be up to 128 characters in length and are *not* case sensitive. +# +# One entry can appear in this file; if you don't +# define a default destination, the first printer or class becomes +# the default. +# + +# +# +# Info: the description for the class. +# + +#Info Acme LaserPrint 1000 Printers + +# +# Location: the location of the printer. +# + +#Location Room 101 in the activities building + +# +# State: sets the initial state of the class. Can be one of the +# following: +# +# Idle - Class is available to print new jobs. +# Stopped - Class is disabled but accepting new jobs. +# + +#State Idle + +# +# StateMessage: sets the printer-state-message attribute for the class. +# + +#StateMessage Class is idle. + +# +# Accepting: is the class accepting jobs? +# +#Accepting Yes +#Accepting No +# + +# +# Printer: adds a printer to the class. +# + +#Printer sample +#Printer sample@host2 +# + +# +# End of "$Id: classes.conf 1152 2000-06-22 18:25:29Z mike $". +# diff --git a/conf/client.conf b/conf/client.conf new file mode 100644 index 0000000000..26d45e8d5b --- /dev/null +++ b/conf/client.conf @@ -0,0 +1,50 @@ +# +# "$Id: client.conf 969 2000-03-10 16:56:46Z mike $" +# +# Sample client configuration file for the Common UNIX Printing System +# (CUPS). +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +######################################################################## +# # +# This is the CUPS client configuration file. This file is used to # +# define client-specific parameters, such as the default server or # +# default printer. # +# # +######################################################################## + +# +# ServerName: the hostname of your server. By default CUPS will use the +# hostname of the system. +# + +#ServerName myhost.domain.com + +# +# DefaultPrinter: the default printer (or class) that clients should use. +# + +#DefaultPrinter myprinter +#DefaultPrinter myprinter@host + +# +# End of "$Id: client.conf 969 2000-03-10 16:56:46Z mike $". +# diff --git a/conf/cupsd.conf b/conf/cupsd.conf new file mode 100644 index 0000000000..158c22ce63 --- /dev/null +++ b/conf/cupsd.conf @@ -0,0 +1,542 @@ +# +# "$Id: cupsd.conf 1171 2000-06-27 21:15:41Z mike $" +# +# Sample configuration file for the Common UNIX Printing System (CUPS) +# scheduler. +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +######################################################################## +# # +# This is the CUPS configuration file. If you are familiar with # +# Apache or any of the other popular web servers, we've followed the # +# same format. Any configuration variable used here has the same # +# semantics as the corresponding variable in Apache. If we need # +# different functionality then a different name is used to avoid # +# confusion... # +# # +######################################################################## + + +######## +######## Server Identity +######## + +# +# ServerName: the hostname of your server, as advertised to the world. +# By default CUPS will use the hostname of the system. +# +# To set the default server used by clients, see the client.conf file. +# + +#ServerName myhost.domain.com + +# +# ServerAdmin: the email address to send all complaints/problems to. +# By default CUPS will use "root@hostname". +# + +#ServerAdmin root@your.domain.com + + +######## +######## Server Options +######## + +# +# AccessLog: the access log file; if this does not start with a leading / +# then it is assumed to be relative to ServerRoot. By default set to +# "/var/log/cups/access_log" +# +# You can also use the special name "syslog" to send the output to the +# syslog file or daemon. +# + +#AccessLog /var/log/cups/access_log + +# +# DataDir: the root directory for the CUPS data files. +# By default /usr/share/cups. +# + +#DataDir /usr/share/cups + +# +# DefaultCharset: the default character set to use. If not specified, +# defaults to utf-8. Note that this can also be overridden in +# HTML documents... +# + +#DefaultCharset utf-8 + +# +# DefaultLanguage: the default language if not specified by the browser. +# If not specified, the current locale is used. +# + +#DefaultLanguage en + +# +# DocumentRoot: the root directory for HTTP documents that are served. +# By default the compiled in directory. +# + +#DocumentRoot /usr/share/cups/doc + +# +# ErrorLog: the error log file; if this does not start with a leading / +# then it is assumed to be relative to ServerRoot. By default set to +# "/var/log/cups/error_log" +# +# You can also use the special name "syslog" to send the output to the +# syslog file or daemon. +# + +#ErrorLog /var/log/cups/error_log + +# +# LogLevel: controls the number of messages logged to the ErrorLog +# file and can be one of the following: +# +# debug Log everything. +# info Log all requests and state changes. +# warn Log errors and warnings. +# error Log only errors. +# none Log nothing. +# + +LogLevel info + +# +# MaxLogSize: controls the maximum size of each log file before they are +# rotated. Defaults to 1048576 (1MB). Set to 0 to disable log rotating. +# + +#MaxLogSize 0 + +# +# PageLog: the page log file; if this does not start with a leading / +# then it is assumed to be relative to ServerRoot. By default set to +# "/var/log/cups/page_log" +# +# You can also use the special name "syslog" to send the output to the +# syslog file or daemon. +# + +#PageLog /var/log/cups/page_log + +# +# PreserveJobHistory: whether or not to preserve the job history after a +# job is completed, cancelled, or stopped. Default is Yes. +# + +#PreserveJobHistory Yes + +# +# PreserveJobFiles: whether or not to preserve the job files after a +# job is completed, cancelled, or stopped. Default is No. +# + +#PreserveJobFiles No + +# +# Printcap: the name of the printcap file. Default is no filename. +# Leave blank to disable printcap file generation. +# + +#Printcap /etc/printcap + +# +# RequestRoot: the directory where request files are stored. +# By default /var/spool/cups. +# + +#RequestRoot /var/spool/cups + +# +# ServerBin: the root directory for the scheduler executables. +# By default /usr/lib/cups or /usr/lib32/cups (IRIX 6.5). +# + +#ServerBin /usr/lib/cups + +# +# ServerRoot: the root directory for the scheduler. +# By default /etc/cups. +# + +#ServerRoot /etc/cups + + +######## +######## Filter Options +######## + +# +# User/Group: the user and group the server runs under. Normally this +# must be lp and sys, however you can configure things for another user +# or group as needed. +# +# Note: the server must be run initially as root to support the +# default IPP port of 631. It changes users whenever an external +# program is run... +# + +#User lp +#Group sys + +# +# RIPCache: the amount of memory that each RIP should use to cache +# bitmaps. The value can be any real number followed by "k" for +# kilobytes, "m" for megabytes, "g" for gigabytes, or "t" for tiles +# (1 tile = 256x256 pixels.) Defaults to "8m" (8 megabytes). +# + +#RIPCache 8m + +# +# TempDir: the directory to put temporary files in. This directory must be +# writable by the user defined above! Defaults to "/var/tmp" or the value +# of the TMPDIR environment variable. +# + +#TempDir /var/tmp + + +######## +######## Network Options +######## + +# +# Ports/addresses that we listen to. The default port 631 is reserved +# for the Internet Printing Protocol (IPP) and is what we use here. +# +# You can have multiple Port/Listen lines to listen to more than one +# port or address, or to restrict access: +# +# Port 80 +# Port 631 +# Listen hostname +# Listen hostname:80 +# Listen hostname:631 +# Listen 1.2.3.4 +# Listen 1.2.3.4:631 +# + +#Port 80 +Port 631 + +# +# HostNameLookups: whether or not to do lookups on IP addresses to get a +# fully-qualified hostname. This defaults to Off for performance reasons... +# + +#HostNameLookups On + +# +# KeepAlive: whether or not to support the Keep-Alive connection +# option. Default is on. +# + +#KeepAlive On + +# +# KeepAliveTimeout: the timeout before Keep-Alive connections are +# automatically closed. Default is 60 seconds. +# + +#KeepAliveTimeout 60 + +# +# MaxClients: controls the maximum number of simultaneous clients that +# will be handled. Defaults to 100. +# + +#MaxClients 100 + +# +# MaxRequestSize: controls the maximum size of HTTP requests and print files. +# Set to 0 to disable this feature (defaults to 0.) +# + +#MaxRequestSize 0 + +# +# Timeout: the timeout before requests time out. Default is 300 seconds. +# + +#Timeout 300 + + +######## +######## Browsing Options +######## + +# +# Browsing: whether or not to broadcast printer information to +# other CUPS servers. Enabled by default. +# + +#Browsing On + +# +# BrowseShortNames: whether or not to use "short" names for remote printers +# when possible (e.g. "printer" instead of "printer@host".) Enabled by +# default. +# + +#BrowseShortNames Yes + +# +# BrowseAddress: specifies a broadcast address to be used. By +# default browsing information is broadcast to all active interfaces. +# +# Note: HP-UX 10.20 and earlier do not properly handle broadcast unless +# you have a Class A, B, C, or D netmask (i.e. no CIDR support). +# + +#BrowseAddress x.y.z.255 +#BrowseAddress x.y.255.255 +#BrowseAddress x.255.255.255 + +# +# BrowseAllow: specifies an address mask to allow for incoming browser +# packets. The default is to allow packets from all addresses. +# +# BrowseDeny: specifies an address mask to deny for incoming browser +# packets. The default is to deny packets from no addresses. +# +# Both "BrowseAllow" and "BrowseDeny" accept the following notations for +# addresses: +# +# All +# None +# *.domain.com +# .domain.com +# host.domain.com +# nnn.* +# nnn.nnn.* +# nnn.nnn.nnn.* +# nnn.nnn.nnn.nnn +# nnn.nnn.nnn.nnn/mm +# nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm +# +# The hostname/domainname restrictions only work if you have turned hostname +# lookups on! +# + +#BrowseAllow address +#BrowseDeny address + +# +# BrowseInterval: the time between browsing updates in seconds. Default +# is 30 seconds. +# +# Note that browsing information is sent whenever a printer's state changes +# as well, so this represents the maximum time between updates. +# +# Set this to 0 to disable outgoing broadcasts so your local printers are +# not advertised but you can still see printers on other hosts. +# + +#BrowseInterval 30 + +# +# BrowseOrder: specifies the order of BrowseAllow/BrowseDeny comparisons. +# + +#BrowseOrder allow,deny +#BrowseOrder deny,allow + +# +# BrowsePoll: poll the named server(s) for printers +# + +#BrowsePoll address:port + +# +# BrowsePort: the port used for UDP broadcasts. By default this is +# the IPP port; if you change this you need to do it on all servers. +# Only one BrowsePort is recognized. +# + +#BrowsePort 631 + +# +# BrowseRelay: relay browser packets from one address/network to another. +# + +#BrowseRelay source-address destination-address + +# +# BrowseTimeout: the timeout for network printers - if we don't +# get an update within this time the printer will be removed +# from the printer list. This number definitely should not be +# less the BrowseInterval value for obvious reasons. Defaults +# to 300 seconds. +# + +#BrowseTimeout 300 + +# +# ImplicitClasses: whether or not to use implicit classes. +# +# Printer classes can be specified explicitly in the classes.conf +# file, implicitly based upon the printers available on the LAN, or +# both. +# +# When ImplicitClasses is On, printers on the LAN with the same name +# (e.g. Acme-LaserPrint-1000) will be put into a class with the same +# name. This allows you to setup multiple redundant queues on a LAN +# without a lot of administrative difficulties. If a user sends a +# job to Acme-LaserPrint-1000, the job will go to the first available +# queue. +# +# Enabled by default. +# + +#ImplicitClasses On + + +######## +######## Security Options +######## + +# +# SystemGroup: the group name for "System" (printer administration) +# access. The default varies depending on the operating system, but +# will be "sys", "system", or "root" (checked for in that order.) +# + +#SystemGroup sys + +# +# Access permissions for each directory served by the scheduler. +# Locations are relative to DocumentRoot... +# +# AuthType: the authorization to use: +# +# None - Perform no authentication +# Basic - Perform authentication using the HTTP Basic method. +# Digest - Perform authentication using the HTTP Digest method. +# +# (Note: local certificate authentication can be substituted by +# the client for Basic or Digest when connecting to the +# localhost interface) +# +# AuthClass: the authorization class; currently only "Anonymous", "User", +# "System" (valid user belonging to group SystemGroup), and "Group" +# (valid user belonging to the specified group) are supported. +# +# AuthGroupName: the group name for "Group" authorization. +# +# Order: the order of Allow/Deny processing. +# +# Allow: allows access from the specified hostname, domain, IP address, or +# network. +# +# Deny: denies access from the specified hostname, domain, IP address, or +# network. +# +# Both "Allow" and "Deny" accept the following notations for addresses: +# +# All +# None +# *.domain.com +# .domain.com +# host.domain.com +# nnn.* +# nnn.nnn.* +# nnn.nnn.nnn.* +# nnn.nnn.nnn.nnn +# nnn.nnn.nnn.nnn/mm +# nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm +# +# The host and domain address require that you enable hostname lookups +# with "HostNameLookups On" above. +# + + + + +# +# +# You may wish to limit access to printers and classes, either with Allow +# and Deny lines, or by requiring a username and password. +# +# + +# +# +# You may wish to limit access to printers and classes, either with Allow +# and Deny lines, or by requiring a username and password. +# +# + +# +# +# You may wish to limit access to printers and classes, either with Allow +# and Deny lines, or by requiring a username and password. +# +# + +# +# +# You may wish to limit access to printers and classes, either with Allow +# and Deny lines, or by requiring a username and password. +# + +## Anonymous access (default) +#AuthType None + +## Require a username and password (Basic authentication) +#AuthType Basic +#AuthClass User + +## Require a username and password (Digest/MD5 authentication) +#AuthType Digest +#AuthClass User + +## Restrict access to local domain +#Order Deny,Allow +#Deny From All +#Allow From .mydomain.com +# + + +# +# You definitely will want to limit access to the administration functions. +# The default configuration requires a local connection from a user who +# is a member of the system group to do any admin tasks. You can change +# the group name using the SystemGroup directive. +# + +AuthType Basic +AuthClass System + +## Restrict access to local domain +Order Deny,Allow +Deny From All +Allow From 127.0.0.1 + + +# +# End of "$Id: cupsd.conf 1171 2000-06-27 21:15:41Z mike $". +# diff --git a/conf/mime.convs b/conf/mime.convs new file mode 100644 index 0000000000..e8bde17fb0 --- /dev/null +++ b/conf/mime.convs @@ -0,0 +1,64 @@ +# +# "$Id: mime.convs 1019 2000-04-18 19:41:12Z mike $" +# +# MIME converts file for the Common UNIX Printing System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +######################################################################## +# +# Format of Lines: +# +# source/type destination/type cost filter +# +# General Notes: +# +# Currently the "cost" field is not used (all filters are assumed to +# be equally costly in terms of speed/memory). Also, a filter program +# *must* accept the standard command-line arguments (job-id, user, title, +# copies,options,[filename or stdin]) or this won't work. +# + +######################################################################## +# +# PostScript filters +# + +#application/msword application/postscript 50 mswordtops +application/pdf application/postscript 50 pdftops +application/postscript application/vnd.cups-postscript 50 pstops +application/vnd.hp-HPGL application/postscript 50 hpgltops +image/* application/vnd.cups-postscript 50 imagetops +#text/html application/postscript 50 htmltops +text/html application/postscript 50 texttops +text/plain application/postscript 50 texttops +application/vnd.cups-form application/vnd.cups-postscript 50 formtops + +######################################################################## +# +# Raster filters... +# + +image/* application/vnd.cups-raster 50 imagetoraster +application/vnd.cups-postscript application/vnd.cups-raster 50 pstoraster + +# +# End of "$Id: mime.convs 1019 2000-04-18 19:41:12Z mike $". +# diff --git a/conf/mime.types b/conf/mime.types new file mode 100644 index 0000000000..86bb24eb7a --- /dev/null +++ b/conf/mime.types @@ -0,0 +1,127 @@ +# +# "$Id: mime.types 1152 2000-06-22 18:25:29Z mike $" +# +# MIME types file for the Common UNIX Printing System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +######################################################################## +# +# Format of Lines: +# +# super/type rules +# +# "rules" can be any combination of: +# +# ( expr ) Parenthesis for expression grouping +# + Logical AND +# , or whitespace Logical OR +# ! Logical NOT +# match("pattern") Pattern match on filename +# extension Pattern match on "*.extension" +# ascii(offset,length) True if bytes are valid printable ASCII +# (CR, NL, TAB, BS, 32-126) +# printable(offset,length) True if bytes are printable 8-bit chars +# (CR, NL, TAB, BS, 32-126, 128-254) +# string(offset,"string") True if bytes are identical to string +# char(offset,value) True if byte is identical +# short(offset,value) True if 16-bit integer is identical +# int(offset,value) True if 32-bit integer is identical +# locale("string") True if current locale matches string +# contains(offset,range,"string") True if the range contains the string +# +# General Notes: +# +# MIME type names are case-insensitive. Internally they are converted +# to lowercase. Multiple occurrences of a type will cause the provided +# rules to be appended to the existing definition. Type names are sorted +# in ascending order, so if two types use the same rules to resolve a type +# (e.g. doc extension for two types), the returned type will be the first +# type in the sorted list. +# +# The "printable" rule differs from the "ascii" rule in that it also +# accepts 8-bit characters in the range 128-255. +# +# String constants must be surrounded by "" if they contain whitespace. +# To instead binary data into a string, use the notation. +# + +######################################################################## +# +# Application-generated files... +# + +application/msword doc string(0,) +application/pdf pdf string(0,%PDF) +application/postscript ai eps ps string(0,%!) string(0,<04>%!) +application/vnd.hp-HPGL hpgl string(0,<1b>%) string(0,<1b>&)\ + string(0,<1b>E) string(0,<201b>)\ + string(0,BP;) string(0,IN;) string(0,DF;) + +######################################################################## +# +# Image files... +# + +image/gif gif string(0,GIF87a) string(0,GIF89a) +image/png png string(0,<89>PNG) +image/jpeg jpeg jpg jpe string(0,) &&\ + (char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\ + char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\ + char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\ + char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef)) +image/tiff tiff tif string(0,MM) string(0,II) +image/x-photocd pcd string(2048,PCD_IPI) +image/x-portable-anymap pnm +image/x-portable-bitmap pbm string(0,P1) string(0,P4) +image/x-portable-graymap pgm string(0,P2) string(0,P5) +image/x-portable-pixmap ppm string(0,P3) string(0,P6) +image/x-sgi-rgb rgb sgi bw icon short(0,474) +image/x-xbitmap xbm +image/x-xpixmap xpm ascii(0,1024) + string(3,"XPM") +image/x-xwindowdump xwd +image/x-sun-raster ras + +#image/fpx fpx +image/x-alias pix short(8,8) short(8,24) +image/x-bitmap bmp string(0,BM) && !printable(2,14) + +######################################################################## +# +# Text files... +# + +text/html html htm printable(0,1024) +\ + (string(0,"") string(0,"") +application/vnd.cups-postscript string(0,<1B>%-12345X) +application/vnd.cups-raster string(0,"RaSt") string(0,"tSaR") +application/vnd.cups-raw + +# +# End of "$Id: mime.types 1152 2000-06-22 18:25:29Z mike $". +# diff --git a/conf/printcap b/conf/printcap new file mode 100644 index 0000000000..230c3017d6 --- /dev/null +++ b/conf/printcap @@ -0,0 +1,2 @@ +# This is a dummy printcap file that is automatically generated by the +# CUPS software for old applications that rely on it. diff --git a/conf/printers.conf b/conf/printers.conf new file mode 100644 index 0000000000..d594875c65 --- /dev/null +++ b/conf/printers.conf @@ -0,0 +1,96 @@ +# +# "$Id: printers.conf 1152 2000-06-22 18:25:29Z mike $" +# +# Sample printer configuration file for the Common UNIX Printing System +# (CUPS) scheduler. +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +######################################################################## +# # +# This is a sample printer configuration file. This file is included # +# from the main configuration file (cups.conf) and lists all of the # +# printers known to the system. # +# # +######################################################################## + +# +# Each printer starts with a definition. Printer names +# can be up to 128 characters in length and are *not* case sensitive. +# +# One entry can appear in this file; if you don't +# define a default destination, the first printer or class becomes the +# default. +# + +# +# +# Info: the description for the printer. +# + +#Info Acme LaserPrint 1000 + +# +# Location: the location of the printer. +# + +#Location Room 101 in the activities building + +# +# DeviceURI: the device URI for this printer. +# + +#DeviceURI parallel:/dev/plp +#DeviceURI serial:/dev/ttyd1?baud=38400+size=8+parity=none+flow=soft +#DeviceURI scsi:/dev/scsi/sc1d6l0 +#DeviceURI socket://hostname:port +#DeviceURI tftp://hostname/path +#DeviceURI ftp://hostname/path +#DeviceURI http://hostname[:port]/path +#DeviceURI ipp://hostname/path +#DeviceURI smb://hostname/printer + +# +# State: sets the initial state of the printer. Can be one of the +# following: +# +# Idle - Printer is available to print new jobs. +# Stopped - Printer is disabled but accepting new jobs. +# + +#State Idle + +# +# StateMessage: sets the printer-state-message attribute for the printer. +# + +#StateMessage Printer is idle. + +# +# Accepting: is the printer accepting jobs? +# +#Accepting Yes +#Accepting No + +# + +# +# End of "$Id: printers.conf 1152 2000-06-22 18:25:29Z mike $". +# diff --git a/config.h.in b/config.h.in new file mode 100644 index 0000000000..0e2c62a638 --- /dev/null +++ b/config.h.in @@ -0,0 +1,127 @@ +/* + * "$Id$" + * + * Configuration file for the Common UNIX Printing System (CUPS). + * + * @configure_input@ + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +/* + * Version of software... + */ + +#define CUPS_SVERSION "CUPS v1.1.1" + +/* + * Where are files stored? + */ + +#define CUPS_LOCALEDIR "/usr/share/locale" +#define CUPS_SERVERROOT "/etc/cups" +#define CUPS_SERVERBIN "/usr/lib/cups" +#define CUPS_DOCROOT "/usr/share/doc/cups" +#define CUPS_REQUESTS "/var/spool/cups" +#define CUPS_LOGDIR "/var/logs/cups" +#define CUPS_DATADIR "/usr/share/cups" + + +/* + * Do we have various image libraries? + */ + +#undef HAVE_LIBPNG +#undef HAVE_LIBZ +#undef HAVE_LIBJPEG +#undef HAVE_LIBTIFF + +/* + * Does this machine store words in big-endian (MSB-first) order? + */ + +#undef WORDS_BIGENDIAN + +/* + * Which directory functions and headers do we use? + */ + +#undef HAVE_DIRENT_H +#undef HAVE_SYS_DIR_H +#undef HAVE_SYS_NDIR_H +#undef HAVE_NDIR_H + +/* + * Do we have PAM stuff? + */ + +#ifndef HAVE_LIBPAM +#define HAVE_LIBPAM 0 +#endif /* !HAVE_LIBPAM */ + +/* + * Do we have ? + */ + +#undef HAVE_SHADOW_H + +/* + * Do we have ? + */ + +#undef HAVE_CRYPT_H + +/* + * Do we have the strXXX() functions? + */ + +#undef HAVE_STRDUP +#undef HAVE_STRCASECMP +#undef HAVE_STRNCASECMP + +/* + * Do we have the vsyslog() function? + */ + +#undef HAVE_VSYSLOG + +/* + * Do we have the (v)snprintf() functions? + */ + +#undef HAVE_SNPRINTF +#undef HAVE_VSNPRINTF + +/* + * What signal functions to use? + */ + +#undef HAVE_SIGSET +#undef HAVE_SIGACTION + +/* + * What wait functions to use? + */ + +#undef HAVE_WAITPID +#undef HAVE_WAIT3 + +/* + * End of "$Id$". + */ diff --git a/configure.in b/configure.in new file mode 100644 index 0000000000..596269e17d --- /dev/null +++ b/configure.in @@ -0,0 +1,483 @@ +dnl +dnl "$Id$" +dnl +dnl Configuration script for the Common UNIX Printing System (CUPS). +dnl +dnl Copyright 1997-2000 by Easy Software Products, all rights reserved. +dnl +dnl These coded instructions, statements, and computer programs are the +dnl property of Easy Software Products and are protected by Federal +dnl copyright law. Distribution and use rights are outlined in the file +dnl "LICENSE.txt" which should have been included with this file. If this +dnl file is missing or damaged please contact Easy Software Products +dnl at: +dnl +dnl Attn: CUPS Licensing Information +dnl Easy Software Products +dnl 44141 Airport View Drive, Suite 204 +dnl Hollywood, Maryland 20636-3111 USA +dnl +dnl Voice: (301) 373-9603 +dnl EMail: cups-info@cups.org +dnl WWW: http://www.cups.org +dnl + +AC_INIT(cups/cups.h) +AC_CONFIG_HEADER(config.h) +AC_PREFIX_DEFAULT(/) + +dnl Get the operating system and version number... + +uname=`uname` +uversion=`uname -r | sed -e '1,$s/[[^0-9]]//g'` +if test "$uname" = "IRIX64"; then + uname="IRIX" +fi + +dnl Clear the debugging and non-shared library options unless the user asks +dnl for them... + +OPTIM="" +AC_SUBST(OPTIM) +PICFLAG=1 +CFLAGS="${CFLAGS:=}" +CXXFLAGS="${CXXFLAGS:=}" + +AC_ARG_ENABLE(debug, [ --enable-debug turn on debugging [default=no]],[if eval "test x$enable_debug = xyes"; then + OPTIM="-g " +fi]) +AC_ARG_ENABLE(shared, [ --enable-shared turn on shared libraries [default=yes]]) +AC_ARG_ENABLE(libtool_unsupported, [ --enable-libtool-unsupported=LIBTOOL_PATH + turn on building with libtool (UNSUPPORTED!) [default=no]],[if eval "test x$enable_libtool_unsupported != xno"; then + LIBTOOL="$enable_libtool_unsupported" + enable_shared=no + echo "WARNING: libtool is not supported or endorsed by Easy Software Products." + echo " WE DO NOT PROVIDE TECHNICAL SUPPORT FOR LIBTOOL PROBLEMS." + echo " (even if you have a support contract)" +else + LIBTOOL="" +fi]) + +if test "$enable_shared" != "no"; then + case "$uname" in + SunOS* | UNIX_S*) + LIBCUPS="libcups.so.2" + LIBCUPSIMAGE="libcupsimage.so.2" + DSO="\$(CC) -Wl,-h,\$@ -G \$(OPTIM) -o" + ;; + HP-UX*) + LIBCUPS="libcups.sl.2" + LIBCUPSIMAGE="libcupsimage.sl.2" + DSO="ld -b -z +h \$@ -o" + ;; + FreeBSD* | NetBSD* | OpenBSD*) + LIBCUPS="libcups.so.2" + LIBCUPSIMAGE="libcupsimage.so.2" + DSO="\$(CC) -Wl,-soname,\$@ -shared \$(OPTIM) -o" + ;; + OSF1* | Linux*) + LIBCUPS="libcups.so.2" + LIBCUPSIMAGE="libcupsimage.so.2" + DSO="\$(CC) -Wl,-soname,\$@ -shared \$(OPTIM) -o" + ;; + IRIX*) + LIBCUPS="libcups.so.2" + LIBCUPSIMAGE="libcupsimage.so.2" + DSO="\$(CC) -soname \$@ -shared \$(OPTIM) -o" + ;; + *) + echo "Warning: shared libraries may not be supported. Trying -shared" + echo " option with compiler." + LIBCUPS="libcups.so.2" + LIBCUPSIMAGE="libcupsimage.so.2" + DSO="\$(CC) -Wl,-soname,\$@ -shared \$(OPTIM) -o" + ;; + esac +else + PICFLAG=0 + LIBCUPS="libcups.a" + LIBCUPSIMAGE="libcupsimage.a" + DSO=":" +fi + +if test "$LIBTOOL" != ""; then + LIBCUPS="libcups.la" + LIBCUPSIMAGE="libcupsimage.la" + LINKCUPS="../cups/\$(LIBCUPS)" + LINKCUPSIMAGE="../filter/\$(LIBCUPSIMAGE)" + DSO=":" +else + LINKCUPS="-L../cups -lcups" + LINKCUPSIMAGE="-L../filter -lcupsimage" +fi + +AC_ARG_ENABLE(pam, [ --enable-pam turn on PAM support [default=yes]]) + +dnl Checks for programs... +AC_PROG_AWK +AC_PROG_CC +AC_PROG_CXX +AC_PROG_CPP +AC_PROG_RANLIB +AC_PATH_PROG(AR,ar) +AC_PATH_PROG(CHMOD,chmod) +AC_PATH_PROG(CP,cp) +AC_PATH_PROG(MV,mv) +AC_PATH_PROG(NROFF,nroff) +if test "$NROFF" = ""; then + AC_PATH_PROG(GROFF,groff) + if test "$GROFF" = ""; then + NROFF="echo" + else + NROFF="$GROFF -T ascii" + fi +fi +AC_PATH_PROG(HTMLDOC,htmldoc) +AC_PATH_PROG(MKDIR,mkdir) +AC_PATH_PROG(RM,rm) +AC_PATH_PROG(SED,sed) + +dnl Architecture checks... +AC_C_BIGENDIAN + +dnl Check for libraries... +AC_CHECK_LIB(c,crypt,LIBS="$LIBS",AC_CHECK_LIB(crypt,crypt)) +AC_CHECK_HEADER(crypt.h, AC_DEFINE(HAVE_CRYPT_H)) +AC_CHECK_LIB(sec,getspent) +if test "$enable_pam" != "no"; then + OLDLIBS="$LIBS" + AC_CHECK_LIB(dl,dlopen) + AC_CHECK_LIB(pam,pam_start) + if test "$ac_cv_lib_pam_pam_start" != "no"; then + PAMDIR="/etc/pam.d" + else + PAMDIR="" + LIBS="$OLDLIBS" + fi + AC_SUBST(PAMDIR) +fi + +NETLIBS="" +AC_SUBST(NETLIBS) +AC_CHECK_LIB(socket,socket, +if test "$uname" != "IRIX"; then + NETLIBS="-lsocket" +else + echo "Not using -lsocket since you are running IRIX." +fi) +AC_CHECK_LIB(nsl,gethostbyaddr, +if test "$uname" != "IRIX"; then + NETLIBS="$NETLIBS -lnsl" +else + echo "Not using -lnsl since you are running IRIX." +fi) + +dnl Save the current libraries since we don't want the image libraries +dnl included with every program... +SAVELIBS="$LIBS" + +dnl Check for image libraries... +LIBJPEG="" +LIBPNG="" +LIBTIFF="" +LIBZ="" + +AC_SUBST(LIBJPEG) +AC_SUBST(LIBPNG) +AC_SUBST(LIBTIFF) +AC_SUBST(LIBZ) + +AC_CHECK_LIB(jpeg, jpeg_destroy_decompress, + AC_DEFINE(HAVE_LIBJPEG) + LIBJPEG="-ljpeg" + LIBS="$LIBS -ljpeg") + +AC_CHECK_LIB(z, gzgets, + AC_DEFINE(HAVE_LIBZ) + LIBZ="-lz" + LIBS="$LIBS -lz") + +dnl PNG library uses math library functions... +AC_CHECK_LIB(m, pow) + +AC_CHECK_LIB(png, png_set_tRNS_to_alpha, + AC_DEFINE(HAVE_LIBPNG) + LIBPNG="-lpng") + +AC_CHECK_LIB(tiff, TIFFReadScanline, + AC_DEFINE(HAVE_LIBTIFF) + LIBTIFF="-ltiff") + +dnl Restore original LIBS settings... +LIBS="$SAVELIBS" + +dnl Checks for header files. +AC_HEADER_STDC +AC_HEADER_DIRENT +AC_CHECK_HEADER(shadow.h,AC_DEFINE(HAVE_SHADOW_H)) + +dnl Checks for string functions. +AC_CHECK_FUNCS(strdup) +AC_CHECK_FUNCS(strcasecmp) +AC_CHECK_FUNCS(strncasecmp) +AC_CHECK_FUNCS(snprintf) +AC_CHECK_FUNCS(vsnprintf) + +dnl Checks for vsyslog function. +AC_CHECK_FUNCS(vsyslog) + +dnl Checks for signal functions. +if test "$uname" != "Linux"; then + AC_CHECK_FUNCS(sigset) +fi + +AC_CHECK_FUNCS(sigaction) + +dnl Checks for wait functions. +AC_CHECK_FUNCS(waitpid) +AC_CHECK_FUNCS(wait3) + +dnl Update compiler options... +if test -n "$GCC"; then + if test -z "$OPTIM"; then + OPTIM="-O2 -g3" + fi + if test $PICFLAG = 1; then + OPTIM="-fPIC $OPTIM" + fi + OPTIM="-Wall $OPTIM" +else + case $uname in + IRIX*) + if test -z "$OPTIM"; then + OPTIM="-O2 -g3" + fi + if test $uversion -ge 62; then + OPTIM="$OPTIM -n32 -mips3" + fi + OPTIM="-fullwarn $OPTIM" + ;; + HP-UX*) + if test -z "$OPTIM"; then + OPTIM="+O2 -g3" + fi + OPTIM="-Ae $OPTIM" + ;; + SunOS*) + # Solaris + if test -z "$OPTIM"; then + OPTIM="-O -g3" + fi + if test $PICFLAG = 1; then + OPTIM="-KPIC $OPTIM" + fi + ;; + *) + # Running some other operating system; inform the user they + # should contribute the necessary options to + # cups-support@cups.org... + echo "Building CUPS with default compiler optimizations; contact" + echo "cups-support@cups.org with uname and compiler options needed" + echo "for your platform, or set the CFLAGS environment variable" + echo "before running configure." + ;; + esac +fi + +if test "$DSO" != ":"; then + # When using DSOs the image libraries are linked to libcupsimage.so + # rather than to the executables. This makes things smaller if you + # are using any static libraries, and it also allows us to distribute + # a single DSO rather than a bunch... + DSOLIBS="\$(LIBJPEG) \$(LIBPNG) \$(LIBTIFF) \$(LIBZ)" + IMGLIBS="" + + # The *BSD, HP-UX, and Solaris run-time linkers need help when + # deciding where to find a DSO. Add linker options to tell them + # where to find the DSO (usually in /usr/lib... duh!) + case $uname in + HP-UX*) + LDFLAGS="$LDFLAGS -Wl,+b,$libdir,+fb" + ;; + SunOS*) + # Solaris + LDFLAGS="$LDFLAGS -R$libdir" + ;; + FreeBSD* | NetBSD* | OpenBSD*) + # *BSD + LDFLAGS="$LDFLAGS -Wl,-R$libdir" + ;; + esac +else + DSOLIBS="" + IMGLIBS="\$(LIBJPEG) \$(LIBPNG) \$(LIBTIFF) \$(LIBZ)" +fi + +AC_SUBST(DSO) +AC_SUBST(DSOLIBS) +AC_SUBST(IMGLIBS) +AC_SUBST(LIBCUPS) +AC_SUBST(LIBCUPSIMAGE) +AC_SUBST(LIBTOOL) +AC_SUBST(LINKCUPS) +AC_SUBST(LINKCUPSIMAGE) + +dnl Fix "prefix" variable if it hasn't been specified... +if test "$prefix" = "NONE"; then + prefix="/" +fi + +dnl Fix "exec_prefix" variable if it hasn't been specified... +if test "$exec_prefix" = "NONE"; then + if test "$prefix" = "/"; then + exec_prefix="/usr" + else + exec_prefix="$prefix" + fi +fi + +dnl Fix "sharedstatedir" variable if it hasn't been specified... +if test "$sharedstatedir" = "\${prefix}/com" -a "$prefix" = "/"; then + sharedstatedir="/usr/com" +fi + +dnl Fix "infodir" variable if it hasn't been specified... +if test "$infodir" = "\${prefix}/info" -a "$prefix" = "/"; then + infodir="/usr/info" +fi + +dnl Fix "datadir" variable if it hasn't been specified... +if test "$datadir" = "\${prefix}/share" -a "$prefix" = "/"; then + datadir="/usr/share" +fi + +dnl Fix "includedir" variable if it hasn't been specified... +if test "$includedir" = "\${prefix}/include" -a "$prefix" = "/"; then + includedir="/usr/include" +fi + +dnl Fix "localstatedir" variable if it hasn't been specified... +if test "$localstatedir" = "\${prefix}/var"; then + if test "$prefix" = "/"; then + localstatedir="/var" + else + localstatedir="$prefix/var" + fi +fi + +dnl Fix "sysconfdir" variable if it hasn't been specified... +if test "$sysconfdir" = "\${prefix}/etc"; then + if test "$prefix" = "/"; then + sysconfdir="/etc" + else + sysconfdir="$prefix/etc" + fi +fi + +dnl Fix "libdir" variable for IRIX 6.x... +if test "$uname" = "IRIX" -a $uversion -ge 62; then + libdir="$exec_prefix/lib32" +fi + +dnl Fix "mandir" variable... +if test "$mandir" = "\${prefix}/man" -a "$prefix" = "/"; then + if test "$uname" = "IRIX"; then + mandir="/usr/share/catman" + else + mandir="/usr/man" + fi +fi + +dnl Setup manpage extensions... +case "$uname" in + FreeBSD* | NetBSD* | OpenBSD*) + # *BSD + CAT1EXT=0 + CAT5EXT=0 + CAT8EXT=0 + ;; + IRIX*) + # SGI IRIX + CAT1EXT=z + CAT5EXT=z + CAT8EXT=z + ;; + *) + # All others + CAT1EXT=1 + CAT5EXT=5 + CAT8EXT=8 + ;; +esac + +AC_SUBST(CAT1EXT) +AC_SUBST(CAT5EXT) +AC_SUBST(CAT8EXT) + +dnl Setup default locations... +CUPS_SERVERROOT='${prefix}/etc/cups' +CUPS_LOGDIR='${prefix}/var/log/cups' +CUPS_REQUESTS='${prefix}/var/spool/cups' + +AC_DEFINE_UNQUOTED(CUPS_SERVERROOT, "$prefix/etc/cups") +AC_DEFINE_UNQUOTED(CUPS_LOGDIR, "$prefix/var/log/cups") +AC_DEFINE_UNQUOTED(CUPS_REQUESTS, "$prefix/var/spool/cups") + +dnl See what directory to put server executables... +case "$uname" in + FreeBSD* | NetBSD* | OpenBSD*) + # *BSD + INSTALL_SYSV="" + CUPS_SERVERBIN='${exec_prefix}/libexec/cups' + AC_DEFINE_UNQUOTED(CUPS_SERVERBIN, "$exec_prefix/libexec/cups") + ;; + *) + # All others + INSTALL_SYSV="install-sysv" + CUPS_SERVERBIN='${exec_prefix}/lib/cups' + AC_DEFINE_UNQUOTED(CUPS_SERVERBIN, "$exec_prefix/lib/cups") + ;; +esac + +AC_SUBST(INSTALL_SYSV) +AC_SUBST(CUPS_SERVERROOT) +AC_SUBST(CUPS_SERVERBIN) +AC_SUBST(CUPS_LOGDIR) +AC_SUBST(CUPS_REQUESTS) + +dnl Set the CUPS_LOCALE directory... +case "$uname" in + Linux* | FreeBSD* | NetBSD* | OpenBSD*) + CUPS_LOCALEDIR='${exec_prefix}/share/locale' + AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$exec_prefix/share/locale") + ;; + + OSF1*) + CUPS_LOCALEDIR='${exec_prefix}/lib/nls/msg' + AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$exec_prefix/lib/nls/msg") + ;; + + *) + # This is the standard System V location... + CUPS_LOCALEDIR='${exec_prefix}/lib/locale' + AC_DEFINE_UNQUOTED(CUPS_LOCALEDIR, "$exec_prefix/lib/locale") + ;; +esac + +AC_SUBST(CUPS_LOCALEDIR) + +dnl Set the CUPS_DATADIR directory... +CUPS_DATADIR='${exec_prefix}/share/cups' +AC_DEFINE_UNQUOTED(CUPS_DATADIR, "$exec_prefix/share/cups") +AC_SUBST(CUPS_DATADIR) + +dnl Set the CUPS_DOCROOT directory... +CUPS_DOCROOT='${exec_prefix}/share/doc/cups' +AC_DEFINE_UNQUOTED(CUPS_DOCROOT, "$exec_prefix/share/doc/cups") +AC_SUBST(CUPS_DOCROOT) + +AC_OUTPUT(Makedefs cups.sh) + +dnl +dnl End of "$Id$". +dnl diff --git a/cups.dsw b/cups.dsw new file mode 100644 index 0000000000..2fc669868f --- /dev/null +++ b/cups.dsw @@ -0,0 +1,128 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "cups"=.\cups\cups.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "cupsd"=.\scheduler\cupsd.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cups + End Project Dependency +}}} + +############################################################################### + +Project: "hpgltops"=.\filter\hpgltops.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cups + End Project Dependency +}}} + +############################################################################### + +Project: "image"=.\filter\image.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "pstops"=.\filter\pstops.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "testmime"=.\cups\testmime.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cups + End Project Dependency +}}} + +############################################################################### + +Project: "testppd"=.\cups\testppd.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cups + End Project Dependency +}}} + +############################################################################### + +Project: "texttops"=.\filter\texttops.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name cups + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/cups.list b/cups.list new file mode 100644 index 0000000000..d2a3f38db5 --- /dev/null +++ b/cups.list @@ -0,0 +1,507 @@ +# +# "$Id: cups.list 1229 2000-07-20 16:51:42Z mike $" +# +# ESP Package Manager (EPM) file list for the Common UNIX Printing +# System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +%product Common UNIX Printing System +%copyright 1993-2000 by Easy Software Products, All Rights Reserved. +%vendor Easy Software Products +%license LICENSE.txt +%readme README.txt +%version 1.1.1 +%incompat printpro + +%system all +# Server files +f 0555 root sys $SBINDIR/cupsd scheduler/cupsd + +d 0555 root sys $SERVERBIN - +d 0555 root sys $SERVERBIN/backend - +f 0555 root sys $SERVERBIN/backend/ipp backend/ipp +l 0555 root sys $SERVERBIN/backend/http ipp +f 0555 root sys $SERVERBIN/backend/lpd backend/lpd +f 0555 root sys $SERVERBIN/backend/parallel backend/parallel +f 0555 root sys $SERVERBIN/backend/serial backend/serial +f 0555 root sys $SERVERBIN/backend/socket backend/socket +f 0555 root sys $SERVERBIN/backend/usb backend/usb +d 0555 root sys $SERVERBIN/cgi-bin - +f 0555 root sys $SERVERBIN/cgi-bin/admin.cgi cgi-bin/admin.cgi +f 0555 root sys $SERVERBIN/cgi-bin/classes.cgi cgi-bin/classes.cgi +f 0555 root sys $SERVERBIN/cgi-bin/jobs.cgi cgi-bin/jobs.cgi +f 0555 root sys $SERVERBIN/cgi-bin/printers.cgi cgi-bin/printers.cgi +d 0555 root sys $SERVERBIN/daemon - +f 0555 root sys $SERVERBIN/daemon/cups-lpd scheduler/cups-lpd +f 0555 root sys $SERVERBIN/daemon/cups-polld scheduler/cups-polld +d 0555 root sys $SERVERBIN/filter - +f 0555 root sys $SERVERBIN/filter/pstoraster pstoraster/pstoraster +f 0555 root sys $SERVERBIN/filter/pdftops pdftops/pdftops +f 0555 root sys $SERVERBIN/filter/imagetops filter/imagetops +f 0555 root sys $SERVERBIN/filter/pstops filter/pstops +f 0555 root sys $SERVERBIN/filter/texttops filter/texttops +f 0555 root sys $SERVERBIN/filter/rastertoepson filter/rastertoepson +f 0555 root sys $SERVERBIN/filter/rastertohp filter/rastertohp +f 0555 root sys $SERVERBIN/filter/hpgltops filter/hpgltops +f 0555 root sys $SERVERBIN/filter/imagetoraster filter/imagetoraster + +# Admin commands +l 0555 root sys $BINDIR/disable $SBINDIR/accept +l 0555 root sys $BINDIR/enable $SBINDIR/accept +l 0555 root sys $LIBDIR/accept $SBINDIR/accept +l 0555 root sys $LIBDIR/lpadmin $SBINDIR/lpadmin +l 0555 root sys $LIBDIR/reject accept +f 0555 root sys $SBINDIR/accept systemv/accept +f 0555 root sys $SBINDIR/lpadmin systemv/lpadmin +f 0555 root sys $SBINDIR/lpc berkeley/lpc +f 0555 root sys $SBINDIR/lpinfo systemv/lpinfo +f 0555 root sys $SBINDIR/lpmove systemv/lpmove +l 0555 root sys $SBINDIR/reject accept + +%system irix +l 0555 root sys /usr/etc/lpc $SBINDIR/lpc +%system all + +# User commands +f 0555 root sys $BINDIR/cancel systemv/cancel +f 0555 root sys $BINDIR/lp systemv/lp +f 0555 root sys $BINDIR/lpoptions systemv/lpoptions +f 4555 root sys $BINDIR/lppasswd systemv/lppasswd +f 0555 root sys $BINDIR/lpq berkeley/lpq +f 0555 root sys $BINDIR/lpr berkeley/lpr +f 0555 root sys $BINDIR/lprm berkeley/lprm +f 0555 root sys $BINDIR/lpstat systemv/lpstat + +%system irix +l 0555 root sys /usr/bsd/lpq $BINDIR/lpq +l 0555 root sys /usr/bsd/lpr $BINDIR/lpr +l 0555 root sys /usr/bsd/lprm $BINDIR/lprm +%system all + +# DSOs +%system hpux +f 0555 root sys $LIBDIR/libcups.sl.2 cups/libcups.sl.2 +l 0555 root sys $LIBDIR/libcups.sl libcups.sl.2 +f 0555 root sys $LIBDIR/libcupsimage.sl.2 filter/libcupsimage.sl.2 +l 0555 root sys $LIBDIR/libcupsimage.sl libcupsimage.sl.2 +%system !hpux +f 0555 root sys $LIBDIR/libcups.so.2 cups/libcups.so.2 +l 0555 root sys $LIBDIR/libcups.so libcups.so.2 +f 0555 root sys $LIBDIR/libcupsimage.so.2 filter/libcupsimage.so.2 +l 0555 root sys $LIBDIR/libcupsimage.so libcupsimage.so.2 +%system all + +# Directories +d 0755 root sys $LOGDIR - +d 0710 root sys $REQUESTS - +d 1770 root sys $REQUESTS/tmp - + +# Data files +f 0444 root sys $LOCALEDIR/C/cups_C locale/C/cups_C +f 0444 root sys $LOCALEDIR/de/cups_de locale/de/cups_de +f 0444 root sys $LOCALEDIR/en/cups_en locale/en/cups_en +f 0444 root sys $LOCALEDIR/es/cups_es locale/es/cups_es +f 0444 root sys $LOCALEDIR/fr/cups_fr locale/fr/cups_fr +f 0444 root sys $LOCALEDIR/it/cups_it locale/it/cups_it + +d 0555 root sys $DATADIR - + +d 0555 root sys $DATADIR/banners - +f 0444 root sys $DATADIR/banners/classified data/classified +f 0444 root sys $DATADIR/banners/confidential data/confidential +f 0444 root sys $DATADIR/banners/secret data/secret +f 0444 root sys $DATADIR/banners/standard data/standard +f 0444 root sys $DATADIR/banners/topsecret data/topsecret +f 0444 root sys $DATADIR/banners/unclassified data/unclassified + +d 0555 root sys $DATADIR/charsets - +f 0444 root sys $DATADIR/charsets/windows-874 data/windows-874 +f 0444 root sys $DATADIR/charsets/windows-1250 data/windows-1250 +f 0444 root sys $DATADIR/charsets/windows-1251 data/windows-1251 +f 0444 root sys $DATADIR/charsets/windows-1252 data/windows-1252 +f 0444 root sys $DATADIR/charsets/windows-1253 data/windows-1253 +f 0444 root sys $DATADIR/charsets/windows-1254 data/windows-1254 +f 0444 root sys $DATADIR/charsets/windows-1255 data/windows-1255 +f 0444 root sys $DATADIR/charsets/windows-1256 data/windows-1256 +f 0444 root sys $DATADIR/charsets/windows-1257 data/windows-1257 +f 0444 root sys $DATADIR/charsets/windows-1258 data/windows-1258 +f 0444 root sys $DATADIR/charsets/iso-8859-1 data/iso-8859-1 +f 0444 root sys $DATADIR/charsets/iso-8859-14 data/iso-8859-14 +f 0444 root sys $DATADIR/charsets/iso-8859-15 data/iso-8859-15 +f 0444 root sys $DATADIR/charsets/iso-8859-2 data/iso-8859-2 +f 0444 root sys $DATADIR/charsets/iso-8859-3 data/iso-8859-3 +f 0444 root sys $DATADIR/charsets/iso-8859-4 data/iso-8859-4 +f 0444 root sys $DATADIR/charsets/iso-8859-5 data/iso-8859-5 +f 0444 root sys $DATADIR/charsets/iso-8859-6 data/iso-8859-6 +f 0444 root sys $DATADIR/charsets/iso-8859-7 data/iso-8859-7 +f 0444 root sys $DATADIR/charsets/iso-8859-8 data/iso-8859-8 +f 0444 root sys $DATADIR/charsets/iso-8859-9 data/iso-8859-9 +f 0444 root sys $DATADIR/charsets/utf-8 data/utf-8 + +d 0555 root sys $DATADIR/data - +f 0444 root sys $DATADIR/data/HPGLprolog data/HPGLprolog +f 0444 root sys $DATADIR/data/psglyphs data/psglyphs +f 0444 root sys $DATADIR/data/testprint.ps data/testprint.ps + +d 0555 root sys $DATADIR/fonts - +f 0444 root sys $DATADIR/fonts/AvantGarde-Book fonts/AvantGarde-Book +f 0444 root sys $DATADIR/fonts/AvantGarde-BookOblique fonts/AvantGarde-BookOblique +f 0444 root sys $DATADIR/fonts/AvantGarde-Demi fonts/AvantGarde-Demi +f 0444 root sys $DATADIR/fonts/AvantGarde-DemiOblique fonts/AvantGarde-DemiOblique +f 0444 root sys $DATADIR/fonts/Bookman-Demi fonts/Bookman-Demi +f 0444 root sys $DATADIR/fonts/Bookman-DemiItalic fonts/Bookman-DemiItalic +f 0444 root sys $DATADIR/fonts/Bookman-Light fonts/Bookman-Light +f 0444 root sys $DATADIR/fonts/Bookman-LightItalic fonts/Bookman-LightItalic +f 0444 root sys $DATADIR/fonts/Charter-Bold fonts/Charter-Bold +f 0444 root sys $DATADIR/fonts/Charter-BoldItalic fonts/Charter-BoldItalic +f 0444 root sys $DATADIR/fonts/Charter-Italic fonts/Charter-Italic +f 0444 root sys $DATADIR/fonts/Charter-Roman fonts/Charter-Roman +f 0444 root sys $DATADIR/fonts/Courier fonts/Courier +f 0444 root sys $DATADIR/fonts/Courier-Bold fonts/Courier-Bold +f 0444 root sys $DATADIR/fonts/Courier-BoldOblique fonts/Courier-BoldOblique +f 0444 root sys $DATADIR/fonts/Courier-Oblique fonts/Courier-Oblique +f 0444 root sys $DATADIR/fonts/Helvetica fonts/Helvetica +f 0444 root sys $DATADIR/fonts/Helvetica-Bold fonts/Helvetica-Bold +f 0444 root sys $DATADIR/fonts/Helvetica-BoldOblique fonts/Helvetica-BoldOblique +f 0444 root sys $DATADIR/fonts/Helvetica-Narrow fonts/Helvetica-Narrow +f 0444 root sys $DATADIR/fonts/Helvetica-Narrow-Bold fonts/Helvetica-Narrow-Bold +f 0444 root sys $DATADIR/fonts/Helvetica-Narrow-BoldOblique fonts/Helvetica-Narrow-BoldOblique +f 0444 root sys $DATADIR/fonts/Helvetica-Narrow-Oblique fonts/Helvetica-Narrow-Oblique +f 0444 root sys $DATADIR/fonts/Helvetica-Oblique fonts/Helvetica-Oblique +f 0444 root sys $DATADIR/fonts/NewCenturySchlbk-Bold fonts/NewCenturySchlbk-Bold +f 0444 root sys $DATADIR/fonts/NewCenturySchlbk-BoldItalic fonts/NewCenturySchlbk-BoldItalic +f 0444 root sys $DATADIR/fonts/NewCenturySchlbk-Italic fonts/NewCenturySchlbk-Italic +f 0444 root sys $DATADIR/fonts/NewCenturySchlbk-Roman fonts/NewCenturySchlbk-Roman +f 0444 root sys $DATADIR/fonts/Palatino-Bold fonts/Palatino-Bold +f 0444 root sys $DATADIR/fonts/Palatino-BoldItalic fonts/Palatino-BoldItalic +f 0444 root sys $DATADIR/fonts/Palatino-Italic fonts/Palatino-Italic +f 0444 root sys $DATADIR/fonts/Palatino-Roman fonts/Palatino-Roman +f 0444 root sys $DATADIR/fonts/Symbol fonts/Symbol +f 0444 root sys $DATADIR/fonts/Times-Bold fonts/Times-Bold +f 0444 root sys $DATADIR/fonts/Times-BoldItalic fonts/Times-BoldItalic +f 0444 root sys $DATADIR/fonts/Times-Italic fonts/Times-Italic +f 0444 root sys $DATADIR/fonts/Times-Roman fonts/Times-Roman +f 0444 root sys $DATADIR/fonts/Utopia-Bold fonts/Utopia-Bold +f 0444 root sys $DATADIR/fonts/Utopia-BoldItalic fonts/Utopia-BoldItalic +f 0444 root sys $DATADIR/fonts/Utopia-Italic fonts/Utopia-Italic +f 0444 root sys $DATADIR/fonts/Utopia-Regular fonts/Utopia-Regular +f 0444 root sys $DATADIR/fonts/ZapfChancery-MediumItalic fonts/ZapfChancery-MediumItalic +f 0444 root sys $DATADIR/fonts/ZapfDingbats fonts/ZapfDingbats + +d 0555 root sys $DATADIR/pstoraster - +f 0444 root sys $DATADIR/pstoraster/Fontmap pstoraster/Fontmap +f 0444 root sys $DATADIR/pstoraster/gs_btokn.ps pstoraster/gs_btokn.ps +f 0444 root sys $DATADIR/pstoraster/gs_ccfnt.ps pstoraster/gs_ccfnt.ps +f 0444 root sys $DATADIR/pstoraster/gs_cff.ps pstoraster/gs_cff.ps +f 0444 root sys $DATADIR/pstoraster/gs_cidfn.ps pstoraster/gs_cidfn.ps +f 0444 root sys $DATADIR/pstoraster/gs_cmap.ps pstoraster/gs_cmap.ps +f 0444 root sys $DATADIR/pstoraster/gs_cmdl.ps pstoraster/gs_cmdl.ps +f 0444 root sys $DATADIR/pstoraster/gs_dbt_e.ps pstoraster/gs_dbt_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_diskf.ps pstoraster/gs_diskf.ps +f 0444 root sys $DATADIR/pstoraster/gs_dpnxt.ps pstoraster/gs_dpnxt.ps +f 0444 root sys $DATADIR/pstoraster/gs_dps.ps pstoraster/gs_dps.ps +f 0444 root sys $DATADIR/pstoraster/gs_dps1.ps pstoraster/gs_dps1.ps +f 0444 root sys $DATADIR/pstoraster/gs_dps2.ps pstoraster/gs_dps2.ps +f 0444 root sys $DATADIR/pstoraster/gs_epsf.ps pstoraster/gs_epsf.ps +f 0444 root sys $DATADIR/pstoraster/gs_fform.ps pstoraster/gs_fform.ps +f 0444 root sys $DATADIR/pstoraster/gs_fonts.ps pstoraster/gs_fonts.ps +f 0444 root sys $DATADIR/pstoraster/gs_init.ps pstoraster/gs_init.ps +f 0444 root sys $DATADIR/pstoraster/gs_iso_e.ps pstoraster/gs_iso_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_kanji.ps pstoraster/gs_kanji.ps +f 0444 root sys $DATADIR/pstoraster/gs_ksb_e.ps pstoraster/gs_ksb_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_lev2.ps pstoraster/gs_lev2.ps +f 0444 root sys $DATADIR/pstoraster/gs_ll3.ps pstoraster/gs_ll3.ps +f 0444 root sys $DATADIR/pstoraster/gs_mex_e.ps pstoraster/gs_mex_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_mro_e.ps pstoraster/gs_mro_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_pfile.ps pstoraster/gs_pfile.ps +f 0444 root sys $DATADIR/pstoraster/gs_res.ps pstoraster/gs_res.ps +f 0444 root sys $DATADIR/pstoraster/gs_setpd.ps pstoraster/gs_setpd.ps +f 0444 root sys $DATADIR/pstoraster/gs_statd.ps pstoraster/gs_statd.ps +f 0444 root sys $DATADIR/pstoraster/gs_std_e.ps pstoraster/gs_std_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_sym_e.ps pstoraster/gs_sym_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_ttf.ps pstoraster/gs_ttf.ps +f 0444 root sys $DATADIR/pstoraster/gs_typ32.ps pstoraster/gs_typ32.ps +f 0444 root sys $DATADIR/pstoraster/gs_typ42.ps pstoraster/gs_typ42.ps +f 0444 root sys $DATADIR/pstoraster/gs_type1.ps pstoraster/gs_type1.ps +f 0444 root sys $DATADIR/pstoraster/gs_wan_e.ps pstoraster/gs_wan_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_wl1_e.ps pstoraster/gs_wl1_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_wl2_e.ps pstoraster/gs_wl2_e.ps +f 0444 root sys $DATADIR/pstoraster/gs_wl5_e.ps pstoraster/gs_wl5_e.ps + +d 0555 root sys $DATADIR/model - +f 0444 root sys $DATADIR/model/deskjet.ppd ppd/deskjet.ppd +f 0444 root sys $DATADIR/model/laserjet.ppd ppd/laserjet.ppd +f 0444 root sys $DATADIR/model/epson9.ppd ppd/epson9.ppd +f 0444 root sys $DATADIR/model/epson24.ppd ppd/epson24.ppd +f 0444 root sys $DATADIR/model/stcolor.ppd ppd/stcolor.ppd +f 0444 root sys $DATADIR/model/stphoto.ppd ppd/stphoto.ppd + +d 0555 root sys $DATADIR/templates - +f 0444 root sys $DATADIR/templates/add-class.tmpl templates/add-class.tmpl +f 0444 root sys $DATADIR/templates/add-printer.tmpl templates/add-printer.tmpl +f 0444 root sys $DATADIR/templates/admin-op.tmpl templates/admin-op.tmpl +f 0444 root sys $DATADIR/templates/admin.tmpl templates/admin.tmpl +f 0444 root sys $DATADIR/templates/choose-device.tmpl templates/choose-device.tmpl +f 0444 root sys $DATADIR/templates/choose-make.tmpl templates/choose-make.tmpl +f 0444 root sys $DATADIR/templates/choose-members.tmpl templates/choose-members.tmpl +f 0444 root sys $DATADIR/templates/choose-model.tmpl templates/choose-model.tmpl +f 0444 root sys $DATADIR/templates/choose-serial.tmpl templates/choose-serial.tmpl +f 0444 root sys $DATADIR/templates/choose-uri.tmpl templates/choose-uri.tmpl +f 0444 root sys $DATADIR/templates/class-added.tmpl templates/class-added.tmpl +f 0444 root sys $DATADIR/templates/class-confirm.tmpl templates/class-confirm.tmpl +f 0444 root sys $DATADIR/templates/class-deleted.tmpl templates/class-deleted.tmpl +f 0444 root sys $DATADIR/templates/class-modified.tmpl templates/class-modified.tmpl +f 0444 root sys $DATADIR/templates/classes.tmpl templates/classes.tmpl +f 0444 root sys $DATADIR/templates/config-printer.tmpl templates/config-printer.tmpl +f 0444 root sys $DATADIR/templates/config-printer2.tmpl templates/config-printer2.tmpl +f 0444 root sys $DATADIR/templates/error.tmpl templates/error.tmpl +f 0444 root sys $DATADIR/templates/header.tmpl templates/header.tmpl +f 0444 root sys $DATADIR/templates/job-cancel.tmpl templates/job-cancel.tmpl +f 0444 root sys $DATADIR/templates/job-hold.tmpl templates/job-hold.tmpl +f 0444 root sys $DATADIR/templates/job-release.tmpl templates/job-release.tmpl +f 0444 root sys $DATADIR/templates/job-restart.tmpl templates/job-restart.tmpl +f 0444 root sys $DATADIR/templates/jobs.tmpl templates/jobs.tmpl +f 0444 root sys $DATADIR/templates/modify-class.tmpl templates/modify-class.tmpl +f 0444 root sys $DATADIR/templates/modify-printer.tmpl templates/modify-printer.tmpl +f 0444 root sys $DATADIR/templates/option-boolean.tmpl templates/option-boolean.tmpl +f 0444 root sys $DATADIR/templates/option-header.tmpl templates/option-header.tmpl +f 0444 root sys $DATADIR/templates/option-pickmany.tmpl templates/option-pickmany.tmpl +f 0444 root sys $DATADIR/templates/option-pickone.tmpl templates/option-pickone.tmpl +f 0444 root sys $DATADIR/templates/option-trailer.tmpl templates/option-trailer.tmpl +f 0444 root sys $DATADIR/templates/printer-accept.tmpl templates/printer-accept.tmpl +f 0444 root sys $DATADIR/templates/printer-added.tmpl templates/printer-added.tmpl +f 0444 root sys $DATADIR/templates/printer-configured.tmpl templates/printer-configured.tmpl +f 0444 root sys $DATADIR/templates/printer-confirm.tmpl templates/printer-confirm.tmpl +f 0444 root sys $DATADIR/templates/printer-deleted.tmpl templates/printer-deleted.tmpl +f 0444 root sys $DATADIR/templates/printer-modified.tmpl templates/printer-modified.tmpl +f 0444 root sys $DATADIR/templates/printer-reject.tmpl templates/printer-reject.tmpl +f 0444 root sys $DATADIR/templates/printer-start.tmpl templates/printer-start.tmpl +f 0444 root sys $DATADIR/templates/printer-stop.tmpl templates/printer-stop.tmpl +f 0444 root sys $DATADIR/templates/printers.tmpl templates/printers.tmpl +f 0444 root sys $DATADIR/templates/test-page.tmpl templates/test-page.tmpl +f 0444 root sys $DATADIR/templates/trailer.tmpl templates/trailer.tmpl + +# Config files +d 0555 root sys $SERVERROOT - +d 0711 root sys $SERVERROOT/certs - +d 0755 root sys $SERVERROOT/interfaces - +d 0755 root sys $SERVERROOT/ppd - +c 0644 root sys $SERVERROOT/classes.conf conf/classes.conf +c 0644 root sys $SERVERROOT/cupsd.conf conf/cupsd.conf +f 0644 root sys $SERVERROOT/mime.convs conf/mime.convs +f 0644 root sys $SERVERROOT/mime.types conf/mime.types +c 0644 root sys $SERVERROOT/printers.conf conf/printers.conf + +%system linux +# Linux version needs PAM... +%requires /lib/libpam.so.0 +d 0555 root sys $PAMDIR - +c 0644 root sys $PAMDIR/cups data/cups.pam +%system all + +# Developer files +d 0555 root sys $INCLUDEDIR/cups - +f 0444 root sys $INCLUDEDIR/cups/cups.h cups/cups.h +f 0444 root sys $INCLUDEDIR/cups/http.h cups/http.h +f 0444 root sys $INCLUDEDIR/cups/image.h filter/image.h +f 0444 root sys $INCLUDEDIR/cups/ipp.h cups/ipp.h +f 0444 root sys $INCLUDEDIR/cups/language.h cups/language.h +f 0444 root sys $INCLUDEDIR/cups/md5.h cups/md5.h +f 0444 root sys $INCLUDEDIR/cups/ppd.h cups/ppd.h +f 0444 root sys $INCLUDEDIR/cups/raster.h filter/raster.h + +f 0444 root sys $LIBDIR/libcups.a cups/libcups.a + +# Documentation files +d 0555 root sys $DOCDIR - +f 0444 root sys $DOCDIR/cups.css doc/cups.css +f 0444 root sys $DOCDIR/documentation.html doc/documentation.html +f 0444 root sys $DOCDIR/index.html doc/index.html + +d 0555 root sys $DOCDIR/images - + +f 0444 root sys $DOCDIR/images/classes.gif doc/images/classes.gif +f 0444 root sys $DOCDIR/images/printer-idle.gif doc/images/printer-idle.gif +f 0444 root sys $DOCDIR/images/printer-processing.gif doc/images/printer-processing.gif +f 0444 root sys $DOCDIR/images/printer-stopped.gif doc/images/printer-stopped.gif + +f 0444 root sys $DOCDIR/images/accept-jobs.gif doc/images/accept-jobs.gif +f 0444 root sys $DOCDIR/images/add-class.gif doc/images/add-class.gif +f 0444 root sys $DOCDIR/images/add-printer.gif doc/images/add-printer.gif +f 0444 root sys $DOCDIR/images/cancel-job.gif doc/images/cancel-job.gif +f 0444 root sys $DOCDIR/images/cancel-jobs.gif doc/images/cancel-jobs.gif +f 0444 root sys $DOCDIR/images/cancel.gif doc/images/cancel.gif +f 0444 root sys $DOCDIR/images/continue.gif doc/images/continue.gif +f 0444 root sys $DOCDIR/images/config-printer.gif doc/images/config-printer.gif +f 0444 root sys $DOCDIR/images/cups-block-diagram.gif doc/images/cups-block-diagram.gif +f 0444 root sys $DOCDIR/images/delete-class.gif doc/images/delete-class.gif +f 0444 root sys $DOCDIR/images/delete-printer.gif doc/images/delete-printer.gif +f 0444 root sys $DOCDIR/images/hold-job.gif doc/images/hold-job.gif +f 0444 root sys $DOCDIR/images/left.gif doc/images/left.gif +f 0444 root sys $DOCDIR/images/logo.gif doc/images/logo.gif +f 0444 root sys $DOCDIR/images/manage-classes.gif doc/images/manage-classes.gif +f 0444 root sys $DOCDIR/images/manage-jobs.gif doc/images/manage-jobs.gif +f 0444 root sys $DOCDIR/images/manage-printers.gif doc/images/manage-printers.gif +f 0444 root sys $DOCDIR/images/modify-class.gif doc/images/modify-class.gif +f 0444 root sys $DOCDIR/images/modify-printer.gif doc/images/modify-printer.gif +f 0444 root sys $DOCDIR/images/navbar.gif doc/images/navbar.gif +f 0444 root sys $DOCDIR/images/print-test-page.gif doc/images/print-test-page.gif +f 0444 root sys $DOCDIR/images/reject-jobs.gif doc/images/reject-jobs.gif +f 0444 root sys $DOCDIR/images/release-job.gif doc/images/release-job.gif +f 0444 root sys $DOCDIR/images/restart-job.gif doc/images/restart-job.gif +f 0444 root sys $DOCDIR/images/right.gif doc/images/right.gif +f 0444 root sys $DOCDIR/images/show-active.gif doc/images/show-active.gif +f 0444 root sys $DOCDIR/images/show-completed.gif doc/images/show-completed.gif +f 0444 root sys $DOCDIR/images/start-class.gif doc/images/start-class.gif +f 0444 root sys $DOCDIR/images/start-printer.gif doc/images/start-printer.gif +f 0444 root sys $DOCDIR/images/stop-class.gif doc/images/stop-class.gif +f 0444 root sys $DOCDIR/images/stop-printer.gif doc/images/stop-printer.gif + +f 0444 root sys $DOCDIR/cmp.html doc/cmp.html +f 0444 root sys $DOCDIR/cmp.pdf doc/cmp.pdf +f 0444 root sys $DOCDIR/cupsdoc.css doc/cupsdoc.css +f 0444 root sys $DOCDIR/idd.html doc/idd.html +f 0444 root sys $DOCDIR/idd.pdf doc/idd.pdf +f 0444 root sys $DOCDIR/ipp.html doc/ipp.html +f 0444 root sys $DOCDIR/ipp.pdf doc/ipp.pdf +f 0444 root sys $DOCDIR/overview.html doc/overview.html +f 0444 root sys $DOCDIR/overview.pdf doc/overview.pdf +f 0444 root sys $DOCDIR/sam.html doc/sam.html +f 0444 root sys $DOCDIR/sam.pdf doc/sam.pdf +f 0444 root sys $DOCDIR/sdd.html doc/sdd.html +f 0444 root sys $DOCDIR/sdd.pdf doc/sdd.pdf +f 0444 root sys $DOCDIR/spm.html doc/spm.html +f 0444 root sys $DOCDIR/spm.pdf doc/spm.pdf +f 0444 root sys $DOCDIR/ssr.html doc/ssr.html +f 0444 root sys $DOCDIR/ssr.pdf doc/ssr.pdf +f 0444 root sys $DOCDIR/sum.html doc/sum.html +f 0444 root sys $DOCDIR/sum.pdf doc/sum.pdf +f 0444 root sys $DOCDIR/svd.html doc/svd.html +f 0444 root sys $DOCDIR/svd.pdf doc/svd.pdf +f 0444 root sys $DOCDIR/images/cups-bar.gif doc/images/cups-bar.gif +f 0444 root sys $DOCDIR/images/cups-large.gif doc/images/cups-large.gif +f 0444 root sys $DOCDIR/images/cups-medium.gif doc/images/cups-medium.gif +f 0444 root sys $DOCDIR/images/cups-small.gif doc/images/cups-small.gif + + +# Man pages +%system irix +d 0555 root sys $MANDIR/a_man - +d 0555 root sys $MANDIR/a_man/cat1 - +d 0555 root sys $MANDIR/u_man - +d 0555 root sys $MANDIR/u_man/cat1 - +d 0555 root sys $MANDIR/u_man/cat5 - + +f 0444 root sys $MANDIR/a_man/cat1/accept.z man/accept.z +l 0444 root sys $MANDIR/a_man/cat1/reject.z accept.z +f 0444 root sys $MANDIR/u_man/cat1/backend.z man/backend.z +f 0444 root sys $MANDIR/u_man/cat5/classes.conf.z man/classes.conf.z +f 0444 root sys $MANDIR/a_man/cat1/cups-lpd.z man/cups-lpd.z +f 0444 root sys $MANDIR/a_man/cat1/cups-polld.z man/cups-polld.z +f 0444 root sys $MANDIR/u_man/cat5/cupsd.conf.z man/cupsd.conf.z +f 0444 root sys $MANDIR/a_man/cat1/cupsd.z man/cupsd.z +f 0444 root sys $MANDIR/a_man/cat1/enable.z man/enable.z +l 0444 root sys $MANDIR/a_man/cat1/disable.z enable.z +f 0444 root sys $MANDIR/u_man/cat1/filter.z man/filter.z +f 0444 root sys $MANDIR/a_man/cat1/lpadmin.z man/lpadmin.z +f 0444 root sys $MANDIR/a_man/cat1/lpc.z man/lpc.z +f 0444 root sys $MANDIR/a_man/cat1/lpinfo.z man/lpinfo.z +f 0444 root sys $MANDIR/a_man/cat1/lpmove.z man/lpmove.z +f 0444 root sys $MANDIR/u_man/cat1/lpoptions.z man/lpoptions.z +f 0444 root sys $MANDIR/u_man/cat1/lpq.z man/lpq.z +f 0444 root sys $MANDIR/u_man/cat1/lprm.z man/lprm.z +f 0444 root sys $MANDIR/u_man/cat1/lpr.z man/lpr.z +f 0444 root sys $MANDIR/u_man/cat1/lpstat.z man/lpstat.z +f 0444 root sys $MANDIR/u_man/cat1/lp.z man/lp.z +l 0444 root sys $MANDIR/u_man/cat1/cancel.z lp.z +f 0444 root sys $MANDIR/u_man/cat5/mime.convs.z man/mime.convs.z +f 0444 root sys $MANDIR/u_man/cat5/mime.types.z man/mime.types.z +f 0444 root sys $MANDIR/u_man/cat5/printers.conf.z man/printers.conf.z + +%system solaris hpux +d 0555 root sys $MANDIR/man1 - +d 0555 root sys $MANDIR/man5 - +d 0555 root sys $MANDIR/man1m - + +f 0444 root sys $MANDIR/man1m/accept.1m man/accept.man +l 0444 root sys $MANDIR/man1m/reject.1m accept.man +f 0444 root sys $MANDIR/man1/backend.1 man/backend.man +f 0444 root sys $MANDIR/man1/classes.conf.5 man/classes.conf.man +f 0444 root sys $MANDIR/man1m/cups-lpd.1m man/cups-lpd.man +f 0444 root sys $MANDIR/man1m/cups-polld.1m man/cups-polld.man +f 0444 root sys $MANDIR/man1m/cupsd.1m man/cupsd.man +f 0444 root sys $MANDIR/man5/cupsd.conf.5 man/cupsd.conf.man +f 0444 root sys $MANDIR/man1m/enable.1m man/enable.man +l 0444 root sys $MANDIR/man1m/disable.1m enable.man +f 0444 root sys $MANDIR/man1/filter.1 man/filter.man +f 0444 root sys $MANDIR/man1m/lpadmin.1m man/lpadmin.man +f 0444 root sys $MANDIR/man1m/lpc.1m man/lpc.man +f 0444 root sys $MANDIR/man1m/lpinfo.1m man/lpinfo.man +f 0444 root sys $MANDIR/man1m/lpmove.1m man/lpmove.man +f 0444 root sys $MANDIR/man1/lpoptions.1 man/lpoptions.man +f 0444 root sys $MANDIR/man1/lpq.1 man/lpq.man +f 0444 root sys $MANDIR/man1/lprm.1 man/lprm.man +f 0444 root sys $MANDIR/man1/lpr.1 man/lpr.man +f 0444 root sys $MANDIR/man1/lpstat.1 man/lpstat.man +f 0444 root sys $MANDIR/man1/lp.1 man/lp.man +l 0444 root sys $MANDIR/man1/cancel.1 lp.man +f 0444 root sys $MANDIR/man5/mime.convs.5 man/mime.convs.man +f 0444 root sys $MANDIR/man5/mime.types.5 man/mime.types.man +f 0444 root sys $MANDIR/man5/printers.conf.5 man/printers.conf.man + +%system !irix !solaris !hpux +d 0555 root sys $MANDIR/man1 - +d 0555 root sys $MANDIR/man5 - +d 0555 root sys $MANDIR/man8 - + +f 0444 root sys $MANDIR/man8/accept.8 man/accept.man +l 0444 root sys $MANDIR/man8/reject.8 accept.man +f 0444 root sys $MANDIR/man1/backend.1 man/backend.man +f 0444 root sys $MANDIR/man1/classes.conf.5 man/classes.conf.man +f 0444 root sys $MANDIR/man8/cups-lpd.8 man/cups-lpd.man +f 0444 root sys $MANDIR/man8/cups-polld.8 man/cups-polld.man +f 0444 root sys $MANDIR/man8/cupsd.8 man/cupsd.man +f 0444 root sys $MANDIR/man5/cupsd.conf.5 man/cupsd.conf.man +f 0444 root sys $MANDIR/man8/enable.8 man/enable.man +l 0444 root sys $MANDIR/man8/disable.8 enable.man +f 0444 root sys $MANDIR/man1/filter.1 man/filter.man +f 0444 root sys $MANDIR/man8/lpadmin.8 man/lpadmin.man +f 0444 root sys $MANDIR/man8/lpc.8 man/lpc.man +f 0444 root sys $MANDIR/man8/lpinfo.8 man/lpinfo.man +f 0444 root sys $MANDIR/man8/lpmove.8 man/lpmove.man +f 0444 root sys $MANDIR/man1/lpoptions.1 man/lpoptions.man +f 0444 root sys $MANDIR/man1/lpq.1 man/lpq.man +f 0444 root sys $MANDIR/man1/lprm.1 man/lprm.man +f 0444 root sys $MANDIR/man1/lpr.1 man/lpr.man +f 0444 root sys $MANDIR/man1/lpstat.1 man/lpstat.man +f 0444 root sys $MANDIR/man1/lp.1 man/lp.man +l 0444 root sys $MANDIR/man1/cancel.1 lp.man +f 0444 root sys $MANDIR/man5/mime.convs.5 man/mime.convs.man +f 0444 root sys $MANDIR/man5/mime.types.5 man/mime.types.man +f 0444 root sys $MANDIR/man5/printers.conf.5 man/printers.conf.man + +# Startup script +%system all +i 0555 root sys cups cups.sh + +# +# End of "$Id: cups.list 1229 2000-07-20 16:51:42Z mike $". +# diff --git a/cups.sh.in b/cups.sh.in new file mode 100755 index 0000000000..ee30dd2602 --- /dev/null +++ b/cups.sh.in @@ -0,0 +1,114 @@ +#!/bin/sh +# +# "$Id$" +# +# Startup/shutdown script for the Common UNIX Printing System (CUPS). +# +# Linux chkconfig stuff: +# +# chkconfig: 02 99 00 +# description: Startup/shutdown script for the Common UNIX \ +# Printing System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +# See what program to use for configuration stuff... +case "`uname`" in + IRIX*) + IS_ON=/sbin/chkconfig + ;; + + *) + IS_ON=/bin/true + ;; +esac + +# The verbose flag controls the printing of the names of +# daemons as they are started. +if $IS_ON verbose; then + ECHO=echo +else + ECHO=: +fi + +# See if the CUPS server is running... +case "`uname`" in + IRIX* | HP-UX | SunOS) + pid=`ps -e | awk '{print $1,$4}' | grep cupsd | awk '{print $1}'` + ;; + OSF1) + pid=`ps -e | awk '{print $1,$5}' | grep cupsd | awk '{print $1}'` + ;; + Linux) + pid=`ps ax | awk '{print $1,$5}' | grep cupsd | awk '{print $1}'` + ;; + *) + pid="" + ;; +esac + +# Start or stop the CUPS server based upon the first argument to the script. +case $1 in + start | restart | reload) + if test "$pid" != ""; then + if $IS_ON cups; then + kill -HUP $pid + $ECHO "cups: scheduler restarted." + else + kill $pid + $ECHO "cups: scheduler stopped." + fi + else + if $IS_ON cups; then + prefix=@prefix@ + exec_prefix=@exec_prefix@ + @sbindir@/cupsd + $ECHO "cups: scheduler started." + fi + fi + ;; + + stop) + if test "$pid" != ""; then + kill $pid + $ECHO "cups: scheduler stopped." + fi + ;; + + status) + if test "$pid" != ""; then + echo "cups: Scheduler is running." + else + echo "cups: Scheduler is not running." + fi + ;; + + *) + echo "Usage: cups {reload|restart|start|status|stop}" + exit 1 + ;; +esac + +exit 0 + + +# +# End of "$Id$". +# diff --git a/cups.spec b/cups.spec new file mode 100644 index 0000000000..33f543f071 --- /dev/null +++ b/cups.spec @@ -0,0 +1,113 @@ +# +# "$Id: cups.spec 1214 2000-07-10 20:58:19Z mike $" +# +# RPM "spec" file for the Common UNIX Printing System (CUPS). +# +# Original version by Jason McMullan . +# +# Copyright 1999-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +Summary: Common Unix Printing System +Name: cups +Version: 1.1 +Release: 0 +Copyright: GPL +Group: System Environment/Daemons +Source: ftp://ftp.easysw.com/pub/cups/1.1/cups-1.1-source.tar.gz +Url: http://www.cups.org +Packager: Michael Sweet +Vendor: Easy Software Products +# use buildroot so as not to disturb the version already installed +BuildRoot: /tmp/rpmbuild +Conflicts: lpr + +%package devel +Summary: Common Unix Printing System - development environment +Group: Development/Libraries + +%description +The Common UNIX Printing System provides a portable printing layer for +UNIX® operating systems. It has been developed by Easy Software Products +to promote a standard printing solution for all UNIX vendors and users. +CUPS provides the System V and Berkeley command-line interfaces. + +%description devel +The Common UNIX Printing System provides a portable printing layer for +UNIX® operating systems. This is the development package for creating +additional printer drivers, and other CUPS services. + +%prep +%setup + +%build +./configure + +# If we got this far, all prerequisite libraries must be here. +make + +%install +# these lines just make sure the directory structure in the +# RPM_BUILD_ROOT exists +rm -rf $RPM_BUILD_ROOT +mkdir -p $RPM_BUILD_ROOT/etc/rc.d/init.d + +make datadir=$RPM_BUILD_ROOT/usr/share \ + exec_prefix=$RPM_BUILD_ROOT/usr \ + includedir=$RPM_BUILD_ROOT/usr/include \ + infodir=$RPM_BUILD_ROOT/usr/info \ + libdir=$RPM_BUILD_ROOT/usr/lib \ + localestatedir=$RPM_BUILD_ROOT/var \ + prefix=$RPM_BUILD_ROOT \ + sharedstatedir=$RPM_BUILD_ROOT/usr/com \ + sysconfdir=$RPM_BUILD_ROOT/etc \ + install + +install -m 755 -o root -g root cups.sh $RPM_BUILD_ROOT/etc/rc.d/init.d/cups + +%post +/sbin/chkconfig --add cups +/sbin/chkconfig cups on +/etc/rc.d/init.d/cups start + +%preun +/etc/rc.d/init.d/cups stop +/sbin/chkconfig --del cups + +%clean +rm -rf $RPM_BUILD_ROOT + +%files +%defattr(-,root,root) +/etc/* +/usr/bin/* +/usr/lib/*.so* +/usr/man/* +/usr/sbin/* +/usr/share/* +/usr/lib/cups/* +/var/* + +%files devel +/usr/include/cups/* +/usr/lib/*.a + +# +# End of "$Id: cups.spec 1214 2000-07-10 20:58:19Z mike $". +# diff --git a/cups/Makefile b/cups/Makefile new file mode 100644 index 0000000000..61baf47957 --- /dev/null +++ b/cups/Makefile @@ -0,0 +1,166 @@ +# +# "$Id$" +# +# Support library Makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products, all rights reserved. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +# +# Object files... +# + +LIBOBJS = dest.o emit.o http.o ipp.o language.o mark.o md5.o md5passwd.o \ + options.o page.o ppd.o snprintf.o string.o usersys.o util.o +OBJS = $(LIBOBJS) testhttp.o testppd.o + + +# +# Header files to install... +# + +HEADERS = cups.h http.h ipp.h language.h md5.h ppd.h + + +# +# Targets in this directory... +# + +TARGETS = $(LIBCUPS) libcups.a + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Remove object and target files... +# + +clean: + $(RM) $(OBJS) $(TARGETS) + + +# +# Install object and target files... +# + +install: all + -$(MKDIR) $(INCLUDEDIR)/cups + $(CHMOD) ugo+rx $(INCLUDEDIR) + $(CHMOD) ugo+rx $(INCLUDEDIR)/cups + $(INSTALL_DATA) $(HEADERS) $(INCLUDEDIR)/cups + -$(MKDIR) $(LIBDIR) + $(CHMOD) ugo+rx $(LIBDIR) + $(INSTALL_LIB) $(LIBCUPS) $(LIBDIR) + if test $(LIBCUPS) != "libcups.a" -a $(LIBCUPS) != "libcups.la"; then \ + $(INSTALL_LIB) libcups.a $(LIBDIR); \ + $(RM) `basename $(LIBCUPS) .2`; \ + $(LN) $(LIBCUPS) `basename $(LIBCUPS) .2`; \ + fi + + +# +# libcups.so.2, libcups.sl.1 +# + +libcups.so.2 libcups.sl.2: $(LIBOBJS) ../Makedefs + echo Linking $@... + $(DSO) $@ $(LIBOBJS) + $(RM) `basename $@ .2` + $(LN) $@ `basename $@ .2` + + +# +# libcups.la +# + +libcups.la: $(LIBOBJS) ../Makedefs + echo Linking $@... + $(CC) -o $@ $(LIBOBJS:.o=.lo) -rpath $(LIBDIR) -version-info 2:0 + + +# +# libcups.a +# + +libcups.a: $(LIBOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + + +# +# cups_C.h - the default POSIX locale that is compiled in. +# + +cups_C.h: ../locale/C/cups_C + echo Generating $@... + $(RM) cups_C.h + $(AWK) '{print "\"" $$0 "\","}' < ../locale/C/cups_C > cups_C.h + +dest.o: cups.h http.h ipp.h language.h string.h +emit.o: ppd.h +http.o: http.h ipp.h md5.h string.h +ipp.o: http.h ipp.h string.h language.h +language.o: cups_C.h language.h string.h +mark.o: ppd.h +md5.o: md5.h +options.o: cups.h +page.o: ppd.h +ppd.o: language.h ppd.h +snprintf.o: string.h +string.o: string.h +usersys.o: cups.h +util.o: cups.h http.h ipp.h + + +# +# testhttp (dependency on static CUPS library is intentional) +# + +testhttp: testhttp.o libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ testhttp.o libcups.a $(NETLIBS) + +testhttp.o: http.h + + +# +# testppd (dependency on static CUPS library is intentional) +# + +testppd: testppd.o libcups.a + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ testppd.o libcups.a $(NETLIBS) + +testppd.o: ppd.h + +$(OBJS): ../Makedefs ../config.h + + +# +# End of "$Id$". +# diff --git a/cups/cups.dsp b/cups/cups.dsp new file mode 100644 index 0000000000..cef2887657 --- /dev/null +++ b/cups/cups.dsp @@ -0,0 +1,180 @@ +# Microsoft Developer Studio Project File - Name="cups" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Static Library" 0x0104 + +CFG=cups - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "cups.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "cups.mak" CFG="cups - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "cups - Win32 Release" (based on "Win32 (x86) Static Library") +!MESSAGE "cups - Win32 Debug" (based on "Win32 (x86) Static Library") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "cups - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I "..\visualc" /I ".." /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"cups.lib" + +!ELSEIF "$(CFG)" == "cups - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I "..\visualc" /I ".." /I "../visualc" /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LIB32=link.exe -lib +# ADD BASE LIB32 /nologo +# ADD LIB32 /nologo /out:"cupsd.lib" + +!ENDIF + +# Begin Target + +# Name "cups - Win32 Release" +# Name "cups - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\emit.c +# End Source File +# Begin Source File + +SOURCE=.\filter.c +# End Source File +# Begin Source File + +SOURCE=.\http.c +# End Source File +# Begin Source File + +SOURCE=.\ipp.c +# End Source File +# Begin Source File + +SOURCE=.\language.c +# End Source File +# Begin Source File + +SOURCE=.\mark.c +# End Source File +# Begin Source File + +SOURCE=.\mime.c +# End Source File +# Begin Source File + +SOURCE=.\options.c +# End Source File +# Begin Source File + +SOURCE=.\page.c +# End Source File +# Begin Source File + +SOURCE=.\ppd.c +# End Source File +# Begin Source File + +SOURCE=.\raster.c +# End Source File +# Begin Source File + +SOURCE=.\snprintf.c +# End Source File +# Begin Source File + +SOURCE=.\string.c +# End Source File +# Begin Source File + +SOURCE=.\type.c +# End Source File +# Begin Source File + +SOURCE=.\util.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\cups.h +# End Source File +# Begin Source File + +SOURCE=.\http.h +# End Source File +# Begin Source File + +SOURCE=.\ipp.h +# End Source File +# Begin Source File + +SOURCE=.\language.h +# End Source File +# Begin Source File + +SOURCE=.\mime.h +# End Source File +# Begin Source File + +SOURCE=.\ppd.h +# End Source File +# Begin Source File + +SOURCE=.\raster.h +# End Source File +# End Group +# End Target +# End Project diff --git a/cups/cups.h b/cups/cups.h new file mode 100644 index 0000000000..f734b4da39 --- /dev/null +++ b/cups/cups.h @@ -0,0 +1,148 @@ +/* + * "$Id$" + * + * API definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +#ifndef _CUPS_CUPS_H_ +# define _CUPS_CUPS_H_ + +/* + * Include necessary headers... + */ + +# include +# include + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Constants... + */ + +# define CUPS_VERSION 1.0100 +# define CUPS_DATE_ANY -1 + + +/* + * Types and structures... + */ + +typedef unsigned cups_ptype_t; /**** Printer Type/Capability Bits ****/ +enum /* Not a typedef'd enum so we can OR */ +{ + CUPS_PRINTER_LOCAL = 0x0000, /* Local printer or class */ + CUPS_PRINTER_CLASS = 0x0001, /* Printer class */ + CUPS_PRINTER_REMOTE = 0x0002, /* Remote printer or class */ + CUPS_PRINTER_BW = 0x0004, /* Can do B&W printing */ + CUPS_PRINTER_COLOR = 0x0008, /* Can do color printing */ + CUPS_PRINTER_DUPLEX = 0x0010, /* Can do duplexing */ + CUPS_PRINTER_STAPLE = 0x0020, /* Can staple output */ + CUPS_PRINTER_COPIES = 0x0040, /* Can do copies */ + CUPS_PRINTER_COLLATE = 0x0080, /* Can collage copies */ + CUPS_PRINTER_PUNCH = 0x0100, /* Can punch output */ + CUPS_PRINTER_COVER = 0x0200, /* Can cover output */ + CUPS_PRINTER_BIND = 0x0400, /* Can bind output */ + CUPS_PRINTER_SORT = 0x0800, /* Can sort output */ + CUPS_PRINTER_SMALL = 0x1000, /* Can do Letter/Legal/A4 */ + CUPS_PRINTER_MEDIUM = 0x2000, /* Can do Tabloid/B/C/A3/A2 */ + CUPS_PRINTER_LARGE = 0x4000, /* Can do D/E/A1/A0 */ + CUPS_PRINTER_VARIABLE = 0x8000, /* Can do variable sizes */ + CUPS_PRINTER_IMPLICIT = 0x10000, /* Implicit class */ + CUPS_PRINTER_OPTIONS = 0xfffc /* ~(CLASS | REMOTE | IMPLICIT) */ +}; + +typedef struct /**** Printer Options ****/ +{ + char *name; /* Name of option */ + char *value; /* Value of option */ +} cups_option_t; + +typedef struct /**** Destination ****/ +{ + char *name, /* Printer or class name */ + *instance; /* Local instance name or NULL */ + int is_default; /* Is this printer the default? */ + int num_options; /* Number of options */ + cups_option_t *options; /* Options */ +} cups_dest_t; + + +/* + * Functions... + */ + +extern int cupsCancelJob(const char *printer, int job); +#define cupsDoRequest(http,request,resource) cupsDoFileRequest((http),(request),(resource),NULL) +extern ipp_t *cupsDoFileRequest(http_t *http, ipp_t *request, + const char *resource, const char *filename); +extern int cupsGetClasses(char ***classes); +extern const char *cupsGetDefault(void); +extern const char *cupsGetPPD(const char *printer); +extern int cupsGetPrinters(char ***printers); +extern ipp_status_t cupsLastError(void); +extern int cupsPrintFile(const char *printer, const char *filename, + const char *title, int num_options, + cups_option_t *options); +extern int cupsPrintFiles(const char *printer, int num_files, + const char **files, const char *title, + int num_options, cups_option_t *options); +extern char *cupsTempFile(char *filename, int len); + +extern int cupsAddDest(const char *name, const char *instance, + int num_dests, cups_dest_t **dests); +extern void cupsFreeDests(int num_dests, cups_dest_t *dests); +extern cups_dest_t *cupsGetDest(const char *name, const char *instance, + int num_dests, cups_dest_t *dests); +extern int cupsGetDests(cups_dest_t **dests); +extern void cupsSetDests(int num_dests, cups_dest_t *dests); + +extern int cupsAddOption(const char *name, const char *value, + int num_options, cups_option_t **options); +extern void cupsFreeOptions(int num_options, cups_option_t *options); +extern const char *cupsGetOption(const char *name, int num_options, + cups_option_t *options); +extern int cupsParseOptions(const char *arg, int num_options, + cups_option_t **options); +extern int cupsMarkOptions(ppd_file_t *ppd, int num_options, + cups_option_t *options); + +extern const char *cupsGetPassword(const char *prompt); +extern const char *cupsServer(void); +extern const char *cupsUser(void); + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_CUPS_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/cups_C.h b/cups/cups_C.h new file mode 100644 index 0000000000..033dcd80c4 --- /dev/null +++ b/cups/cups_C.h @@ -0,0 +1,132 @@ +"iso-8859-1", +"OK", +"Cancel", +"Help", +"Quit", +"Close", +"Yes", +"No", +"On", +"Off", +"Save", +"Discard", +"Default", +"Options", +"More Info", +"Black", +"Color", +"Cyan", +"Magenta", +"Yellow", +"Copyright 1993-2000 by Easy Software Products, All Rights Reserved.", +"General", +"Printer", +"Image", +"HP-GL/2", +"Extra", +"Document", +"Other", +"Print Pages: ", +"Entire Document", +"Page Range:", +"Reverse Order: ", +"Page Format: ", +" 1-Up", +" 2-Up", +" 4-Up", +"Image Scaling: ", +"Use Natural Image Size", +"Zoom by Percent", +"Zoom by PPI", +"Mirror Image: ", +"Color Saturation: ", +"Color Hue: ", +"Fit to Page: ", +"Shading: ", +"Pen Width: ", +"Gamma Correction: ", +"Brightness: ", +"Add", +"Delete", +"Modify", +"Printer URI", +"Printer Name", +"Printer Location", +"Printer Info", +"Printer Make and Model", +"Device URI", +"Formatting Page", +"Printing Page", +"Initializing Printer", +"Printer State", +"Accepting Jobs", +"Not Accepting Jobs", +"Print Jobs", +"Class", +"Local", +"Remote", +"Duplexing", +"Stapling", +"Fast Copies", +"Collated Copies", +"Hole Punching", +"Covering", +"Binding", +"Sorting", +"Small (up to 9.5x14in)", +"Medium (9.5x14in to 13x19in)", +"Large (13x19in and larger)", +"Custom Size", +"Idle", +"Processing", +"Stopped", +"All", +"Odd", +"Even", +"Darker Lighter", +"Media Size", +"Media Type", +"Media Source", +"Orientation: ", +"Portrait", +"Landscape", +"Job State", +"Job Name", +"User Name", +"Priority", +"Copies", +"File Size", +"Pending", +"Output Mode", +"Resolution", +"Text", +"Pretty Print", +"Margins", +"Left", +"Right", +"Bottom", +"Top", +"Filename(s)", +"Print", +"400 Your browser sent a request that this server could not understand.", +"This server could not verify that you are authorized to access the resource.", +"You must pay to access this server.", +"You don't have permission to access the resource on this server.", +"The requested resource was not found on this server.", +"The requested method is not allowed with the resource.", +"An appropriate representation for the resource was not found on this server.", +"You don't have permission to use this server as a proxy host.", +"The request has taken too long to complete and has been aborted.", +"The requested resource has more than one value.", +"The requested resource is gone and has not been replaced.", +"The requested method requires a valid Content-Length.", +"The precondition on the request evaluated to false.", +"The request is too large for this server to process.", +"The request URI is too large for this server to process.", +"The request format is not understood by this server.", +"500 The server has detected an unrecoverable error and cannot process your request.", +"The requested method is not implemented by this server.", +"The proxy server received an invalid response from an upstream server.", +"The requested resource is currently unavailable on this server.", +"The proxy server has taken too long to respond to this server.", +"This server does not support the HTTP version required by your browser.", diff --git a/cups/debug.h b/cups/debug.h new file mode 100644 index 0000000000..c7918b9bf3 --- /dev/null +++ b/cups/debug.h @@ -0,0 +1,57 @@ +/* + * "$Id$" + * + * Debugging macros for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +#ifndef _CUPS_DEBUG_H_ +# define _CUPS_DEBUG_H_ + +/* + * Include necessary headers... + */ + +# include + +/* + * The debug macros are used if you compile with DEBUG defined. + * + * Usage: + * + * DEBUG_puts("string") + * DEBUG_printf(("format string", arg, arg, ...)); + * + * Note the extra parenthesis around the DEBUG_printf macro... + */ + +# ifdef DEBUG +# define DEBUG_puts(x) puts(x) +# define DEBUG_printf(x) printf x +# else +# define DEBUG_puts(x) +# define DEBUG_printf(x) +# endif /* DEBUG */ + +#endif /* !_CUPS_DEBUG_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/dest.c b/cups/dest.c new file mode 100644 index 0000000000..8eb68e8f04 --- /dev/null +++ b/cups/dest.c @@ -0,0 +1,504 @@ +/* + * "$Id$" + * + * User-defined destination (and option) support for the Common UNIX + * Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * cupsAddDest() - Add a destination to the list of destinations. + * cupsFreeDests() - Free the memory used by the list of destinations. + * cupsGetDest() - Get the named destination from the list. + * cupsGetDests() - Get the list of destinations. + * cupsSetDests() - Set the list of destinations. + * cups_get_dests() - Get destinations from a file. + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include "string.h" +#include +#include + + +/* + * Local functions... + */ + +static int cups_get_dests(const char *filename, int num_dests, + cups_dest_t **dests); + + +/* + * 'cupsAddDest()' - Add a destination to the list of destinations. + */ + +int /* O - New number of destinations */ +cupsAddDest(const char *name, /* I - Name of destination */ + const char *instance, /* I - Instance of destination */ + int num_dests, /* I - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ +{ + int i; /* Looping var */ + cups_dest_t *dest; /* Destination pointer */ + + + if (name == NULL || dests == NULL) + return (0); + + if ((dest = cupsGetDest(name, instance, num_dests, *dests)) != NULL) + return (num_dests); + + /* + * Add new destination... + */ + + if (num_dests == 0) + dest = malloc(sizeof(cups_dest_t)); + else + dest = realloc(*dests, sizeof(cups_dest_t) * (num_dests + 1)); + + if (dest == NULL) + return (num_dests); + + *dests = dest; + + for (i = num_dests; i > 0; i --, dest ++) + if (strcasecmp(name, dest->name) < 0) + break; + else if (strcasecmp(name, dest->name) == 0 && + instance != NULL && dest->instance != NULL && + strcasecmp(instance, dest->instance) < 0) + break; + + if (i > 0) + memmove(dest + 1, dest, i * sizeof(cups_dest_t)); + + dest->name = strdup(name); + dest->is_default = 0; + dest->num_options = 0; + dest->options = (cups_option_t *)0; + + if (instance == NULL) + dest->instance = NULL; + else + dest->instance = strdup(instance); + + return (num_dests + 1); +} + + +/* + * 'cupsFreeDests()' - Free the memory used by the list of destinations. + */ + +void +cupsFreeDests(int num_dests, /* I - Number of destinations */ + cups_dest_t *dests) /* I - Destinations */ +{ + int i; /* Looping var */ + cups_dest_t *dest; /* Current destination */ + + + if (num_dests == 0 || dests == NULL) + return; + + for (i = num_dests, dest = dests; i > 0; i --, dest ++) + { + free(dest->name); + + if (dest->instance) + free(dest->instance); + + cupsFreeOptions(dest->num_options, dest->options); + } + + free(dests); +} + + +/* + * 'cupsGetDest()' - Get the named destination from the list. + */ + +cups_dest_t * /* O - Destination pointer or NULL */ +cupsGetDest(const char *name, /* I - Name of destination */ + const char *instance, /* I - Instance of destination */ + int num_dests, /* I - Number of destinations */ + cups_dest_t *dests) /* I - Destinations */ +{ + int comp; /* Result of comparison */ + + + if (num_dests == 0 || dests == NULL) + return (NULL); + + if (name == NULL) + { + /* + * NULL name for default printer. + */ + + while (num_dests > 0) + { + if (dests->is_default) + return (dests); + + num_dests --; + dests ++; + } + } + else + { + /* + * Lookup name and optionally the instance... + */ + + while (num_dests > 0) + { + if ((comp = strcasecmp(name, dests->name)) < 0) + return (NULL); + else if (comp == 0) + { + if ((instance == NULL && dests->instance == NULL) || + (instance != NULL && dests->instance != NULL && + strcasecmp(instance, dests->instance) == 0)) + return (dests); + } + + num_dests --; + dests ++; + } + } + + return (NULL); +} + + +/* + * 'cupsGetDests()' - Get the list of destinations. + */ + +int /* O - Number of destinations */ +cupsGetDests(cups_dest_t **dests) /* O - Destinations */ +{ + int i; /* Looping var */ + int num_dests; /* Number of destinations */ + int count; /* Number of printers/classes */ + char **names; /* Printer/class names */ + cups_dest_t *dest; /* Destination pointer */ + const char *home; /* HOME environment variable */ + char filename[1024]; /* Local ~/.lpoptions file */ + + + /* + * Initialize destination array... + */ + + num_dests = 0; + *dests = (cups_dest_t *)0; + + /* + * Grab all available printers... + */ + + if ((count = cupsGetPrinters(&names)) > 0) + { + for (i = 0; i < count; i ++) + { + num_dests = cupsAddDest(names[i], NULL, num_dests, dests); + free(names[i]); + } + + free(names); + } + + /* + * Grab all available classes... + */ + + if ((count = cupsGetClasses(&names)) > 0) + { + for (i = 0; i < count; i ++) + { + num_dests = cupsAddDest(names[i], NULL, num_dests, dests); + free(names[i]); + } + + free(names); + } + + /* + * Grab the default destination... + */ + + if ((dest = cupsGetDest(cupsGetDefault(), NULL, num_dests, *dests)) != NULL) + dest->is_default = 1; + + /* + * Load the /etc/cups/lpoptions and ~/.lpoptions files... + */ + + if ((home = getenv("CUPS_SERVERROOT")) != NULL) + { + snprintf(filename, sizeof(filename), "%s/lpoptions", home); + num_dests = cups_get_dests(filename, num_dests, dests); + } + else + num_dests = cups_get_dests(CUPS_SERVERROOT "/lpoptions", num_dests, dests); + + if ((home = getenv("HOME")) != NULL) + { + snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + num_dests = cups_get_dests(filename, num_dests, dests); + } + + /* + * Return the number of destinations... + */ + + return (num_dests); +} + + +/* + * 'cupsSetDests()' - Set the list of destinations. + */ + +void +cupsSetDests(int num_dests, /* I - Number of destinations */ + cups_dest_t *dests) /* I - Destinations */ +{ + int i, j; /* Looping vars */ + cups_dest_t *dest; /* Current destination */ + cups_option_t *option; /* Current option */ + FILE *fp; /* File pointer */ + const char *home; /* HOME environment variable */ + char filename[1024]; /* lpoptions file */ + + + /* + * Figure out which file to write to... + */ + + if (getuid() == 0) + { + if ((home = getenv("CUPS_SERVERROOT")) != NULL) + snprintf(filename, sizeof(filename), "%s/lpoptions", home); + else + strcpy(filename, CUPS_SERVERROOT "/lpoptions"); + } + else if ((home = getenv("HOME")) != NULL) + snprintf(filename, sizeof(filename), "%s/.lpoptions", home); + else + return; + + /* + * Try to open the file... + */ + + if ((fp = fopen(filename, "w")) == NULL) + return; + + /* + * Write each printer; each line looks like: + * + * Dest name[/instance] options + * Default name[/instance] options + */ + + for (i = num_dests, dest = dests; i > 0; i --, dest ++) + if (dest->instance != NULL || dest->num_options != 0 || dest->is_default) + { + fprintf(fp, "%s %s", dest->is_default ? "Default" : "Dest", + dest->name); + if (dest->instance) + fprintf(fp, "/%s", dest->instance); + + for (j = dest->num_options, option = dest->options; j > 0; j --, option ++) + if (option->value[0]) + fprintf(fp, " %s=%s", option->name, option->value); + else + fprintf(fp, " %s", option->name); + + fputs("\n", fp); + } + + /* + * Close the file and return... + */ + + fclose(fp); +} + + +/* + * 'cups_get_dests()' - Get destinations from a file. + */ + +static int /* O - Number of destinations */ +cups_get_dests(const char *filename, /* I - File to read from */ + int num_dests, /* I - Number of destinations */ + cups_dest_t **dests) /* IO - Destinations */ +{ + int i; /* Looping var */ + cups_dest_t *dest; /* Current destination */ + FILE *fp; /* File pointer */ + char line[8192], /* Line from file */ + *lineptr, /* Pointer into line */ + *name, /* Name of destination/option */ + *instance; /* Instance of destination */ + + + /* + * Try to open the file... + */ + + if ((fp = fopen(filename, "r")) == NULL) + return (num_dests); + + /* + * Read each printer; each line looks like: + * + * Dest name[/instance] options + * Default name[/instance] options + */ + + while (fgets(line, sizeof(line), fp) != NULL) + { + /* + * See what type of line it is... + */ + + if (strncasecmp(line, "dest", 4) == 0 && isspace(line[4])) + lineptr = line + 4; + else if (strncasecmp(line, "default", 7) == 0 && isspace(line[7])) + lineptr = line + 7; + else + continue; + + /* + * Skip leading whitespace... + */ + + while (isspace(*lineptr)) + lineptr ++; + + if (!*lineptr) + continue; + + name = lineptr; + + /* + * Search for an instance... + */ + + while (!isspace(*lineptr) && *lineptr && *lineptr != '/') + lineptr ++; + + if (!*lineptr) + continue; + + if (*lineptr == '/') + { + /* + * Found an instance... + */ + + *lineptr++ = '\0'; + instance = lineptr; + + /* + * Search for an instance... + */ + + while (!isspace(*lineptr) && *lineptr) + lineptr ++; + } + else + instance = NULL; + + *lineptr++ = '\0'; + + /* + * Add the destination... + */ + + num_dests = cupsAddDest(name, instance, num_dests, dests); + + if ((dest = cupsGetDest(name, instance, num_dests, *dests)) == NULL) + { + /* + * Out of memory! + */ + + fclose(fp); + return (num_dests); + } + + /* + * Add options until we hit the end of the line... + */ + + if (dest->num_options) + { + /* + * Free old options... + */ + + cupsFreeOptions(dest->num_options, dest->options); + + dest->num_options = 0; + dest->options = (cups_option_t *)0; + } + + dest->num_options = cupsParseOptions(lineptr, dest->num_options, + &(dest->options)); + + /* + * Set this as default if needed... + */ + + if (strncasecmp(line, "default", 7) == 0) + { + for (i = 0; i < num_dests; i ++) + (*dests)[i].is_default = 0; + + dest->is_default = 1; + } + } + + /* + * Close the file and return... + */ + + fclose(fp); + + return (num_dests); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/emit.c b/cups/emit.c new file mode 100644 index 0000000000..f5873fbb72 --- /dev/null +++ b/cups/emit.c @@ -0,0 +1,305 @@ +/* + * "$Id$" + * + * PPD code emission routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * PostScript is a trademark of Adobe Systems, Inc. + * + * Contents: + * + * ppdEmit() - Emit code for marked options to a file. + * ppdEmitFd() - Emit code for marked options to a file. + */ + +/* + * Include necessary headers... + */ + +#include "ppd.h" +#include +#include "string.h" + +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * Local functions... + */ + +static int ppd_sort(ppd_choice_t **c1, ppd_choice_t **c2); +static int ppd_collect(ppd_file_t *ppd, ppd_section_t section, + ppd_choice_t ***choices); + + +/* + * 'ppdEmit()' - Emit code for marked options to a file. + */ + +int /* O - 0 on success, -1 on failure */ +ppdEmit(ppd_file_t *ppd, /* I - PPD file record */ + FILE *fp, /* I - File to write to */ + ppd_section_t section) /* I - Section to write */ +{ + int i, /* Looping var */ + count; /* Number of choices */ + ppd_choice_t **choices; /* Choices */ + ppd_size_t *size; /* Custom page size */ + + + if ((count = ppd_collect(ppd, section, &choices)) == 0) + return (0); + + for (i = 0; i < count; i ++) + if (section != PPD_ORDER_EXIT && section != PPD_ORDER_JCL) + { + /* + * Send DSC comments with option... + */ + + if (fprintf(fp, "%%%%BeginFeature: %s %s\n", + ((ppd_option_t *)choices[i]->option)->keyword, + choices[i]->choice) < 0) + { + free(choices); + return (-1); + } + + fputs("[{\n", fp); + + if (strcasecmp(((ppd_option_t *)choices[i]->option)->keyword, "PageSize") == 0 && + strcasecmp(choices[i]->choice, "Custom") == 0) + { + /* + * Variable size; write out standard size options (this should + * eventually be changed to use the parameter positions defined + * in the PPD file...) + */ + + size = ppdPageSize(ppd, "Custom"); + fprintf(fp, "%.0f %.0f 0 0 0\n", size->width, size->length); + + if (choices[i]->code == NULL) + { + /* + * This can happen with certain buggy PPD files that don't include + * a CustomPageSize command sequence... We just use a generic + * Level 2 command sequence... + */ + + fputs("pop pop pop\n", fp); + fputs("<>setpagedevice\n", fp); + } + } + + if (choices[i]->code != NULL && choices[i]->code[0] != '\0') + { + if (fputs(choices[i]->code, fp) < 0) + { + free(choices); + return (-1); + } + + if (choices[i]->code[strlen(choices[i]->code) - 1] != '\n') + putc('\n', fp); + } + + fputs("} stopped cleartomark\n", fp); + + if (fputs("%%EndFeature\n", fp) < 0) + { + free(choices); + return (-1); + } + } + else if (fputs(choices[i]->code, fp) < 0) + { + free(choices); + return (-1); + } + + free(choices); + return (0); +} + + +/* + * 'ppdEmitFd()' - Emit code for marked options to a file. + */ + +int /* O - 0 on success, -1 on failure */ +ppdEmitFd(ppd_file_t *ppd, /* I - PPD file record */ + int fd, /* I - File to write to */ + ppd_section_t section) /* I - Section to write */ +{ + int i, /* Looping var */ + count; /* Number of choices */ + ppd_choice_t **choices; /* Choices */ + char buf[1024]; /* Output buffer for feature */ + + + if ((count = ppd_collect(ppd, section, &choices)) == 0) + return (0); + + for (i = 0; i < count; i ++) + if (section != PPD_ORDER_EXIT && section != PPD_ORDER_JCL) + { + /* + * Send DSC comments with option... + */ + + sprintf(buf, "%%%%BeginFeature: %s %s\n", + ((ppd_option_t *)choices[i]->option)->keyword, choices[i]->choice); + + if (write(fd, buf, strlen(buf)) < 1) + { + free(choices); + return (-1); + } + + if (write(fd, choices[i]->code, strlen(choices[i]->code)) < 1) + { + free(choices); + return (-1); + } + + if (write(fd, "%%EndFeature\n", 13) < 1) + { + free(choices); + return (-1); + } + } + else if (write(fd, choices[i]->code, strlen(choices[i]->code)) < 1) + { + free(choices); + return (-1); + } + + free(choices); + return (0); +} + + +/* + * 'ppd_sort()' - Sort options by ordering numbers... + */ + +static int /* O - -1 if c1 < c2, 0 if equal, 1 otherwise */ +ppd_sort(ppd_choice_t **c1, /* I - First choice */ + ppd_choice_t **c2) /* I - Second choice */ +{ + if (((ppd_option_t *)(*c1)->option)->order < ((ppd_option_t *)(*c2)->option)->order) + return (-1); + else if (((ppd_option_t *)(*c1)->option)->order > ((ppd_option_t *)(*c2)->option)->order) + return (1); + else + return (0); +} + + +/* + * 'ppd_collect()' - Collect all marked options that reside in the specified + * section. + */ + +static int /* O - Number of options marked */ +ppd_collect(ppd_file_t *ppd, /* I - PPD file data */ + ppd_section_t section, /* I - Section to collect */ + ppd_choice_t ***choices) /* O - Pointers to choices */ +{ + int i, j, k, m; /* Looping vars */ + ppd_group_t *g, /* Current group */ + *sg; /* Current sub-group */ + ppd_option_t *o; /* Current option */ + ppd_choice_t *c; /* Current choice */ + int count; /* Number of choices collected */ + ppd_choice_t **collect; /* Collected choices */ + + + if (ppd == NULL) + return (0); + + /* + * Allocate memory for up to 1000 selected choices... + */ + + count = 0; + collect = calloc(sizeof(ppd_choice_t *), 1000); + + /* + * Loop through all options and add choices as needed... + */ + + for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) + { + for (j = g->num_options, o = g->options; j > 0; j --, o ++) + if (o->section == section) + for (k = o->num_choices, c = o->choices; k > 0; k --, c ++) + if (c->marked && count < 1000) + { + collect[count] = c; + count ++; + } + + for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++) + for (k = sg->num_options, o = sg->options; k > 0; k --, o ++) + if (o->section == section) + for (m = o->num_choices, c = o->choices; m > 0; m --, c ++) + if (c->marked && count < 1000) + { + collect[count] = c; + count ++; + } + } + + /* + * If we have more than 1 marked choice, sort them... + */ + + if (count > 1) + qsort(collect, count, sizeof(ppd_choice_t *), + (int (*)(const void *, const void *))ppd_sort); + + /* + * Return the array and number of choices; if 0, free the array since + * it isn't needed. + */ + + if (count > 0) + { + *choices = collect; + return (count); + } + else + { + *choices = NULL; + free(collect); + return (0); + } +} + + +/* + * End of "$Id$". + */ diff --git a/cups/http.c b/cups/http.c new file mode 100644 index 0000000000..5f1aa713ee --- /dev/null +++ b/cups/http.c @@ -0,0 +1,1665 @@ +/* + * "$Id$" + * + * HTTP routines for the Common UNIX Printing System (CUPS) scheduler. + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These statusd instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * httpInitialize() - Initialize the HTTP interface library and set the + * default HTTP proxy (if any). + * httpCheck() - Check to see if there is a pending response from + * the server. + * httpClose() - Close an HTTP connection... + * httpConnect() - Connect to a HTTP server. + * httpReconnect() - Reconnect to a HTTP server... + * httpSeparate() - Separate a Universal Resource Identifier into its + * components. + * httpSetField() - Set the value of an HTTP header. + * httpDelete() - Send a DELETE request to the server. + * httpGet() - Send a GET request to the server. + * httpHead() - Send a HEAD request to the server. + * httpOptions() - Send an OPTIONS request to the server. + * httpPost() - Send a POST request to the server. + * httpPut() - Send a PUT request to the server. + * httpTrace() - Send an TRACE request to the server. + * httpFlush() - Flush data from a HTTP connection. + * httpRead() - Read data from a HTTP connection. + * httpWrite() - Write data to a HTTP connection. + * httpGets() - Get a line of text from a HTTP connection. + * httpPrintf() - Print a formatted string to a HTTP connection. + * httpStatus() - Return a short string describing a HTTP status code. + * httpGetDateString() - Get a formatted date/time string from a time value. + * httpGetDateTime() - Get a time value from a formatted date/time string. + * httpUpdate() - Update the current HTTP state for incoming data. + * httpDecode64() - Base64-decode a string. + * httpEncode64() - Base64-encode a string. + * httpGetLength() - Get the amount of data remaining from the + * content-length or transfer-encoding fields. + * http_field() - Return the field index for a field name. + * http_send() - Send a request with all fields and the trailing + * blank line. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include "string.h" +#include +#include + +#include "http.h" +#include "ipp.h" +#include "debug.h" + +#if !defined(WIN32) && !defined(__EMX__) +# include +#endif /* !WIN32 && !__EMX__ */ + +/* + * Some operating systems have done away with the Fxxxx constants for + * the fcntl() call; this works around that "feature"... + */ + +#ifndef FNONBLK +# define FNONBLK O_NONBLOCK +#endif /* !FNONBLK */ + + +/* + * Local functions... + */ + +static http_field_t http_field(const char *name); +static int http_send(http_t *http, http_state_t request, + const char *uri); + + +/* + * Local globals... + */ + +static const char *http_fields[] = + { + "Accept-Language", + "Accept-Ranges", + "Authorization", + "Connection", + "Content-Encoding", + "Content-Language", + "Content-Length", + "Content-Location", + "Content-MD5", + "Content-Range", + "Content-Type", + "Content-Version", + "Date", + "Host", + "If-Modified-Since", + "If-Unmodified-since", + "Keep-Alive", + "Last-Modified", + "Link", + "Location", + "Range", + "Referer", + "Retry-After", + "Transfer-Encoding", + "Upgrade", + "User-Agent", + "WWW-Authenticate" + }; +static const char *days[7] = + { + "Sun", + "Mon", + "Tue", + "Wed", + "Thu", + "Fri", + "Sat" + }; +static const char *months[12] = + { + "Jan", + "Feb", + "Mar", + "Apr", + "May", + "Jun", + "Jul", + "Aug", + "Sep", + "Oct", + "Nov", + "Dec" + }; + + +/* + * 'httpInitialize()' - Initialize the HTTP interface library and set the + * default HTTP proxy (if any). + */ + +void +httpInitialize(void) +{ +#if defined(WIN32) || defined(__EMX__) + WSADATA winsockdata; /* WinSock data */ + static int initialized = 0;/* Has WinSock been initialized? */ + + + if (!initialized) + WSAStartup(MAKEWORD(1,1), &winsockdata); +#elif defined(HAVE_SIGSET) + sigset(SIGPIPE, SIG_IGN); +#elif defined(HAVE_SIGACTION) + struct sigaction action; /* POSIX sigaction data */ + + + /* + * Ignore SIGPIPE signals... + */ + + memset(&action, 0, sizeof(action)); + action.sa_handler = SIG_IGN; + sigaction(SIGPIPE, &action, NULL); +#else + signal(SIGPIPE, SIG_IGN); +#endif /* WIN32 || __EMX__ */ +} + + +/* + * 'httpCheck()' - Check to see if there is a pending response from the server. + */ + +int /* O - 0 = no data, 1 = data available */ +httpCheck(http_t *http) /* I - HTTP connection */ +{ + fd_set input; /* Input set for select() */ + struct timeval timeout; /* Timeout */ + + + /* + * First see if there is data in the buffer... + */ + + if (http == NULL) + return (0); + + if (http->used) + return (1); + + /* + * Then try doing a select() to poll the socket... + */ + + FD_ZERO(&input); + FD_SET(http->fd, &input); + + timeout.tv_sec = 0; + timeout.tv_usec = 0; + + return (select(http->fd + 1, &input, NULL, NULL, &timeout) > 0); +} + + +/* + * 'httpClose()' - Close an HTTP connection... + */ + +void +httpClose(http_t *http) /* I - Connection to close */ +{ + if (http == NULL) + return; + +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif /* WIN32 */ + + free(http); +} + + +/* + * 'httpConnect()' - Connect to a HTTP server. + */ + +http_t * /* O - New HTTP connection */ +httpConnect(const char *host, /* I - Host to connect to */ + int port) /* I - Port number */ +{ + http_t *http; /* New HTTP connection */ + struct hostent *hostaddr; /* Host address data */ + + + if (host == NULL) + return (NULL); + + httpInitialize(); + + /* + * Lookup the host... + */ + + if ((hostaddr = gethostbyname(host)) == NULL) + return (NULL); + + /* + * Allocate memory for the structure... + */ + + http = calloc(sizeof(http_t), 1); + if (http == NULL) + return (NULL); + + http->version = HTTP_1_1; + http->blocking = 1; + http->activity = time(NULL); + + /* + * Copy the hostname and port and then "reconnect"... + */ + + strncpy(http->hostname, host, sizeof(http->hostname) - 1); + memcpy((char *)&(http->hostaddr.sin_addr), hostaddr->h_addr, hostaddr->h_length); + http->hostaddr.sin_family = hostaddr->h_addrtype; +#ifdef WIN32 + http->hostaddr.sin_port = htons((u_short)port); +#else + http->hostaddr.sin_port = htons(port); +#endif /* WIN32 */ + if (httpReconnect(http)) + { + free(http); + return (NULL); + } + else + return (http); +} + + +/* + * 'httpReconnect()' - Reconnect to a HTTP server... + */ + +int /* O - 0 on success, non-zero on failure */ +httpReconnect(http_t *http) /* I - HTTP data */ +{ + int val; /* Socket option value */ + + + /* + * Close any previously open socket... + */ + + if (http->fd) +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif /* WIN32 */ + + /* + * Create the socket and set options to allow reuse. + */ + + if ((http->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) + { +#if defined(WIN32) || defined(__EMX__) + http->error = WSAGetLastError(); +#else + http->error = errno; +#endif /* WIN32 || __EMX__ */ + http->status = HTTP_ERROR; + return (-1); + } + +#ifdef FD_CLOEXEC + fcntl(http->fd, F_SETFD, FD_CLOEXEC); /* Close this socket when starting * + * other processes... */ +#endif /* FD_CLOEXEC */ + + val = 1; + setsockopt(http->fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val)); + +#ifdef SO_REUSEPORT + val = 1; + setsockopt(http->fd, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val)); +#endif /* SO_REUSEPORT */ + + /* + * Connect to the server... + */ + + if (connect(http->fd, (struct sockaddr *)&(http->hostaddr), + sizeof(http->hostaddr)) < 0) + { +#if defined(WIN32) || defined(__EMX__) + http->error = WSAGetLastError(); +#else + http->error = errno; +#endif /* WIN32 || __EMX__ */ + http->status = HTTP_ERROR; + +#ifdef WIN32 + closesocket(http->fd); +#else + close(http->fd); +#endif + + return (-1); + } + + http->error = 0; + http->status = HTTP_CONTINUE; + + return (0); +} + + +/* + * 'httpSeparate()' - Separate a Universal Resource Identifier into its + * components. + */ + +void +httpSeparate(const char *uri, /* I - Universal Resource Identifier */ + char *method, /* O - Method [32] (http, https, etc.) */ + char *username, /* O - Username [32] */ + char *host, /* O - Hostname [32] */ + int *port, /* O - Port number to use */ + char *resource) /* O - Resource/filename [1024] */ +{ + char *ptr; /* Pointer into string... */ + + + if (uri == NULL || method == NULL || username == NULL || host == NULL || + port == NULL || resource == NULL) + return; + + /* + * Grab the method portion of the URI... + */ + + if (strncmp(uri, "//", 2) == 0) + { + /* + * Workaround for HP IPP client bug... + */ + + strcpy(method, "ipp"); + } + else + { + /* + * Standard URI with method... + */ + + ptr = host; + while (*uri != ':' && *uri != '\0') + *ptr++ = *uri++; + + *ptr = '\0'; + if (*uri == ':') + uri ++; + + /* + * If the method contains a period or slash, then it's probably + * hostname/filename... + */ + + if (strchr(host, '.') != NULL || strchr(host, '/') != NULL || *uri == '\0') + { + if ((ptr = strchr(host, '/')) != NULL) + { + strncpy(resource, ptr, HTTP_MAX_URI - 1); + resource[HTTP_MAX_URI - 1] = '\0'; + *ptr = '\0'; + } + else + resource[0] = '\0'; + + if (isdigit(*uri)) + { + /* + * OK, we have "hostname:port[/resource]"... + */ + + *port = strtol(uri, (char **)&uri, 10); + + if (*uri == '/') + { + strncpy(resource, uri, HTTP_MAX_URI - 1); + resource[HTTP_MAX_URI - 1] = '\0'; + } + } + else + *port = 631; + + strcpy(method, "http"); + username[0] = '\0'; + return; + } + else + { + strncpy(method, host, 31); + method[31] = '\0'; + } + } + + /* + * If the method starts with less than 2 slashes then it is a local resource... + */ + + if (strncmp(uri, "//", 2) != 0) + { + strncpy(resource, uri, 1023); + resource[1023] = '\0'; + + username[0] = '\0'; + host[0] = '\0'; + *port = 0; + return; + } + + /* + * Grab the hostname... + */ + + while (*uri == '/') + uri ++; + + ptr = host; + while (!(*uri == ':' && isdigit(uri[1])) && *uri != '@' && *uri != '/' && *uri != '\0') + *ptr ++ = *uri ++; + + *ptr = '\0'; + + if (*uri == '@') + { + /* + * Got a username... + */ + + strncpy(username, host, 31); + username[31] = '\0'; + + ptr = host; + uri ++; + while (*uri != ':' && *uri != '/' && *uri != '\0') + *ptr ++ = *uri ++; + + *ptr = '\0'; + } + else + username[0] = '\0'; + + if (*uri != ':') + { + if (strcasecmp(method, "http") == 0) + *port = 80; + else if (strcasecmp(method, "https") == 0) + *port = 443; + else if (strcasecmp(method, "ipp") == 0) /* Not registered yet... */ + *port = ippPort(); + else if (strcasecmp(method, "socket") == 0) /* Not registered yet... */ + *port = 9100; + else + *port = 0; + } + else + { + /* + * Parse port number... + */ + + *port = 0; + uri ++; + while (isdigit(*uri)) + { + *port = (*port * 10) + *uri - '0'; + uri ++; + } + } + + if (*uri == '\0') + { + /* + * Hostname but no port or path... + */ + + resource[0] = '/'; + resource[1] = '\0'; + return; + } + + /* + * The remaining portion is the resource string... + */ + + strncpy(resource, uri, HTTP_MAX_URI - 1); + resource[HTTP_MAX_URI - 1] = '\0'; +} + + +/* + * 'httpGetSubField()' - Get a sub-field value. + */ + +char * /* O - Value or NULL */ +httpGetSubField(http_t *http, /* I - HTTP data */ + http_field_t field, /* I - Field index */ + const char *name, /* I - Name of sub-field */ + char *value) /* O - Value string */ +{ + const char *fptr; /* Pointer into field */ + char temp[HTTP_MAX_VALUE], /* Temporary buffer for name */ + *ptr; /* Pointer into string buffer */ + + + if (http == NULL || + field < HTTP_FIELD_ACCEPT_LANGUAGE || + field > HTTP_FIELD_WWW_AUTHENTICATE || + name == NULL || value == NULL) + return (NULL); + + for (fptr = http->fields[field]; *fptr;) + { + /* + * Skip leading whitespace... + */ + + while (isspace(*fptr)); + fptr ++; + + if (*fptr == ',') + { + fptr ++; + continue; + } + + /* + * Get the sub-field name... + */ + + for (ptr = temp; + *fptr && *fptr != '=' && !isspace(*fptr) && ptr < (temp + sizeof(temp) - 1); + *ptr++ = *fptr++); + + *ptr = '\0'; + + /* + * Skip trailing chars up to the '='... + */ + + while (*fptr && *fptr != '=') + fptr ++; + + if (!*fptr) + break; + + /* + * Skip = and leading whitespace... + */ + + fptr ++; + + while (isspace(*fptr)); + fptr ++; + + if (*fptr == '\"') + { + /* + * Read quoted string... + */ + + for (ptr = value, fptr ++; + *fptr && *fptr != '\"' && ptr < (value + HTTP_MAX_VALUE - 1); + *ptr++ = *fptr++); + + *ptr = '\0'; + + while (*fptr && *fptr != '\"') + fptr ++; + + if (*fptr) + fptr ++; + } + else + { + /* + * Read unquoted string... + */ + + for (ptr = value; + *fptr && !isspace(*fptr) && *fptr != ',' && ptr < (value + HTTP_MAX_VALUE - 1); + *ptr++ = *fptr++); + + *ptr = '\0'; + + while (*fptr && !isspace(*fptr) && *fptr != ',') + fptr ++; + } + + /* + * See if this is the one... + */ + + if (strcmp(name, temp) == 0) + return (value); + } + + value[0] = '\0'; + + return (NULL); +} + + +/* + * 'httpSetField()' - Set the value of an HTTP header. + */ + +void +httpSetField(http_t *http, /* I - HTTP data */ + http_field_t field, /* I - Field index */ + const char *value) /* I - Value */ +{ + if (http == NULL || + field < HTTP_FIELD_ACCEPT_LANGUAGE || + field > HTTP_FIELD_WWW_AUTHENTICATE || + value == NULL) + return; + + strncpy(http->fields[field], value, HTTP_MAX_VALUE - 1); + http->fields[field][HTTP_MAX_VALUE - 1] = '\0'; +} + + +/* + * 'httpDelete()' - Send a DELETE request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpDelete(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI to delete */ +{ + return (http_send(http, HTTP_DELETE, uri)); +} + + +/* + * 'httpGet()' - Send a GET request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpGet(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI to get */ +{ + return (http_send(http, HTTP_GET, uri)); +} + + +/* + * 'httpHead()' - Send a HEAD request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpHead(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI for head */ +{ + return (http_send(http, HTTP_HEAD, uri)); +} + + +/* + * 'httpOptions()' - Send an OPTIONS request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpOptions(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI for options */ +{ + return (http_send(http, HTTP_OPTIONS, uri)); +} + + +/* + * 'httpPost()' - Send a POST request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpPost(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI for post */ +{ + httpGetLength(http); + + return (http_send(http, HTTP_POST, uri)); +} + + +/* + * 'httpPut()' - Send a PUT request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpPut(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI to put */ +{ + httpGetLength(http); + + return (http_send(http, HTTP_PUT, uri)); +} + + +/* + * 'httpTrace()' - Send an TRACE request to the server. + */ + +int /* O - Status of call (0 = success) */ +httpTrace(http_t *http, /* I - HTTP data */ + const char *uri) /* I - URI for trace */ +{ + return (http_send(http, HTTP_TRACE, uri)); +} + + +/* + * 'httpFlush()' - Flush data from a HTTP connection. + */ + +void +httpFlush(http_t *http) /* I - HTTP data */ +{ + char buffer[8192]; /* Junk buffer */ + + + while (httpRead(http, buffer, sizeof(buffer)) > 0); +} + + +/* + * 'httpRead()' - Read data from a HTTP connection. + */ + +int /* O - Number of bytes read */ +httpRead(http_t *http, /* I - HTTP data */ + char *buffer, /* I - Buffer for data */ + int length) /* I - Maximum number of bytes */ +{ + int bytes; /* Bytes read */ + char len[32]; /* Length string */ + + + DEBUG_printf(("httpRead(%08x, %08x, %d)\n", http, buffer, length)); + + if (http == NULL || buffer == NULL) + return (-1); + + http->activity = time(NULL); + + if (length <= 0) + return (0); + + if (http->data_encoding == HTTP_ENCODE_CHUNKED && + http->data_remaining <= 0) + { + DEBUG_puts("httpRead: Getting chunk length..."); + + if (httpGets(len, sizeof(len), http) == NULL) + { + DEBUG_puts("httpRead: Could not get length!"); + return (0); + } + + http->data_remaining = strtol(len, NULL, 16); + } + + DEBUG_printf(("httpRead: data_remaining = %d\n", http->data_remaining)); + + if (http->data_remaining == 0) + { + /* + * A zero-length chunk ends a transfer; unless we are reading POST + * data, go idle... + */ + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + httpGets(len, sizeof(len), http); + + if (http->state == HTTP_POST_RECV) + http->state ++; + else + http->state = HTTP_WAITING; + + return (0); + } + else if (length > http->data_remaining) + length = http->data_remaining; + + if (http->used > 0) + { + if (length > http->used) + length = http->used; + + bytes = length; + + DEBUG_printf(("httpRead: grabbing %d bytes from input buffer...\n", bytes)); + + memcpy(buffer, http->buffer, length); + http->used -= length; + + if (http->used > 0) + memcpy(http->buffer, http->buffer + length, http->used); + } + else + { + DEBUG_printf(("httpRead: reading %d bytes from socket...\n", length)); + bytes = recv(http->fd, buffer, length, 0); + DEBUG_printf(("httpRead: read %d bytes from socket...\n", bytes)); + } + + if (bytes > 0) + http->data_remaining -= bytes; + else if (bytes < 0) +#if defined(WIN32) || defined(__EMX__) + http->error = WSAGetLastError(); +#else + http->error = errno; +#endif /* WIN32 || __EMX__ */ + + if (http->data_remaining == 0) + { + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + httpGets(len, sizeof(len), http); + + if (http->data_encoding != HTTP_ENCODE_CHUNKED) + { + if (http->state == HTTP_POST_RECV) + http->state ++; + else + http->state = HTTP_WAITING; + } + } + + return (bytes); +} + + +/* + * 'httpWrite()' - Write data to a HTTP connection. + */ + +int /* O - Number of bytes written */ +httpWrite(http_t *http, /* I - HTTP data */ + const char *buffer, /* I - Buffer for data */ + int length) /* I - Number of bytes to write */ +{ + int tbytes, /* Total bytes sent */ + bytes; /* Bytes sent */ + + + if (http == NULL || buffer == NULL) + return (-1); + + http->activity = time(NULL); + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + { + if (httpPrintf(http, "%x\r\n", length) < 0) + return (-1); + + if (length == 0) + { + /* + * A zero-length chunk ends a transfer; unless we are sending POST + * data, go idle... + */ + + DEBUG_puts("httpWrite: changing states..."); + + if (http->state == HTTP_POST_RECV) + http->state ++; + else + http->state = HTTP_WAITING; + + if (httpPrintf(http, "\r\n") < 0) + return (-1); + + return (0); + } + } + + tbytes = 0; + + while (length > 0) + { + bytes = send(http->fd, buffer, length, 0); + if (bytes < 0) + { + DEBUG_puts("httpWrite: error writing data...\n"); + + return (-1); + } + + buffer += bytes; + tbytes += bytes; + length -= bytes; + if (http->data_encoding == HTTP_ENCODE_LENGTH) + http->data_remaining -= bytes; + } + + if (http->data_encoding == HTTP_ENCODE_CHUNKED) + if (httpPrintf(http, "\r\n") < 0) + return (-1); + + if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODE_LENGTH) + { + /* + * Finished with the transfer; unless we are sending POST data, go idle... + */ + + DEBUG_puts("httpWrite: changing states..."); + + if (http->state == HTTP_POST_RECV) + http->state ++; + else + http->state = HTTP_WAITING; + } + + DEBUG_printf(("httpWrite: wrote %d bytes...\n", tbytes)); + + return (tbytes); +} + + +/* + * 'httpGets()' - Get a line of text from a HTTP connection. + */ + +char * /* O - Line or NULL */ +httpGets(char *line, /* I - Line to read into */ + int length, /* I - Max length of buffer */ + http_t *http) /* I - HTTP data */ +{ + char *lineptr, /* Pointer into line */ + *bufptr, /* Pointer into input buffer */ + *bufend; /* Pointer to end of buffer */ + int bytes; /* Number of bytes read */ + + + DEBUG_printf(("httpGets(%08x, %d, %08x)\n", line, length, http)); + + if (http == NULL || line == NULL) + return (NULL); + + /* + * Pre-scan the buffer and see if there is a newline in there... + */ + +#if defined(WIN32) || defined(__EMX__) + WSASetLastError(0); +#else + errno = 0; +#endif /* WIN32 || __EMX__ */ + + do + { + bufptr = http->buffer; + bufend = http->buffer + http->used; + + while (bufptr < bufend) + if (*bufptr == 0x0a) + break; + else + bufptr ++; + + if (bufptr >= bufend) + { + /* + * No newline; see if there is more data to be read... + */ + + if ((bytes = recv(http->fd, bufend, HTTP_MAX_BUFFER - http->used, 0)) < 0) + { + /* + * Nope, can't get a line this time... + */ + +#if defined(WIN32) || defined(__EMX__) + if (WSAGetLastError() != http->error) + { + http->error = WSAGetLastError(); + continue; + } + + DEBUG_printf(("httpGets(): recv() error %d!\n", WSAGetLastError())); +#else + if (errno != http->error) + { + http->error = errno; + continue; + } + + DEBUG_printf(("httpGets(): recv() error %d!\n", errno)); +#endif /* WIN32 || __EMX__ */ + + return (NULL); + } + else if (bytes == 0) + { + if (http->blocking) + http->error = EPIPE; + + return (NULL); + } + + /* + * Yup, update the amount used and the end pointer... + */ + + http->used += bytes; + bufend += bytes; + } + } + while (bufptr >= bufend); + + http->activity = time(NULL); + + /* + * Read a line from the buffer... + */ + + lineptr = line; + bufptr = http->buffer; + bytes = 0; + + while (bufptr < bufend && bytes < length) + { + bytes ++; + + if (*bufptr == 0x0a) + { + bufptr ++; + *lineptr = '\0'; + + http->used -= bytes; + if (http->used > 0) + memcpy(http->buffer, bufptr, http->used); + + DEBUG_printf(("httpGets(): Returning \"%s\"\n", line)); + return (line); + } + else if (*bufptr == 0x0d) + bufptr ++; + else + *lineptr++ = *bufptr++; + } + + DEBUG_puts("httpGets(): No new line available!"); + + return (NULL); +} + + +/* + * 'httpPrintf()' - Print a formatted string to a HTTP connection. + */ + +int /* O - Number of bytes written */ +httpPrintf(http_t *http, /* I - HTTP data */ + const char *format, /* I - printf-style format string */ + ...) /* I - Additional args as needed */ +{ + int bytes, /* Number of bytes to write */ + nbytes, /* Number of bytes written */ + tbytes; /* Number of bytes all together */ + char buf[HTTP_MAX_BUFFER], /* Buffer for formatted string */ + *bufptr; /* Pointer into buffer */ + va_list ap; /* Variable argument pointer */ + + + va_start(ap, format); + bytes = vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + DEBUG_printf(("httpPrintf: %s", buf)); + + for (tbytes = 0, bufptr = buf; tbytes < bytes; tbytes += nbytes, bufptr += nbytes) + if ((nbytes = send(http->fd, bufptr, bytes - tbytes, 0)) < 0) + return (-1); + + return (bytes); +} + + +/* + * 'httpStatus()' - Return a short string describing a HTTP status code. + */ + +const char * /* O - String or NULL */ +httpStatus(http_status_t status) /* I - HTTP status code */ +{ + switch (status) + { + case HTTP_OK : + return ("OK"); + case HTTP_CREATED : + return ("Created"); + case HTTP_ACCEPTED : + return ("Accepted"); + case HTTP_NO_CONTENT : + return ("No Content"); + case HTTP_NOT_MODIFIED : + return ("Not Modified"); + case HTTP_BAD_REQUEST : + return ("Bad Request"); + case HTTP_UNAUTHORIZED : + return ("Unauthorized"); + case HTTP_FORBIDDEN : + return ("Forbidden"); + case HTTP_NOT_FOUND : + return ("Not Found"); + case HTTP_REQUEST_TOO_LARGE : + return ("Request Entity Too Large"); + case HTTP_URI_TOO_LONG : + return ("URI Too Long"); + case HTTP_NOT_IMPLEMENTED : + return ("Not Implemented"); + case HTTP_NOT_SUPPORTED : + return ("Not Supported"); + default : + return ("Unknown"); + } +} + + +/* + * 'httpGetDateString()' - Get a formatted date/time string from a time value. + */ + +const char * /* O - Date/time string */ +httpGetDateString(time_t t) /* I - UNIX time */ +{ + struct tm *tdate; + static char datetime[256]; + + + tdate = gmtime(&t); + sprintf(datetime, "%s, %02d %s %d %02d:%02d:%02d GMT", + days[tdate->tm_wday], tdate->tm_mday, months[tdate->tm_mon], + tdate->tm_year + 1900, tdate->tm_hour, tdate->tm_min, tdate->tm_sec); + + return (datetime); +} + + +/* + * 'httpGetDateTime()' - Get a time value from a formatted date/time string. + */ + +time_t /* O - UNIX time */ +httpGetDateTime(const char *s) /* I - Date/time string */ +{ + int i; /* Looping var */ + struct tm tdate; /* Time/date structure */ + char mon[16]; /* Abbreviated month name */ + int day, year; /* Day of month and year */ + int hour, min, sec; /* Time */ + + + if (sscanf(s, "%*s%d%15s%d%d:%d:%d", &day, mon, &year, &hour, &min, &sec) < 6) + return (0); + + for (i = 0; i < 12; i ++) + if (strcasecmp(mon, months[i]) == 0) + break; + + if (i >= 12) + return (0); + + tdate.tm_mon = i; + tdate.tm_mday = day; + tdate.tm_year = year - 1900; + tdate.tm_hour = hour; + tdate.tm_min = min; + tdate.tm_sec = sec; + tdate.tm_isdst = 0; + + return (mktime(&tdate)); +} + + +/* + * 'httpUpdate()' - Update the current HTTP state for incoming data. + */ + +http_status_t /* O - HTTP status */ +httpUpdate(http_t *http) /* I - HTTP data */ +{ + char line[1024], /* Line from connection... */ + *value; /* Pointer to value on line */ + http_field_t field; /* Field index */ + int major, minor; /* HTTP version numbers */ + http_status_t status; /* Authorization status */ + + + DEBUG_printf(("httpUpdate(%08x)\n", http)); + + /* + * If we haven't issued any commands, then there is nothing to "update"... + */ + + if (http->state == HTTP_WAITING) + return (HTTP_CONTINUE); + + /* + * Grab all of the lines we can from the connection... + */ + + while (httpGets(line, sizeof(line), http) != NULL) + { + DEBUG_puts(line); + + if (line[0] == '\0') + { + /* + * Blank line means the start of the data section (if any). Return + * the result code, too... + * + * If we get status 100 (HTTP_CONTINUE), then we *don't* change states. + * Instead, we just return HTTP_CONTINUE to the caller and keep on + * tryin'... + */ + + if (http->status == HTTP_CONTINUE) + return (http->status); + + httpGetLength(http); + + switch (http->state) + { + case HTTP_GET : + case HTTP_POST : + case HTTP_POST_RECV : + case HTTP_PUT : + http->state ++; + break; + + default : + http->state = HTTP_WAITING; + break; + } + + return (http->status); + } + else if (strncmp(line, "HTTP/", 5) == 0) + { + /* + * Got the beginning of a response... + */ + + if (sscanf(line, "HTTP/%d.%d%d", &major, &minor, (int *)&status) != 3) + return (HTTP_ERROR); + + http->version = (http_version_t)(major * 100 + minor); + http->status = status; + } + else if ((value = strchr(line, ':')) != NULL) + { + /* + * Got a value... + */ + + *value++ = '\0'; + while (isspace(*value)) + value ++; + + /* + * Be tolerants of servers that send unknown attribute fields... + */ + + if ((field = http_field(line)) == HTTP_FIELD_UNKNOWN) + { + DEBUG_printf(("httpUpdate: unknown field %s seen!\n", line)); + continue; + } + + httpSetField(http, field, value); + } + else + { + http->status = HTTP_ERROR; + return (HTTP_ERROR); + } + } + + /* + * See if there was an error... + */ + + if (http->error) + { + http->status = HTTP_ERROR; + return (HTTP_ERROR); + } + + /* + * If we haven't already returned, then there is nothing new... + */ + + return (HTTP_CONTINUE); +} + + +/* + * 'httpDecode64()' - Base64-decode a string. + */ + +char * /* O - Decoded string */ +httpDecode64(char *out, /* I - String to write to */ + const char *in) /* I - String to read from */ +{ + int pos, /* Bit position */ + base64; /* Value of this character */ + char *outptr; /* Output pointer */ + + + for (outptr = out, pos = 0; *in != '\0'; in ++) + { + /* + * Decode this character into a number from 0 to 63... + */ + + if (*in >= 'A' && *in <= 'Z') + base64 = *in - 'A'; + else if (*in >= 'a' && *in <= 'z') + base64 = *in - 'a' + 26; + else if (*in >= '0' && *in <= '9') + base64 = *in - '0' + 52; + else if (*in == '+') + base64 = 62; + else if (*in == '/') + base64 = 63; + else if (*in == '=') + break; + else + continue; + + /* + * Store the result in the appropriate chars... + */ + + switch (pos) + { + case 0 : + *outptr = base64 << 2; + pos ++; + break; + case 1 : + *outptr++ |= (base64 >> 4) & 3; + *outptr = (base64 << 4) & 255; + pos ++; + break; + case 2 : + *outptr++ |= (base64 >> 2) & 15; + *outptr = (base64 << 6) & 255; + pos ++; + break; + case 3 : + *outptr++ |= base64; + pos = 0; + break; + } + } + + *outptr = '\0'; + + /* + * Return the decoded string... + */ + + return (out); +} + + +/* + * 'httpEncode64()' - Base64-encode a string. + */ + +char * /* O - Encoded string */ +httpEncode64(char *out, /* I - String to write to */ + const char *in) /* I - String to read from */ +{ + char *outptr; /* Output pointer */ + static char base64[] = /* Base64 characters... */ + { + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789" + "+/" + }; + + + for (outptr = out; *in != '\0'; in ++) + { + /* + * Encode the up to 3 characters as 4 Base64 numbers... + */ + + *outptr ++ = base64[in[0] >> 2]; + *outptr ++ = base64[((in[0] << 4) | (in[1] >> 4)) & 63]; + + in ++; + if (*in == '\0') + { + *outptr ++ = '='; + break; + } + + *outptr ++ = base64[((in[0] << 2) | (in[1] >> 6)) & 63]; + + in ++; + if (*in == '\0') + break; + + *outptr ++ = base64[in[0] & 63]; + } + + *outptr ++ = '='; + *outptr = '\0'; + + /* + * Return the encoded string... + */ + + return (out); +} + + +/* + * 'httpGetLength()' - Get the amount of data remaining from the + * content-length or transfer-encoding fields. + */ + +int /* O - Content length */ +httpGetLength(http_t *http) /* I - HTTP data */ +{ + DEBUG_printf(("httpGetLength(%08x)\n", http)); + + if (strcasecmp(http->fields[HTTP_FIELD_TRANSFER_ENCODING], "chunked") == 0) + { + DEBUG_puts("httpGetLength: chunked request!"); + + http->data_encoding = HTTP_ENCODE_CHUNKED; + http->data_remaining = 0; + } + else + { + http->data_encoding = HTTP_ENCODE_LENGTH; + + /* + * The following is a hack for HTTP servers that don't send a + * content-length or transfer-encoding field... + * + * If there is no content-length then the connection must close + * after the transfer is complete... + */ + + if (http->fields[HTTP_FIELD_CONTENT_LENGTH][0] == '\0') + http->data_remaining = 2147483647; + else + http->data_remaining = atoi(http->fields[HTTP_FIELD_CONTENT_LENGTH]); + + DEBUG_printf(("httpGetLength: content_length = %d\n", http->data_remaining)); + } + + return (http->data_remaining); +} + + +/* + * 'http_field()' - Return the field index for a field name. + */ + +static http_field_t /* O - Field index */ +http_field(const char *name) /* I - String name */ +{ + int i; /* Looping var */ + + + for (i = 0; i < HTTP_FIELD_MAX; i ++) + if (strcasecmp(name, http_fields[i]) == 0) + return ((http_field_t)i); + + return (HTTP_FIELD_UNKNOWN); +} + + +/* + * 'http_send()' - Send a request with all fields and the trailing blank line. + */ + +static int /* O - 0 on success, non-zero on error */ +http_send(http_t *http, /* I - HTTP data */ + http_state_t request, /* I - Request code */ + const char *uri) /* I - URI */ +{ + int i; /* Looping var */ + char *ptr, /* Pointer in buffer */ + buf[1024]; /* Encoded URI buffer */ + static const char *codes[] = /* Request code strings */ + { + NULL, + "OPTIONS", + "GET", + NULL, + "HEAD", + "POST", + NULL, + NULL, + "PUT", + NULL, + "DELETE", + "TRACE", + "CLOSE" + }; + static const char *hex = "0123456789ABCDEF"; + /* Hex digits */ + + + if (http == NULL || uri == NULL) + return (-1); + + /* + * Encode the URI as needed... + */ + + for (ptr = buf; *uri != '\0'; uri ++) + if (*uri <= ' ' || *uri >= 127) + { + *ptr ++ = '%'; + *ptr ++ = hex[(*uri >> 4) & 15]; + *ptr ++ = hex[*uri & 15]; + } + else + *ptr ++ = *uri; + + *ptr = '\0'; + + /* + * See if we had an error the last time around; if so, reconnect... + */ + + if (http->status == HTTP_ERROR || http->status >= HTTP_BAD_REQUEST) + httpReconnect(http); + + /* + * Send the request header... + */ + + http->state = request; + if (request == HTTP_POST || request == HTTP_PUT) + http->state ++; + + http->status = HTTP_CONTINUE; + + if (httpPrintf(http, "%s %s HTTP/1.1\r\n", codes[request], buf) < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + + for (i = 0; i < HTTP_FIELD_MAX; i ++) + if (http->fields[i][0] != '\0') + { + DEBUG_printf(("%s: %s\n", http_fields[i], http->fields[i])); + + if (httpPrintf(http, "%s: %s\r\n", http_fields[i], http->fields[i]) < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + } + + if (httpPrintf(http, "\r\n") < 1) + { + http->status = HTTP_ERROR; + return (-1); + } + + httpClearFields(http); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/http.h b/cups/http.h new file mode 100644 index 0000000000..c67ef32e69 --- /dev/null +++ b/cups/http.h @@ -0,0 +1,325 @@ +/* + * "$Id$" + * + * Hyper-Text Transport Protocol definitions for the Common UNIX Printing + * System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +#ifndef _CUPS_HTTP_H_ +# define _CUPS_HTTP_H_ + +/* + * Include necessary headers... + */ + +# include +# include +# if defined(WIN32) || defined(__EMX__) +# include +# else +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# endif /* WIN32 || __EMX__ */ + +# include + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Limits... + */ + +# define HTTP_MAX_URI 1024 /* Max length of URI string */ +# define HTTP_MAX_HOST 256 /* Max length of hostname string */ +# define HTTP_MAX_BUFFER 2048 /* Max length of data buffer */ +# define HTTP_MAX_VALUE 256 /* Max header field value length */ + + +/* + * HTTP state values... + */ + +typedef enum /* States are server-oriented */ +{ + HTTP_WAITING, /* Waiting for command */ + HTTP_OPTIONS, /* OPTIONS command, waiting for blank line */ + HTTP_GET, /* GET command, waiting for blank line */ + HTTP_GET_SEND, /* GET command, sending data */ + HTTP_HEAD, /* HEAD command, waiting for blank line */ + HTTP_POST, /* POST command, waiting for blank line */ + HTTP_POST_RECV, /* POST command, receiving data */ + HTTP_POST_SEND, /* POST command, sending data */ + HTTP_PUT, /* PUT command, waiting for blank line */ + HTTP_PUT_RECV, /* PUT command, receiving data */ + HTTP_DELETE, /* DELETE command, waiting for blank line */ + HTTP_TRACE, /* TRACE command, waiting for blank line */ + HTTP_CLOSE, /* CLOSE command, waiting for blank line */ + HTTP_STATUS /* Command complete, sending status */ +} http_state_t; + + +/* + * HTTP version numbers... + */ + +typedef enum +{ + HTTP_0_9 = 9, /* HTTP/0.9 */ + HTTP_1_0 = 100, /* HTTP/1.0 */ + HTTP_1_1 = 101 /* HTTP/1.1 */ +} http_version_t; + + +/* + * HTTP keep-alive values... + */ + +typedef enum +{ + HTTP_KEEPALIVE_OFF = 0, + HTTP_KEEPALIVE_ON +} http_keepalive_t; + + +/* + * HTTP transfer encoding values... + */ + +typedef enum +{ + HTTP_ENCODE_LENGTH, /* Data is sent with Content-Length */ + HTTP_ENCODE_CHUNKED /* Data is chunked */ +} http_encoding_t; + + +/* + * HTTP authentication types... + */ + +typedef enum +{ + HTTP_AUTH_NONE, /* No authentication in use */ + HTTP_AUTH_BASIC, /* Basic authentication in use */ + HTTP_AUTH_MD5, /* Digest authentication in use */ + HTTP_AUTH_MD5_SESS, /* MD5-session authentication in use */ + HTTP_AUTH_MD5_INT, /* Digest authentication in use for body */ + HTTP_AUTH_MD5_SESS_INT /* MD5-session authentication in use for body */ +} http_auth_t; + + +/* + * HTTP status codes... + */ + +typedef enum +{ + HTTP_ERROR = -1, /* An error response from httpXxxx() */ + + HTTP_CONTINUE = 100, /* Everything OK, keep going... */ + + HTTP_OK = 200, /* OPTIONS/GET/HEAD/POST/TRACE command was successful */ + HTTP_CREATED, /* PUT command was successful */ + HTTP_ACCEPTED, /* DELETE command was successful */ + HTTP_NOT_AUTHORITATIVE, /* Information isn't authoritative */ + HTTP_NO_CONTENT, /* Successful command, no new data */ + HTTP_RESET_CONTENT, /* Content was reset/recreated */ + HTTP_PARTIAL_CONTENT, /* Only a partial file was recieved/sent */ + + HTTP_MULTIPLE_CHOICES = 300, /* Multiple files match request */ + HTTP_MOVED_PERMANENTLY, /* Document has moved permanently */ + HTTP_MOVED_TEMPORARILY, /* Document has moved temporarily */ + HTTP_SEE_OTHER, /* See this other link... */ + HTTP_NOT_MODIFIED, /* File not modified */ + HTTP_USE_PROXY, /* Must use a proxy to access this URI */ + + HTTP_BAD_REQUEST = 400, /* Bad request */ + HTTP_UNAUTHORIZED, /* Unauthorized to access host */ + HTTP_PAYMENT_REQUIRED, /* Payment required */ + HTTP_FORBIDDEN, /* Forbidden to access this URI */ + HTTP_NOT_FOUND, /* URI was not found */ + HTTP_METHOD_NOT_ALLOWED, /* Method is not allowed */ + HTTP_NOT_ACCEPTABLE, /* Not Acceptable */ + HTTP_PROXY_AUTHENTICATION, /* Proxy Authentication is Required */ + HTTP_REQUEST_TIMEOUT, /* Request timed out */ + HTTP_CONFLICT, /* Request is self-conflicting */ + HTTP_GONE, /* Server has gone away */ + HTTP_LENGTH_REQUIRED, /* A content length or encoding is required */ + HTTP_PRECONDITION, /* Precondition failed */ + HTTP_REQUEST_TOO_LARGE, /* Request entity too large */ + HTTP_URI_TOO_LONG, /* URI too long */ + HTTP_UNSUPPORTED_MEDIATYPE, /* The requested media type is unsupported */ + + HTTP_SERVER_ERROR = 500, /* Internal server error */ + HTTP_NOT_IMPLEMENTED, /* Feature not implemented */ + HTTP_BAD_GATEWAY, /* Bad gateway */ + HTTP_SERVICE_UNAVAILABLE, /* Service is unavailable */ + HTTP_GATEWAY_TIMEOUT, /* Gateway connection timed out */ + HTTP_NOT_SUPPORTED /* HTTP version not supported */ +} http_status_t; + + +/* + * HTTP field names... + */ + +typedef enum +{ + HTTP_FIELD_UNKNOWN = -1, + HTTP_FIELD_ACCEPT_LANGUAGE, + HTTP_FIELD_ACCEPT_RANGES, + HTTP_FIELD_AUTHORIZATION, + HTTP_FIELD_CONNECTION, + HTTP_FIELD_CONTENT_ENCODING, + HTTP_FIELD_CONTENT_LANGUAGE, + HTTP_FIELD_CONTENT_LENGTH, + HTTP_FIELD_CONTENT_LOCATION, + HTTP_FIELD_CONTENT_MD5, + HTTP_FIELD_CONTENT_RANGE, + HTTP_FIELD_CONTENT_TYPE, + HTTP_FIELD_CONTENT_VERSION, + HTTP_FIELD_DATE, + HTTP_FIELD_HOST, + HTTP_FIELD_IF_MODIFIED_SINCE, + HTTP_FIELD_IF_UNMODIFIED_SINCE, + HTTP_FIELD_KEEP_ALIVE, + HTTP_FIELD_LAST_MODIFIED, + HTTP_FIELD_LINK, + HTTP_FIELD_LOCATION, + HTTP_FIELD_RANGE, + HTTP_FIELD_REFERER, + HTTP_FIELD_RETRY_AFTER, + HTTP_FIELD_TRANSFER_ENCODING, + HTTP_FIELD_UPGRADE, + HTTP_FIELD_USER_AGENT, + HTTP_FIELD_WWW_AUTHENTICATE, + HTTP_FIELD_MAX +} http_field_t; + + +/* + * HTTP connection structure... + */ + +typedef struct +{ + int fd; /* File descriptor for this socket */ + int blocking; /* To block or not to block */ + int error; /* Last error on read */ + time_t activity; /* Time since last read/write */ + http_state_t state; /* State of client */ + http_status_t status; /* Status of last request */ + http_version_t version; /* Protocol version */ + http_keepalive_t keep_alive; /* Keep-alive supported? */ + struct sockaddr_in hostaddr; /* Address of connected host */ + char hostname[HTTP_MAX_HOST], + /* Name of connected host */ + fields[HTTP_FIELD_MAX][HTTP_MAX_VALUE]; + /* Field values */ + char *data; /* Pointer to data buffer */ + http_encoding_t data_encoding; /* Chunked or not */ + int data_remaining; /* Number of bytes left */ + int used; /* Number of bytes used in buffer */ + char buffer[HTTP_MAX_BUFFER]; + /* Buffer for messages */ + int auth_type; /* Authentication in use */ + md5_state_t md5_state; /* MD5 state */ + char nonce[HTTP_MAX_VALUE]; + /* Nonce value */ + int nonce_count; /* Nonce count */ + void *tls; /* TLS state information */ +} http_t; + + +/* + * Prototypes... + */ + +# define httpBlocking(http,b) (http)->blocking = (b) +extern int httpCheck(http_t *http); +# define httpClearFields(http) memset((http)->fields, 0, sizeof((http)->fields)),\ + httpSetField((http), HTTP_FIELD_HOST, (http)->hostname) +extern void httpClose(http_t *http); +extern http_t *httpConnect(const char *host, int port); +extern int httpDelete(http_t *http, const char *uri); +# define httpError(http) ((http)->error) +extern void httpFlush(http_t *http); +extern int httpGet(http_t *http, const char *uri); +extern char *httpGets(char *line, int length, http_t *http); +extern const char *httpGetDateString(time_t t); +extern time_t httpGetDateTime(const char *s); +# define httpGetField(http,field) (http)->fields[field] +extern char *httpGetSubField(http_t *http, http_field_t field, + const char *name, char *value); +extern int httpHead(http_t *http, const char *uri); +extern void httpInitialize(void); +extern int httpOptions(http_t *http, const char *uri); +extern int httpPost(http_t *http, const char *uri); +extern int httpPrintf(http_t *http, const char *format, ...); +extern int httpPut(http_t *http, const char *uri); +extern int httpRead(http_t *http, char *buffer, int length); +extern int httpReconnect(http_t *http); +extern void httpSeparate(const char *uri, char *method, + char *username, char *host, int *port, + char *resource); +extern void httpSetField(http_t *http, http_field_t field, + const char *value); +extern const char *httpStatus(http_status_t status); +extern int httpTrace(http_t *http, const char *uri); +extern http_status_t httpUpdate(http_t *http); +extern int httpWrite(http_t *http, const char *buffer, int length); +extern char *httpEncode64(char *out, const char *in); +extern char *httpDecode64(char *out, const char *in); +extern int httpGetLength(http_t *http); +extern char *httpMD5(const char *, const char *, const char *, + char [33]); +extern char *httpMD5Final(const char *, const char *, const char *, + char [33]); +extern char *httpMD5String(const md5_byte_t *, char [33]); + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_HTTP_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/ipp.c b/cups/ipp.c new file mode 100644 index 0000000000..03f329fbfa --- /dev/null +++ b/cups/ipp.c @@ -0,0 +1,1701 @@ +/* + * "$Id$" + * + * Internet Printing Protocol support functions for the Common UNIX + * Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ippAddBoolean() - Add a boolean attribute to an IPP request. + * ippAddBooleans() - Add an array of boolean values. + * ippAddDate() - Add a date attribute to an IPP request. + * ippAddInteger() - Add a integer attribute to an IPP request. + * ippAddIntegers() - Add an array of integer values. + * ippAddString() - Add a language-encoded string to an IPP request. + * ippAddStrings() - Add language-encoded strings to an IPP request. + * ippAddRange() - Add a range of values to an IPP request. + * ippAddRanges() - Add ranges of values to an IPP request. + * ippAddResolution() - Add a resolution value to an IPP request. + * ippAddResolutions() - Add resolution values to an IPP request. + * ippAddSeparator() - Add a group separator to an IPP request. + * ippDateToTime() - Convert from RFC 1903 Date/Time format to UNIX time + * ippDelete() - Delete an IPP request. + * ippErrorString() - Return a textual message for the given error message. + * ippFindAttribute() - Find a named attribute in a request... + * ippLength() - Compute the length of an IPP request. + * ippNew() - Allocate a new IPP request. + * ippPort() - Return the default IPP port number. + * ippRead() - Read data for an IPP request. + * ippTimeToDate() - Convert from UNIX time to RFC 1903 format. + * ippWrite() - Write data for an IPP request. + * _ipp_add_attr() - Add a new attribute to the request. + * _ipp_free_attr() - Free an attribute. + * ipp_read() - Semi-blocking read on a HTTP connection... + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include "string.h" +#include "language.h" + +#include "ipp.h" +#include "debug.h" +#include + + +/* + * Local functions... + */ + +static int ipp_read(http_t *http, unsigned char *buffer, int length); + + +/* + * 'ippAddBoolean()' - Add a boolean attribute to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddBoolean(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + char value) /* I - Value of attribute */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + DEBUG_printf(("ippAddBoolean(%08x, %02x, \'%s\', %d)\n", ipp, group, name, value)); + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, 1)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_BOOLEAN; + attr->values[0].boolean = value; + + return (attr); +} + + +/* + * 'ippAddBooleans()' - Add an array of boolean values. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddBooleans(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + int num_values, /* I - Number of values */ + const char *values) /* I - Values */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* New attribute */ + + + DEBUG_printf(("ippAddBooleans(%08x, %02x, \'%s\', %d, %08x)\n", ipp, + group, name, num_values, values)); + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_BOOLEAN; + + if (values != NULL) + for (i = 0; i < num_values; i ++) + attr->values[i].boolean = values[i]; + + return (attr); +} + + +/* + * 'ippAddDate()' - Add a date attribute to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddDate(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + const ipp_uchar_t *value) /* I - Value */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + DEBUG_printf(("ippAddDate(%08x, %02x, \'%s\', %08x)\n", ipp, group, name, + value)); + + if (ipp == NULL || name == NULL || value == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, 1)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_DATE; + memcpy(attr->values[0].date, value, 11); + + return (attr); +} + + +/* + * 'ippAddInteger()' - Add a integer attribute to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddInteger(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + ipp_tag_t type, /* I - Type of attribute */ + const char *name, /* I - Name of attribute */ + int value) /* I - Value of attribute */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + DEBUG_printf(("ippAddInteger(%08x, %d, \'%s\', %d)\n", ipp, group, name, + value)); + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, 1)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = type; + attr->values[0].integer = value; + + return (attr); +} + + +/* + * 'ippAddIntegers()' - Add an array of integer values. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddIntegers(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + ipp_tag_t type, /* I - Type of attribute */ + const char *name, /* I - Name of attribute */ + int num_values, /* I - Number of values */ + const int *values) /* I - Values */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* New attribute */ + + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = type; + + if (values != NULL) + for (i = 0; i < num_values; i ++) + attr->values[i].integer = values[i]; + + return (attr); +} + + +/* + * 'ippAddString()' - Add a language-encoded string to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddString(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + ipp_tag_t type, /* I - Type of attribute */ + const char *name, /* I - Name of attribute */ + const char *charset, /* I - Character set */ + const char *value) /* I - Value */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, 1)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = type; + attr->values[0].string.charset = charset ? strdup(charset) : NULL; + attr->values[0].string.text = strdup(value); + + if (type == IPP_TAG_LANGUAGE || type == IPP_TAG_CHARSET) + { + /* + * Convert to lowercase and change _ to - as needed... + */ + + char *p; + + + for (p = attr->values[0].string.text; *p; p ++) + if (*p == '_') + *p = '-'; + else + *p = tolower(*p); + } + + return (attr); +} + + +/* + * 'ippAddStrings()' - Add language-encoded strings to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddStrings(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + ipp_tag_t type, /* I - Type of attribute */ + const char *name, /* I - Name of attribute */ + int num_values, /* I - Number of values */ + const char *charset, /* I - Character set */ + const char **values) /* I - Values */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* New attribute */ + + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = type; + + if (values != NULL) + for (i = 0; i < num_values; i ++) + { + if (i == 0) + attr->values[0].string.charset = charset ? strdup(charset) : NULL; + else + attr->values[i].string.charset = attr->values[0].string.charset; + + attr->values[i].string.text = strdup(values[i]); + } + + return (attr); +} + + +/* + * 'ippAddRange()' - Add a range of values to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddRange(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + int lower, /* I - Lower value */ + int upper) /* I - Upper value */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, 1)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_RANGE; + attr->values[0].range.lower = lower; + attr->values[0].range.upper = upper; + + return (attr); +} + + +/* + * 'ippAddRanges()' - Add ranges of values to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddRanges(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + int num_values, /* I - Number of values */ + const int *lower, /* I - Lower values */ + const int *upper) /* I - Upper values */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* New attribute */ + + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_RANGE; + + if (lower != NULL && upper != NULL) + for (i = 0; i < num_values; i ++) + { + attr->values[i].range.lower = lower[i]; + attr->values[i].range.upper = upper[i]; + } + + return (attr); +} + + +/* + * 'ippAddResolution()' - Add a resolution value to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddResolution(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + ipp_res_t units, /* I - Units for resolution */ + int xres, /* I - X resolution */ + int yres) /* I - Y resolution */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, 1)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_RESOLUTION; + attr->values[0].resolution.xres = xres; + attr->values[0].resolution.yres = yres; + attr->values[0].resolution.units = units; + + return (attr); +} + + +/* + * 'ippAddResolutions()' - Add resolution values to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddResolutions(ipp_t *ipp, /* I - IPP request */ + ipp_tag_t group, /* I - IPP group */ + const char *name, /* I - Name of attribute */ + int num_values,/* I - Number of values */ + ipp_res_t units, /* I - Units for resolution */ + const int *xres, /* I - X resolutions */ + const int *yres) /* I - Y resolutions */ +{ + int i; /* Looping var */ + ipp_attribute_t *attr; /* New attribute */ + + + if (ipp == NULL || name == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, num_values)) == NULL) + return (NULL); + + attr->name = strdup(name); + attr->group_tag = group; + attr->value_tag = IPP_TAG_RESOLUTION; + + if (xres != NULL && yres != NULL) + for (i = 0; i < num_values; i ++) + { + attr->values[i].resolution.xres = xres[i]; + attr->values[i].resolution.yres = yres[i]; + attr->values[i].resolution.units = units; + } + + return (attr); +} + + +/* + * 'ippAddSeparator()' - Add a group separator to an IPP request. + */ + +ipp_attribute_t * /* O - New attribute */ +ippAddSeparator(ipp_t *ipp) /* I - IPP request */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + DEBUG_printf(("ippAddSeparator(%08x)\n", ipp)); + + if (ipp == NULL) + return (NULL); + + if ((attr = _ipp_add_attr(ipp, 0)) == NULL) + return (NULL); + + attr->group_tag = IPP_TAG_ZERO; + attr->value_tag = IPP_TAG_ZERO; + + return (attr); +} + + +/* + * 'ippDateToTime()' - Convert from RFC 1903 Date/Time format to UNIX time + * in seconds. + */ + +time_t /* O - UNIX time value */ +ippDateToTime(const ipp_uchar_t *date) /* I - RFC 1903 date info */ +{ + struct tm unixdate; /* UNIX date/time info */ + time_t t; /* Computed time */ + + + memset(&unixdate, 0, sizeof(unixdate)); + + /* + * RFC-1903 date/time format is: + * + * Byte(s) Description + * ------- ----------- + * 0-1 Year (0 to 65535) + * 2 Month (1 to 12) + * 3 Day (1 to 31) + * 4 Hours (0 to 23) + * 5 Minutes (0 to 59) + * 6 Seconds (0 to 60, 60 = "leap second") + * 7 Deciseconds (0 to 9) + * 8 +/- UTC + * 9 UTC hours (0 to 11) + * 10 UTC minutes (0 to 59) + */ + + unixdate.tm_year = ((date[0] << 8) | date[1]) - 1900; + unixdate.tm_mon = date[2] - 1; + unixdate.tm_mday = date[3]; + unixdate.tm_hour = date[4]; + unixdate.tm_min = date[5]; + unixdate.tm_sec = date[6]; + + t = mktime(&unixdate); + + if (date[8] == '-') + t += date[9] * 3600 + date[10] * 60; + else + t -= date[9] * 3600 + date[10] * 60; + + return (t); +} + + +/* + * 'ippDelete()' - Delete an IPP request. + */ + +void +ippDelete(ipp_t *ipp) /* I - IPP request */ +{ + ipp_attribute_t *attr, /* Current attribute */ + *next; /* Next attribute */ + + + if (ipp == NULL) + return; + + for (attr = ipp->attrs; attr != NULL; attr = next) + { + next = attr->next; + _ipp_free_attr(attr); + } + + free(ipp); +} + + +/* + * 'ippErrorString()' - Return a textual message for the given error message. + */ + +const char * /* O - Text string */ +ippErrorString(ipp_status_t error) /* I - Error status */ +{ + static cups_lang_t *language = 0; /* Language info */ + + + /* + * Load the localized message file as needed... + */ + + if (!language) + language = cupsLangDefault(); + + /* + * Return the appropriate message... + */ + + switch (error) + { + case IPP_OK : + case IPP_OK_SUBST : + case IPP_OK_CONFLICT : + return ("OK"); + + case IPP_BAD_REQUEST : + return (cupsLangString(language, HTTP_BAD_REQUEST)); + + case IPP_FORBIDDEN : + return (cupsLangString(language, HTTP_FORBIDDEN)); + + case IPP_NOT_AUTHENTICATED : + case IPP_NOT_AUTHORIZED : + return (cupsLangString(language, HTTP_UNAUTHORIZED)); + + case IPP_NOT_POSSIBLE : + return (cupsLangString(language, HTTP_METHOD_NOT_ALLOWED)); + + case IPP_TIMEOUT : + return (cupsLangString(language, HTTP_REQUEST_TIMEOUT)); + + case IPP_NOT_FOUND : + return (cupsLangString(language, HTTP_NOT_FOUND)); + + case IPP_GONE : + return (cupsLangString(language, HTTP_GONE)); + + case IPP_DOCUMENT_FORMAT : + return (cupsLangString(language, HTTP_UNSUPPORTED_MEDIATYPE)); + + case IPP_CONFLICT : + return (cupsLangString(language, HTTP_CONFLICT)); + + case IPP_INTERNAL_ERROR : + return (cupsLangString(language, HTTP_SERVER_ERROR)); + + case IPP_OPERATION_NOT_SUPPORTED : + case IPP_VERSION_NOT_SUPPORTED : + return (cupsLangString(language, HTTP_NOT_SUPPORTED)); + + case IPP_SERVICE_UNAVAILABLE : + case IPP_DEVICE_ERROR : + case IPP_TEMPORARY_ERROR : + case IPP_PRINTER_BUSY : + return (cupsLangString(language, HTTP_SERVICE_UNAVAILABLE)); + + case IPP_NOT_ACCEPTING : + return (cupsLangString(language, CUPS_MSG_NOT_ACCEPTING_JOBS)); + + default : + return ("ERROR"); + } + +} + + +/* + * 'ippFindAttribute()' - Find a named attribute in a request... + */ + +ipp_attribute_t * /* O - Matching attribute */ +ippFindAttribute(ipp_t *ipp, /* I - IPP request */ + const char *name, /* I - Name of attribute */ + ipp_tag_t type) /* I - Type of attribute */ +{ + ipp_attribute_t *attr; /* Current atttribute */ + + + DEBUG_printf(("ippFindAttribute(%08x, \'%s\')\n", ipp, name)); + + if (ipp == NULL || name == NULL) + return (NULL); + + for (attr = ipp->attrs; attr != NULL; attr = attr->next) + { + DEBUG_printf(("ippFindAttribute: attr = %08x, name = \'%s\'\n", attr, + attr->name)); + + if (attr->name != NULL && strcasecmp(attr->name, name) == 0 && + (attr->value_tag == type || type == IPP_TAG_ZERO || + (attr->value_tag == IPP_TAG_TEXTLANG && type == IPP_TAG_TEXT) || + (attr->value_tag == IPP_TAG_NAMELANG && type == IPP_TAG_NAME))) + return (attr); + } + + return (NULL); +} + + +/* + * 'ippLength()' - Compute the length of an IPP request. + */ + +size_t /* O - Size of IPP request */ +ippLength(ipp_t *ipp) /* I - IPP request */ +{ + int i; /* Looping var */ + int bytes; /* Number of bytes */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_tag_t group; /* Current group */ + + + if (ipp == NULL) + return (0); + + /* + * Start with 8 bytes for the IPP request or status header... + */ + + bytes = 8; + + /* + * Then add the lengths of each attribute... + */ + + group = IPP_TAG_ZERO; + + for (attr = ipp->attrs; attr != NULL; attr = attr->next) + { + if (attr->group_tag != group) + { + group = attr->group_tag; + if (group == IPP_TAG_ZERO) + continue; + + bytes ++; /* Group tag */ + } + + DEBUG_printf(("attr->name = %s, attr->num_values = %d, bytes = %d\n", + attr->name, attr->num_values, bytes)); + + bytes += strlen(attr->name); /* Name */ + bytes += attr->num_values; /* Value tag for each value */ + bytes += 2 * attr->num_values; /* Name lengths */ + bytes += 2 * attr->num_values; /* Value lengths */ + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + bytes += 4 * attr->num_values; + break; + + case IPP_TAG_BOOLEAN : + bytes += attr->num_values; + break; + + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_STRING : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + for (i = 0; i < attr->num_values; i ++) + bytes += strlen(attr->values[i].string.text); + break; + + case IPP_TAG_DATE : + bytes += 11 * attr->num_values; + break; + + case IPP_TAG_RESOLUTION : + bytes += 9 * attr->num_values; + break; + + case IPP_TAG_RANGE : + bytes += 8 * attr->num_values; + break; + + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + bytes += 4 * attr->num_values;/* Charset + text length */ + for (i = 0; i < attr->num_values; i ++) + bytes += strlen(attr->values[i].string.charset) + + strlen(attr->values[i].string.text); + break; + + default : + for (i = 0; i < attr->num_values; i ++) + bytes += attr->values[0].unknown.length; + break; + } + } + + /* + * Finally, add 1 byte for the "end of attributes" tag and return... + */ + + DEBUG_printf(("bytes = %d\n", bytes + 1)); + + return (bytes + 1); +} + + +/* + * 'ippNew()' - Allocate a new IPP request. + */ + +ipp_t * /* O - New IPP request */ +ippNew(void) +{ + ipp_t *temp; /* New IPP request */ + + + if ((temp = (ipp_t *)calloc(sizeof(ipp_t), 1)) != NULL) + { + /* + * Default to IPP 1.1... + */ + + temp->request.any.version[0] = 1; + temp->request.any.version[1] = 1; + } + + return (temp); +} + + +/* + * 'ippRead()' - Read data for an IPP request. + */ + +ipp_state_t /* O - Current state */ +ippRead(http_t *http, /* I - HTTP data */ + ipp_t *ipp) /* I - IPP data */ +{ + int n; /* Length of data */ + unsigned char buffer[8192], /* Data buffer */ + *bufptr; /* Pointer into buffer */ + ipp_attribute_t *attr; /* Current attribute */ + ipp_tag_t tag; /* Current tag */ + + + DEBUG_printf(("ippRead(%08x, %08x)\n", http, ipp)); + + if (http == NULL || ipp == NULL) + return (IPP_ERROR); + + switch (ipp->state) + { + case IPP_IDLE : + ipp->state ++; /* Avoid common problem... */ + + case IPP_HEADER : + /* + * Get the request header... + */ + + if ((n = ipp_read(http, buffer, 8)) < 8) + { + DEBUG_printf(("ippRead: Unable to read header (%d bytes read)!\n", n)); + return (n == 0 ? IPP_IDLE : IPP_ERROR); + } + + /* + * Verify the major version number... + */ + + if (buffer[0] != 1) + { + DEBUG_printf(("ippRead: version number (%d.%d) is bad.\n", buffer[0], + buffer[1])); + return (IPP_ERROR); + } + + /* + * Then copy the request header over... + */ + + ipp->request.any.version[0] = buffer[0]; + ipp->request.any.version[1] = buffer[1]; + ipp->request.any.op_status = (buffer[2] << 8) | buffer[3]; + ipp->request.any.request_id = (((((buffer[4] << 8) | buffer[5]) << 8) | + buffer[6]) << 8) | buffer[7]; + + ipp->state = IPP_ATTRIBUTE; + ipp->current = NULL; + ipp->curtag = IPP_TAG_ZERO; + + /* + * If blocking is disabled, stop here... + */ + + if (!http->blocking && http->used == 0) + break; + + case IPP_ATTRIBUTE : + while (ipp_read(http, buffer, 1) > 0) + { + /* + * Read this attribute... + */ + + tag = (ipp_tag_t)buffer[0]; + + if (tag == IPP_TAG_END) + { + /* + * No more attributes left... + */ + + DEBUG_puts("ippRead: IPP_TAG_END!"); + + ipp->state = IPP_DATA; + break; + } + else if (tag < IPP_TAG_UNSUPPORTED_VALUE) + { + /* + * Group tag... Set the current group and continue... + */ + + if (ipp->curtag == tag) + ippAddSeparator(ipp); + + ipp->curtag = tag; + ipp->current = NULL; + DEBUG_printf(("ippRead: group tag = %x\n", tag)); + continue; + } + + DEBUG_printf(("ippRead: value tag = %x\n", tag)); + + /* + * Get the name... + */ + + if (ipp_read(http, buffer, 2) < 2) + { + DEBUG_puts("ippRead: unable to read name length!"); + return (IPP_ERROR); + } + + n = (buffer[0] << 8) | buffer[1]; + + DEBUG_printf(("ippRead: name length = %d\n", n)); + + if (n == 0) + { + /* + * More values for current attribute... + */ + + if (ipp->current == NULL) + return (IPP_ERROR); + + attr = ipp->current; + + if (attr->num_values >= IPP_MAX_VALUES) + return (IPP_ERROR); + } + else + { + /* + * New attribute; read the name and add it... + */ + + if (ipp_read(http, buffer, n) < n) + { + DEBUG_puts("ippRead: unable to read name!"); + return (IPP_ERROR); + } + + buffer[n] = '\0'; + DEBUG_printf(("ippRead: name = \'%s\'\n", buffer)); + + attr = ipp->current = _ipp_add_attr(ipp, IPP_MAX_VALUES); + + attr->group_tag = ipp->curtag; + attr->value_tag = tag; + attr->name = strdup((char *)buffer); + attr->num_values = 0; + } + + if (ipp_read(http, buffer, 2) < 2) + { + DEBUG_puts("ippRead: unable to read value length!"); + return (IPP_ERROR); + } + + n = (buffer[0] << 8) | buffer[1]; + DEBUG_printf(("ippRead: value length = %d\n", n)); + + switch (tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + if (ipp_read(http, buffer, 4) < 4) + return (IPP_ERROR); + + n = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | + buffer[3]; + + attr->values[attr->num_values].integer = n; + break; + case IPP_TAG_BOOLEAN : + if (ipp_read(http, buffer, 1) < 1) + return (IPP_ERROR); + + attr->values[attr->num_values].boolean = buffer[0]; + break; + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_STRING : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + if (ipp_read(http, buffer, n) < n) + return (IPP_ERROR); + + buffer[n] = '\0'; + DEBUG_printf(("ippRead: value = \'%s\'\n", buffer)); + + attr->values[attr->num_values].string.text = strdup((char *)buffer); + break; + case IPP_TAG_DATE : + if (ipp_read(http, buffer, 11) < 11) + return (IPP_ERROR); + + memcpy(attr->values[attr->num_values].date, buffer, 11); + break; + case IPP_TAG_RESOLUTION : + if (ipp_read(http, buffer, 9) < 9) + return (IPP_ERROR); + + attr->values[attr->num_values].resolution.xres = + (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | + buffer[3]; + attr->values[attr->num_values].resolution.yres = + (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) | + buffer[7]; + attr->values[attr->num_values].resolution.units = + (ipp_res_t)buffer[8]; + break; + case IPP_TAG_RANGE : + if (ipp_read(http, buffer, 8) < 8) + return (IPP_ERROR); + + attr->values[attr->num_values].range.lower = + (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) | + buffer[3]; + attr->values[attr->num_values].range.upper = + (((((buffer[4] << 8) | buffer[5]) << 8) | buffer[6]) << 8) | + buffer[7]; + break; + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + if (ipp_read(http, buffer, n) < n) + return (IPP_ERROR); + + bufptr = buffer; + + /* + * text-with-language and name-with-language are composite + * values: + * + * charset-length + * charset + * text-length + * text + */ + + n = (bufptr[0] << 8) | bufptr[1]; + + attr->values[attr->num_values].string.charset = calloc(n + 1, 1); + + memcpy(attr->values[attr->num_values].string.charset, + bufptr + 2, n); + + bufptr += 2 + n; + n = (bufptr[0] << 8) | bufptr[1]; + + attr->values[attr->num_values].string.text = calloc(n + 1, 1); + + memcpy(attr->values[attr->num_values].string.text, + bufptr + 2, n); + + break; + + default : /* Other unsupported values */ + attr->values[attr->num_values].unknown.length = n; + if (n > 0) + { + attr->values[attr->num_values].unknown.data = malloc(n); + if (ipp_read(http, attr->values[attr->num_values].unknown.data, n) < n) + return (IPP_ERROR); + } + else + attr->values[attr->num_values].unknown.data = NULL; + break; + } + + attr->num_values ++; + + /* + * If blocking is disabled, stop here... + */ + + if (!http->blocking && http->used == 0) + break; + } + break; + + case IPP_DATA : + break; + + default : + break; /* anti-compiler-warning-code */ + } + + return (ipp->state); +} + + +/* + * 'ippTimeToDate()' - Convert from UNIX time to RFC 1903 format. + */ + +const ipp_uchar_t * /* O - RFC-1903 date/time data */ +ippTimeToDate(time_t t) /* I - UNIX time value */ +{ + struct tm *unixdate; /* UNIX unixdate/time info */ + static ipp_uchar_t date[11]; /* RFC-1903 date/time data */ + + + /* + * RFC-1903 date/time format is: + * + * Byte(s) Description + * ------- ----------- + * 0-1 Year (0 to 65535) + * 2 Month (1 to 12) + * 3 Day (1 to 31) + * 4 Hours (0 to 23) + * 5 Minutes (0 to 59) + * 6 Seconds (0 to 60, 60 = "leap second") + * 7 Deciseconds (0 to 9) + * 8 +/- UTC + * 9 UTC hours (0 to 11) + * 10 UTC minutes (0 to 59) + */ + + unixdate = gmtime(&t); + unixdate->tm_year += 1900; + + date[0] = unixdate->tm_year >> 8; + date[1] = unixdate->tm_year; + date[2] = unixdate->tm_mon + 1; + date[3] = unixdate->tm_mday; + date[4] = unixdate->tm_hour; + date[5] = unixdate->tm_min; + date[6] = unixdate->tm_sec; + date[7] = 0; + date[8] = '+'; + date[9] = 0; + date[10] = 0; + + return (date); +} + + +/* + * 'ippWrite()' - Write data for an IPP request. + */ + +ipp_state_t /* O - Current state */ +ippWrite(http_t *http, /* I - HTTP data */ + ipp_t *ipp) /* I - IPP data */ +{ + int i; /* Looping var */ + int n; /* Length of data */ + unsigned char buffer[8192], /* Data buffer */ + *bufptr; /* Pointer into buffer */ + ipp_attribute_t *attr; /* Current attribute */ + + + if (http == NULL || ipp == NULL) + return (IPP_ERROR); + + switch (ipp->state) + { + case IPP_IDLE : + ipp->state ++; /* Avoid common problem... */ + + case IPP_HEADER : + /* + * Send the request header... + */ + + bufptr = buffer; + + *bufptr++ = ipp->request.any.version[0]; + *bufptr++ = ipp->request.any.version[1]; + *bufptr++ = ipp->request.any.op_status >> 8; + *bufptr++ = ipp->request.any.op_status; + *bufptr++ = ipp->request.any.request_id >> 24; + *bufptr++ = ipp->request.any.request_id >> 16; + *bufptr++ = ipp->request.any.request_id >> 8; + *bufptr++ = ipp->request.any.request_id; + + if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP header..."); + return (IPP_ERROR); + } + + ipp->state = IPP_ATTRIBUTE; + ipp->current = ipp->attrs; + ipp->curtag = IPP_TAG_ZERO; + + /* + * If blocking is disabled, stop here... + */ + + if (!http->blocking) + break; + + case IPP_ATTRIBUTE : + while (ipp->current != NULL) + { + /* + * Write this attribute... + */ + + bufptr = buffer; + attr = ipp->current; + + ipp->current = ipp->current->next; + + if (ipp->curtag != attr->group_tag) + { + /* + * Send a group operation tag... + */ + + ipp->curtag = attr->group_tag; + + if (attr->group_tag == IPP_TAG_ZERO) + continue; + + DEBUG_printf(("ippWrite: wrote group tag = %x\n", attr->group_tag)); + *bufptr++ = attr->group_tag; + } + + n = strlen(attr->name); + + DEBUG_printf(("ippWrite: writing value tag = %x\n", attr->value_tag)); + DEBUG_printf(("ippWrite: writing name = %d, \'%s\'\n", n, attr->name)); + + *bufptr++ = attr->value_tag; + *bufptr++ = n >> 8; + *bufptr++ = n; + memcpy(bufptr, attr->name, n); + bufptr += n; + + switch (attr->value_tag) + { + case IPP_TAG_INTEGER : + case IPP_TAG_ENUM : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 4; + *bufptr++ = attr->values[i].integer >> 24; + *bufptr++ = attr->values[i].integer >> 16; + *bufptr++ = attr->values[i].integer >> 8; + *bufptr++ = attr->values[i].integer; + } + break; + + case IPP_TAG_BOOLEAN : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 1; + *bufptr++ = attr->values[i].boolean; + } + break; + + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_STRING : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + DEBUG_printf(("ippWrite: writing value tag = %x\n", + attr->value_tag)); + DEBUG_printf(("ippWrite: writing name = 0, \'\'\n")); + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + n = strlen(attr->values[i].string.text); + + DEBUG_printf(("ippWrite: writing string = %d, \'%s\'\n", n, + attr->values[i].string.text)); + + if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2)) + { + if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + *bufptr++ = n >> 8; + *bufptr++ = n; + memcpy(bufptr, attr->values[i].string.text, n); + bufptr += n; + } + break; + + case IPP_TAG_DATE : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 11; + memcpy(bufptr, attr->values[i].date, 11); + bufptr += 11; + } + break; + + case IPP_TAG_RESOLUTION : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 9; + *bufptr++ = attr->values[i].resolution.xres >> 24; + *bufptr++ = attr->values[i].resolution.xres >> 16; + *bufptr++ = attr->values[i].resolution.xres >> 8; + *bufptr++ = attr->values[i].resolution.xres; + *bufptr++ = attr->values[i].resolution.yres >> 24; + *bufptr++ = attr->values[i].resolution.yres >> 16; + *bufptr++ = attr->values[i].resolution.yres >> 8; + *bufptr++ = attr->values[i].resolution.yres; + *bufptr++ = attr->values[i].resolution.units; + } + break; + + case IPP_TAG_RANGE : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + *bufptr++ = 0; + *bufptr++ = 8; + *bufptr++ = attr->values[i].range.lower >> 24; + *bufptr++ = attr->values[i].range.lower >> 16; + *bufptr++ = attr->values[i].range.lower >> 8; + *bufptr++ = attr->values[i].range.lower; + *bufptr++ = attr->values[i].range.upper >> 24; + *bufptr++ = attr->values[i].range.upper >> 16; + *bufptr++ = attr->values[i].range.upper >> 8; + *bufptr++ = attr->values[i].range.upper; + } + break; + + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + n = strlen(attr->values[i].string.charset) + + strlen(attr->values[i].string.text) + + 2; + + if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2)) + { + if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + /* Length of entire value */ + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Length of charset */ + n = strlen(attr->values[i].string.charset); + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Charset */ + memcpy(bufptr, attr->values[i].string.charset, n); + bufptr += n; + + /* Length of text */ + n = strlen(attr->values[i].string.text); + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Text */ + memcpy(bufptr, attr->values[i].string.text, n); + bufptr += n; + } + break; + + default : + for (i = 0; i < attr->num_values; i ++) + { + if (i) + { + /* + * Arrays and sets are done by sending additional + * values with a zero-length name... + */ + + *bufptr++ = attr->value_tag; + *bufptr++ = 0; + *bufptr++ = 0; + } + + n = attr->values[i].unknown.length; + + if ((sizeof(buffer) - (bufptr - buffer)) < (n + 2)) + { + if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + bufptr = buffer; + } + + /* Length of unknown value */ + *bufptr++ = n >> 8; + *bufptr++ = n; + + /* Value */ + if (n > 0) + { + memcpy(bufptr, attr->values[i].unknown.data, n); + bufptr += n; + } + } + break; + } + + /* + * Write the data out... + */ + + if (httpWrite(http, (char *)buffer, bufptr - buffer) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP attribute..."); + return (IPP_ERROR); + } + + DEBUG_printf(("ippWrite: wrote %d bytes\n", bufptr - buffer)); + + /* + * If blocking is disabled, stop here... + */ + + if (!http->blocking) + break; + } + + if (ipp->current == NULL) + { + /* + * Done with all of the attributes; add the end-of-attributes tag... + */ + + buffer[0] = IPP_TAG_END; + if (httpWrite(http, (char *)buffer, 1) < 0) + { + DEBUG_puts("ippWrite: Could not write IPP end-tag..."); + return (IPP_ERROR); + } + + ipp->state = IPP_DATA; + } + break; + + case IPP_DATA : + break; + + default : + break; /* anti-compiler-warning-code */ + } + + return (ipp->state); +} + + +/* + * 'ippPort()' - Return the default IPP port number. + */ + +int /* O - Port number */ +ippPort(void) +{ + const char *server_port; /* SERVER_PORT environment variable */ + struct servent *port; /* Port number info */ + + + if ((server_port = getenv("IPP_PORT")) != NULL) + return (atoi(server_port)); + else if ((port = getservbyname("ipp", NULL)) == NULL) + return (IPP_PORT); + else + return (ntohs(port->s_port)); +} + + +/* + * '_ipp_add_attr()' - Add a new attribute to the request. + */ + +ipp_attribute_t * /* O - New attribute */ +_ipp_add_attr(ipp_t *ipp, /* I - IPP request */ + int num_values) /* I - Number of values */ +{ + ipp_attribute_t *attr; /* New attribute */ + + + DEBUG_printf(("_ipp_add_attr(%08x, %d)\n", ipp, num_values)); + + if (ipp == NULL || num_values < 0) + return (NULL); + + attr = calloc(sizeof(ipp_attribute_t) + + (num_values - 1) * sizeof(ipp_value_t), 1); + + attr->num_values = num_values; + + if (attr == NULL) + return (NULL); + + if (ipp->last == NULL) + ipp->attrs = attr; + else + ipp->last->next = attr; + + ipp->last = attr; + + return (attr); +} + + +/* + * '_ipp_free_attr()' - Free an attribute. + */ + +void +_ipp_free_attr(ipp_attribute_t *attr) /* I - Attribute to free */ +{ + int i; /* Looping var */ + + + switch (attr->value_tag) + { + case IPP_TAG_TEXT : + case IPP_TAG_NAME : + case IPP_TAG_KEYWORD : + case IPP_TAG_STRING : + case IPP_TAG_URI : + case IPP_TAG_URISCHEME : + case IPP_TAG_CHARSET : + case IPP_TAG_LANGUAGE : + case IPP_TAG_MIMETYPE : + for (i = 0; i < attr->num_values; i ++) + free(attr->values[i].string.text); + break; + + case IPP_TAG_TEXTLANG : + case IPP_TAG_NAMELANG : + for (i = 0; i < attr->num_values; i ++) + { + if (attr->values[i].string.charset) + free(attr->values[i].string.charset); + free(attr->values[i].string.text); + } + break; + + default : + break; /* anti-compiler-warning-code */ + } + + if (attr->name != NULL) + free(attr->name); + + free(attr); +} + + +/* + * 'ipp_read()' - Semi-blocking read on a HTTP connection... + */ + +static int /* O - Number of bytes read */ +ipp_read(http_t *http, /* I - Client connection */ + unsigned char *buffer, /* O - Buffer for data */ + int length) /* I - Total length */ +{ + int tbytes, /* Total bytes read */ + bytes; /* Bytes read this pass */ + + + /* + * Loop until all bytes are read... + */ + + for (tbytes = 0; tbytes < length; tbytes += bytes, buffer += bytes) + if ((bytes = httpRead(http, (char *)buffer, length - tbytes)) <= 0) + break; + + /* + * Return the number of bytes read... + */ + + return (tbytes); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/ipp.h b/cups/ipp.h new file mode 100644 index 0000000000..320c719321 --- /dev/null +++ b/cups/ipp.h @@ -0,0 +1,361 @@ +/* + * "$Id$" + * + * Internet Printing Protocol definitions for the Common UNIX Printing + * System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +#ifndef _CUPS_IPP_H_ +# define _CUPS_IPP_H_ + +/* + * Include necessary headers... + */ + +# include + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * IPP version string... + */ + +# define IPP_VERSION "\001\000" + +/* + * IPP registered port number... This is the default value - applications + * should use the ippPort() function so that you can customize things in + * /etc/services if needed! + */ + +# define IPP_PORT 631 + +/* + * Common limits... + */ + +# define IPP_MAX_NAME 256 +# define IPP_MAX_VALUES 100 + + +/* + * Types and structures... + */ + +typedef enum /**** Format tags for attribute formats... ****/ +{ + IPP_TAG_ZERO = 0x00, + IPP_TAG_OPERATION, + IPP_TAG_JOB, + IPP_TAG_END, + IPP_TAG_PRINTER, + IPP_TAG_UNSUPPORTED_GROUP, + IPP_TAG_UNSUPPORTED_VALUE = 0x10, + IPP_TAG_DEFAULT, + IPP_TAG_UNKNOWN, + IPP_TAG_NOVALUE, + IPP_TAG_NOTSETTABLE = 0x15, + IPP_TAG_DELETEATTR, + IPP_TAG_ANYVALUE, + IPP_TAG_INTEGER = 0x21, + IPP_TAG_BOOLEAN, + IPP_TAG_ENUM, + IPP_TAG_STRING = 0x30, + IPP_TAG_DATE, + IPP_TAG_RESOLUTION, + IPP_TAG_RANGE, + IPP_TAG_COLLECTION, + IPP_TAG_TEXTLANG, + IPP_TAG_NAMELANG, + IPP_TAG_TEXT = 0x41, + IPP_TAG_NAME, + IPP_TAG_KEYWORD = 0x44, + IPP_TAG_URI, + IPP_TAG_URISCHEME, + IPP_TAG_CHARSET, + IPP_TAG_LANGUAGE, + IPP_TAG_MIMETYPE +} ipp_tag_t; + +typedef enum /**** Resolution units... ****/ +{ + IPP_RES_PER_INCH = 3, + IPP_RES_PER_CM +} ipp_res_t; + +typedef enum /**** Finishings... ****/ +{ + IPP_FINISH_NONE = 3, + IPP_FINISH_STAPLE, + IPP_FINISH_PUNCH, + IPP_FINISH_COVER, + IPP_FINISH_BIND +} ipp_finish_t; + +typedef enum /**** Orientation... ****/ +{ + IPP_PORTRAIT = 3, /* No rotation */ + IPP_LANDSCAPE, /* 90 degrees counter-clockwise */ + IPP_REVERSE_LANDSCAPE, /* 90 degrees clockwise */ + IPP_REVERSE_PORTRAIT /* 180 degrees */ +} ipp_orient_t; + +typedef enum /**** Qualities... ****/ +{ + IPP_QUALITY_DRAFT = 3, + IPP_QUALITY_NORMAL, + IPP_QUALITY_HIGH +} ipp_quality_t; + +typedef enum /**** Job States.... */ +{ + IPP_JOB_PENDING = 3, + IPP_JOB_HELD, + IPP_JOB_PROCESSING, + IPP_JOB_STOPPED, + IPP_JOB_CANCELLED, + IPP_JOB_ABORTED, + IPP_JOB_COMPLETED +} ipp_jstate_t; + +typedef enum /**** Printer States.... */ +{ + IPP_PRINTER_IDLE = 3, + IPP_PRINTER_PROCESSING, + IPP_PRINTER_STOPPED +} ipp_pstate_t; + +typedef enum /**** IPP states... ****/ +{ + IPP_ERROR = -1, /* An error occurred */ + IPP_IDLE, /* Nothing is happening/request completed */ + IPP_HEADER, /* The request header needs to be sent/received */ + IPP_ATTRIBUTE, /* One or more attributes need to be sent/received */ + IPP_DATA /* IPP request data needs to be sent/received */ +} ipp_state_t; + +typedef enum /**** IPP operations... ****/ +{ + IPP_PRINT_JOB = 0x0002, + IPP_PRINT_URI, + IPP_VALIDATE_JOB, + IPP_CREATE_JOB, + IPP_SEND_DOCUMENT, + IPP_SEND_URI, + IPP_CANCEL_JOB, + IPP_GET_JOB_ATTRIBUTES, + IPP_GET_JOBS, + IPP_GET_PRINTER_ATTRIBUTES, + IPP_HOLD_JOB, + IPP_RELEASE_JOB, + IPP_RESTART_JOB, + IPP_PAUSE_PRINTER = 0x0010, + IPP_RESUME_PRINTER, + IPP_PURGE_JOBS, + IPP_SET_PRINTER_ATTRIBUTES, + IPP_SET_JOB_ATTRIBUTES, + IPP_GET_PRINTER_SUPPORTED_VALUES, + IPP_PRIVATE = 0x4000, + CUPS_GET_DEFAULT, + CUPS_GET_PRINTERS, + CUPS_ADD_PRINTER, + CUPS_DELETE_PRINTER, + CUPS_GET_CLASSES, + CUPS_ADD_CLASS, + CUPS_DELETE_CLASS, + CUPS_ACCEPT_JOBS, + CUPS_REJECT_JOBS, + CUPS_SET_DEFAULT, + CUPS_GET_DEVICES, + CUPS_GET_PPDS, + CUPS_MOVE_JOB +} ipp_op_t; + +typedef enum /**** IPP status codes... ****/ +{ + IPP_OK = 0x0000, + IPP_OK_SUBST, + IPP_OK_CONFLICT, + IPP_BAD_REQUEST = 0x0400, + IPP_FORBIDDEN, + IPP_NOT_AUTHENTICATED, + IPP_NOT_AUTHORIZED, + IPP_NOT_POSSIBLE, + IPP_TIMEOUT, + IPP_NOT_FOUND, + IPP_GONE, + IPP_REQUEST_ENTITY, + IPP_REQUEST_VALUE, + IPP_DOCUMENT_FORMAT, + IPP_ATTRIBUTES, + IPP_URI_SCHEME, + IPP_CHARSET, + IPP_CONFLICT, + IPP_COMPRESSION_NOT_SUPPORTED, + IPP_COMPRESSION_ERROR, + IPP_DOCUMENT_FORMAT_ERROR, + IPP_DOCUMENT_ACCESS_ERROR, + IPP_INTERNAL_ERROR = 0x0500, + IPP_OPERATION_NOT_SUPPORTED, + IPP_SERVICE_UNAVAILABLE, + IPP_VERSION_NOT_SUPPORTED, + IPP_DEVICE_ERROR, + IPP_TEMPORARY_ERROR, + IPP_NOT_ACCEPTING, + IPP_PRINTER_BUSY, + IPP_ERROR_JOB_CANCELLED, + IPP_MULTIPLE_JOBS_NOT_SUPPORTED +} ipp_status_t; + +typedef unsigned char ipp_uchar_t;/**** Unsigned 8-bit integer/character ****/ + +typedef union /**** Request Header ****/ +{ + struct /* Any Header */ + { + ipp_uchar_t version[2]; /* Protocol version number */ + int op_status; /* Operation ID or status code*/ + int request_id; /* Request ID */ + } any; + + struct /* Operation Header */ + { + ipp_uchar_t version[2]; /* Protocol version number */ + ipp_op_t operation_id; /* Operation ID */ + int request_id; /* Request ID */ + } op; + + struct /* Status Header */ + { + ipp_uchar_t version[2]; /* Protocol version number */ + ipp_status_t status_code; /* Status code */ + int request_id; /* Request ID */ + } status; +} ipp_request_t; + + +typedef union /**** Attribute Value ****/ +{ + int integer; /* Integer/enumerated value */ + + char boolean; /* Boolean value */ + + ipp_uchar_t date[11]; /* Date/time value */ + + struct + { + int xres, /* Horizontal resolution */ + yres; /* Vertical resolution */ + ipp_res_t units; /* Resolution units */ + } resolution; /* Resolution value */ + + struct + { + int lower, /* Lower value */ + upper; /* Upper value */ + } range; /* Range of integers value */ + + struct + { + char *charset; /* Character set */ + char *text; /* String */ + } string; /* String with language value */ + + struct + { + int length; /* Length of attribute */ + void *data; /* Data in attribute */ + } unknown; /* Unknown attribute type */ +} ipp_value_t; + +typedef struct ipp_attribute_s /**** Attribute ****/ +{ + struct ipp_attribute_s *next; + /* Next atrtribute in list */ + ipp_tag_t group_tag, /* Job/Printer/Operation group tag */ + value_tag; /* What type of value is it? */ + char *name; /* Name of attribute */ + int num_values; /* Number of values */ + ipp_value_t values[1]; /* Values */ +} ipp_attribute_t; + +typedef struct /**** Request State ****/ +{ + ipp_state_t state; /* State of request */ + ipp_request_t request; /* Request header */ + ipp_attribute_t *attrs, /* Attributes */ + *last, /* Last attribute in list */ + *current; /* Current attribute (for read/write) */ + ipp_tag_t curtag; /* Current attribute group tag */ +} ipp_t; + + +/* + * Prototypes... + */ + +extern ipp_attribute_t *ippAddBoolean(ipp_t *ipp, ipp_tag_t group, const char *name, char value); +extern ipp_attribute_t *ippAddBooleans(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, const char *values); +extern ipp_attribute_t *ippAddDate(ipp_t *ipp, ipp_tag_t group, const char *name, const ipp_uchar_t *value); +extern ipp_attribute_t *ippAddInteger(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, int value); +extern ipp_attribute_t *ippAddIntegers(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, int num_values, const int *values); +extern ipp_attribute_t *ippAddRange(ipp_t *ipp, ipp_tag_t group, const char *name, int lower, int upper); +extern ipp_attribute_t *ippAddRanges(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, const int *lower, const int *upper); +extern ipp_attribute_t *ippAddResolution(ipp_t *ipp, ipp_tag_t group, const char *name, ipp_res_t units, int xres, int yres); +extern ipp_attribute_t *ippAddResolutions(ipp_t *ipp, ipp_tag_t group, const char *name, int num_values, ipp_res_t units, const int *xres, const int *yres); +extern ipp_attribute_t *ippAddSeparator(ipp_t *ipp); +extern ipp_attribute_t *ippAddString(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, const char *charset, const char *value); +extern ipp_attribute_t *ippAddStrings(ipp_t *ipp, ipp_tag_t group, ipp_tag_t type, const char *name, int num_values, const char *charset, const char **values); +extern time_t ippDateToTime(const ipp_uchar_t *date); +extern void ippDelete(ipp_t *ipp); +extern const char *ippErrorString(ipp_status_t error); +extern ipp_attribute_t *ippFindAttribute(ipp_t *ipp, const char *name, ipp_tag_t type); +extern size_t ippLength(ipp_t *ipp); +extern ipp_t *ippNew(void); +extern ipp_state_t ippRead(http_t *http, ipp_t *ipp); +extern const ipp_uchar_t *ippTimeToDate(time_t t); +extern ipp_state_t ippWrite(http_t *http, ipp_t *ipp); +extern int ippPort(void); + +extern ipp_attribute_t *_ipp_add_attr(ipp_t *, int); +extern void _ipp_free_attr(ipp_attribute_t *); + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_IPP_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/language.c b/cups/language.c new file mode 100644 index 0000000000..94ae2ae88d --- /dev/null +++ b/cups/language.c @@ -0,0 +1,402 @@ +/* + * "$Id$" + * + * I18N/language support for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * cupsLangEncoding() - Return the character encoding (us-ascii, etc.) + * for the given language. + * cupsLangFlush() - Flush all language data out of the cache. + * cupsLangFree() - Free language data. + * cupsLangGet() - Get a language. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include "string.h" +#include "language.h" + + +/* + * Local globals... + */ + +static cups_lang_t *lang_cache = NULL; /* Language string cache */ +static char *lang_blank = ""; /* Blank constant string */ +static char *lang_encodings[] = /* Encoding strings */ + { + "us-ascii", + "iso-8859-1", + "iso-8859-2", + "iso-8859-3", + "iso-8859-4", + "iso-8859-5", + "iso-8859-6", + "iso-8859-7", + "iso-8859-8", + "iso-8859-9", + "iso-8859-10", + "utf-8", + "iso-8859-13", + "iso-8859-14", + "iso-8859-15", + "windows-874", + "windows-1250", + "windows-1251", + "windows-1252", + "windows-1253", + "windows-1254", + "windows-1255", + "windows-1256", + "windows-1257", + "windows-1258" + }; +static char *lang_default[] = /* Default POSIX locale */ + { +#include "cups_C.h" + NULL + }; + + +/* + * 'cupsLangEncoding()' - Return the character encoding (us-ascii, etc.) + * for the given language. + */ + +char * /* O - Character encoding */ +cupsLangEncoding(cups_lang_t *lang) /* I - Language data */ +{ + if (lang == NULL) + return (lang_encodings[0]); + else + return (lang_encodings[lang->encoding]); +} + + +/* + * 'cupsLangFlush()' - Flush all language data out of the cache. + */ + +void +cupsLangFlush(void) +{ + int i; /* Looping var */ + cups_lang_t *lang, /* Current language */ + *next; /* Next language */ + + + for (lang = lang_cache; lang != NULL; lang = next) + { + for (i = 0; i < CUPS_MSG_MAX; i ++) + if (lang->messages[i] != NULL && lang->messages[i] != lang_blank) + free(lang->messages[i]); + + next = lang->next; + free(lang); + } +} + + +/* + * 'cupsLangFree()' - Free language data. + * + * This does not actually free anything; use cupsLangFlush() for that. + */ + +void +cupsLangFree(cups_lang_t *lang) /* I - Language to free */ +{ + if (lang != NULL && lang->used > 0) + lang->used --; +} + + +/* + * 'cupsLangGet()' - Get a language. + */ + +cups_lang_t * /* O - Language data */ +cupsLangGet(const char *language) /* I - Language or locale */ +{ + int i, count; /* Looping vars */ + char langname[16], /* Requested language name */ + real[16], /* Real language name */ + filename[1024], /* Filename for language locale file */ + *localedir; /* Directory for locale files */ + FILE *fp; /* Language locale file pointer */ + char line[1024]; /* Line from file */ + cups_msg_t msg; /* Message number */ + char *text; /* Message text */ + cups_lang_t *lang; /* Current language... */ + + + /* + * Convert the language string passed in to a locale string. "C" is the + * standard POSIX locale and is copied unchanged. Otherwise the + * language string is converted from ll-cc (language-country) to ll_cc + * to match the file naming convention used by all POSIX-compliant + * operating systems. Any trailing character set specification is + * dropped. + */ + + if (language == NULL || language[0] == '\0' || + strcmp(language, "POSIX") == 0) + strcpy(langname, "C"); + else + { + /* + * Copy the locale string over safely... + */ + + strncpy(langname, language, sizeof(langname) - 1); + langname[sizeof(langname) - 1] = '\0'; + + /* + * Strip charset from "locale.charset"... + */ + + if ((text = strchr(langname, '.')) != NULL) + *text = '\0'; + } + + if (strlen(langname) < 2) + strcpy(real, "C"); + else + { + real[0] = tolower(langname[0]); + real[1] = tolower(langname[1]); + + if (langname[2] == '_' || langname[2] == '-') + { + real[2] = '_'; + real[3] = toupper(langname[3]); + real[4] = toupper(langname[4]); + real[5] = '\0'; + langname[5] = '\0'; + } + else + { + langname[2] = '\0'; + real[2] = '\0'; + } + } + + /* + * Next try to open a locale file; we will try the country-localized file + * first, and then look for generic language file. If all else fails we + * will use the POSIX locale. + */ + + if ((localedir = getenv("LOCALEDIR")) == NULL) + localedir = CUPS_LOCALEDIR; + + snprintf(filename, sizeof(filename), "%s/%s/cups_%s", localedir, real, real); + + if ((fp = fopen(filename, "r")) == NULL) + if (strlen(real) > 2) + { + /* + * Nope, see if we can open a generic language file... + */ + + real[2] = '\0'; + snprintf(filename, sizeof(filename), "%s/%s/cups_%s", localedir, real, + real); + fp = fopen(filename, "r"); + } + + /* + * Then see if we already have this language loaded... + */ + + for (lang = lang_cache; lang != NULL; lang = lang->next) + if (strcmp(lang->language, langname) == 0) + { + lang->used ++; + + if (fp != NULL) + fclose(fp); + + return (lang); + } + + /* + * OK, we have an open messages file; the first line will contain the + * language encoding (us-ascii, iso-8859-1, etc.), and the rest will + * be messages consisting of: + * + * #### SP message text + * + * or: + * + * message text + * + * If the line starts with a number, then message processing picks up + * where the number indicates. Otherwise the last message number is + * incremented. + * + * All leading whitespace is deleted. + */ + + if (fp == NULL) + strcpy(line, lang_default[0]); + else if (fgets(line, sizeof(line), fp) == NULL) + { + /* + * Can't read encoding! + */ + + fclose(fp); + return (NULL); + } + + i = strlen(line) - 1; + if (line[i] == '\n') + line[i] = '\0'; /* Strip LF */ + + /* + * See if there is a free language available; if so, use that + * record... + */ + + for (lang = lang_cache; lang != NULL; lang = lang->next) + if (lang->used == 0) + break; + + if (lang == NULL) + { + /* + * Allocate memory for the language and add it to the cache. + */ + + if ((lang = calloc(sizeof(cups_lang_t), 1)) == NULL) + { + fclose(fp); + return (NULL); + } + + lang->next = lang_cache; + lang_cache = lang; + } + + /* + * Free all old strings as needed... + */ + + for (i = 0; i < CUPS_MSG_MAX; i ++) + { + if (lang->messages[i] != NULL && lang->messages[i] != lang_blank) + free(lang->messages[i]); + + lang->messages[i] = lang_blank; + } + + /* + * Then assign the language and encoding fields... + */ + + lang->used ++; + strcpy(lang->language, langname); + + for (i = 0; i < (sizeof(lang_encodings) / sizeof(lang_encodings[0])); i ++) + if (strcmp(lang_encodings[i], line) == 0) + { + lang->encoding = (cups_encoding_t)i; + break; + } + + /* + * Read the strings from the file... + */ + + msg = (cups_msg_t)-1; + count = 1; + + for (;;) + { + /* + * Read a line from memory or from a file... + */ + + if (fp == NULL) + { + if (lang_default[count] == NULL) + break; + + strcpy(line, lang_default[count]); + } + else if (fgets(line, sizeof(line), fp) == NULL) + break; + + count ++; + + /* + * Ignore blank lines... + */ + + i = strlen(line) - 1; + if (line[i] == '\n') + line[i] = '\0'; /* Strip LF */ + + if (line[0] == '\0') + continue; + + /* + * Grab the message number and text... + */ + + if (isdigit(line[0])) + msg = (cups_msg_t)atoi(line); + else + msg ++; + + if (msg < 0 || msg >= CUPS_MSG_MAX) + continue; + + text = line; + while (isdigit(*text)) + text ++; + while (isspace(*text)) + text ++; + + lang->messages[msg] = strdup(text); + } + + /* + * Close the file and return... + */ + + if (fp != NULL) + fclose(fp); + + return (lang); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/language.h b/cups/language.h new file mode 100644 index 0000000000..76a14a41c3 --- /dev/null +++ b/cups/language.h @@ -0,0 +1,222 @@ +/* + * "$Id$" + * + * Multi-language support for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +#ifndef _CUPS_LANGUAGE_H_ +# define _CUPS_LANGUAGE_H_ + +/* + * Include necessary headers... + */ + +# include + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* + * Messages... + */ + +typedef enum /**** Message Indices ****/ +{ + CUPS_MSG_OK, + CUPS_MSG_CANCEL, + CUPS_MSG_HELP, + CUPS_MSG_QUIT, + CUPS_MSG_CLOSE, + CUPS_MSG_YES, + CUPS_MSG_NO, + CUPS_MSG_ON, + CUPS_MSG_OFF, + CUPS_MSG_SAVE, + CUPS_MSG_DISCARD, + CUPS_MSG_DEFAULT, + CUPS_MSG_OPTIONS, + CUPS_MSG_MORE_INFO, + CUPS_MSG_BLACK, + CUPS_MSG_COLOR, + CUPS_MSG_CYAN, + CUPS_MSG_MAGENTA, + CUPS_MSG_YELLOW, + CUPS_MSG_COPYRIGHT, + CUPS_MSG_GENERAL, + CUPS_MSG_PRINTER, + CUPS_MSG_IMAGE, + CUPS_MSG_HPGL2, + CUPS_MSG_EXTRA, + CUPS_MSG_DOCUMENT, + CUPS_MSG_OTHER, + CUPS_MSG_PRINT_PAGES, + CUPS_MSG_ENTIRE_DOCUMENT, + CUPS_MSG_PAGE_RANGE, + CUPS_MSG_REVERSE_ORDER, + CUPS_MSG_PAGE_FORMAT, + CUPS_MSG_1_UP, + CUPS_MSG_2_UP, + CUPS_MSG_4_UP, + CUPS_MSG_IMAGE_SCALING, + CUPS_MSG_USE_NATURAL_IMAGE_SIZE, + CUPS_MSG_ZOOM_BY_PERCENT, + CUPS_MSG_ZOOM_BY_PPI, + CUPS_MSG_MIRROR_IMAGE, + CUPS_MSG_COLOR_SATURATION, + CUPS_MSG_COLOR_HUE, + CUPS_MSG_FIT_TO_PAGE, + CUPS_MSG_SHADING, + CUPS_MSG_DEFAULT_PEN_WIDTH, + CUPS_MSG_GAMMA_CORRECTION, + CUPS_MSG_BRIGHTNESS, + CUPS_MSG_ADD, + CUPS_MSG_DELETE, + CUPS_MSG_MODIFY, + CUPS_MSG_PRINTER_URI, + CUPS_MSG_PRINTER_NAME, + CUPS_MSG_PRINTER_LOCATION, + CUPS_MSG_PRINTER_INFO, + CUPS_MSG_PRINTER_MAKE_AND_MODEL, + CUPS_MSG_DEVICE_URI, + CUPS_MSG_FORMATTING_PAGE, + CUPS_MSG_PRINTING_PAGE, + CUPS_MSG_INITIALIZING_PRINTER, + CUPS_MSG_PRINTER_STATE, + CUPS_MSG_ACCEPTING_JOBS, + CUPS_MSG_NOT_ACCEPTING_JOBS, + CUPS_MSG_PRINT_JOBS, + CUPS_MSG_CLASS, + CUPS_MSG_LOCAL, + CUPS_MSG_REMOTE, + CUPS_MSG_DUPLEXING, + CUPS_MSG_STAPLING, + CUPS_MSG_FAST_COPIES, + CUPS_MSG_COLLATED_COPIES, + CUPS_MSG_PUNCHING, + CUPS_MSG_COVERING, + CUPS_MSG_BINDING, + CUPS_MSG_SORTING, + CUPS_MSG_SMALL, + CUPS_MSG_MEDIUM, + CUPS_MSG_LARGE, + CUPS_MSG_VARIABLE, + CUPS_MSG_IDLE, + CUPS_MSG_PROCESSING, + CUPS_MSG_STOPPED, + CUPS_MSG_ALL, + CUPS_MSG_ODD, + CUPS_MSG_EVEN_PAGES, + CUPS_MSG_DARKER_LIGHTER, + CUPS_MSG_MEDIA_SIZE, + CUPS_MSG_MEDIA_TYPE, + CUPS_MSG_MEDIA_SOURCE, + CUPS_MSG_ORIENTATION, + CUPS_MSG_PORTRAIT, + CUPS_MSG_LANDSCAPE, + CUPS_MSG_JOB_STATE, + CUPS_MSG_JOB_NAME, + CUPS_MSG_USER_NAME, + CUPS_MSG_PRIORITY, + CUPS_MSG_COPIES, + CUPS_MSG_FILE_SIZE, + CUPS_MSG_PENDING, + CUPS_MSG_OUTPUT_MODE, + CUPS_MSG_RESOLUTION, + CUPS_MSG_TEXT, + CUPS_MSG_PRETTYPRINT, + CUPS_MSG_MARGINS, + CUPS_MSG_LEFT, + CUPS_MSG_RIGHT, + CUPS_MSG_BOTTOM, + CUPS_MSG_TOP, + CUPS_MSG_FILENAME, + CUPS_MSG_PRINT, + CUPS_MSG_HTTP_BASE = 200, + CUPS_MSG_HTTP_END = 505, + CUPS_MSG_MAX +} cups_msg_t; + +typedef enum /**** Language Encodings ****/ +{ + CUPS_US_ASCII, + CUPS_ISO8859_1, + CUPS_ISO8859_2, + CUPS_ISO8859_3, + CUPS_ISO8859_4, + CUPS_ISO8859_5, + CUPS_ISO8859_6, + CUPS_ISO8859_7, + CUPS_ISO8859_8, + CUPS_ISO8859_9, + CUPS_ISO8859_10, + CUPS_UTF8, + CUPS_ISO8859_13, + CUPS_ISO8859_14, + CUPS_ISO8859_15, + CUPS_WINDOWS_874, + CUPS_WINDOWS_1250, + CUPS_WINDOWS_1251, + CUPS_WINDOWS_1252, + CUPS_WINDOWS_1253, + CUPS_WINDOWS_1254, + CUPS_WINDOWS_1255, + CUPS_WINDOWS_1256, + CUPS_WINDOWS_1257, + CUPS_WINDOWS_1258 +} cups_encoding_t; + +typedef struct cups_lang_str /**** Language Cache Structure ****/ +{ + struct cups_lang_str *next; /* Next language in cache */ + int used; /* Number of times this entry has been used. */ + cups_encoding_t encoding; /* Text encoding */ + char language[16]; /* Language/locale name */ + char *messages[CUPS_MSG_MAX]; + /* Message array */ +} cups_lang_t; + + +/* + * Prototypes... + */ + +# ifdef WIN32 +# define cupsLangDefault() cupsLangGet(setlocale(LC_ALL, "")) +# else /* This fix works around bugs in the Linux and HP-UX setlocale() */ +# define cupsLangDefault() cupsLangGet(getenv("LANG")) +# endif /* WIN32 */ + +extern char *cupsLangEncoding(cups_lang_t *lang); +extern void cupsLangFlush(void); +extern void cupsLangFree(cups_lang_t *lang); +extern cups_lang_t *cupsLangGet(const char *language); +# define cupsLangString(lang,msg) (lang)->messages[(msg)] + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_LANGUAGE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/mark.c b/cups/mark.c new file mode 100644 index 0000000000..d9869beb76 --- /dev/null +++ b/cups/mark.c @@ -0,0 +1,437 @@ +/* + * "$Id$" + * + * Option marking routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * PostScript is a trademark of Adobe Systems, Inc. + * + * Contents: + * + * ppdConflicts() - Check to see if there are any conflicts. + * ppdFindChoice() - Return a pointer to an option choice. + * ppdFindMarkedChoice() - Return the marked choice for the specified option. + * ppdFindOption() - Return a pointer to the specified option. + * ppdIsMarked() - Check to see if an option is marked... + * ppdMarkDefaults() - Mark all default options in the PPD file. + * ppdMarkOption() - Mark an option in a PPD file. + * ppd_defaults() - Set the defaults for this group and all sub-groups. + */ + +/* + * Include necessary headers... + */ + +#include "ppd.h" +#include "string.h" +#include "debug.h" + + +/* + * Local functions... + */ + +static void ppd_defaults(ppd_file_t *ppd, ppd_group_t *g); + + +/* + * 'ppdConflicts()' - Check to see if there are any conflicts. + */ + +int /* O - Number of conflicts found */ +ppdConflicts(ppd_file_t *ppd) /* I - PPD to check */ +{ + int i, j, k, /* Looping variables */ + conflicts; /* Number of conflicts */ + ppd_const_t *c; /* Current constraint */ + ppd_group_t *g, *sg; /* Groups */ + ppd_option_t *o1, *o2; /* Options */ + ppd_choice_t *c1, *c2; /* Choices */ + + + if (ppd == NULL) + return (0); + + /* + * Clear all conflicts... + */ + + conflicts = 0; + + for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) + { + for (j = g->num_options, o1 = g->options; j > 0; j --, o1 ++) + o1->conflicted = 0; + + for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++) + for (k = sg->num_options, o1 = sg->options; k > 0; k --, o1 ++) + o1->conflicted = 0; + } + + /* + * Loop through all of the UI constraints and flag any options + * that conflict... + */ + + for (i = ppd->num_consts, c = ppd->consts; i > 0; i --, c ++) + { + /* + * Grab pointers to the first option... + */ + + o1 = ppdFindOption(ppd, c->option1); + + if (o1 == NULL) + continue; + else if (c->choice1[0] != '\0') + { + /* + * This constraint maps to a specific choice. + */ + + c1 = ppdFindChoice(o1, c->choice1); + } + else + { + /* + * This constraint applies to any choice for this option. + */ + + for (j = o1->num_choices, c1 = o1->choices; j > 0; j --, c1 ++) + if (c1->marked) + break; + + if (j == 0 || strcasecmp(c1->choice, "None") == 0 || + strcasecmp(c1->choice, "False") == 0) + c1 = NULL; + } + + /* + * Grab pointers to the second option... + */ + + o2 = ppdFindOption(ppd, c->option2); + + if (o2 == NULL) + continue; + else if (c->choice2[0] != '\0') + { + /* + * This constraint maps to a specific choice. + */ + + c2 = ppdFindChoice(o2, c->choice2); + } + else + { + /* + * This constraint applies to any choice for this option. + */ + + for (j = o2->num_choices, c2 = o2->choices; j > 0; j --, c2 ++) + if (c2->marked) + break; + + if (j == 0 || strcasecmp(c2->choice, "None") == 0 || + strcasecmp(c2->choice, "False") == 0) + c2 = NULL; + } + + /* + * If both options are marked then there is a conflict... + */ + + if (c1 != NULL && c1->marked && + c2 != NULL && c2->marked) + { + DEBUG_printf(("%s->%s conflicts with %s->%s (%s %s %s %s)\n", + o1->keyword, c1->choice, o2->keyword, c2->choice, + c->option1, c->choice1, c->option2, c->choice2)); + conflicts ++; + o1->conflicted = 1; + o2->conflicted = 1; + } + } + + /* + * Return the number of conflicts found... + */ + + return (conflicts); +} + + +/* + * 'ppdFindChoice()' - Return a pointer to an option choice. + */ + +ppd_choice_t * /* O - Choice pointer or NULL */ +ppdFindChoice(ppd_option_t *o, /* I - Pointer to option */ + const char *choice) /* I - Name of choice */ +{ + int i; /* Looping var */ + ppd_choice_t *c; /* Current choice */ + + + if (o == NULL || choice == NULL) + return (NULL); + + for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) + if (strcasecmp(c->choice, choice) == 0) + return (c); + + return (NULL); +} + + +/* + * 'ppdFindMarkedChoice()' - Return the marked choice for the specified option. + */ + +ppd_choice_t * /* O - Pointer to choice or NULL */ +ppdFindMarkedChoice(ppd_file_t *ppd, /* I - PPD file */ + const char *option) /* I - Keyword/option name */ +{ + int i; /* Looping var */ + ppd_option_t *o; /* Pointer to option */ + ppd_choice_t *c; /* Pointer to choice */ + + + if ((o = ppdFindOption(ppd, option)) == NULL) + return (NULL); + + for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) + if (c->marked) + return (c); + + return (NULL); +} + + +/* + * 'ppdFindOption()' - Return a pointer to the specified option. + */ + +ppd_option_t * /* O - Pointer to option or NULL */ +ppdFindOption(ppd_file_t *ppd, /* I - PPD file data */ + const char *option) /* I - Option/Keyword name */ +{ + int i, j, k; /* Looping vars */ + ppd_option_t *o; /* Pointer to option */ + ppd_group_t *g, /* Pointer to group */ + *sg; /* Pointer to subgroup */ + + + if (ppd == NULL || option == NULL) + return (NULL); + + for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) + { + for (j = g->num_options, o = g->options; j > 0; j --, o ++) + if (strcasecmp(o->keyword, option) == 0) + return (o); + + for (j = g->num_subgroups, sg = g->subgroups; j > 0; j --, sg ++) + for (k = sg->num_options, o = sg->options; k > 0; k --, o ++) + if (strcasecmp(o->keyword, option) == 0) + return (o); + } + + return (NULL); +} + + +/* + * 'ppdIsMarked()' - Check to see if an option is marked... + */ + +int /* O - Non-zero if option is marked */ +ppdIsMarked(ppd_file_t *ppd, /* I - PPD file data */ + const char *option, /* I - Option/Keyword name */ + const char *choice) /* I - Choice name */ +{ + ppd_option_t *o; /* Option pointer */ + ppd_choice_t *c; /* Choice pointer */ + + + if (ppd == NULL) + return (0); + + if ((o = ppdFindOption(ppd, option)) == NULL) + return (0); + + if ((c = ppdFindChoice(o, choice)) == NULL) + return (0); + + return (c->marked); +} + + +/* + * 'ppdMarkDefaults()' - Mark all default options in the PPD file. + */ + +void +ppdMarkDefaults(ppd_file_t *ppd)/* I - PPD file record */ +{ + int i; /* Looping variables */ + ppd_group_t *g; /* Current group */ + + + if (ppd == NULL) + return; + + for (i = ppd->num_groups, g = ppd->groups; i > 0; i --, g ++) + ppd_defaults(ppd, g); +} + + +/* + * 'ppdMarkOption()' - Mark an option in a PPD file. + * + * Notes: + * + * -1 is returned if the given option would conflict with any currently + * selected option. + */ + +int /* O - Number of conflicts */ +ppdMarkOption(ppd_file_t *ppd, /* I - PPD file record */ + const char *option, /* I - Keyword */ + const char *choice) /* I - Option name */ +{ + int i; /* Looping var */ + ppd_option_t *o; /* Option pointer */ + ppd_choice_t *c; /* Choice pointer */ + + + if (ppd == NULL) + return (0); + + if (strcasecmp(option, "PageSize") == 0 && strncasecmp(choice, "Custom.", 7) == 0) + { + /* + * Handle variable page sizes... + */ + + ppdPageSize(ppd, choice); + choice = "Custom"; + } + + if ((o = ppdFindOption(ppd, option)) == NULL) + return (0); + + for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) + if (strcasecmp(c->choice, choice) == 0) + break; + + if (i) + { + /* + * Option found; mark it and then handle unmarking any other options. + */ + + c->marked = 1; + + if (o->ui != PPD_UI_PICKMANY) + for (i = o->num_choices, c = o->choices; i > 0; i --, c ++) + if (strcasecmp(c->choice, choice) != 0) + c->marked = 0; + + if (strcasecmp(option, "PageSize") == 0 || strcasecmp(option, "PageRegion") == 0) + { + /* + * Mark current page size... + */ + + for (i = 0; i < ppd->num_sizes; i ++) + ppd->sizes[i].marked = strcasecmp(ppd->sizes[i].name, choice) == 0; + + /* + * Unmark the current PageSize or PageRegion setting, as appropriate... + */ + + if (strcasecmp(option, "PageSize") == 0) + { + if ((o = ppdFindOption(ppd, "PageRegion")) != NULL) + for (i = 0; i < o->num_choices; i ++) + o->choices[i].marked = 0; + } + else + { + if ((o = ppdFindOption(ppd, "PageSize")) != NULL) + for (i = 0; i < o->num_choices; i ++) + o->choices[i].marked = 0; + } + } + else if (strcasecmp(option, "InputSlot") == 0) + { + /* + * Unmark ManualFeed option... + */ + + if ((o = ppdFindOption(ppd, "ManualFeed")) != NULL) + for (i = 0; i < o->num_choices; i ++) + o->choices[i].marked = 0; + } + else if (strcasecmp(option, "ManualFeed") == 0) + { + /* + * Unmark InputSlot option... + */ + + if ((o = ppdFindOption(ppd, "InputSlot")) != NULL) + for (i = 0; i < o->num_choices; i ++) + o->choices[i].marked = 0; + } + } + + return (ppdConflicts(ppd)); +} + + +/* + * 'ppd_defaults()' - Set the defaults for this group and all sub-groups. + */ + +static void +ppd_defaults(ppd_file_t *ppd, /* I - PPD file */ + ppd_group_t *g) /* I - Group to default */ +{ + int i; /* Looping var */ + ppd_option_t *o; /* Current option */ + ppd_group_t *sg; /* Current sub-group */ + + + if (g == NULL) + return; + + for (i = g->num_options, o = g->options; i > 0; i --, o ++) + if (strcasecmp(o->keyword, "PageRegion") != 0) + ppdMarkOption(ppd, o->keyword, o->defchoice); + + for (i = g->num_subgroups, sg = g->subgroups; i > 0; i --, sg ++) + ppd_defaults(ppd, sg); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/md5.c b/cups/md5.c new file mode 100644 index 0000000000..5db868858e --- /dev/null +++ b/cups/md5.c @@ -0,0 +1,392 @@ +/* + Copyright (C) 1999 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/*$Id$ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321. + It is derived directly from the text of the RFC and not from the + reference implementation. + + The original and principal author of md5.c is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5). + 1999-05-03 lpd Original version. + */ + +#include "md5.h" +#include "string.h" + +#ifdef TEST +/* + * Compile with -DTEST to create a self-contained executable test program. + * The test program should print out the same values as given in section + * A.5 of RFC 1321, reproduced below. + */ +main() +{ + static const char *const test[7] = { + "", /*d41d8cd98f00b204e9800998ecf8427e*/ + "a", /*0cc175b9c0f1b6a831c399e269772661*/ + "abc", /*900150983cd24fb0d6963f7d28e17f72*/ + "message digest", /*f96b697d7cb7938d525a2f31aaf161d0*/ + "abcdefghijklmnopqrstuvwxyz", /*c3fcd3d76192e4007dfb496cca67e13b*/ + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + /*d174ab98d277d9f5a5611c2c9f419d9f*/ + "12345678901234567890123456789012345678901234567890123456789012345678901234567890" /*57edf4a22be3c955ac49da2e2107b67a*/ + }; + int i; + + for (i = 0; i < 7; ++i) { + md5_state_t state; + md5_byte_t digest[16]; + int di; + + md5_init(&state); + md5_append(&state, (const md5_byte_t *)test[i], strlen(test[i])); + md5_finish(&state, digest); + printf("MD5 (\"%s\") = ", test[i]); + for (di = 0; di < 16; ++di) + printf("%02x", digest[di]); + printf("\n"); + } + return 0; +} +#endif /* TEST */ + + +/* + * For reference, here is the program that computed the T values. + */ +#if 0 +#include +main() +{ + int i; + for (i = 1; i <= 64; ++i) { + unsigned long v = (unsigned long)(4294967296.0 * fabs(sin((double)i))); + printf("#define T%d 0x%08lx\n", i, v); + } + return 0; +} +#endif +/* + * End of T computation program. + */ +#define T1 0xd76aa478 +#define T2 0xe8c7b756 +#define T3 0x242070db +#define T4 0xc1bdceee +#define T5 0xf57c0faf +#define T6 0x4787c62a +#define T7 0xa8304613 +#define T8 0xfd469501 +#define T9 0x698098d8 +#define T10 0x8b44f7af +#define T11 0xffff5bb1 +#define T12 0x895cd7be +#define T13 0x6b901122 +#define T14 0xfd987193 +#define T15 0xa679438e +#define T16 0x49b40821 +#define T17 0xf61e2562 +#define T18 0xc040b340 +#define T19 0x265e5a51 +#define T20 0xe9b6c7aa +#define T21 0xd62f105d +#define T22 0x02441453 +#define T23 0xd8a1e681 +#define T24 0xe7d3fbc8 +#define T25 0x21e1cde6 +#define T26 0xc33707d6 +#define T27 0xf4d50d87 +#define T28 0x455a14ed +#define T29 0xa9e3e905 +#define T30 0xfcefa3f8 +#define T31 0x676f02d9 +#define T32 0x8d2a4c8a +#define T33 0xfffa3942 +#define T34 0x8771f681 +#define T35 0x6d9d6122 +#define T36 0xfde5380c +#define T37 0xa4beea44 +#define T38 0x4bdecfa9 +#define T39 0xf6bb4b60 +#define T40 0xbebfbc70 +#define T41 0x289b7ec6 +#define T42 0xeaa127fa +#define T43 0xd4ef3085 +#define T44 0x04881d05 +#define T45 0xd9d4d039 +#define T46 0xe6db99e5 +#define T47 0x1fa27cf8 +#define T48 0xc4ac5665 +#define T49 0xf4292244 +#define T50 0x432aff97 +#define T51 0xab9423a7 +#define T52 0xfc93a039 +#define T53 0x655b59c3 +#define T54 0x8f0ccc92 +#define T55 0xffeff47d +#define T56 0x85845dd1 +#define T57 0x6fa87e4f +#define T58 0xfe2ce6e0 +#define T59 0xa3014314 +#define T60 0x4e0811a1 +#define T61 0xf7537e82 +#define T62 0xbd3af235 +#define T63 0x2ad7d2bb +#define T64 0xeb86d391 + +static void +md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/) +{ + md5_word_t + a = pms->abcd[0], b = pms->abcd[1], + c = pms->abcd[2], d = pms->abcd[3]; + md5_word_t t; + +#ifndef ARCH_IS_BIG_ENDIAN +# define ARCH_IS_BIG_ENDIAN 1 /* slower, default implementation */ +#endif +#if ARCH_IS_BIG_ENDIAN + + /* + * On big-endian machines, we must arrange the bytes in the right + * order. (This also works on machines of unknown byte order.) + */ + md5_word_t X[16]; + const md5_byte_t *xp = data; + int i; + + for (i = 0; i < 16; ++i, xp += 4) + X[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24); + +#else /* !ARCH_IS_BIG_ENDIAN */ + + /* + * On little-endian machines, we can process properly aligned data + * without copying it. + */ + md5_word_t xbuf[16]; + const md5_word_t *X; + + if (!((data - (const md5_byte_t *)0) & 3)) { + /* data are properly aligned */ + X = (const md5_word_t *)data; + } else { + /* not aligned */ + memcpy(xbuf, data, 64); + X = xbuf; + } +#endif + +#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32 - (n)))) + + /* Round 1. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + F(b,c,d) + X[k] + T[i]) <<< s). */ +#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + F(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 7, T1); + SET(d, a, b, c, 1, 12, T2); + SET(c, d, a, b, 2, 17, T3); + SET(b, c, d, a, 3, 22, T4); + SET(a, b, c, d, 4, 7, T5); + SET(d, a, b, c, 5, 12, T6); + SET(c, d, a, b, 6, 17, T7); + SET(b, c, d, a, 7, 22, T8); + SET(a, b, c, d, 8, 7, T9); + SET(d, a, b, c, 9, 12, T10); + SET(c, d, a, b, 10, 17, T11); + SET(b, c, d, a, 11, 22, T12); + SET(a, b, c, d, 12, 7, T13); + SET(d, a, b, c, 13, 12, T14); + SET(c, d, a, b, 14, 17, T15); + SET(b, c, d, a, 15, 22, T16); +#undef SET + + /* Round 2. */ + /* Let [abcd k s i] denote the operation + a = b + ((a + G(b,c,d) + X[k] + T[i]) <<< s). */ +#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + G(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 1, 5, T17); + SET(d, a, b, c, 6, 9, T18); + SET(c, d, a, b, 11, 14, T19); + SET(b, c, d, a, 0, 20, T20); + SET(a, b, c, d, 5, 5, T21); + SET(d, a, b, c, 10, 9, T22); + SET(c, d, a, b, 15, 14, T23); + SET(b, c, d, a, 4, 20, T24); + SET(a, b, c, d, 9, 5, T25); + SET(d, a, b, c, 14, 9, T26); + SET(c, d, a, b, 3, 14, T27); + SET(b, c, d, a, 8, 20, T28); + SET(a, b, c, d, 13, 5, T29); + SET(d, a, b, c, 2, 9, T30); + SET(c, d, a, b, 7, 14, T31); + SET(b, c, d, a, 12, 20, T32); +#undef SET + + /* Round 3. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + H(b,c,d) + X[k] + T[i]) <<< s). */ +#define H(x, y, z) ((x) ^ (y) ^ (z)) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + H(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 5, 4, T33); + SET(d, a, b, c, 8, 11, T34); + SET(c, d, a, b, 11, 16, T35); + SET(b, c, d, a, 14, 23, T36); + SET(a, b, c, d, 1, 4, T37); + SET(d, a, b, c, 4, 11, T38); + SET(c, d, a, b, 7, 16, T39); + SET(b, c, d, a, 10, 23, T40); + SET(a, b, c, d, 13, 4, T41); + SET(d, a, b, c, 0, 11, T42); + SET(c, d, a, b, 3, 16, T43); + SET(b, c, d, a, 6, 23, T44); + SET(a, b, c, d, 9, 4, T45); + SET(d, a, b, c, 12, 11, T46); + SET(c, d, a, b, 15, 16, T47); + SET(b, c, d, a, 2, 23, T48); +#undef SET + + /* Round 4. */ + /* Let [abcd k s t] denote the operation + a = b + ((a + I(b,c,d) + X[k] + T[i]) <<< s). */ +#define I(x, y, z) ((y) ^ ((x) | ~(z))) +#define SET(a, b, c, d, k, s, Ti)\ + t = a + I(b,c,d) + X[k] + Ti;\ + a = ROTATE_LEFT(t, s) + b + /* Do the following 16 operations. */ + SET(a, b, c, d, 0, 6, T49); + SET(d, a, b, c, 7, 10, T50); + SET(c, d, a, b, 14, 15, T51); + SET(b, c, d, a, 5, 21, T52); + SET(a, b, c, d, 12, 6, T53); + SET(d, a, b, c, 3, 10, T54); + SET(c, d, a, b, 10, 15, T55); + SET(b, c, d, a, 1, 21, T56); + SET(a, b, c, d, 8, 6, T57); + SET(d, a, b, c, 15, 10, T58); + SET(c, d, a, b, 6, 15, T59); + SET(b, c, d, a, 13, 21, T60); + SET(a, b, c, d, 4, 6, T61); + SET(d, a, b, c, 11, 10, T62); + SET(c, d, a, b, 2, 15, T63); + SET(b, c, d, a, 9, 21, T64); +#undef SET + + /* Then perform the following additions. (That is increment each + of the four registers by the value it had before this block + was started.) */ + pms->abcd[0] += a; + pms->abcd[1] += b; + pms->abcd[2] += c; + pms->abcd[3] += d; +} + +void +md5_init(md5_state_t *pms) +{ + pms->count[0] = pms->count[1] = 0; + pms->abcd[0] = 0x67452301; + pms->abcd[1] = 0xefcdab89; + pms->abcd[2] = 0x98badcfe; + pms->abcd[3] = 0x10325476; +} + +void +md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes) +{ + const md5_byte_t *p = data; + int left = nbytes; + int offset = (pms->count[0] >> 3) & 63; + md5_word_t nbits = (md5_word_t)(nbytes << 3); + + if (nbytes <= 0) + return; + + /* Update the message length. */ + pms->count[1] += nbytes >> 29; + pms->count[0] += nbits; + if (pms->count[0] < nbits) + pms->count[1]++; + + /* Process an initial partial block. */ + if (offset) { + int copy = (offset + nbytes > 64 ? 64 - offset : nbytes); + + memcpy(pms->buf + offset, p, copy); + if (offset + copy < 64) + return; + p += copy; + left -= copy; + md5_process(pms, pms->buf); + } + + /* Process full blocks. */ + for (; left >= 64; p += 64, left -= 64) + md5_process(pms, p); + + /* Process a final partial block. */ + if (left) + memcpy(pms->buf, p, left); +} + +void +md5_finish(md5_state_t *pms, md5_byte_t digest[16]) +{ + static const md5_byte_t pad[64] = { + 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + }; + md5_byte_t data[8]; + int i; + + /* Save the length before padding. */ + for (i = 0; i < 8; ++i) + data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3)); + /* Pad to 56 bytes mod 64. */ + md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1); + /* Append the length. */ + md5_append(pms, data, 8); + for (i = 0; i < 16; ++i) + digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3)); +} diff --git a/cups/md5.h b/cups/md5.h new file mode 100644 index 0000000000..a2d7b34156 --- /dev/null +++ b/cups/md5.h @@ -0,0 +1,94 @@ +/* + Copyright (C) 1999 Aladdin Enterprises. All rights reserved. + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any damages + arising from the use of this software. + + Permission is granted to anyone to use this software for any purpose, + including commercial applications, and to alter it and redistribute it + freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you must not + claim that you wrote the original software. If you use this software + in a product, an acknowledgment in the product documentation would be + appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and must not be + misrepresented as being the original software. + 3. This notice may not be removed or altered from any source distribution. + + L. Peter Deutsch + ghost@aladdin.com + + */ +/*$Id$ */ +/* + Independent implementation of MD5 (RFC 1321). + + This code implements the MD5 Algorithm defined in RFC 1321. + It is derived directly from the text of the RFC and not from the + reference implementation. + + The original and principal author of md5.h is L. Peter Deutsch + . Other authors are noted in the change history + that follows (in reverse chronological order): + + 1999-11-04 lpd Edited comments slightly for automatic TOC extraction. + 1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5); + added conditionalization for C++ compilation from Martin + Purschke . + 1999-05-03 lpd Original version. + */ + +#ifndef md5_INCLUDED +# define md5_INCLUDED + +/* + * This code has some adaptations for the Ghostscript environment, but it + * will compile and run correctly in any environment with 8-bit chars and + * 32-bit ints. Specifically, it assumes that if the following are + * defined, they have the same meaning as in Ghostscript: P1, P2, P3, + * ARCH_IS_BIG_ENDIAN. + */ + +typedef unsigned char md5_byte_t; /* 8-bit byte */ +typedef unsigned int md5_word_t; /* 32-bit word */ + +/* Define the state of the MD5 Algorithm. */ +typedef struct md5_state_s { + md5_word_t count[2]; /* message length in bits, lsw first */ + md5_word_t abcd[4]; /* digest buffer */ + md5_byte_t buf[64]; /* accumulate block */ +} md5_state_t; + +#ifdef __cplusplus +extern "C" +{ +#endif + +/* Initialize the algorithm. */ +#ifdef P1 +void md5_init(P1(md5_state_t *pms)); +#else +void md5_init(md5_state_t *pms); +#endif + +/* Append a string to the message. */ +#ifdef P3 +void md5_append(P3(md5_state_t *pms, const md5_byte_t *data, int nbytes)); +#else +void md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes); +#endif + +/* Finish the message and return the digest. */ +#ifdef P2 +void md5_finish(P2(md5_state_t *pms, md5_byte_t digest[16])); +#else +void md5_finish(md5_state_t *pms, md5_byte_t digest[16]); +#endif + +#ifdef __cplusplus +} /* end extern "C" */ +#endif + +#endif /* md5_INCLUDED */ diff --git a/cups/md5passwd.c b/cups/md5passwd.c new file mode 100644 index 0000000000..bf63460cce --- /dev/null +++ b/cups/md5passwd.c @@ -0,0 +1,148 @@ +/* + * "$Id$" + * + * MD5 password support for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * httpMD5() - Compute the MD5 sum of the username:group:password. + * httpMD5Nonce() - Combine the MD5 sum of the username, group, and password + * with the server-supplied nonce value. + * httpMD5String() - Convert an MD5 sum to a character string. + */ + +/* + * Include necessary headers... + */ + +#include "http.h" +#include "string.h" + + +/* + * 'httpMD5()' - Compute the MD5 sum of the username:group:password. + */ + +char * /* O - MD5 sum */ +httpMD5(const char *username, /* I - User name */ + const char *realm, /* I - Realm name */ + const char *passwd, /* I - Password string */ + char md5[33]) /* O - MD5 string */ +{ + md5_state_t state; /* MD5 state info */ + md5_byte_t sum[16]; /* Sum data */ + char line[256]; /* Line to sum */ + + + /* + * Compute the MD5 sum of the user name, group name, and password. + */ + + snprintf(line, sizeof(line), "%s:%s:%s", username, realm, passwd); + md5_init(&state); + md5_append(&state, (md5_byte_t *)line, strlen(line)); + md5_finish(&state, sum); + + /* + * Return the sum... + */ + + return (httpMD5String(sum, md5)); +} + + +/* + * 'httpMD5Final()' - Combine the MD5 sum of the username, group, and password + * with the server-supplied nonce value, method, and + * request-uri. + */ + +char * /* O - New sum */ +httpMD5Final(const char *nonce, /* I - Server nonce value */ + const char *method, /* I - METHOD (GET, POST, etc.) */ + const char *resource, /* I - Resource path */ + char md5[33]) /* IO - MD5 sum */ +{ + md5_state_t state; /* MD5 state info */ + md5_byte_t sum[16]; /* Sum data */ + char line[1024]; /* Line of data */ + char a2[33]; /* Hash of method and resource */ + + + /* + * First compute the MD5 sum of the method and resource... + */ + + snprintf(line, sizeof(line), "%s:%s", method, resource); + md5_init(&state); + md5_append(&state, (md5_byte_t *)line, strlen(line)); + md5_finish(&state, sum); + httpMD5String(sum, a2); + + /* + * Then combine A1 (MD5 of username, realm, and password) with the nonce + * and A2 (method + resource) values to get the final MD5 sum for the + * request... + */ + + snprintf(line, sizeof(line), "%s%s:%s", md5, nonce, a2); + + md5_init(&state); + md5_append(&state, (md5_byte_t *)line, strlen(line)); + md5_finish(&state, sum); + + return (httpMD5String(sum, md5)); +} + + +/* + * 'httpMD5String()' - Convert an MD5 sum to a character string. + */ + +char * /* O - MD5 sum in hex */ +httpMD5String(const md5_byte_t *sum, /* I - MD5 sum data */ + char md5[33]) /* O - MD5 sum in hex */ +{ + int i; /* Looping var */ + char *md5ptr; /* Pointer into MD5 string */ + static char *hex = "0123456789abcdef"; + /* Hex digits */ + + + /* + * Convert the MD5 sum to hexadecimal... + */ + + for (i = 16, md5ptr = md5; i > 0; i --, sum ++) + { + *md5ptr++ = hex[*sum >> 4]; + *md5ptr++ = hex[*sum & 15]; + } + + *md5ptr = '\0'; + + return (md5); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/options.c b/cups/options.c new file mode 100644 index 0000000000..7f3f7be7f8 --- /dev/null +++ b/cups/options.c @@ -0,0 +1,384 @@ +/* + * "$Id$" + * + * Option routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * cupsAddOption() - Add an option to an option array. + * cupsFreeOptions() - Free all memory used by options. + * cupsGetOption() - Get an option value. + * cupsParseOptions() - Parse options from a command-line argument. + * cupsMarkOptions() - Mark command-line options in a PPD file. + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include +#include +#include "string.h" + + +/* + * 'cupsAddOption()' - Add an option to an option array. + */ + +int /* O - Number of options */ +cupsAddOption(const char *name, /* I - Name of option */ + const char *value, /* I - Value of option */ + int num_options, /* I - Number of options */ + cups_option_t **options) /* IO - Pointer to options */ +{ + int i; /* Looping var */ + cups_option_t *temp; /* Pointer to new option */ + + + if (name == NULL || value == NULL || options == NULL) + return (0); + + /* + * Look for an existing option with the same name... + */ + + for (i = 0, temp = *options; i < num_options; i ++, temp ++) + if (strcasecmp(temp->name, name) == 0) + break; + + if (i >= num_options) + { + /* + * No matching option name... + */ + + if (num_options == 0) + temp = (cups_option_t *)malloc(sizeof(cups_option_t)); + else + temp = (cups_option_t *)realloc(*options, sizeof(cups_option_t) * + (num_options + 1)); + + if (temp == NULL) + return (0); + + *options = temp; + temp += num_options; + temp->name = strdup(name); + num_options ++; + } + else + { + /* + * Match found; free the old value... + */ + + free(temp->value); + } + + temp->value = strdup(value); + + return (num_options); +} + + +/* + * 'cupsFreeOptions()' - Free all memory used by options. + */ + +void +cupsFreeOptions(int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Pointer to options */ +{ + int i; /* Looping var */ + + + if (num_options == 0 || options == NULL) + return; + + for (i = 0; i < num_options; i ++) + { + free(options[i].name); + free(options[i].value); + } + + free(options); +} + + +/* + * 'cupsGetOption()' - Get an option value. + */ + +const char * /* O - Option value or NULL */ +cupsGetOption(const char *name, /* I - Name of option */ + int num_options,/* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + int i; /* Looping var */ + + + if (name == NULL || num_options == 0 || options == NULL) + return (NULL); + + for (i = 0; i < num_options; i ++) + if (strcasecmp(options[i].name, name) == 0) + return (options[i].value); + + return (NULL); +} + + +/* + * 'cupsParseOptions()' - Parse options from a command-line argument. + */ + +int /* O - Number of options found */ +cupsParseOptions(const char *arg, /* I - Argument to parse */ + int num_options, /* I - Number of options */ + cups_option_t **options) /* O - Options found */ +{ + char *copyarg, /* Copy of input string */ + *ptr, /* Pointer into string */ + *name, /* Pointer to name */ + *value; /* Pointer to value */ + + + if (arg == NULL || options == NULL) + return (0); + + /* + * Make a copy of the argument string and then divide it up... + */ + + copyarg = strdup(arg); + ptr = copyarg; + + while (*ptr != '\0') + { + /* + * Get the name up to a SPACE, =, or end-of-string... + */ + + name = ptr; + while (!isspace(*ptr) && *ptr != '=' && *ptr != '\0') + ptr ++; + + /* + * Skip trailing spaces... + */ + + while (isspace(*ptr)) + *ptr++ = '\0'; + + if (*ptr != '=') + { + /* + * Start of another option... + */ + + num_options = cupsAddOption(name, "", num_options, options); + continue; + } + + /* + * Remove = and parse the value... + */ + + *ptr++ = '\0'; + + if (*ptr == '\'') + { + /* + * Quoted string constant... + */ + + ptr ++; + value = ptr; + + while (*ptr != '\'' && *ptr != '\0') + ptr ++; + + if (*ptr != '\0') + *ptr++ = '\0'; + } + else if (*ptr == '\"') + { + /* + * Double-quoted string constant... + */ + + ptr ++; + value = ptr; + + while (*ptr != '\"' && *ptr != '\0') + ptr ++; + + if (*ptr != '\0') + *ptr++ = '\0'; + } + else + { + /* + * Normal space-delimited string... + */ + + value = ptr; + + while (!isspace(*ptr) && *ptr != '\0') + ptr ++; + + while (isspace(*ptr)) + *ptr++ = '\0'; + } + + /* + * Add the string value... + */ + + num_options = cupsAddOption(name, value, num_options, options); + } + + /* + * Free the copy of the argument we made and return the number of options + * found. + */ + + free(copyarg); + + return (num_options); +} + + +/* + * 'cupsMarkOptions()' - Mark command-line options in a PPD file. + */ + +int /* O - 1 if conflicting */ +cupsMarkOptions(ppd_file_t *ppd, /* I - PPD file */ + int num_options, /* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + int i; /* Looping var */ + int conflict; /* Option conflicts */ + char *val, /* Pointer into value */ + *ptr, /* Pointer into string */ + s[255]; /* Temporary string */ + + + conflict = 0; + + for (i = num_options; i > 0; i --, options ++) + if (strcasecmp(options->name, "media") == 0) + { + /* + * Loop through the option string, separating it at commas and + * marking each individual option. + */ + + for (val = options->value; *val;) + { + /* + * Extract the sub-option from the string... + */ + + for (ptr = s; *val && *val != ',' && (ptr - s) < (sizeof(s) - 1);) + *ptr++ = *val++; + *ptr++ = '\0'; + + if (*val == ',') + val ++; + + /* + * Mark it... + */ + + if (ppdMarkOption(ppd, "PageSize", s)) + conflict = 1; + if (ppdMarkOption(ppd, "InputSlot", s)) + conflict = 1; + if (ppdMarkOption(ppd, "MediaType", s)) + conflict = 1; + if (ppdMarkOption(ppd, "EFMediaQualityMode", s)) /* EFI */ + conflict = 1; + if (strcasecmp(s, "manual") == 0) + if (ppdMarkOption(ppd, "ManualFeed", "True")) + conflict = 1; + } + } + else if (strcasecmp(options->name, "sides") == 0) + { + if (strcasecmp(options->value, "one-sided") == 0) + { + if (ppdMarkOption(ppd, "Duplex", "None")) + conflict = 1; + if (ppdMarkOption(ppd, "EFDuplex", "None")) /* EFI */ + conflict = 1; + if (ppdMarkOption(ppd, "KD03Duplex", "None")) /* Kodak */ + conflict = 1; + } + else if (strcasecmp(options->value, "two-sided-long-edge") == 0) + { + if (ppdMarkOption(ppd, "Duplex", "DuplexNoTumble")) + conflict = 1; + if (ppdMarkOption(ppd, "EFDuplex", "DuplexNoTumble")) /* EFI */ + conflict = 1; + if (ppdMarkOption(ppd, "KD03Duplex", "DuplexNoTumble")) /* Kodak */ + conflict = 1; + } + else if (strcasecmp(options->value, "two-sided-short-edge") == 0) + { + if (ppdMarkOption(ppd, "Duplex", "DuplexTumble")) + conflict = 1; + if (ppdMarkOption(ppd, "EFDuplex", "DuplexTumble")) /* EFI */ + conflict = 1; + if (ppdMarkOption(ppd, "KD03Duplex", "DuplexTumble")) /* Kodak */ + conflict = 1; + } + } + else if (strcasecmp(options->name, "resolution") == 0 || + strcasecmp(options->name, "printer-resolution") == 0) + { + if (ppdMarkOption(ppd, "Resolution", options->value)) + conflict = 1; + if (ppdMarkOption(ppd, "SetResolution", options->value)) + /* Calcomp, Linotype, QMS, Summagraphics, Tektronix, Varityper */ + conflict = 1; + if (ppdMarkOption(ppd, "JCLResolution", options->value)) /* HP */ + conflict = 1; + if (ppdMarkOption(ppd, "CNRes_PGP", options->value)) /* Canon */ + conflict = 1; + } + else if (strcasecmp(options->name, "output-bin") == 0) + { + if (ppdMarkOption(ppd, "OutputBin", options->value)) + conflict = 1; + } + else if (ppdMarkOption(ppd, options->name, options->value)) + conflict = 1; + + return (conflict); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/page.c b/cups/page.c new file mode 100644 index 0000000000..b9a206948b --- /dev/null +++ b/cups/page.c @@ -0,0 +1,189 @@ +/* + * "$Id$" + * + * Page size functions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * PostScript is a trademark of Adobe Systems, Inc. + * + * Contents: + * + * ppdPageSize() - Get the page size record for the given size. + * ppdPageWidth() - Get the page width for the given size. + * ppdPageLength() - Get the page length for the given size. + */ + +/* + * Include necessary headers... + */ + +#include "ppd.h" +#include "string.h" +#include + + +/* + * 'ppdPageSize()' - Get the page size record for the given size. + */ + +ppd_size_t * /* O - Size record for page or NULL */ +ppdPageSize(ppd_file_t *ppd, /* I - PPD file record */ + const char *name) /* I - Size name */ +{ + int i; /* Looping var */ + float w, l; /* Width and length of page */ + char units[255]; /* Page size units... */ + + + if (ppd == NULL) + return (NULL); + + if (name != NULL) + { + if (strncmp(name, "Custom.", 7) == 0 && ppd->variable_sizes) + { + /* + * Find the custom page size... + */ + + for (i = 0; i < ppd->num_sizes; i ++) + if (strcmp("Custom", ppd->sizes[i].name) == 0) + break; + + if (i == ppd->num_sizes) + return (NULL); + + /* + * Variable size; size name can be one of the following: + * + * Custom.WIDTHxLENGTHin - Size in inches + * Custom.WIDTHxLENGTHcm - Size in centimeters + * Custom.WIDTHxLENGTHmm - Size in millimeters + * Custom.WIDTHxLENGTH[pt] - Size in points + */ + + units[0] = '\0'; + if (sscanf(name + 7, "%fx%f%254s", &w, &l, units) < 2) + return (NULL); + + if (strcasecmp(units, "in") == 0) + { + ppd->sizes[i].width = w * 72.0f; + ppd->sizes[i].length = l * 72.0f; + ppd->sizes[i].left = ppd->custom_margins[0]; + ppd->sizes[i].bottom = ppd->custom_margins[1]; + ppd->sizes[i].right = w * 72.0f - ppd->custom_margins[2]; + ppd->sizes[i].top = l * 72.0f - ppd->custom_margins[3]; + } + else if (strcasecmp(units, "cm") == 0) + { + ppd->sizes[i].width = w / 2.54f * 72.0f; + ppd->sizes[i].length = l / 2.54f * 72.0f; + ppd->sizes[i].left = ppd->custom_margins[0]; + ppd->sizes[i].bottom = ppd->custom_margins[1]; + ppd->sizes[i].right = w / 2.54f * 72.0f - ppd->custom_margins[2]; + ppd->sizes[i].top = l / 2.54f * 72.0f - ppd->custom_margins[3]; + } + else if (strcasecmp(units, "mm") == 0) + { + ppd->sizes[i].width = w / 25.4f * 72.0f; + ppd->sizes[i].length = l / 25.4f * 72.0f; + ppd->sizes[i].left = ppd->custom_margins[0]; + ppd->sizes[i].bottom = ppd->custom_margins[1]; + ppd->sizes[i].right = w / 25.4f * 72.0f - ppd->custom_margins[2]; + ppd->sizes[i].top = l / 25.4f * 72.0f - ppd->custom_margins[3]; + } + else + { + ppd->sizes[i].width = w; + ppd->sizes[i].length = l; + ppd->sizes[i].left = ppd->custom_margins[0]; + ppd->sizes[i].bottom = ppd->custom_margins[1]; + ppd->sizes[i].right = w - ppd->custom_margins[2]; + ppd->sizes[i].top = l - ppd->custom_margins[3]; + } + + return (ppd->sizes + i); + } + else + { + /* + * Lookup by name... + */ + + for (i = 0; i < ppd->num_sizes; i ++) + if (strcmp(name, ppd->sizes[i].name) == 0) + return (ppd->sizes + i); + } + } + else + { + /* + * Find default... + */ + + for (i = 0; i < ppd->num_sizes; i ++) + if (ppd->sizes[i].marked) + return (ppd->sizes + i); + } + + return (NULL); +} + + +/* + * 'ppdPageWidth()' - Get the page width for the given size. + */ + +float /* O - Width of page in points or 0.0 */ +ppdPageWidth(ppd_file_t *ppd, /* I - PPD file record */ + const char *name) /* I - Size name */ +{ + ppd_size_t *size; /* Page size */ + + + if ((size = ppdPageSize(ppd, name)) == NULL) + return (0.0); + else + return (size->width); +} + + +/* + * 'ppdPageLength()' - Get the page length for the given size. + */ + +float /* O - Length of page in points or 0.0 */ +ppdPageLength(ppd_file_t *ppd, /* I - PPD file */ + const char *name) /* I - Size name */ +{ + ppd_size_t *size; /* Page size */ + + + if ((size = ppdPageSize(ppd, name)) == NULL) + return (0.0); + else + return (size->length); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/ppd.c b/cups/ppd.c new file mode 100644 index 0000000000..1aa9821e94 --- /dev/null +++ b/cups/ppd.c @@ -0,0 +1,1904 @@ +/* + * "$Id$" + * + * PPD file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * PostScript is a trademark of Adobe Systems, Inc. + * + * This code and any derivative of it may be used and distributed + * freely under the terms of the GNU General Public License when + * used with GNU Ghostscript or its derivatives. Use of the code + * (or any derivative of it) with software other than GNU + * GhostScript (or its derivatives) is governed by the CUPS license + * agreement. + * + * Contents: + * + * ppdClose() - Free all memory used by the PPD file. + * ppd_free_group() - Free a single UI group. + * ppd_free_option() - Free a single option. + * ppdOpen() - Read a PPD file into memory. + * ppdOpenFd() - Read a PPD file into memory. + * ppdOpenFile() - Read a PPD file into memory. + * ppd_read() - Read a line from a PPD file, skipping comment lines + * as necessary. + * compare_strings() - Compare two strings. + * compare_groups() - Compare two groups. + * compare_options() - Compare two options. + * compare_choices() - Compare two choices. + */ + +/* + * Include necessary headers. + */ + +#include "ppd.h" +#include +#include +#include "string.h" +#include "language.h" +#include "debug.h" + + +/* + * Definitions... + */ + +#if defined(WIN32) || defined(__EMX__) +# define READ_BINARY "rb" /* Open a binary file for reading */ +# define WRITE_BINARY "wb" /* Open a binary file for writing */ +#else +# define READ_BINARY "r" /* Open a binary file for reading */ +# define WRITE_BINARY "w" /* Open a binary file for writing */ +#endif /* WIN32 || __EMX__ */ + +#define safe_free(p) if (p) free(p) /* Safe free macro */ + +#define PPD_KEYWORD 1 /* Line contained a keyword */ +#define PPD_OPTION 2 /* Line contained an option name */ +#define PPD_TEXT 4 /* Line contained human-readable text */ +#define PPD_STRING 8 /* Line contained a string or code */ + + +/* + * Local functions... + */ + +static int compare_strings(char *s, char *t); +static int compare_groups(ppd_group_t *g0, ppd_group_t *g1); +static int compare_options(ppd_option_t *o0, ppd_option_t *o1); +static int compare_choices(ppd_choice_t *c0, ppd_choice_t *c1); +static int ppd_read(FILE *fp, char *keyword, char *option, + char *text, char **string); +static void ppd_decode(char *string); +static void ppd_fix(char *string); +static void ppd_free_group(ppd_group_t *group); +static void ppd_free_option(ppd_option_t *option); +static ppd_group_t *ppd_get_group(ppd_file_t *ppd, char *name); +static ppd_option_t *ppd_get_option(ppd_group_t *group, char *name); +static ppd_choice_t *ppd_add_choice(ppd_option_t *option, char *name); + + +/* + * 'ppdClose()' - Free all memory used by the PPD file. + */ + +void +ppdClose(ppd_file_t *ppd) /* I - PPD file record */ +{ + int i; /* Looping var */ + ppd_emul_t *emul; /* Current emulation */ + ppd_group_t *group; /* Current group */ + char **font; /* Current font */ + + + /* + * Range check the PPD file record... + */ + + if (ppd == NULL) + return; + + /* + * Free all strings at the top level... + */ + + safe_free(ppd->lang_encoding); + safe_free(ppd->lang_version); + safe_free(ppd->modelname); + safe_free(ppd->ttrasterizer); + safe_free(ppd->manufacturer); + safe_free(ppd->product); + safe_free(ppd->nickname); + safe_free(ppd->shortnickname); + + /* + * Free any emulations... + */ + + if (ppd->num_emulations > 0) + { + for (i = ppd->num_emulations, emul = ppd->emulations; i > 0; i --, emul ++) + { + safe_free(emul->start); + safe_free(emul->stop); + } + + safe_free(ppd->emulations); + } + + /* + * Free any UI groups, subgroups, and options... + */ + + if (ppd->num_groups > 0) + { + for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) + ppd_free_group(group); + + safe_free(ppd->groups); + } + + /* + * Free any page sizes... + */ + + if (ppd->num_sizes > 0) + safe_free(ppd->sizes); + + /* + * Free any constraints... + */ + + if (ppd->num_consts > 0) + safe_free(ppd->consts); + + /* + * Free any fonts... + */ + + if (ppd->num_fonts > 0) + { + for (i = ppd->num_fonts, font = ppd->fonts; i > 0; i --, font ++) + safe_free(*font); + + safe_free(ppd->fonts); + } + + /* + * Free any profiles... + */ + + if (ppd->num_profiles > 0) + safe_free(ppd->profiles); + + /* + * Free the whole record... + */ + + safe_free(ppd); +} + + +/* + * 'ppd_free_group()' - Free a single UI group. + */ + +static void +ppd_free_group(ppd_group_t *group) /* I - Group to free */ +{ + int i; /* Looping var */ + ppd_option_t *option; /* Current option */ + ppd_group_t *subgroup; /* Current sub-group */ + + + if (group->num_options > 0) + { + for (i = group->num_options, option = group->options; + i > 0; + i --, option ++) + ppd_free_option(option); + + safe_free(group->options); + } + + if (group->num_subgroups > 0) + { + for (i = group->num_subgroups, subgroup = group->subgroups; + i > 0; + i --, subgroup ++) + ppd_free_group(subgroup); + + safe_free(group->subgroups); + } +} + + +/* + * 'ppd_free_option()' - Free a single option. + */ + +static void +ppd_free_option(ppd_option_t *option) /* I - Option to free */ +{ + int i; /* Looping var */ + ppd_choice_t *choice; /* Current choice */ + + + if (option->num_choices > 0) + { + for (i = option->num_choices, choice = option->choices; + i > 0; + i --, choice ++) + safe_free(choice->code); + + safe_free(option->choices); + } +} + + +/* + * 'ppd_get_group()' - Find or create the named group as needed. + */ + +static ppd_group_t * /* O - Named group */ +ppd_get_group(ppd_file_t *ppd, /* I - PPD file */ + char *name) /* I - Name of group */ +{ + int i; /* Looping var */ + ppd_group_t *group; /* Group */ + + + for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) + if (strcmp(group->text, name) == 0) + break; + + if (i == 0) + { + if (ppd->num_groups == 0) + group = malloc(sizeof(ppd_group_t)); + else + group = realloc(ppd->groups, + (ppd->num_groups + 1) * sizeof(ppd_group_t)); + + if (group == NULL) + return (NULL); + + ppd->groups = group; + group += ppd->num_groups; + ppd->num_groups ++; + + memset(group, 0, sizeof(ppd_group_t)); + strncpy(group->text, name, sizeof(group->text) - 1); + } + + return (group); +} + + +/* + * 'ppd_get_option()' - Find or create the named option as needed. + */ + +static ppd_option_t * /* O - Named option */ +ppd_get_option(ppd_group_t *group, /* I - Group */ + char *name) /* I - Name of option */ +{ + int i; /* Looping var */ + ppd_option_t *option; /* Option */ + + + for (i = group->num_options, option = group->options; i > 0; i --, option ++) + if (strcmp(option->keyword, name) == 0) + break; + + if (i == 0) + { + if (group->num_options == 0) + option = malloc(sizeof(ppd_option_t)); + else + option = realloc(group->options, + (group->num_options + 1) * sizeof(ppd_option_t)); + + if (option == NULL) + return (NULL); + + group->options = option; + option += group->num_options; + group->num_options ++; + + memset(option, 0, sizeof(ppd_option_t)); + strncpy(option->keyword, name, sizeof(option->keyword) - 1); + } + + return (option); +} + + +/* + * 'ppd_add_choice()' - Add a choice to an option. + */ + +static ppd_choice_t * /* O - Named choice */ +ppd_add_choice(ppd_option_t *option, /* I - Option */ + char *name) /* I - Name of choice */ +{ + ppd_choice_t *choice; /* Choice */ + + + if (option->num_choices == 0) + choice = malloc(sizeof(ppd_choice_t)); + else + choice = realloc(option->choices, + sizeof(ppd_choice_t) * (option->num_choices + 1)); + + if (choice == NULL) + return (NULL); + + option->choices = choice; + choice += option->num_choices; + option->num_choices ++; + + memset(choice, 0, sizeof(ppd_choice_t)); + strncpy(choice->choice, name, sizeof(choice->choice) - 1); + + return (choice); +} + + +/* + * 'ppd_add_size()' - Add a page size. + */ + +static ppd_size_t * /* O - Named size */ +ppd_add_size(ppd_file_t *ppd, /* I - PPD file */ + char *name) /* I - Name of size */ +{ + ppd_size_t *size; /* Size */ + + + if (ppd->num_sizes == 0) + size = malloc(sizeof(ppd_size_t)); + else + size = realloc(ppd->sizes, sizeof(ppd_size_t) * (ppd->num_sizes + 1)); + + if (size == NULL) + return (NULL); + + ppd->sizes = size; + size += ppd->num_sizes; + ppd->num_sizes ++; + + memset(size, 0, sizeof(ppd_size_t)); + strncpy(size->name, name, sizeof(size->name) - 1); + + return (size); +} + + +/* + * 'ppdOpen()' - Read a PPD file into memory. + */ + +ppd_file_t * /* O - PPD file record */ +ppdOpen(FILE *fp) /* I - File to read from */ +{ + int i, j, k, m; /* Looping vars */ + int count; /* Temporary count */ + ppd_file_t *ppd; /* PPD file record */ + ppd_group_t *group, /* Current group */ + *subgroup; /* Current sub-group */ + ppd_option_t *option; /* Current option */ + ppd_choice_t *choice; /* Current choice */ + ppd_const_t *constraint; /* Current constraint */ + ppd_size_t *size; /* Current page size */ + int mask; /* Line data mask */ + char keyword[41], /* Keyword from file */ + name[41], /* Option from file */ + text[81], /* Human-readable text from file */ + *string, /* Code/text from file */ + *sptr, /* Pointer into string */ + *nameptr; /* Pointer into name */ + float order; /* Order dependency number */ + ppd_section_t section; /* Order dependency section */ + ppd_profile_t *profile; /* Pointer to color profile */ + char **filter; /* Pointer to filter */ + cups_lang_t *language; /* Default language */ + + + /* + * Get the default language for the user... + */ + + language = cupsLangDefault(); + + /* + * Range check input... + */ + + if (fp == NULL) + return (NULL); + + /* + * Grab the first line and make sure it reads '*PPD-Adobe: "major.minor"'... + */ + + mask = ppd_read(fp, keyword, name, text, &string); + + if (mask == 0 || + strcmp(keyword, "PPD-Adobe") != 0 || + string == NULL || string[0] != '4') + { + /* + * Either this is not a PPD file, or it is not a 4.x PPD file. + */ + + safe_free(string); + + return (NULL); + } + + DEBUG_printf(("ppdOpen: keyword = %s, string = %08x\n", keyword, string)); + + safe_free(string); + + /* + * Allocate memory for the PPD file record... + */ + + if ((ppd = calloc(sizeof(ppd_file_t), 1)) == NULL) + return (NULL); + + ppd->language_level = 1; + ppd->color_device = 0; + ppd->colorspace = PPD_CS_GRAY; + ppd->landscape = 90; + + /* + * Read lines from the PPD file and add them to the file record... + */ + + group = NULL; + subgroup = NULL; + option = NULL; + choice = NULL; + + while ((mask = ppd_read(fp, keyword, name, text, &string)) != 0) + { +#ifdef DEBUG + printf("mask = %x, keyword = \"%s\"", mask, keyword); + + if (name[0] != '\0') + printf(", name = \"%s\"", name); + + if (text[0] != '\0') + printf(", text = \"%s\"", text); + + if (string != NULL) + { + if (strlen(string) > 40) + printf(", string = %08x", string); + else + printf(", string = \"%s\"", string); + } + + puts(""); +#endif /* DEBUG */ + + if (strcmp(keyword, "LanguageLevel") == 0) + ppd->language_level = atoi(string); + else if (strcmp(keyword, "LanguageEncoding") == 0) + { + ppd->lang_encoding = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "LanguageVersion") == 0) + { + ppd->lang_version = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "Manufacturer") == 0) + { + ppd->manufacturer = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "ModelName") == 0) + { + ppd->modelname = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "NickName") == 0) + { + ppd->nickname = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "Product") == 0) + { + ppd->product = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "ShortNickName") == 0) + { + ppd->shortnickname = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "TTRasterizer") == 0) + { + ppd->ttrasterizer = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "JCLBegin") == 0) + { + ppd_decode(string); /* Decode quoted string */ + ppd->jcl_begin = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "JCLEnd") == 0) + { + ppd_decode(string); /* Decode quoted string */ + ppd->jcl_end = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "JCLToPSInterpreter") == 0) + { + ppd_decode(string); /* Decode quoted string */ + ppd->jcl_ps = string; + string = NULL; /* Don't free this string below */ + } + else if (strcmp(keyword, "AccurateScreensSupport") == 0) + ppd->accurate_screens = strcmp(string, "True") == 0; + else if (strcmp(keyword, "ColorDevice") == 0) + ppd->color_device = strcmp(string, "True") == 0; + else if (strcmp(keyword, "ContoneOnly") == 0) + ppd->contone_only = strcmp(string, "True") == 0; + else if (strcmp(keyword, "DefaultColorSpace") == 0) + { + if (strcmp(string, "CMY") == 0) + ppd->colorspace = PPD_CS_CMY; + else if (strcmp(string, "CMYK") == 0) + ppd->colorspace = PPD_CS_CMYK; + else if (strcmp(string, "RGB") == 0) + ppd->colorspace = PPD_CS_RGB; + else if (strcmp(string, "RGBK") == 0) + ppd->colorspace = PPD_CS_RGBK; + else if (strcmp(string, "N") == 0) + ppd->colorspace = PPD_CS_N; + else + ppd->colorspace = PPD_CS_GRAY; + } + else if (strcmp(keyword, "cupsFlipDuplex") == 0) + ppd->flip_duplex = strcmp(string, "True") == 0; + else if (strcmp(keyword, "cupsManualCopies") == 0) + ppd->manual_copies = strcmp(string, "True") == 0; + else if (strcmp(keyword, "cupsModelNumber") == 0) + ppd->model_number = atoi(string); + else if (strcmp(keyword, "cupsColorProfile") == 0) + { + if (ppd->num_profiles == 0) + profile = malloc(sizeof(ppd_profile_t)); + else + profile = realloc(ppd->profiles, sizeof(ppd_profile_t) * + (ppd->num_profiles + 1)); + + ppd->profiles = profile; + profile += ppd->num_profiles; + ppd->num_profiles ++; + + memset(profile, 0, sizeof(ppd_profile_t)); + strncpy(profile->resolution, name, sizeof(profile->resolution) - 1); + strncpy(profile->media_type, text, sizeof(profile->media_type) - 1); + sscanf(string, "%f%f%f%f%f%f%f%f%f%f%f", &(profile->density), + &(profile->gamma), + profile->matrix[0] + 0, profile->matrix[0] + 1, + profile->matrix[0] + 2, profile->matrix[1] + 0, + profile->matrix[1] + 1, profile->matrix[1] + 2, + profile->matrix[2] + 0, profile->matrix[2] + 1, + profile->matrix[2] + 2); + } + else if (strcmp(keyword, "cupsFilter") == 0) + { + if (ppd->num_filters == 0) + filter = malloc(sizeof(char *)); + else + filter = realloc(ppd->filters, sizeof(char *) * (ppd->num_filters + 1)); + + ppd->filters = filter; + filter += ppd->num_filters; + ppd->num_filters ++; + + /* + * Copy filter string and prevent it from being freed below... + */ + + *filter = string; + string = NULL; + } + else if (strcmp(keyword, "Throughput") == 0) + ppd->throughput = atoi(string); + else if (strcmp(keyword, "Font") == 0) + { + /* + * Add this font to the list of available fonts... + */ + + if (ppd->num_fonts == 0) + ppd->fonts = (char **)malloc(sizeof(char *)); + else + ppd->fonts = (char **)realloc(ppd->fonts, + sizeof(char *) * (ppd->num_fonts + 1)); + + if (ppd->fonts == NULL) + { + ppdClose(ppd); + return (NULL); + } + + ppd->fonts[ppd->num_fonts] = strdup(name); + ppd->num_fonts ++; + } + else if (strcmp(keyword, "VariablePaperSize") == 0 && + strcmp(string, "True") == 0 && + !ppd->variable_sizes) + { + ppd->variable_sizes = 1; + + /* + * Add a "Custom" page size entry... + */ + + ppd_add_size(ppd, "Custom"); + + /* + * Add a "Custom" page size option... + */ + + if ((option = ppdFindOption(ppd, "PageSize")) == NULL) + { + ppd_group_t *temp; + + + if ((temp = ppd_get_group(ppd, + cupsLangString(language, + CUPS_MSG_GENERAL))) == NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + if ((option = ppd_get_option(temp, "PageSize")) == NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + } + + if ((choice = ppd_add_choice(option, "Custom")) == NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + strncpy(choice->text, cupsLangString(language, CUPS_MSG_VARIABLE), + sizeof(choice->text) - 1); + option = NULL; + } + else if (strcmp(keyword, "MaxMediaWidth") == 0) + ppd->custom_max[0] = (float)atof(string); + else if (strcmp(keyword, "MaxMediaHeight") == 0) + ppd->custom_max[1] = (float)atof(string); + else if (strcmp(keyword, "ParamCustomPageSize") == 0) + { + if (strcmp(name, "Width") == 0) + sscanf(string, "%*s%*s%f%f", ppd->custom_min + 0, + ppd->custom_max + 0); + else if (strcmp(name, "Height") == 0) + sscanf(string, "%*s%*s%f%f", ppd->custom_min + 1, + ppd->custom_max + 1); + } + else if (strcmp(keyword, "HWMargins") == 0) + sscanf(string, "%f%f%f%f", ppd->custom_margins + 0, + ppd->custom_margins + 1, ppd->custom_margins + 2, + ppd->custom_margins + 3); + else if (strcmp(keyword, "CustomPageSize") == 0 && + strcmp(name, "True") == 0) + { + if (!ppd->variable_sizes) + { + ppd->variable_sizes = 1; + + /* + * Add a "Custom" page size entry... + */ + + ppd_add_size(ppd, "Custom"); + + /* + * Add a "Custom" page size option... + */ + + if ((option = ppdFindOption(ppd, "PageSize")) == NULL) + { + ppd_group_t *temp; + + + if ((temp = ppd_get_group(ppd, + cupsLangString(language, + CUPS_MSG_GENERAL))) == NULL) + { + DEBUG_puts("Unable to get general group!"); + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + if ((option = ppd_get_option(temp, "PageSize")) == NULL) + { + DEBUG_puts("Unable to get PageSize option!"); + ppdClose(ppd); + safe_free(string); + return (NULL); + } + } + + if ((choice = ppd_add_choice(option, "Custom")) == NULL) + { + DEBUG_puts("Unable to add Custom choice!"); + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + strncpy(choice->text, cupsLangString(language, CUPS_MSG_VARIABLE), + sizeof(choice->text) - 1); + option = NULL; + } + + if ((option = ppdFindOption(ppd, "PageSize")) == NULL) + { + DEBUG_puts("Unable to find PageSize option!"); + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + if ((choice = ppdFindChoice(option, "Custom")) == NULL) + { + DEBUG_puts("Unable to find Custom choice!"); + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + choice->code = string; + string = NULL; + option = NULL; + } + else if (strcmp(keyword, "LandscapeOrientation") == 0) + { + if (strcmp(string, "Minus90") == 0) + ppd->landscape = -90; + else + ppd->landscape = 90; + } + else if (strcmp(keyword, "Emulators") == 0) + { + for (count = 1, sptr = string; sptr != NULL;) + if ((sptr = strchr(sptr, ' ')) != NULL) + { + count ++; + while (*sptr == ' ') + sptr ++; + } + + ppd->num_emulations = count; + ppd->emulations = calloc(sizeof(ppd_emul_t), count); + + for (i = 0, sptr = string; i < count; i ++) + { + for (nameptr = ppd->emulations[i].name; *sptr != '\0' && *sptr != ' ';) + *nameptr ++ = *sptr ++; + + *nameptr = '\0'; + + while (*sptr == ' ') + sptr ++; + } + } + else if (strncmp(keyword, "StartEmulator_", 14) == 0) + { + ppd_decode(string); + + for (i = 0; i < ppd->num_emulations; i ++) + if (strcmp(keyword + 14, ppd->emulations[i].name) == 0) + { + ppd->emulations[i].start = string; + string = NULL; + } + } + else if (strncmp(keyword, "StopEmulator_", 13) == 0) + { + ppd_decode(string); + + for (i = 0; i < ppd->num_emulations; i ++) + if (strcmp(keyword + 13, ppd->emulations[i].name) == 0) + { + ppd->emulations[i].stop = string; + string = NULL; + } + } + else if (strcmp(keyword, "JobPatchFile") == 0) + { + if (ppd->patches == NULL) + { + ppd->patches = string; + string = NULL; + } + else + { + ppd->patches = realloc(ppd->patches, strlen(ppd->patches) + + strlen(string) + 1); + + strcpy(ppd->patches + strlen(ppd->patches), string); + } + } + else if (strcmp(keyword, "OpenUI") == 0) + { + /* + * Add an option record to the current sub-group, group, or file... + */ + + if (name[0] == '*') + strcpy(name, name + 1); + + if (string == NULL) + { + ppdClose(ppd); + return (NULL); + } + + if (subgroup != NULL) + option = ppd_get_option(subgroup, name); + else if (group == NULL) + { + if (strcmp(name, "Collate") != 0 && + strcmp(name, "Duplex") != 0 && + strcmp(name, "InputSlot") != 0 && + strcmp(name, "ManualFeed") != 0 && + strcmp(name, "MediaType") != 0 && + strcmp(name, "MediaColor") != 0 && + strcmp(name, "MediaWeight") != 0 && + strcmp(name, "OutputBin") != 0 && + strcmp(name, "OutputMode") != 0 && + strcmp(name, "OutputOrder") != 0 && + strcmp(name, "PageSize") != 0 && + strcmp(name, "PageRegion") != 0) + group = ppd_get_group(ppd, cupsLangString(language, CUPS_MSG_EXTRA)); + else + group = ppd_get_group(ppd, cupsLangString(language, CUPS_MSG_GENERAL)); + + if (group == NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + option = ppd_get_option(group, name); + group = NULL; + } + else + option = ppd_get_option(group, name); + + if (option == NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + /* + * Now fill in the initial information for the option... + */ + + if (strcmp(string, "PickMany") == 0) + option->ui = PPD_UI_PICKMANY; + else if (strcmp(string, "Boolean") == 0) + option->ui = PPD_UI_BOOLEAN; + else + option->ui = PPD_UI_PICKONE; + + if (text[0]) + { + strncpy(option->text, text, sizeof(option->text) - 1); + ppd_fix(option->text); + } + else + { + if (strcmp(name, "PageSize") == 0) + strncpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_SIZE), + sizeof(option->text) - 1); + else if (strcmp(name, "MediaType") == 0) + strncpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_TYPE), + sizeof(option->text) - 1); + else if (strcmp(name, "InputSlot") == 0) + strncpy(option->text, cupsLangString(language, CUPS_MSG_MEDIA_SOURCE), + sizeof(option->text) - 1); + else if (strcmp(name, "ColorModel") == 0) + strncpy(option->text, cupsLangString(language, CUPS_MSG_OUTPUT_MODE), + sizeof(option->text) - 1); + else if (strcmp(name, "Resolution") == 0) + strncpy(option->text, cupsLangString(language, CUPS_MSG_RESOLUTION), + sizeof(option->text) - 1); + else + strncpy(option->text, name, sizeof(option->text) - 1); + } + + option->section = PPD_ORDER_ANY; + } + else if (strcmp(keyword, "JCLOpenUI") == 0) + { + /* + * Find the JCL group, and add if needed... + */ + + group = ppd_get_group(ppd, "JCL"); + + if (group == NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + /* + * Add an option record to the current JCLs... + */ + + if (name[0] == '*') + strcpy(name, name + 1); + + option = ppd_get_option(group, name); + + if (option == NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + /* + * Now fill in the initial information for the option... + */ + + if (strcmp(string, "PickMany") == 0) + option->ui = PPD_UI_PICKMANY; + else if (strcmp(string, "Boolean") == 0) + option->ui = PPD_UI_BOOLEAN; + else + option->ui = PPD_UI_PICKONE; + + strncpy(option->text, text, sizeof(option->text) - 1); + + option->section = PPD_ORDER_JCL; + group = NULL; + } + else if (strcmp(keyword, "CloseUI") == 0 || + strcmp(keyword, "JCLCloseUI") == 0) + option = NULL; + else if (strcmp(keyword, "OpenGroup") == 0) + { + /* + * Open a new group... + */ + + if (group != NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + if (strchr(string, '/') != NULL) /* Just show human readable text */ + strcpy(string, strchr(string, '/') + 1); + + ppd_decode(string); + ppd_fix(string); + group = ppd_get_group(ppd, string); + } + else if (strcmp(keyword, "CloseGroup") == 0) + group = NULL; + else if (strcmp(keyword, "OpenSubGroup") == 0) + { + /* + * Open a new sub-group... + */ + + DEBUG_printf(("group = %p, subgroup = %p\n", group, subgroup)); + + if (group == NULL || subgroup != NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + if (group->num_subgroups == 0) + subgroup = malloc(sizeof(ppd_group_t)); + else + subgroup = realloc(group->subgroups, + (group->num_subgroups + 1) * sizeof(ppd_group_t)); + + if (subgroup == NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + group->subgroups = subgroup; + subgroup += group->num_subgroups; + group->num_subgroups ++; + + memset(subgroup, 0, sizeof(ppd_group_t)); + ppd_decode(string); + ppd_fix(string); + strncpy(subgroup->text, string, sizeof(subgroup->text) - 1); + } + else if (strcmp(keyword, "CloseSubGroup") == 0) + subgroup = NULL; + else if (strcmp(keyword, "OrderDependency") == 0 || + strcmp(keyword, "NonUIOrderDependency") == 0) + { + if (sscanf(string, "%f%40s%40s", &order, name, keyword) != 3) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + if (keyword[0] == '*') + strcpy(keyword, keyword + 1); + + if (strcmp(name, "ExitServer") == 0) + section = PPD_ORDER_EXIT; + else if (strcmp(name, "Prolog") == 0) + section = PPD_ORDER_PROLOG; + else if (strcmp(name, "DocumentSetup") == 0) + section = PPD_ORDER_DOCUMENT; + else if (strcmp(name, "PageSetup") == 0) + section = PPD_ORDER_PAGE; + else if (strcmp(name, "JCLSetup") == 0) + section = PPD_ORDER_JCL; + else + section = PPD_ORDER_ANY; + + if (option == NULL) + { + ppd_group_t *temp; + + + /* + * Only valid for Non-UI options... + */ + + for (i = ppd->num_groups, temp = ppd->groups; i > 0; i --, temp ++) + if (temp->text[0] == '\0') + break; + + if (i > 0) + for (i = 0; i < temp->num_options; i ++) + if (strcmp(keyword, temp->options[i].keyword) == 0) + { + temp->options[i].section = section; + temp->options[i].order = order; + break; + } + } + else + { + option->section = section; + option->order = order; + } + } + else if (strncmp(keyword, "Default", 7) == 0) + { + if (string == NULL) + continue; + + if (strchr(string, '/') != NULL) + *strchr(string, '/') = '\0'; + + if (option == NULL) + { + ppd_group_t *temp; + + + /* + * Only valid for Non-UI options... + */ + + for (i = ppd->num_groups, temp = ppd->groups; i > 0; i --, temp ++) + if (temp->text[0] == '\0') + break; + + if (i > 0) + for (i = 0; i < temp->num_options; i ++) + if (strcmp(keyword, temp->options[i].keyword) == 0) + { + strncpy(temp->options[i].defchoice, string, + sizeof(temp->options[i].defchoice) - 1); + break; + } + } + else + strncpy(option->defchoice, string, sizeof(option->defchoice) - 1); + } + else if (strcmp(keyword, "UIConstraints") == 0 || + strcmp(keyword, "NonUIConstraints") == 0) + { + if (ppd->num_consts == 0) + constraint = calloc(sizeof(ppd_const_t), 1); + else + constraint = realloc(ppd->consts, + (ppd->num_consts + 1) * sizeof(ppd_const_t)); + + if (constraint == NULL) + { + ppdClose(ppd); + safe_free(string); + return (NULL); + } + + ppd->consts = constraint; + constraint += ppd->num_consts; + ppd->num_consts ++; + + switch (sscanf(string, "%40s%40s%40s%40s", constraint->option1, + constraint->choice1, constraint->option2, + constraint->choice2)) + { + case 0 : /* Error */ + case 1 : /* Error */ + ppdClose(ppd); + safe_free(string); + break; + + case 2 : /* Two options... */ + if (constraint->option1[0] == '*') + strcpy(constraint->option1, constraint->option1 + 1); + + if (constraint->choice1[0] == '*') + strcpy(constraint->option2, constraint->choice1 + 1); + else + strcpy(constraint->option2, constraint->choice1); + + constraint->choice1[0] = '\0'; + constraint->choice2[0] = '\0'; + break; + + case 3 : /* Two options, one choice... */ + if (constraint->option1[0] == '*') + strcpy(constraint->option1, constraint->option1 + 1); + + if (constraint->choice1[0] == '*') + { + strcpy(constraint->choice2, constraint->option2); + strcpy(constraint->option2, constraint->choice1 + 1); + constraint->choice1[0] = '\0'; + } + else + { + if (constraint->option2[0] == '*') + strcpy(constraint->option2, constraint->option2 + 1); + + constraint->choice2[0] = '\0'; + } + break; + + case 4 : /* Two options, two choices... */ + if (constraint->option1[0] == '*') + strcpy(constraint->option1, constraint->option1 + 1); + + if (constraint->option2[0] == '*') + strcpy(constraint->option2, constraint->option2 + 1); + break; + } + } + else if (strcmp(keyword, "PaperDimension") == 0) + { + if ((size = ppdPageSize(ppd, name)) != NULL) + sscanf(string, "%f%f", &(size->width), &(size->length)); + } + else if (strcmp(keyword, "ImageableArea") == 0) + { + if ((size = ppdPageSize(ppd, name)) != NULL) + sscanf(string, "%f%f%f%f", &(size->left), &(size->bottom), + &(size->right), &(size->top)); + } + else if (option != NULL && + (mask & (PPD_KEYWORD | PPD_OPTION | PPD_STRING)) == + (PPD_KEYWORD | PPD_OPTION | PPD_STRING)) + { + DEBUG_printf(("group = %p, subgroup = %p\n", group, subgroup)); + + if (strcmp(keyword, "PageSize") == 0) + { + /* + * Add a page size... + */ + + ppd_add_size(ppd, name); + } + + /* + * Add the option choice... + */ + + choice = ppd_add_choice(option, name); + + if (mask & PPD_TEXT) + { + strncpy(choice->text, text, sizeof(choice->text) - 1); + ppd_fix(choice->text); + } + else if (strcmp(name, "True") == 0) + strcpy(choice->text, "Yes"); + else if (strcmp(name, "False") == 0) + strcpy(choice->text, "No"); + else + strncpy(choice->text, name, sizeof(choice->text) - 1); + + if (strncmp(keyword, "JCL", 3) == 0) + ppd_decode(string); /* Decode quoted string */ + + choice->code = string; + string = NULL; /* Don't free this string below */ + } + + safe_free(string); + } + +#ifdef DEBUG + if (!feof(fp)) + printf("Premature EOF at %d...\n", ftell(fp)); +#endif /* DEBUG */ + + /* + * Set the option back-pointer for each choice... + */ + + qsort(ppd->groups, ppd->num_groups, sizeof(ppd_group_t), + (int (*)(const void *, const void *))compare_groups); + + for (i = ppd->num_groups, group = ppd->groups; + i > 0; + i --, group ++) + { + qsort(group->options, group->num_options, sizeof(ppd_option_t), + (int (*)(const void *, const void *))compare_options); + + for (j = group->num_options, option = group->options; + j > 0; + j --, option ++) + { + qsort(option->choices, option->num_choices, sizeof(ppd_choice_t), + (int (*)(const void *, const void *))compare_choices); + + for (k = 0; k < option->num_choices; k ++) + option->choices[k].option = (void *)option; + } + + qsort(group->subgroups, group->num_subgroups, sizeof(ppd_group_t), + (int (*)(const void *, const void *))compare_groups); + + for (j = group->num_subgroups, subgroup = group->subgroups; + j > 0; + j --, subgroup ++) + { + qsort(subgroup->options, subgroup->num_options, sizeof(ppd_option_t), + (int (*)(const void *, const void *))compare_options); + + for (k = group->num_options, option = group->options; + k > 0; + k --, option ++) + { + qsort(option->choices, option->num_choices, sizeof(ppd_choice_t), + (int (*)(const void *, const void *))compare_choices); + + for (m = 0; m < option->num_choices; m ++) + option->choices[m].option = (void *)option; + } + } + } + + return (ppd); +} + + +/* + * 'ppdOpenFd()' - Read a PPD file into memory. + */ + +ppd_file_t * /* O - PPD file record */ +ppdOpenFd(int fd) /* I - File to read from */ +{ + FILE *fp; /* File pointer */ + ppd_file_t *ppd; /* PPD file record */ + + + /* + * Range check input... + */ + + if (fd < 0) + return (NULL); + + /* + * Try to open the file and parse it... + */ + + if ((fp = fdopen(fd, "r")) != NULL) + { + setbuf(fp, NULL); + + ppd = ppdOpen(fp); + + safe_free(fp); + } + else + ppd = NULL; + + return (ppd); +} + + +/* + * 'ppdOpenFile()' - Read a PPD file into memory. + */ + +ppd_file_t * /* O - PPD file record */ +ppdOpenFile(const char *filename) /* I - File to read from */ +{ + FILE *fp; /* File pointer */ + ppd_file_t *ppd; /* PPD file record */ + + + /* + * Range check input... + */ + + if (filename == NULL) + return (NULL); + + /* + * Try to open the file and parse it... + */ + + if ((fp = fopen(filename, "r")) != NULL) + { + ppd = ppdOpen(fp); + + fclose(fp); + } + else + ppd = NULL; + + return (ppd); +} + + +/* + * 'compare_strings()' - Compare two strings. + */ + +int /* O - Result of comparison */ +compare_strings(char *s, /* I - First string */ + char *t) /* I - Second string */ +{ + int diff, /* Difference between digits */ + digits; /* Number of digits */ + + + /* + * Loop through both strings, returning only when a difference is + * seen. Also, compare whole numbers rather than just characters, too! + */ + + while (*s && *t) + { + if (isdigit(*s) && isdigit(*t)) + { + /* + * Got a number; start by skipping leading 0's... + */ + + while (*s == '0') + s ++; + while (*t == '0') + t ++; + + /* + * Skip equal digits... + */ + + while (isdigit(*s) && *s == *t) + { + s ++; + t ++; + } + + /* + * Bounce out if *s and *t aren't both digits... + */ + + if (isdigit(*s) && !isdigit(*t)) + return (1); + else if (!isdigit(*s) && isdigit(*t)) + return (-1); + else if (!isdigit(*s) || !isdigit(*t)) + continue; + + if (*s < *t) + diff = -1; + else + diff = 1; + + /* + * Figure out how many more digits there are... + */ + + digits = 0; + + while (isdigit(*s)) + { + digits ++; + s ++; + } + + while (isdigit(*t)) + { + digits --; + t ++; + } + + /* + * Return if the number or value of the digits is different... + */ + + if (digits < 0) + return (-1); + else if (digits > 0) + return (1); + else + return (diff); + } + else if (tolower(*s) < tolower(*t)) + return (-1); + else if (tolower(*s) > tolower(*t)) + return (1); + else + { + s ++; + t ++; + } + } + + /* + * Return the results of the final comparison... + */ + + if (*s) + return (1); + else if (*t) + return (-1); + else + return (0); +} + + +/* + * 'compare_groups()' - Compare two groups. + */ + +static int /* O - Result of comparison */ +compare_groups(ppd_group_t *g0, /* I - First group */ + ppd_group_t *g1) /* I - Second group */ +{ + return (compare_strings(g0->text, g1->text)); +} + + +/* + * 'compare_options()' - Compare two options. + */ + +static int /* O - Result of comparison */ +compare_options(ppd_option_t *o0,/* I - First option */ + ppd_option_t *o1)/* I - Second option */ +{ + return (compare_strings(o0->text, o1->text)); +} + + +/* + * 'compare_choices()' - Compare two choices. + */ + +static int /* O - Result of comparison */ +compare_choices(ppd_choice_t *c0,/* I - First choice */ + ppd_choice_t *c1)/* I - Second choice */ +{ + return (compare_strings(c0->text, c1->text)); +} + + +/* + * 'ppd_read()' - Read a line from a PPD file, skipping comment lines as + * necessary. + */ + +static int /* O - Bitmask of fields read */ +ppd_read(FILE *fp, /* I - File to read from */ + char *keyword, /* O - Keyword from line */ + char *option, /* O - Option from line */ + char *text, /* O - Human-readable text from line */ + char **string) /* O - Code/string data */ +{ + int ch, /* Character from file */ + endquote, /* Waiting for an end quote */ + mask; /* Mask to be returned */ + char *keyptr, /* Keyword pointer */ + *optptr, /* Option pointer */ + *textptr, /* Text pointer */ + *strptr, /* Pointer into string */ + *lineptr, /* Current position in line buffer */ + line[65536]; /* Line buffer (64k) */ + + + /* + * Range check everything... + */ + + if (fp == NULL || keyword == NULL || option == NULL || text == NULL || + string == NULL) + return (0); + + /* + * Now loop until we have a valid line... + */ + + *string = NULL; + + do + { + /* + * Read the line... + */ + + lineptr = line; + endquote = 0; + + while ((ch = getc(fp)) != EOF && + (lineptr - line) < (sizeof(line) - 1)) + { + if (ch == '\r' || ch == '\n') + { + /* + * Line feed or carriage return... + */ + + if (lineptr == line) /* Skip blank lines */ + continue; + + if (ch == '\r') + { + /* + * Check for a trailing line feed... + */ + + if ((ch = getc(fp)) == EOF) + break; + if (ch != 0x0a) + ungetc(ch, fp); + } + + ch = '\n'; + + if (!endquote) /* Continue for multi-line text */ + break; + + *lineptr++ = '\n'; + } + else + { + /* + * Any other character... + */ + + *lineptr++ = ch; + + if (ch == '\"') + endquote = !endquote; + } + } + + if (endquote) + { + /* + * Didn't finish this quoted string... + */ + + while ((ch = getc(fp)) != EOF) + if (ch == '\"') + break; + } + + if (ch != '\n') + { + /* + * Didn't finish this line... + */ + + while ((ch = getc(fp)) != EOF) + if (ch == '\r' || ch == '\n') + { + /* + * Line feed or carriage return... + */ + + if (ch == '\r') + { + /* + * Check for a trailing line feed... + */ + + if ((ch = getc(fp)) == EOF) + break; + if (ch != 0x0a) + ungetc(ch, fp); + } + + break; + } + } + + if (lineptr > line && lineptr[-1] == '\n') + lineptr --; + + *lineptr = '\0'; + + if (ch == EOF && lineptr == line) + return (0); + + /* + * Now parse it... + */ + + mask = 0; + lineptr = line + 1; + + keyword[0] = '\0'; + option[0] = '\0'; + text[0] = '\0'; + *string = NULL; + + if (line[0] != '*') /* All lines start with an asterisk */ + continue; + + if (strncmp(line, "*%", 2) == 0 || /* Comment line */ + strncmp(line, "*?", 2) == 0 || /* Query line */ + strcmp(line, "*End") == 0) /* End of multi-line string */ + continue; + + /* + * Get a keyword... + */ + + keyptr = keyword; + + while (*lineptr != '\0' && *lineptr != ':' && !isspace(*lineptr) && + (keyptr - keyword) < 40) + *keyptr++ = *lineptr++; + + *keyptr = '\0'; + mask |= PPD_KEYWORD; + + if (*lineptr == ' ' || *lineptr == '\t') + { + /* + * Get an option name... + */ + + while (*lineptr == ' ' || *lineptr == '\t') + lineptr ++; + + optptr = option; + + while (*lineptr != '\0' && *lineptr != '\n' && *lineptr != ':' && + *lineptr != '/' && (optptr - option) < 40) + *optptr++ = *lineptr++; + + *optptr = '\0'; + mask |= PPD_OPTION; + + if (*lineptr == '/') + { + /* + * Get human-readable text... + */ + + lineptr ++; + + textptr = text; + + while (*lineptr != '\0' && *lineptr != '\n' && *lineptr != ':' && + (textptr - text) < 80) + *textptr++ = *lineptr++; + + *textptr = '\0'; + ppd_decode(text); + + mask |= PPD_TEXT; + } + } + + if (*lineptr == ':') + { + /* + * Get string... + */ + + *string = malloc(strlen(lineptr) + 1); + + while (*lineptr == ':' || isspace(*lineptr)) + lineptr ++; + + strptr = *string; + + while (*lineptr != '\0') + { + if (*lineptr != '\"') + *strptr++ = *lineptr++; + else + lineptr ++; + } + + *strptr = '\0'; + + mask |= PPD_STRING; + } + } + while (mask == 0); + + return (mask); +} + + +/* + * 'ppd_decode()' - Decode a string value... + */ + +static void +ppd_decode(char *string) /* I - String to decode */ +{ + char *inptr, /* Input pointer */ + *outptr; /* Output pointer */ + + + inptr = string; + outptr = string; + + while (*inptr != '\0') + if (*inptr == '<' && isxdigit(inptr[1])) + { + /* + * Convert hex to 8-bit values... + */ + + inptr ++; + while (isxdigit(*inptr)) + { + if (isalpha(*inptr)) + *outptr = (tolower(*inptr) - 'a' + 10) << 4; + else + *outptr = (*inptr - '0') << 4; + + inptr ++; + + if (isalpha(*inptr)) + *outptr |= tolower(*inptr) - 'a' + 10; + else + *outptr |= *inptr - '0'; + + inptr ++; + outptr ++; + } + + while (*inptr != '>' && *inptr != '\0') + inptr ++; + while (*inptr == '>') + inptr ++; + } + else + *outptr++ = *inptr++; + + *outptr = '\0'; +} + + +/* + * 'ppd_fix()' - Fix WinANSI characters in the range 0x80 to 0x9f to be + * valid ISO-8859-1 characters... + */ + +static void +ppd_fix(char *string) /* IO - String to fix */ +{ + unsigned char *p; /* Pointer into string */ + static unsigned char lut[32] =/* Lookup table for characters */ + { + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 0x20, + 'l', + '`', + '\'', + '^', + '~', + 0x20, /* bar */ + 0x20, /* circumflex */ + 0x20, /* dot */ + 0x20, /* double dot */ + 0x20, + 0x20, /* circle */ + 0x20, /* ??? */ + 0x20, + '\"', /* should be right quotes */ + 0x20, /* ??? */ + 0x20 /* accent */ + }; + + + for (p = (unsigned char *)string; *p; p ++) + if (*p >= 0x80 && *p < 0xa0) + *p = lut[*p - 0x80]; +} + + +/* + * End of "$Id$". + */ diff --git a/cups/ppd.h b/cups/ppd.h new file mode 100644 index 0000000000..622866b10b --- /dev/null +++ b/cups/ppd.h @@ -0,0 +1,241 @@ +/* + * "$Id$" + * + * PostScript Printer Description definitions for the Common UNIX Printing + * System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * PostScript is a trademark of Adobe Systems, Inc. + * + * This code and any derivative of it may be used and distributed + * freely under the terms of the GNU General Public License when + * used with GNU Ghostscript or its derivatives. Use of the code + * (or any derivative of it) with software other than GNU + * GhostScript (or its derivatives) is governed by the CUPS license + * agreement. + */ + +#ifndef _CUPS_PPD_H_ +# define _CUPS_PPD_H_ + +/* + * Include necessary headers... + */ + +# include + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * PPD version... + */ + +# define PPD_VERSION 4.3 /* Kept in sync with Adobe version number */ + + +/* + * Types and structures... + */ + +typedef enum /**** UI types ****/ +{ + PPD_UI_BOOLEAN, /* True or False option */ + PPD_UI_PICKONE, /* Pick one from a list */ + PPD_UI_PICKMANY /* Pick zero or more from a list */ +} ppd_ui_t; + +typedef enum /**** Order dependency sections ****/ +{ + PPD_ORDER_ANY, /* Option code can be anywhere in the file */ + PPD_ORDER_DOCUMENT, /* ... must be in the DocumentSetup section */ + PPD_ORDER_EXIT, /* ... must be sent prior to the document */ + PPD_ORDER_JCL, /* ... must be sent as a JCL command */ + PPD_ORDER_PAGE, /* ... must be in the PageSetup section */ + PPD_ORDER_PROLOG /* ... must be in the Prolog section */ +} ppd_section_t; + +typedef enum /**** Colorspaces ****/ +{ + PPD_CS_CMYK = -4, /* CMYK colorspace */ + PPD_CS_CMY, /* CMY colorspace */ + PPD_CS_GRAY = 1, /* Grayscale colorspace */ + PPD_CS_RGB = 3, /* RGB colorspace */ + PPD_CS_RGBK, /* RGBK (K = gray) colorspace */ + PPD_CS_N /* DeviceN colorspace */ +} ppd_cs_t; + +typedef struct /**** Option choices ****/ +{ + char marked, /* 0 if not selected, 1 otherwise */ + choice[41], /* Computer-readable option name */ + text[81], /* Human-readable option name */ + *code; /* Code to send for this option */ + void *option; /* Pointer to parent option structure */ +} ppd_choice_t; + +typedef struct /**** Options ****/ +{ + char conflicted, /* 0 if no conflicts exist, 1 otherwise */ + keyword[41], /* Option keyword name ("PageSize", etc.) */ + defchoice[41], /* Default option choice */ + text[81]; /* Human-readable text */ + ppd_ui_t ui; /* Type of UI option */ + ppd_section_t section; /* Section for command */ + float order; /* Order number */ + int num_choices; /* Number of option choices */ + ppd_choice_t *choices; /* Option choices */ +} ppd_option_t; + +typedef struct ppd_group_str /**** Groups ****/ +{ + char text[81]; /* Human-readable group name */ + int num_options; /* Number of options */ + ppd_option_t *options; /* Options */ + int num_subgroups; /* Number of sub-groups */ + struct ppd_group_str *subgroups; + /* Sub-groups (max depth = 1) */ +} ppd_group_t; + +typedef struct /**** Constraints ****/ +{ + char option1[41], /* First keyword */ + choice1[41], /* First option/choice (blank for all) */ + option2[41], /* Second keyword */ + choice2[41]; /* Second option/choice (blank for all) */ +} ppd_const_t; + +typedef struct /**** Page Sizes ****/ +{ + int marked; /* Page size selected? */ + char name[41]; /* Media size option */ + float width, /* Width of media in points */ + length, /* Length of media in points */ + left, /* Left printable margin in points */ + bottom, /* Bottom printable margin in points */ + right, /* Right printable margin in points */ + top; /* Top printable margin in points */ +} ppd_size_t; + +typedef struct /**** Emulators ****/ +{ + char name[41], /* Emulator name */ + *start, /* Code to switch to this emulation */ + *stop; /* Code to stop this emulation */ +} ppd_emul_t; + +typedef struct /**** sRGB Color Profiles ****/ +{ + char resolution[41], /* Resolution or "-" */ + media_type[41]; /* Media type of "-" */ + float density, /* Ink density to use */ + gamma, /* Gamma correction to use */ + matrix[3][3]; /* Transform matrix */ +} ppd_profile_t; + +typedef struct /**** Files ****/ +{ + int language_level, /* Language level of device */ + color_device, /* 1 = color device, 0 = grayscale */ + variable_sizes, /* 1 = supports variable sizes, 0 = doesn't */ + accurate_screens,/* 1 = supports accurate screens, 0 = not */ + contone_only, /* 1 = continuous tone only, 0 = not */ + landscape, /* -90 or 90 */ + model_number, /* Device-specific model number */ + manual_copies, /* 1 = Copies done manually, 0 = hardware */ + throughput; /* Pages per minute */ + ppd_cs_t colorspace; /* Default colorspace */ + char *patches; /* Patch commands to be sent to printer */ + int num_emulations; /* Number of emulations supported */ + ppd_emul_t *emulations; /* Emulations and the code to invoke them */ + char *jcl_begin, /* Start JCL commands */ + *jcl_ps, /* Enter PostScript interpreter */ + *jcl_end, /* End JCL commands */ + *lang_encoding, /* Language encoding */ + *lang_version, /* Language version (English, Spanish, etc.) */ + *modelname, /* Model name (general) */ + *ttrasterizer, /* Truetype rasterizer */ + *manufacturer, /* Manufacturer name */ + *product, /* Product name (from PS RIP/interpreter) */ + *nickname, /* Nickname (specific) */ + *shortnickname; /* Short version of nickname */ + int num_groups; /* Number of UI groups */ + ppd_group_t *groups; /* UI groups */ + int num_sizes; /* Number of page sizes */ + ppd_size_t *sizes; /* Page sizes */ + float custom_min[2], /* Minimum variable page size */ + custom_max[2], /* Maximum variable page size */ + custom_margins[4];/* Margins around page */ + int num_consts; /* Number of UI/Non-UI constraints */ + ppd_const_t *consts; /* UI/Non-UI constraints */ + int num_fonts; /* Number of pre-loaded fonts */ + char **fonts; /* Pre-loaded fonts */ + int num_profiles; /* Number of sRGB color profiles */ + ppd_profile_t *profiles; /* sRGB color profiles */ + int num_filters; /* Number of filters */ + char **filters; /* Filter strings... */ + int flip_duplex; /* 1 = Flip page for back sides */ +} ppd_file_t; + + +/* + * Prototypes... + */ + +extern void ppdClose(ppd_file_t *ppd); +extern int ppdConflicts(ppd_file_t *ppd); +extern int ppdEmit(ppd_file_t *ppd, FILE *fp, + ppd_section_t section); +extern int ppdEmitFd(ppd_file_t *ppd, int fd, + ppd_section_t section); +extern int ppdIsMarked(ppd_file_t *ppd, const char *keyword, + const char *option); +extern void ppdMarkDefaults(ppd_file_t *ppd); +extern int ppdMarkOption(ppd_file_t *ppd, const char *keyword, + const char *option); +extern ppd_choice_t *ppdFindChoice(ppd_option_t *o, const char *option); +extern ppd_choice_t *ppdFindMarkedChoice(ppd_file_t *ppd, const char *keyword); +extern ppd_option_t *ppdFindOption(ppd_file_t *ppd, const char *keyword); +extern ppd_file_t *ppdOpen(FILE *fp); +extern ppd_file_t *ppdOpenFd(int fd); +extern ppd_file_t *ppdOpenFile(const char *filename); +extern float ppdPageLength(ppd_file_t *ppd, const char *name); +extern ppd_size_t *ppdPageSize(ppd_file_t *ppd, const char *name); +extern float ppdPageWidth(ppd_file_t *ppd, const char *name); + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ +#endif /* !_CUPS_PPD_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/snprintf.c b/cups/snprintf.c new file mode 100644 index 0000000000..2cb180ed95 --- /dev/null +++ b/cups/snprintf.c @@ -0,0 +1,287 @@ +/* + * "$Id$" + * + * snprintf functions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * vsnprintf() - Format a string into a fixed size buffer. + * snprintf() - Format a string into a fixed size buffer. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include "string.h" + + +#ifndef HAVE_VSNPRINTF +/* + * 'vsnprintf()' - Format a string into a fixed size buffer. + */ + +int /* O - Number of bytes formatted */ +vsnprintf(char *buffer, /* O - Output buffer */ + size_t bufsize, /* O - Size of output buffer */ + const char *format, /* I - printf-style format string */ + va_list ap) /* I - Pointer to additional arguments */ +{ + char *bufptr, /* Pointer to position in buffer */ + *bufend, /* Pointer to end of buffer */ + sign, /* Sign of format width */ + size, /* Size character (h, l, L) */ + type; /* Format type character */ + const char *bufformat; /* Start of format */ + int width, /* Width of field */ + prec; /* Number of characters of precision */ + char tformat[100], /* Temporary format string for sprintf() */ + temp[1024]; /* Buffer for formatted numbers */ + int *chars; /* Pointer to integer for %p */ + char *s; /* Pointer to string */ + int slen; /* Length of string */ + + + /* + * Loop through the format string, formatting as needed... + */ + + bufptr = buffer; + bufend = buffer + bufsize - 1; + + while (*format && bufptr < bufend) + { + if (*format == '%') + { + bufformat = format; + format ++; + + if (*format == '%') + { + *bufptr++ = *format++; + continue; + } + else if (strchr(" -+#\'", *format)) + sign = *format++; + else + sign = 0; + + width = 0; + while (isdigit(*format)) + width = width * 10 + *format++ - '0'; + + if (*format == '.') + { + format ++; + prec = 0; + + while (isdigit(*format)) + prec = prec * 10 + *format++ - '0'; + } + else + prec = -1; + + if (*format == 'l' && format[1] == 'l') + { + size = 'L'; + format += 2; + } + else if (*format == 'h' || *format == 'l' || *format == 'L') + size = *format++; + + if (!*format) + break; + + type = *format++; + + switch (type) + { + case 'E' : /* Floating point formats */ + case 'G' : + case 'e' : + case 'f' : + case 'g' : + if ((format - bufformat + 1) > sizeof(tformat) || + (width + 2) > sizeof(temp)) + break; + + strncpy(tformat, bufformat, format - bufformat); + tformat[format - bufformat] = '\0'; + + sprintf(temp, tformat, va_arg(ap, double)); + + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, bufend - bufptr); + bufptr = bufend; + break; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + break; + + case 'B' : /* Integer formats */ + case 'X' : + case 'b' : + case 'd' : + case 'i' : + case 'o' : + case 'u' : + case 'x' : + if ((format - bufformat + 1) > sizeof(tformat) || + (width + 2) > sizeof(temp)) + break; + + strncpy(tformat, bufformat, format - bufformat); + tformat[format - bufformat] = '\0'; + + sprintf(temp, tformat, va_arg(ap, int)); + + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, bufend - bufptr); + bufptr = bufend; + break; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + break; + + case 'p' : /* Pointer value */ + if ((chars = va_arg(ap, int *)) != NULL) + *chars = bufptr - buffer; + break; + + case 'c' : /* Character or character array */ + if (width <= 1) + *bufptr++ = va_arg(ap, int); + else + { + if ((bufptr + width) > bufend) + width = bufend - bufptr; + + memcpy(bufptr, va_arg(ap, char *), width); + bufptr += width; + } + break; + + case 's' : /* String */ + if ((s = va_arg(ap, char *)) == NULL) + s = "(null)"; + + slen = strlen(s); + if (slen > width && prec != width) + width = slen; + + if ((bufptr + width) > bufend) + width = bufend - bufptr; + + if (slen > width) + slen = width; + + if (sign == '-') + { + strncpy(bufptr, s, slen); + memset(bufptr + slen, ' ', width - slen); + } + else + { + memset(bufptr, ' ', width - slen); + strncpy(bufptr + width - slen, s, slen); + } + + bufptr += width; + break; + + case 'n' : /* Output number of chars so far */ + if ((format - bufformat + 1) > sizeof(tformat) || + (width + 2) > sizeof(temp)) + break; + + strncpy(tformat, bufformat, format - bufformat); + tformat[format - bufformat] = '\0'; + + sprintf(temp, tformat, va_arg(ap, int)); + + if ((bufptr + strlen(temp)) > bufend) + { + strncpy(bufptr, temp, bufend - bufptr); + bufptr = bufend; + break; + } + else + { + strcpy(bufptr, temp); + bufptr += strlen(temp); + } + break; + } + } + else + *bufptr++ = *format++; + } + + /* + * Nul-terminate the string and return the number of characters in it. + */ + + *bufptr = '\0'; + return (bufptr - buffer); +} +#endif /* !HAVE_VSNPRINT */ + + +#ifndef HAVE_SNPRINTF +/* + * 'snprintf()' - Format a string into a fixed size buffer. + */ + +int /* O - Number of bytes formatted */ +snprintf(char *buffer, /* O - Output buffer */ + size_t bufsize, /* O - Size of output buffer */ + const char *format, /* I - printf-style format string */ + ...) /* I - Additional arguments as needed */ +{ + int bytes; /* Number of bytes formatted */ + va_list ap; /* Pointer to additional arguments */ + + + va_start(ap, format); + bytes = vsnprintf(buffer, bufsize, format, ap); + va_end(ap); + + return (bytes); +} +#endif /* !HAVE_SNPRINTF */ + + +/* + * End of "$Id$". + */ + diff --git a/cups/string.c b/cups/string.c new file mode 100644 index 0000000000..b295162c73 --- /dev/null +++ b/cups/string.c @@ -0,0 +1,125 @@ +/* + * "$Id$" + * + * String functions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * strdup() - Duplicate a string. + * strcasecmp() - Do a case-insensitive comparison. + * strncasecmp() - Do a case-insensitive comparison on up to N chars. + */ + +/* + * Include necessary headers... + */ + +#include "string.h" + + +/* + * 'strdup()' - Duplicate a string. + */ + +# ifndef HAVE_STRDUP +char * /* O - New string pointer */ +strdup(const char *s) /* I - String to duplicate */ +{ + char *t; /* New string pointer */ + + + if (s == NULL) + return (NULL); + + if ((t = malloc(strlen(s) + 1)) == NULL) + return (NULL); + + return (strcpy(t, s)); +} +# endif /* !HAVE_STRDUP */ + + +/* + * 'strcasecmp()' - Do a case-insensitive comparison. + */ + +# ifndef HAVE_STRCASECMP +int /* O - Result of comparison (-1, 0, or 1) */ +strcasecmp(const char *s, /* I - First string */ + const char *t) /* I - Second string */ +{ + while (*s != '\0' && *t != '\0') + { + if (tolower(*s) < tolower(*t)) + return (-1); + else if (tolower(*s) > tolower(*t)) + return (1); + + s ++; + t ++; + } + + if (*s == '\0' && *t == '\0') + return (0); + else if (*s != '\0') + return (1); + else + return (-1); +} +# endif /* !HAVE_STRCASECMP */ + +/* + * 'strncasecmp()' - Do a case-insensitive comparison on up to N chars. + */ + +# ifndef HAVE_STRNCASECMP +int /* O - Result of comparison (-1, 0, or 1) */ +strncasecmp(const char *s, /* I - First string */ + const char *t, /* I - Second string */ + size_t n) /* I - Maximum number of characters to compare */ +{ + while (*s != '\0' && *t != '\0' && n > 0) + { + if (tolower(*s) < tolower(*t)) + return (-1); + else if (tolower(*s) > tolower(*t)) + return (1); + + s ++; + t ++; + n --; + } + + if (n == 0) + return (0); + else if (*s == '\0' && *t == '\0') + return (0); + else if (*s != '\0') + return (1); + else + return (-1); +} +# endif /* !HAVE_STRNCASECMP */ + + +/* + * End of "$Id$". + */ diff --git a/cups/string.h b/cups/string.h new file mode 100644 index 0000000000..5c3464ae76 --- /dev/null +++ b/cups/string.h @@ -0,0 +1,94 @@ +/* + * "$Id$" + * + * String definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +#ifndef _CUPS_STRING_H_ +# define _CUPS_STRING_H_ + +/* + * Include necessary headers... + */ + +# include +# include +# include +# include + + +/* + * Stuff for WIN32 and OS/2... + */ + +# if defined(WIN32) || defined(__EMX__) +# define strcasecmp stricmp +# define strncasecmp strnicmp +# endif /* WIN32 || __EMX__ */ + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + + +/* + * Prototypes... + */ + +# ifndef HAVE_STRDUP +extern char *strdup(const char *); +# endif /* !HAVE_STRDUP */ + +# ifndef HAVE_STRCASECMP +extern int strcasecmp(const char *, const char *); +# endif /* !HAVE_STRCASECMP */ + +# ifndef HAVE_STRNCASECMP +extern int strncasecmp(const char *, const char *, size_t n); +# endif /* !HAVE_STRNCASECMP */ + +# ifndef HAVE_SNPRINTF +extern int snprintf(char *, size_t, const char *, ...); +# endif /* !HAVE_SNPRINTF */ + +# ifndef HAVE_VSNPRINTF +extern int vsnprintf(char *, size_t, const char *, va_list); +# endif /* !HAVE_VSNPRINTF */ + + +/* + * C++ magic... + */ + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_STRING_H_ */ + +/* + * End of "$Id$". + */ diff --git a/cups/testhttp.c b/cups/testhttp.c new file mode 100644 index 0000000000..a800feb51a --- /dev/null +++ b/cups/testhttp.c @@ -0,0 +1,109 @@ +/* + * "$Id$" + * + * HTTP test program for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry. + */ + +/* + * Include necessary headers... + */ + +#include +#include "http.h" + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + http_t *http; /* HTTP connection */ + http_status_t status; /* Status of GET command */ + char buffer[1024]; /* Input buffer */ + long bytes; /* Number of bytes read */ + FILE *out; /* Output file */ + +#define HOST "dns.easysw.com" +#define PORT 80 + + puts("Connecting to " HOST "..."); + + httpInitialize(); + http = httpConnect(HOST, PORT); + if (http == NULL) + { + puts("Unable to connect to " HOST "!"); + return (1); + } + + puts("Connected to " HOST "..."); + + out = stdout; + + for (i = 1; i < argc; i ++) + { + if (strcmp(argv[i], "-o") == 0) + { + i ++; + out = fopen(argv[i], "wb"); + continue; + } + + printf("Requesting file \"%s\"...\n", argv[i]); + httpClearFields(http); + httpSetField(http, HTTP_FIELD_ACCEPT_LANGUAGE, "en"); + httpGet(http, argv[i]); + status = httpUpdate(http); + + if (status == HTTP_OK) + puts("GET OK:"); + else + printf("GET failed with status %d...\n", status); + + while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0) + { + fwrite(buffer, bytes, 1, out); + if (out != stdout) + printf("Read %ld bytes, %ld total...\n", bytes, ftell(out)); + } + } + + puts("Closing connection to server..."); + httpClose(http); + + if (out != stdout) + fclose(out); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testmime.dsp b/cups/testmime.dsp new file mode 100644 index 0000000000..33fbd301af --- /dev/null +++ b/cups/testmime.dsp @@ -0,0 +1,102 @@ +# Microsoft Developer Studio Project File - Name="testmime" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=testmime - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "testmime.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "testmime.mak" CFG="testmime - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "testmime - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "testmime - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "testmime - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 cups.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"testmime.exe" + +!ELSEIF "$(CFG)" == "testmime - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "testmime___Win32_Debug" +# PROP BASE Intermediate_Dir "testmime___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /I "../visualc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 cupsd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"testmimed.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "testmime - Win32 Release" +# Name "testmime - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\testmime.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\mime.h +# End Source File +# End Group +# End Target +# End Project diff --git a/cups/testppd.c b/cups/testppd.c new file mode 100644 index 0000000000..62d31b48c5 --- /dev/null +++ b/cups/testppd.c @@ -0,0 +1,187 @@ +/* + * "$Id$" + * + * PPD test program for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products, all rights reserved. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * PostScript is a trademark of Adobe Systems, Inc. + * + * Contents: + * + * main() - Main entry for test program. + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include "string.h" + + +/* + * 'main()' - Main entry for test program. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i, j, k, m; /* Looping vars */ + const char *filename; /* File to load */ + ppd_file_t *ppd; /* PPD file record */ + ppd_size_t *size; /* Size record */ + ppd_group_t *group; /* UI group */ + ppd_option_t *option; /* Standard UI option */ + ppd_choice_t *choice; /* Standard UI option choice */ + static char *uis[] = { "BOOLEAN", "PICKONE", "PICKMANY" }; + static char *sections[] = { "ANY", "DOCUMENT", "EXIT", + "JCL", "PAGE", "PROLOG" }; + + + /* + * Display PPD files for each file listed on the command-line... + */ + + if (argc == 1) + { + fputs("Usage: ppdtest filename1.ppd [... filenameN.ppd]\n", stderr); + return (1); + } + + for (i = 1; i < argc; i ++) + { + if (strstr(argv[i], ".ppd")) + filename = argv[i]; + else + filename = cupsGetPPD(argv[i]); + + if ((ppd = ppdOpenFile(filename)) == NULL) + { + fprintf(stderr, "Unable to open \'%s\' as a PPD file!\n", filename); + continue; + } + + printf("FILE: %s\n", filename); + printf(" language_level = %d\n", ppd->language_level); + printf(" color_device = %s\n", ppd->color_device ? "TRUE" : "FALSE"); + printf(" variable_sizes = %s\n", ppd->variable_sizes ? "TRUE" : "FALSE"); + printf(" landscape = %d\n", ppd->landscape); + + switch (ppd->colorspace) + { + case PPD_CS_CMYK : + puts(" colorspace = PPD_CS_CMYK"); + break; + case PPD_CS_CMY : + puts(" colorspace = PPD_CS_CMY"); + break; + case PPD_CS_GRAY : + puts(" colorspace = PPD_CS_GRAY"); + break; + case PPD_CS_RGB : + puts(" colorspace = PPD_CS_RGB"); + break; + default : + puts(" colorspace = "); + break; + } + + printf(" num_emulations = %d\n", ppd->num_emulations); + for (j = 0; j < ppd->num_emulations; j ++) + printf(" emulations[%d] = %s\n", j, ppd->emulations[j].name); + + printf(" lang_encoding = %s\n", ppd->lang_encoding); + printf(" lang_version = %s\n", ppd->lang_version); + printf(" modelname = %s\n", ppd->modelname); + printf(" ttrasterizer = %s\n", + ppd->ttrasterizer == NULL ? "None" : ppd->ttrasterizer); + printf(" manufacturer = %s\n", ppd->manufacturer); + printf(" product = %s\n", ppd->product); + printf(" nickname = %s\n", ppd->nickname); + printf(" shortnickname = %s\n", ppd->shortnickname); + printf(" patches = %d bytes\n", + ppd->patches == NULL ? 0 : strlen(ppd->patches)); + + printf(" num_groups = %d\n", ppd->num_groups); + for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++) + { + printf(" group[%d] = %s\n", j, group->text); + + for (k = 0, option = group->options; k < group->num_options; k ++, option ++) + { + printf(" options[%d] = %s (%s) %s %s %.0f\n", k, + option->keyword, option->text, uis[option->ui], + sections[option->section], option->order); + + if (strcmp(option->keyword, "PageSize") == 0 || + strcmp(option->keyword, "PageRegion") == 0) + { + for (m = option->num_choices, choice = option->choices; + m > 0; + m --, choice ++) + { + size = ppdPageSize(ppd, choice->choice); + + if (size == NULL) + printf(" %s (%s) = ERROR", choice->choice, choice->text); + else + printf(" %s (%s) = %.2fx%.2fin (%.1f,%.1f,%.1f,%.1f)", choice->choice, + choice->text, size->width / 72.0, size->length / 72.0, + size->left / 72.0, size->bottom / 72.0, + size->right / 72.0, size->top / 72.0); + + if (strcmp(option->defchoice, choice->choice) == 0) + puts(" *"); + else + putchar('\n'); + } + } + else + { + for (m = option->num_choices, choice = option->choices; + m > 0; + m --, choice ++) + { + printf(" %s (%s)", choice->choice, choice->text); + + if (strcmp(option->defchoice, choice->choice) == 0) + puts(" *"); + else + putchar('\n'); + } + } + } + } + + printf(" num_fonts = %d\n", ppd->num_fonts); + for (j = 0; j < ppd->num_fonts; j ++) + printf(" fonts[%d] = %s\n", j, ppd->fonts[j]); + + ppdClose(ppd); + } + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/testppd.dsp b/cups/testppd.dsp new file mode 100644 index 0000000000..27d4f035ce --- /dev/null +++ b/cups/testppd.dsp @@ -0,0 +1,102 @@ +# Microsoft Developer Studio Project File - Name="testppd" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=testppd - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "testppd.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "testppd.mak" CFG="testppd - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "testppd - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "testppd - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "testppd - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD CPP /nologo /MT /W3 /GX /O2 /I ".." /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 cups.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 /out:"testppd.exe" + +!ELSEIF "$(CFG)" == "testppd - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "testppd___Win32_Debug" +# PROP BASE Intermediate_Dir "testppd___Win32_Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD CPP /nologo /MTd /W3 /Gm /GX /Zi /Od /I ".." /I "../visualc" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 cupsd.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /incremental:no /debug /machine:I386 /out:"testppdd.exe" /pdbtype:sept + +!ENDIF + +# Begin Target + +# Name "testppd - Win32 Release" +# Name "testppd - Win32 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\testppd.c +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\ppd.h +# End Source File +# End Group +# End Target +# End Project diff --git a/cups/usersys.c b/cups/usersys.c new file mode 100644 index 0000000000..3a8ae31706 --- /dev/null +++ b/cups/usersys.c @@ -0,0 +1,201 @@ +/* + * "$Id$" + * + * User, system, and password routines for the Common UNIX Printing + * System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * cupsUser() - Return the current users name. + * cupsGetPassword() - Get a password from the user... + * cupsServer() - Return the hostname of the default server... + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include +#include +#include + + +#if defined(WIN32) || defined(__EMX__) +/* + * WIN32 and OS/2 username and password stuff... + */ + +/* + * 'cupsUser()' - Return the current user's name. + */ + +const char * /* O - User name */ +cupsUser(void) +{ + return ("WindowsUser"); +} + + +/* + * 'cupsGetPassword()' - Get a password from the user... + */ + +const char * /* O - Password */ +cupsGetPassword(const char *prompt) /* I - Prompt string */ +{ + return (NULL); +} +#else +/* + * UNIX username and password stuff... + */ + +# include + +/* + * 'cupsUser()' - Return the current user's name. + */ + +const char * /* O - User name */ +cupsUser(void) +{ + struct passwd *pwd; /* User/password entry */ + + + /* + * Rewind the password file... + */ + + setpwent(); + + /* + * Lookup the password entry for the current user. + */ + + if ((pwd = getpwuid(getuid())) == NULL) + return ("unknown"); /* Unknown user! */ + + /* + * Rewind the password file again and return the username... + */ + + setpwent(); + + return (pwd->pw_name); +} + + +/* + * 'cupsGetPassword()' - Get a password from the user... + */ + +const char * /* O - Password */ +cupsGetPassword(const char *prompt) /* I - Prompt string */ +{ + return (getpass(prompt)); +} +#endif /* WIN32 || __EMX__ */ + + +/* + * 'cupsServer()' - Return the hostname of the default server... + */ + +const char * /* O - Server name */ +cupsServer(void) +{ + FILE *fp; /* client.conf file */ + char *server; /* Pointer to server name */ + const char *home; /* Home directory of user */ + static char line[1024]; /* Line from file */ + + + /* + * First see if the CUPS_SERVER environment variable is set... + */ + + if ((server = getenv("CUPS_SERVER")) != NULL) + return (server); + + /* + * Next check to see if we have a $HOME/.cupsrc or client.conf file... + */ + + if ((home = getenv("HOME")) != NULL) + { + snprintf(line, sizeof(line), "%s/.cupsrc", home); + fp = fopen(line, "r"); + } + else + fp = NULL; + + if (fp == NULL) + { + if ((home = getenv("CUPS_SERVERROOT")) != NULL) + { + snprintf(line, sizeof(line), "%s/client.conf", home); + fp = fopen(line, "r"); + } + else + fp = fopen(CUPS_SERVERROOT "/client.conf", "r"); + } + + if (fp == NULL) + return ("localhost"); + + /* + * Read the config file and look for a ServerName line... + */ + + while (fgets(line, sizeof(line), fp) != NULL) + if (strncmp(line, "ServerName ", 11) == 0) + { + /* + * Got it! Drop any trailing newline and find the name... + */ + + server = line + strlen(line) - 1; + if (*server == '\n') + *server = '\0'; + + for (server = line + 11; isspace(*server); server ++); + + if (*server) + { + fclose(fp); + return (server); + } + } + + /* + * Didn't see a ServerName line, so return "localhost"... + */ + + fclose(fp); + + return ("localhost"); +} + + +/* + * End of "$Id$". + */ diff --git a/cups/util.c b/cups/util.c new file mode 100644 index 0000000000..2c765e2e87 --- /dev/null +++ b/cups/util.c @@ -0,0 +1,1500 @@ +/* + * "$Id$" + * + * Printing utilities for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * cupsCancelJob() - Cancel a print job. + * cupsDoFileRequest() - Do an IPP request... + * cupsGetClasses() - Get a list of printer classes. + * cupsGetDefault() - Get the default printer or class. + * cupsGetPPD() - Get the PPD file for a printer. + * cupsGetPrinters() - Get a list of printers. + * cupsLastError() - Return the last IPP error that occurred. + * cupsPrintFile() - Print a file to a printer or class. + * cupsPrintFiles() - Print one or more files to a printer or class. + * cupsTempFile() - Generate a temporary filename. + * cups_connect() - Connect to the specified host... + * cups_local_auth() - Get the local authorization certificate if + * available/applicable... + */ + +/* + * Include necessary headers... + */ + +#include "cups.h" +#include "ipp.h" +#include "language.h" +#include "string.h" +#include "debug.h" +#include +#include +#include +#include +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * Local globals... + */ + +static http_t *cups_server = NULL; /* Current server connection */ +static ipp_status_t last_error = IPP_OK; /* Last IPP error */ +static char authstring[1024] = ""; /* Authorization string */ + + +/* + * Local functions... + */ + +static char *cups_connect(const char *name, char *printer, char *hostname); +static int cups_local_auth(http_t *http); + + +/* + * 'cupsCancelJob()' - Cancel a print job. + */ + +int /* O - 1 on success, 0 on failure */ +cupsCancelJob(const char *name, /* I - Name of printer or class */ + int job) /* I - Job ID */ +{ + char printer[HTTP_MAX_URI], /* Printer name */ + hostname[HTTP_MAX_URI], /* Hostname */ + uri[HTTP_MAX_URI]; /* Printer URI */ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + cups_lang_t *language; /* Language info */ + + + /* + * See if we can connect to the server... + */ + + if (!cups_connect(name, printer, hostname)) + { + last_error = IPP_SERVICE_UNAVAILABLE; + return (0); + } + + /* + * Build an IPP_CANCEL_JOB request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + * job-id + * [requesting-user-name] + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_CANCEL_JOB; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, + language != NULL ? language->language : "C"); + + snprintf(uri, sizeof(uri), "ipp://%s:%d/printers/%s", hostname, ippPort(), printer); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + + /* + * Do the request... + */ + + if ((response = cupsDoRequest(cups_server, request, "/jobs/")) == NULL) + { + last_error = IPP_BAD_REQUEST; + return (0); + } + else + { + last_error = response->request.status.status_code; + ippDelete(response); + + return (1); + } +} + + +/* + * 'cupsDoFileRequest()' - Do an IPP request... + */ + +ipp_t * /* O - Response data */ +cupsDoFileRequest(http_t *http, /* I - HTTP connection to server */ + ipp_t *request, /* I - IPP request */ + const char *resource, /* I - HTTP resource for POST */ + const char *filename) /* I - File to send or NULL */ +{ + ipp_t *response; /* IPP response data */ + char length[255]; /* Content-Length field */ + http_status_t status; /* Status of HTTP request */ + FILE *file; /* File to send */ + struct stat fileinfo; /* File information */ + int bytes; /* Number of bytes read/written */ + char buffer[8192]; /* Output buffer */ + const char *password; /* Password string */ + char realm[HTTP_MAX_VALUE], /* realm="xyz" string */ + nonce[HTTP_MAX_VALUE], /* nonce="xyz" string */ + plain[255], /* Plaintext username:password */ + encode[255]; /* Encoded username:password */ + + + DEBUG_printf(("cupsDoFileRequest(%08x, %08s, \'%s\', \'%s\')\n", + http, request, resource, filename ? filename : "(null)")); + + /* + * See if we have a file to send... + */ + + if (filename != NULL) + { + if (stat(filename, &fileinfo)) + { + /* + * Can't get file information! + */ + + ippDelete(request); + last_error = IPP_NOT_FOUND; + return (NULL); + } + + if ((file = fopen(filename, "rb")) == NULL) + { + /* + * Can't open file! + */ + + ippDelete(request); + last_error = IPP_NOT_FOUND; + return (NULL); + } + } + else + file = NULL; + + /* + * Loop until we can send the request without authorization problems. + */ + + response = NULL; + status = HTTP_ERROR; + + while (response == NULL) + { + DEBUG_puts("cupsDoFileRequest: setup..."); + + /* + * Setup the HTTP variables needed... + */ + + if (filename != NULL) + sprintf(length, "%u", ippLength(request) + (size_t)fileinfo.st_size); + else + sprintf(length, "%u", ippLength(request)); + + httpClearFields(http); + httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length); + httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp"); + httpSetField(http, HTTP_FIELD_AUTHORIZATION, authstring); + + /* + * Try the request... + */ + + DEBUG_puts("cupsDoFileRequest: post..."); + + if (httpPost(http, resource)) + continue; + + /* + * Send the IPP data and wait for the response... + */ + + DEBUG_puts("cupsDoFileRequest: ipp write..."); + + request->state = IPP_IDLE; + if (ippWrite(http, request) != IPP_ERROR) + if (filename != NULL) + { + DEBUG_puts("cupsDoFileRequest: file write..."); + + /* + * Send the file... + */ + + rewind(file); + + while ((bytes = fread(buffer, 1, sizeof(buffer), file)) > 0) + if (httpWrite(http, buffer, bytes) < bytes) + break; + } + + /* + * Get the server's return status... + */ + + DEBUG_puts("cupsDoFileRequest: update..."); + + while ((status = httpUpdate(http)) == HTTP_CONTINUE); + + if (status == HTTP_UNAUTHORIZED) + { + DEBUG_puts("cupsDoFileRequest: unauthorized..."); + + /* + * Flush any error message... + */ + + httpFlush(http); + + /* + * See if we can do local authentication... + */ + + if (cups_local_auth(http)) + continue; + + /* + * Nope - get a password from the user... + */ + + printf("Authentication required for %s on %s...\n", cupsUser(), + http->hostname); + + if ((password = cupsGetPassword("UNIX Password: ")) != NULL) + { + /* + * Got a password; send it to the server... + */ + + if (!password[0]) + break; + + if (strncmp(http->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0) + { + /* + * Basic authentication... + */ + + snprintf(plain, sizeof(plain), "%s:%s", cupsUser(), password); + httpEncode64(encode, plain); + snprintf(authstring, sizeof(authstring), "Basic %s", encode); + } + else + { + /* + * Digest authentication... + */ + + httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm); + httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce); + + httpMD5(cupsUser(), realm, password, encode); + httpMD5Final(nonce, "POST", resource, encode); + snprintf(authstring, sizeof(authstring), + "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", " + "response=\"%s\"", cupsUser(), realm, nonce, encode); + } + continue; + } + else + break; + } + else if (status == HTTP_ERROR) + { +#if defined(WIN32) || defined(__EMX__) + if (http->error != WSAENETDOWN && http->error != WSAENETUNREACH) +#else + if (http->error != ENETDOWN && http->error != ENETUNREACH) +#endif /* WIN32 || __EMX__ */ + continue; + else + break; + } + else if (status != HTTP_OK) + { + DEBUG_printf(("cupsDoFileRequest: error %d...\n", status)); + + /* + * Flush any error message... + */ + + httpFlush(http); + break; + } + else + { + /* + * Read the response... + */ + + DEBUG_puts("cupsDoFileRequest: response..."); + + response = ippNew(); + + if (ippRead(http, response) == IPP_ERROR) + { + /* + * Delete the response... + */ + + ippDelete(response); + response = NULL; + + last_error = IPP_SERVICE_UNAVAILABLE; + + /* + * Flush any remaining data... + */ + + httpFlush(http); + break; + } + } + } + + /* + * Close the file if needed... + */ + + if (filename != NULL) + fclose(file); + + /* + * Delete the original request and return the response... + */ + + ippDelete(request); + + if (response) + last_error = response->request.status.status_code; + else if (status == HTTP_NOT_FOUND) + last_error = IPP_NOT_FOUND; + else if (status == HTTP_UNAUTHORIZED) + last_error = IPP_NOT_AUTHORIZED; + else if (status != HTTP_OK) + last_error = IPP_SERVICE_UNAVAILABLE; + + return (response); +} + + +/* + * 'cupsGetClasses()' - Get a list of printer classes. + */ + +int /* O - Number of classes */ +cupsGetClasses(char ***classes) /* O - Classes */ +{ + int n; /* Number of classes */ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + cups_lang_t *language; /* Default language */ + char **temp; /* Temporary pointer */ + + + /* + * Try to connect to the server... + */ + + if (!cups_connect("default", NULL, NULL)) + { + last_error = IPP_SERVICE_UNAVAILABLE; + return (0); + } + + /* + * Build a CUPS_GET_CLASSES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_GET_CLASSES; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + /* + * Do the request and get back a response... + */ + + n = 0; + *classes = NULL; + + if ((response = cupsDoRequest(cups_server, request, "/")) != NULL) + { + last_error = response->request.status.status_code; + + for (attr = response->attrs; attr != NULL; attr = attr->next) + if (attr->name != NULL && + strcasecmp(attr->name, "printer-name") == 0 && + attr->value_tag == IPP_TAG_NAME) + { + if (n == 0) + temp = malloc(sizeof(char *)); + else + temp = realloc(*classes, sizeof(char *) * (n + 1)); + + if (temp == NULL) + { + /* + * Ran out of memory! + */ + + while (n > 0) + { + n --; + free((*classes)[n]); + } + + free(*classes); + ippDelete(response); + return (0); + } + + *classes = temp; + temp[n] = strdup(attr->values[0].string.text); + n ++; + } + + ippDelete(response); + } + else + last_error = IPP_BAD_REQUEST; + + return (n); +} + + +/* + * 'cupsGetDefault()' - Get the default printer or class. + */ + +const char * /* O - Default printer or NULL */ +cupsGetDefault(void) +{ + FILE *fp; /* cupsd.conf file */ + char *printer; /* Pointer to server name */ + char line[1024]; /* Line from file */ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + cups_lang_t *language; /* Default language */ + const char *var; /* Environment variable */ + static char def_printer[256];/* Default printer */ + + + /* + * First see if the LPDEST or PRINTER environment variables are + * set... However, if PRINTER is set to "lp", ignore it to work + * around a "feature" in most Linux distributions - the default + * user login scripts set PRINTER to "lp"... + */ + + if ((var = getenv("LPDEST")) != NULL) + return (var); + else if ((var = getenv("PRINTER")) != NULL && strcmp(var, "lp") != 0) + return (var); + + /* + * Next check to see if we have a client.conf file... + */ + + if ((var = getenv("CUPS_SERVERROOT")) != NULL) + snprintf(line, sizeof(line), "%s/client.conf", var); + else + strcpy(line, CUPS_SERVERROOT "/client.conf"); + + if ((fp = fopen(line, "r")) != NULL) + { + /* + * Read the client.conf file and look for a DefaultPrinter line... + */ + + while (fgets(line, sizeof(line), fp) != NULL) + if (strncmp(line, "DefaultPrinter ", 15) == 0) + { + /* + * Got it! Drop any trailing newline and find the name... + */ + + printer = line + strlen(line) - 1; + if (*printer == '\n') + *printer = '\0'; + + for (printer = line + 15; isspace(*printer); printer ++); + + if (*printer) + { + strncpy(def_printer, printer, sizeof(def_printer) - 1); + def_printer[sizeof(def_printer) - 1] = '\0'; + + fclose(fp); + + return (def_printer); + } + } + + fclose(fp); + } + + /* + * Try to connect to the server... + */ + + if (!cups_connect("default", NULL, NULL)) + { + last_error = IPP_SERVICE_UNAVAILABLE; + return (NULL); + } + + /* + * Build a CUPS_GET_DEFAULT request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_GET_DEFAULT; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(cups_server, request, "/")) != NULL) + { + last_error = response->request.status.status_code; + + if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL) + { + strncpy(def_printer, attr->values[0].string.text, sizeof(def_printer) - 1); + def_printer[sizeof(def_printer) - 1] = '\0'; + ippDelete(response); + return (def_printer); + } + + ippDelete(response); + } + else + last_error = IPP_BAD_REQUEST; + + return (NULL); +} + + +/* + * 'cupsGetPPD()' - Get the PPD file for a printer. + */ + +const char * /* O - Filename for PPD file */ +cupsGetPPD(const char *name) /* I - Printer name */ +{ + ipp_t *request, /* IPP request */ + *response; /* IPP response */ + ipp_attribute_t *attr; /* Current attribute */ + cups_lang_t *language; /* Local language */ + FILE *fp; /* PPD file */ + int bytes; /* Number of bytes read */ + char buffer[8192]; /* Buffer for file */ + char printer[HTTP_MAX_URI], /* Printer name */ + method[HTTP_MAX_URI], /* Method/scheme name */ + username[HTTP_MAX_URI], /* Username:password */ + hostname[HTTP_MAX_URI], /* Hostname */ + resource[HTTP_MAX_URI]; /* Resource name */ + int port; /* Port number */ + const char *password; /* Password string */ + char realm[HTTP_MAX_VALUE], /* realm="xyz" string */ + nonce[HTTP_MAX_VALUE], /* nonce="xyz" string */ + plain[255], /* Plaintext username:password */ + encode[255]; /* Encoded username:password */ + http_status_t status; /* HTTP status from server */ + static char filename[HTTP_MAX_URI]; /* Local filename */ + + + /* + * See if we can connect to the server... + */ + + if (!cups_connect(name, printer, hostname)) + { + last_error = IPP_SERVICE_UNAVAILABLE; + return (NULL); + } + + if (strchr(name, '@') == NULL) + { + /* + * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + * printer-uri + */ + + request = ippNew(); + + request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + snprintf(buffer, sizeof(buffer), "ipp://localhost/printers/%s", name); + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, + "printer-uri", NULL, buffer); + + /* + * Do the request and get back a response... + */ + + if ((response = cupsDoRequest(cups_server, request, "/")) != NULL) + { + last_error = response->request.status.status_code; + + if ((attr = ippFindAttribute(response, "printer-uri-supported", + IPP_TAG_URI)) != NULL) + { + /* + * Get the actual server and printer names... + */ + + httpSeparate(attr->values[0].string.text, method, username, hostname, + &port, resource); + strcpy(printer, strrchr(resource, '/') + 1); + + /* + * Remap local hostname to localhost... + */ + + gethostname(buffer, sizeof(buffer)); + + if (strcasecmp(buffer, hostname) == 0) + strcpy(hostname, "localhost"); + } + + ippDelete(response); + } + + cupsLangFree(language); + + /* + * Reconnect to the correct server as needed... + */ + + if (strcasecmp(cups_server->hostname, hostname) != 0) + { + httpClose(cups_server); + + if ((cups_server = httpConnect(hostname, ippPort())) == NULL) + { + last_error = IPP_SERVICE_UNAVAILABLE; + return (NULL); + } + } + } + + /* + * Get a temp file... + */ + + cupsTempFile(filename, sizeof(filename)); + + /* + * And send a request to the HTTP server... + */ + + snprintf(resource, sizeof(resource), "/printers/%s.ppd", printer); + + do + { + httpClearFields(cups_server); + httpSetField(cups_server, HTTP_FIELD_HOST, hostname); + httpSetField(cups_server, HTTP_FIELD_AUTHORIZATION, authstring); + + if (httpGet(cups_server, resource)) + { + status = HTTP_UNAUTHORIZED; + continue; + } + + while ((status = httpUpdate(cups_server)) == HTTP_CONTINUE); + + if (status == HTTP_UNAUTHORIZED) + { + DEBUG_puts("cupsGetPPD: unauthorized..."); + + /* + * Flush any error message... + */ + + httpFlush(cups_server); + + /* + * See if we can do local authentication... + */ + + if (cups_local_auth(cups_server)) + continue; + + /* + * Nope, get a password from the user... + */ + + printf("Authentication required for %s on %s...\n", cupsUser(), + cups_server->hostname); + + if ((password = cupsGetPassword("UNIX Password: ")) != NULL) + { + /* + * Got a password; send it to the server... + */ + + if (!password[0]) + break; + + if (strncmp(cups_server->fields[HTTP_FIELD_WWW_AUTHENTICATE], "Basic", 5) == 0) + { + /* + * Basic authentication... + */ + + snprintf(plain, sizeof(plain), "%s:%s", cupsUser(), password); + httpEncode64(encode, plain); + snprintf(authstring, sizeof(authstring), "Basic %s", encode); + } + else + { + /* + * Digest authentication... + */ + + httpGetSubField(cups_server, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm); + httpGetSubField(cups_server, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce); + + httpMD5(cupsUser(), realm, password, encode); + httpMD5Final(nonce, "GET", resource, encode); + snprintf(authstring, sizeof(authstring), + "Digest username=\"%s\", realm=\"%s\", nonce=\"%s\", " + "response=\"%s\"", cupsUser(), realm, nonce, encode); + } + continue; + } + else + break; + } + } + while (status == HTTP_UNAUTHORIZED); + + /* + * OK, we need to copy the file; open the file and copy it... + */ + + unlink(filename); + if ((fp = fopen(filename, "w")) == NULL) + { + /* + * Can't open file; close the server connection and return NULL... + */ + + httpFlush(cups_server); + httpClose(cups_server); + cups_server = NULL; + return (NULL); + } + + while ((bytes = httpRead(cups_server, buffer, sizeof(buffer))) > 0) + fwrite(buffer, bytes, 1, fp); + + fclose(fp); + + return (filename); +} + + +/* + * 'cupsGetPrinters()' - Get a list of printers. + */ + +int /* O - Number of printers */ +cupsGetPrinters(char ***printers) /* O - Printers */ +{ + int n; /* Number of printers */ + ipp_t *request, /* IPP Request */ + *response; /* IPP Response */ + ipp_attribute_t *attr; /* Current attribute */ + cups_lang_t *language; /* Default language */ + char **temp; /* Temporary pointer */ + + + /* + * Try to connect to the server... + */ + + if (!cups_connect("default", NULL, NULL)) + { + last_error = IPP_SERVICE_UNAVAILABLE; + return (0); + } + + /* + * Build a CUPS_GET_PRINTERS request, which requires the following + * attributes: + * + * attributes-charset + * attributes-natural-language + */ + + request = ippNew(); + + request->request.op.operation_id = CUPS_GET_PRINTERS; + request->request.op.request_id = 1; + + language = cupsLangDefault(); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, language->language); + + /* + * Do the request and get back a response... + */ + + n = 0; + *printers = NULL; + + if ((response = cupsDoRequest(cups_server, request, "/")) != NULL) + { + last_error = response->request.status.status_code; + + for (attr = response->attrs; attr != NULL; attr = attr->next) + if (attr->name != NULL && + strcasecmp(attr->name, "printer-name") == 0 && + attr->value_tag == IPP_TAG_NAME) + { + if (n == 0) + temp = malloc(sizeof(char *)); + else + temp = realloc(*printers, sizeof(char *) * (n + 1)); + + if (temp == NULL) + { + /* + * Ran out of memory! + */ + + while (n > 0) + { + n --; + free((*printers)[n]); + } + + free(*printers); + ippDelete(response); + return (0); + } + + *printers = temp; + temp[n] = strdup(attr->values[0].string.text); + n ++; + } + + ippDelete(response); + } + else + last_error = IPP_BAD_REQUEST; + + return (n); +} + + +/* + * 'cupsLastError()' - Return the last IPP error that occurred. + */ + +ipp_status_t /* O - IPP error code */ +cupsLastError(void) +{ + return (last_error); +} + + +/* + * 'cupsPrintFile()' - Print a file to a printer or class. + */ + +int /* O - Job ID */ +cupsPrintFile(const char *name, /* I - Printer or class name */ + const char *filename, /* I - File to print */ + const char *title, /* I - Title of job */ + int num_options,/* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + DEBUG_printf(("cupsPrintFile(\'%s\', \'%s\', %d, %08x)\n", + printer, filename, num_options, options)); + + return (cupsPrintFiles(name, 1, &filename, title, num_options, options)); +} + + +/* + * 'cupsPrintFiles()' - Print one or more files to a printer or class. + */ + +int /* O - Job ID */ +cupsPrintFiles(const char *name, /* I - Printer or class name */ + int num_files, /* I - Number of files */ + const char **files, /* I - File(s) to print */ + const char *title, /* I - Title of job */ + int num_options,/* I - Number of options */ + cups_option_t *options) /* I - Options */ +{ + int i; /* Looping var */ + int n, n2; /* Attribute values */ + char *option, /* Name of option */ + *s; /* Pointer into option value */ + const char *val; /* Pointer to option value */ + ipp_t *request; /* IPP request */ + ipp_t *response; /* IPP response */ + ipp_attribute_t *attr; /* IPP job-id attribute */ + char hostname[HTTP_MAX_URI], /* Hostname */ + printer[HTTP_MAX_URI], /* Printer or class name */ + uri[HTTP_MAX_URI]; /* Printer URI */ + cups_lang_t *language; /* Language to use */ + int jobid; /* New job ID */ + + + DEBUG_printf(("cupsPrintFiles(\'%s\', %d, %p, %d, %08x)\n", + printer, num_files, files, num_options, options)); + + if (name == NULL || num_files < 1 || files == NULL) + return (0); + + /* + * Setup a connection and request data... + */ + + if (!cups_connect(name, printer, hostname)) + { + DEBUG_printf(("cupsPrintFile: Unable to open connection - %s.\n", + strerror(errno))); + last_error = IPP_SERVICE_UNAVAILABLE; + return (0); + } + + language = cupsLangDefault(); + + /* + * Build a standard CUPS URI for the printer and fill the standard IPP + * attributes... + */ + + if ((request = ippNew()) == NULL) + return (0); + + request->request.op.operation_id = num_files == 1 ? IPP_PRINT_JOB : + IPP_CREATE_JOB; + request->request.op.request_id = 1; + + snprintf(uri, sizeof(uri), "ipp://%s:%d/printers/%s", hostname, ippPort(), printer); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, + language != NULL ? language->language : "C"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", + NULL, uri); + + /* + * Handle raw print files... + */ + + if (cupsGetOption("raw", num_options, options)) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", + NULL, "application/vnd.cups-raw"); + else if ((val = cupsGetOption("document-format", num_options, options)) != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", + NULL, val); + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", + NULL, "application/octet-stream"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + + if (title) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title); + + /* + * Then add all options on the command-line... + */ + + for (i = 0; i < num_options; i ++) + { + /* + * Skip the "raw" option - handled above... + */ + + if (strcasecmp(options[i].name, "raw") == 0 || + strcasecmp(options[i].name, "document-format") == 0) + continue; + + /* + * See what the option value is; for compatibility with older interface + * scripts, we have to support single-argument options as well as + * option=value, option=low-high, and option=MxN. + */ + + option = options[i].name; + val = options[i].value; + + if (*val == '\0') + val = NULL; + + if (val != NULL) + { + if (strcasecmp(val, "true") == 0 || + strcasecmp(val, "on") == 0 || + strcasecmp(val, "yes") == 0) + { + /* + * Boolean value - true... + */ + + n = 1; + val = ""; + } + else if (strcasecmp(val, "false") == 0 || + strcasecmp(val, "off") == 0 || + strcasecmp(val, "no") == 0) + { + /* + * Boolean value - false... + */ + + n = 0; + val = ""; + } + + n = strtol(val, &s, 0); + } + else + { + if (strncasecmp(option, "no", 2) == 0) + { + option += 2; + n = 0; + } + else + n = 1; + + s = ""; + } + + if (*s != '\0' && *s != '-' && (*s != 'x' || s == val)) + { + /* + * String value(s)... + */ + + DEBUG_printf(("cupsPrintFile: Adding string option \'%s\' with value \'%s\'...\n", + option, val)); + + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, option, NULL, val); + } + else if (val != NULL) + { + /* + * Numeric value, range, or resolution... + */ + + if (*s == '-') + { + n2 = strtol(s + 1, NULL, 0); + ippAddRange(request, IPP_TAG_JOB, option, n, n2); + + DEBUG_printf(("cupsPrintFile: Adding range option \'%s\' with value %d-%d...\n", + option, n, n2)); + } + else if (*s == 'x') + { + n2 = strtol(s + 1, &s, 0); + + if (strcasecmp(s, "dpc") == 0) + ippAddResolution(request, IPP_TAG_JOB, option, IPP_RES_PER_CM, n, n2); + else if (strcasecmp(s, "dpi") == 0) + ippAddResolution(request, IPP_TAG_JOB, option, IPP_RES_PER_INCH, n, n2); + else + ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, option, NULL, val); + + DEBUG_printf(("cupsPrintFile: Adding resolution option \'%s\' with value %s...\n", + option, val)); + } + else + { + ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, option, n); + + DEBUG_printf(("cupsPrintFile: Adding integer option \'%s\' with value %d...\n", + option, n)); + } + } + else + { + /* + * Boolean value... + */ + + DEBUG_printf(("cupsPrintFile: Adding boolean option \'%s\' with value %d...\n", + option, n)); + ippAddBoolean(request, IPP_TAG_JOB, option, (char)n); + } + } + + /* + * Do the request... + */ + + snprintf(uri, sizeof(uri), "/printers/%s", printer); + + if (num_files == 1) + response = cupsDoFileRequest(cups_server, request, uri, *files); + else + response = cupsDoRequest(cups_server, request, uri); + + if (response == NULL) + jobid = 0; + else if (response->request.status.status_code > IPP_OK_CONFLICT) + { + DEBUG_printf(("IPP response code was 0x%x!\n", + response->request.status.status_code)); + jobid = 0; + } + else if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL) + { + DEBUG_puts("No job ID!"); + jobid = 0; + } + else + jobid = attr->values[0].integer; + + if (response != NULL) + ippDelete(response); + + /* + * Handle multiple file jobs if the create-job operation worked... + */ + + if (jobid > 0 && num_files > 1) + for (i = 0; i < num_files; i ++) + { + /* + * Build a standard CUPS URI for the job and fill the standard IPP + * attributes... + */ + + if ((request = ippNew()) == NULL) + return (0); + + request->request.op.operation_id = IPP_SEND_DOCUMENT; + request->request.op.request_id = 1; + + snprintf(uri, sizeof(uri), "ipp://%s:%d/jobs/%d", hostname, ippPort(), + jobid); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, + "attributes-charset", NULL, cupsLangEncoding(language)); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, + "attributes-natural-language", NULL, + language != NULL ? language->language : "C"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", + NULL, uri); + + /* + * Handle raw print files... + */ + + if (cupsGetOption("raw", num_options, options)) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", + NULL, "application/vnd.cups-raw"); + else if ((val = cupsGetOption("document-format", num_options, options)) != NULL) + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", + NULL, val); + else + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", + NULL, "application/octet-stream"); + + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", + NULL, cupsUser()); + + /* + * Is this the last document? + */ + + if (i == (num_files - 1)) + ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); + + /* + * Send the file... + */ + + snprintf(uri, sizeof(uri), "/printers/%s", printer); + + if ((response = cupsDoFileRequest(cups_server, request, uri, + files[i])) != NULL) + ippDelete(response); + } + + return (jobid); +} + + +/* + * 'cupsTempFile()' - Generate a temporary filename. + */ + +char * /* O - Filename */ +cupsTempFile(char *filename, /* I - Pointer to buffer */ + int len) /* I - Size of buffer */ +{ + char *tmpdir; /* TMPDIR environment var */ + static char buf[1024] = ""; /* Buffer if you pass in NULL and 0 */ + + + /* + * See if a filename was specified... + */ + + if (filename == NULL) + { + filename = buf; + len = sizeof(buf); + } + + /* + * See if TMPDIR is defined... + */ + + if ((tmpdir = getenv("TMPDIR")) == NULL) + { +#ifdef WIN32 + tmpdir = "C:/WINDOWS/TEMP"; +#else + /* + * Put root temp files in restricted temp directory... + */ + + if (getuid() == 0) + tmpdir = CUPS_REQUESTS "/tmp"; + else + tmpdir = "/var/tmp"; +#endif /* WIN32 */ + } + + /* + * Make the temporary name using the specified directory... + */ + + snprintf(filename, len, "%s/XXXXXX", tmpdir); + return (mktemp(filename)); +} + + +/* + * 'cups_connect()' - Connect to the specified host... + */ + +static char * /* I - Printer name or NULL */ +cups_connect(const char *name, /* I - Destination (printer[@host]) */ + char *printer, /* O - Printer name [HTTP_MAX_URI] */ + char *hostname) /* O - Hostname [HTTP_MAX_URI] */ +{ + char hostbuf[HTTP_MAX_URI]; + /* Name of host */ + static char printerbuf[HTTP_MAX_URI]; + /* Name of printer or class */ + + + if (name == NULL) + { + last_error = IPP_BAD_REQUEST; + return (NULL); + } + + if (sscanf(name, "%1023[^@]@%1023s", printerbuf, hostbuf) == 1) + { + strncpy(hostbuf, cupsServer(), sizeof(hostbuf) - 1); + hostbuf[sizeof(hostbuf) - 1] = '\0'; + } + + if (hostname != NULL) + { + strncpy(hostname, hostbuf, HTTP_MAX_URI - 1); + hostname[HTTP_MAX_URI - 1] = '\0'; + } + else + hostname = hostbuf; + + if (printer != NULL) + { + strncpy(printer, printerbuf, HTTP_MAX_URI - 1); + printer[HTTP_MAX_URI - 1] = '\0'; + } + else + printer = printerbuf; + + if (cups_server != NULL) + { + if (strcasecmp(cups_server->hostname, hostname) == 0) + return (printer); + + httpClose(cups_server); + } + + if ((cups_server = httpConnect(hostname, ippPort())) == NULL) + { + last_error = IPP_SERVICE_UNAVAILABLE; + return (NULL); + } + else + return (printer); +} + + +/* + * 'cups_local_auth()' - Get the local authorization certificate if + * available/applicable... + */ + +static int /* O - 1 if available, 0 if not */ +cups_local_auth(http_t *http) /* I - Connection */ +{ +#if defined(WIN32) || defined(__EMX__) + /* + * Currently WIN32 and OS-2 do not support the CUPS server... + */ + + return (0); +#else + int pid; /* Current process ID */ + FILE *fp; /* Certificate file */ + char filename[1024], /* Certificate filename */ + certificate[33]; /* Certificate string */ + + + /* + * See if we are accessing localhost... + */ + + if (ntohl(http->hostaddr.sin_addr.s_addr) != 0x7f000001 && + strcasecmp(http->hostname, "localhost") != 0) + return (0); + + /* + * Try opening a certificate file for this PID. If that fails, + * try the root certificate... + */ + + pid = getpid(); + sprintf(filename, CUPS_SERVERROOT "/certs/%d", pid); + if ((fp = fopen(filename, "r")) == NULL && pid > 0) + fp = fopen(CUPS_SERVERROOT "/certs/0", "r"); + + if (fp == NULL) + return (0); + + /* + * Read the certificate from the file... + */ + + fgets(certificate, sizeof(certificate), fp); + fclose(fp); + + /* + * Set the authorization string and return... + */ + + sprintf(authstring, "Local %s", certificate); + + return (1); +#endif /* WIN32 || __EMX__ */ +} + + +/* + * End of "$Id$". + */ diff --git a/data/HPGLprolog b/data/HPGLprolog new file mode 100644 index 0000000000..21b244ca23 --- /dev/null +++ b/data/HPGLprolog @@ -0,0 +1,37 @@ +%%BeginResource: procset hpgltops 1.1 0 +% +% "$Id: HPGLprolog 932 2000-02-26 20:01:37Z mike $" +% +% HP-GL/2 filter procset for the Common UNIX Printing System (CUPS). +% +% This procset contains the basic drawing commands that are used to +% reduce output size. Note the 'MP' (make newpath) definition - this +% should be called 'NP' (newpath), but GhostScript uses the 'NP' name +% for 'noaccess put' in some of its font files... +% +% Copyright 1993-2000 Easy Software Products +% +% These coded instructions, statements, and computer programs are the +% property of Easy Software Products and are protected by Federal +% copyright law. Distribution and use rights are outlined in the file +% "LICENSE.txt" which should have been included with this file. If this +% file is missing or damaged please contact Easy Software Products +% at: +% +% Attn: CUPS Licensing Information +% Easy Software Products +% 44141 Airport View Drive, Suite 204 +% Hollywood, Maryland 20636-3111 USA +% +% Voice: (301) 373-9603 +% EMail: cups-info@cups.org +% WWW: http://www.cups.org +% +/MO { moveto } bind def +/LI { lineto } bind def +/FI { fill } bind def +/ST { stroke } bind def +/CP { closepath } bind def +/MP { newpath } bind def +/SP { setlinewidth setrgbcolor } bind def +%%EndResource diff --git a/data/Makefile b/data/Makefile new file mode 100644 index 0000000000..2ff64ef14a --- /dev/null +++ b/data/Makefile @@ -0,0 +1,103 @@ +# +# "$Id$" +# +# Datafile makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1993-2000 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +# +# Data files... +# + +BANNERS = classified \ + confidential \ + secret \ + standard \ + topsecret \ + unclassified + +CHARSETS = windows-874 \ + windows-1250 \ + windows-1251 \ + windows-1252 \ + windows-1253 \ + windows-1254 \ + windows-1255 \ + windows-1256 \ + windows-1257 \ + windows-1258 \ + iso-8859-1 \ + iso-8859-2 \ + iso-8859-3 \ + iso-8859-4 \ + iso-8859-5 \ + iso-8859-6 \ + iso-8859-7 \ + iso-8859-8 \ + iso-8859-9 \ + iso-8859-10 \ + iso-8859-13 \ + iso-8859-14 \ + iso-8859-15 \ + utf-8 +DATAFILES = HPGLprolog psglyphs testprint.ps + + +# +# Make everything... +# + +all: + + +# +# Clean all config and object files... +# + +clean: + + +# +# Install files... +# + +install: + -$(MKDIR) $(DATADIR)/banners + $(CHMOD) ugo+rx $(DATADIR) + $(CHMOD) ugo+rx $(DATADIR)/banners + $(INSTALL_DATA) $(BANNERS) $(DATADIR)/banners + -$(MKDIR) $(DATADIR)/charsets + $(CHMOD) ugo+rx $(DATADIR)/charsets + $(INSTALL_DATA) $(CHARSETS) $(DATADIR)/charsets + -$(MKDIR) $(DATADIR)/data + $(CHMOD) ugo+rx $(DATADIR)/data + $(INSTALL_DATA) $(DATAFILES) $(DATADIR)/data + -if test "$(PAMDIR)" != ""; then \ + $(MKDIR) $(PAMDIR); \ + $(CHMOD) ugo+rx $(PAMDIR); \ + $(INSTALL_DATA) cups.pam $(PAMDIR)/cups; \ + fi + + +# +# End of "$Id$". +# diff --git a/data/classified b/data/classified new file mode 100644 index 0000000000..e33b15daf2 --- /dev/null +++ b/data/classified @@ -0,0 +1,259 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 +%%Pages: 1 +%%LanguageLevel: 1 +%%DocumentData: Clean7Bit +%%DocumentSuppliedResources: procset bannerprint/1.0 +%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman +%%Creator: Michael Sweet, Easy Software Products +%%CreationDate: May 10, 2000 +%%Title: Test Page +%%EndComments +%%BeginProlog +%%BeginResource procset bannerprint 1.1 0 +% +% PostScript banner page for the Common UNIX Printing System ("CUPS"). +% +% Copyright 1993-2000 Easy Software Products +% +% These coded instructions, statements, and computer programs contain +% unpublished proprietary information of Easy Software Products, and +% are protected by Federal copyright law. They may not be disclosed +% to third parties or copied or duplicated in any form, in whole or +% in part, without the prior written consent of Easy Software Products. +% +/CENTER \{ % Draw centered text + % (name) CENTER - + dup stringwidth pop % Get the width of the string + 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance + show % Show the string +} bind def +/RIGHT \{ % Draw right-justified text + % (name) RIGHT - + dup stringwidth pop % Get the width of the string + neg 0 rmoveto % Shift left the entire distance + show % Show the string +} bind def +/NUMBER \{ % Draw a number + % power n NUMBER - + 1 index 1 eq \{ % power == 1? + round cvi exch pop % Convert "n" to integer + } \{ + 1 index mul round exch div % Truncate extra decimal places + } ifelse + 100 string cvs show % Convert to a string and show it... +} bind def +/CUPSLOGO \{ % Draw the CUPS logo + % height CUPSLOGO + % Start with a big C... + /Helvetica findfont 1 index scalefont setfont + 0 setgray + 0 0 moveto + (C) show + + % Then "UNIX Printing System" much smaller... + /Helvetica-Bold findfont 1 index 9 div scalefont setfont + 0.25 mul + dup dup 2.0 mul moveto + (UNIX) show + dup dup 1.6 mul moveto + (Printing) show + dup 1.2 mul moveto + (System) show +} bind def +/ESPLOGO \{ % Draw the ESP logo + % height ESPLOGO + % Compute the size of the logo... + 0 0 + 2 index 1.5 mul 3 index + + % Do the "metallic" fill from 10% black to 40% black... + 1 -0.001 0 \{ + dup % loopval + -0.15 mul % loopval * -0.15 + 0.9 add % 0.9 - loopval * 0.15 + setgray % set gray shade + + 0 % x + 1 index neg % loopval + 1 add % 1 - loopval + 3 index % height + mul % height * (1 - loopval) + moveto % starting point + + dup % loopval + 3 index % width + mul % loopval * width + 2 index % height + lineto % Next point + + 0 % x + 2 index % height + lineto % Next point + + closepath + fill + + dup % loopval + 0.15 mul % loopval * 0.15 + 0.6 add % 0.6 + loopval * 0.15 + setgray + + dup % loopval + neg 1 add % 1 - loopval + 3 index % width + mul % (1 - loopval) * width + 0 % y + moveto % Starting point + + 2 index % width + exch % loopval + 2 index % height + mul % loopval * height + lineto % Next point + + 1 index % width + 0 % y + lineto % Next point + + closepath + fill + } for + + 0 setgray rectstroke + + /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont + dup 40 div + + dup 4 mul 1 index 25 mul moveto (E) show + dup 10 mul 1 index 15 mul moveto (S) show + dup 16 mul 1 index 5 mul moveto (P) show + + /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont + dup 14 mul 1 index 29 mul moveto (asy) show + dup 20 mul 1 index 19 mul moveto (oftware) show + dup 26 mul 1 index 9 mul moveto (roducts) show + + pop +} bind def +%%EndResource +%%EndProlog +%%Page: 1 1 +gsave + + % Determine the imageable area and device resolution... + initclip newpath clippath pathbbox % Get bounding rectangle + 72 div /pageTop exch def % Get top margin in inches + 72 div /pageRight exch def % Get right margin in inches + 72 div /pageBottom exch def % Get bottom margin in inches + 72 div /pageLeft exch def % Get left margin in inches + + /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft + /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom + + newpath % Clear bounding path + + % Create fonts... + /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold + pageWidth 4 mul scalefont def % size = pageWidth * 4 (nominally 34) + + /mediumFont /Helvetica findfont % mediumFont = Helvetica + pageWidth 2 mul scalefont def % size = pageWidth * 2 (nominally 17) + + % Offset page to account for lower-left margin... + pageLeft 72 mul + pageBottom 72 mul + translate + + % Draw the label at the top and bottom... + 0 setgray % Color + + pageWidth 36 mul % Center of page + pageHeight 72 mul % Top of page + pageWidth -9 mul add % - 1 line + moveto % Position text + bigFont setfont % Font + (Classified) CENTER % Show text centered + + pageWidth 36 mul % Center of page + pageWidth 8 mul % Bottom of page + moveto % Position text + bigFont setfont % Font + (Classified) CENTER % Show text centered + + % Job information box... + pageWidth 18 mul 9 add % x = pageWidth * 1/4 * 72 + 9 + pageHeight 27 mul 9 sub % y = pageHeight * 3/8 * 72 - 9 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + 0.5 setgray rectfill % Draw a shadow + + pageWidth 18 mul % x = pageWidth * 1/4 * 72 + pageHeight 27 mul % y = pageHeight * 3/8 * 72 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + + 4 copy 1 setgray rectfill % Clear the box to white + 0 setgray rectstroke % Draw a black box around it... + + % Job information text... + mediumFont setfont % Medium sized font + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 4 mul add % y += 2 lines + 2 copy % Copy X & Y + moveto + (Job ID: ) RIGHT + moveto + ({printer-name}-{job-id}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 1 mul add % y += 1 line + 2 copy % Copy X & Y + moveto + (Title: ) RIGHT + moveto + ({job-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -2 mul add % y -= 1 line + 2 copy % Copy X & Y + moveto + (Requesting User: ) RIGHT + moveto + ({job-originating-user-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -5 mul add % y -= 2 lines + 2 copy % Copy X & Y + moveto + (Billing Info: ) RIGHT + moveto + ({job-billing}) show + + % Then the CUPS logo.... + gsave + pageWidth 4 mul + pageWidth 6 mul + translate + pageWidth 9 mul CUPSLOGO + grestore + + % And the ESP logo.... + gsave + pageWidth 59 mul + pageWidth 6 mul + translate + pageWidth 6 mul ESPLOGO + grestore +% Show the page... +grestore +showpage +% +% End of "$Id: classified 1075 2000-05-11 20:02:21Z mike $". +% +%%EOF diff --git a/data/confidential b/data/confidential new file mode 100644 index 0000000000..c5980cdde9 --- /dev/null +++ b/data/confidential @@ -0,0 +1,259 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 +%%Pages: 1 +%%LanguageLevel: 1 +%%DocumentData: Clean7Bit +%%DocumentSuppliedResources: procset bannerprint/1.0 +%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman +%%Creator: Michael Sweet, Easy Software Products +%%CreationDate: May 10, 2000 +%%Title: Test Page +%%EndComments +%%BeginProlog +%%BeginResource procset bannerprint 1.1 0 +% +% PostScript banner page for the Common UNIX Printing System ("CUPS"). +% +% Copyright 1993-2000 Easy Software Products +% +% These coded instructions, statements, and computer programs contain +% unpublished proprietary information of Easy Software Products, and +% are protected by Federal copyright law. They may not be disclosed +% to third parties or copied or duplicated in any form, in whole or +% in part, without the prior written consent of Easy Software Products. +% +/CENTER \{ % Draw centered text + % (name) CENTER - + dup stringwidth pop % Get the width of the string + 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance + show % Show the string +} bind def +/RIGHT \{ % Draw right-justified text + % (name) RIGHT - + dup stringwidth pop % Get the width of the string + neg 0 rmoveto % Shift left the entire distance + show % Show the string +} bind def +/NUMBER \{ % Draw a number + % power n NUMBER - + 1 index 1 eq \{ % power == 1? + round cvi exch pop % Convert "n" to integer + } \{ + 1 index mul round exch div % Truncate extra decimal places + } ifelse + 100 string cvs show % Convert to a string and show it... +} bind def +/CUPSLOGO \{ % Draw the CUPS logo + % height CUPSLOGO + % Start with a big C... + /Helvetica findfont 1 index scalefont setfont + 0 setgray + 0 0 moveto + (C) show + + % Then "UNIX Printing System" much smaller... + /Helvetica-Bold findfont 1 index 9 div scalefont setfont + 0.25 mul + dup dup 2.0 mul moveto + (UNIX) show + dup dup 1.6 mul moveto + (Printing) show + dup 1.2 mul moveto + (System) show +} bind def +/ESPLOGO \{ % Draw the ESP logo + % height ESPLOGO + % Compute the size of the logo... + 0 0 + 2 index 1.5 mul 3 index + + % Do the "metallic" fill from 10% black to 40% black... + 1 -0.001 0 \{ + dup % loopval + -0.15 mul % loopval * -0.15 + 0.9 add % 0.9 - loopval * 0.15 + setgray % set gray shade + + 0 % x + 1 index neg % loopval + 1 add % 1 - loopval + 3 index % height + mul % height * (1 - loopval) + moveto % starting point + + dup % loopval + 3 index % width + mul % loopval * width + 2 index % height + lineto % Next point + + 0 % x + 2 index % height + lineto % Next point + + closepath + fill + + dup % loopval + 0.15 mul % loopval * 0.15 + 0.6 add % 0.6 + loopval * 0.15 + setgray + + dup % loopval + neg 1 add % 1 - loopval + 3 index % width + mul % (1 - loopval) * width + 0 % y + moveto % Starting point + + 2 index % width + exch % loopval + 2 index % height + mul % loopval * height + lineto % Next point + + 1 index % width + 0 % y + lineto % Next point + + closepath + fill + } for + + 0 setgray rectstroke + + /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont + dup 40 div + + dup 4 mul 1 index 25 mul moveto (E) show + dup 10 mul 1 index 15 mul moveto (S) show + dup 16 mul 1 index 5 mul moveto (P) show + + /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont + dup 14 mul 1 index 29 mul moveto (asy) show + dup 20 mul 1 index 19 mul moveto (oftware) show + dup 26 mul 1 index 9 mul moveto (roducts) show + + pop +} bind def +%%EndResource +%%EndProlog +%%Page: 1 1 +gsave + + % Determine the imageable area and device resolution... + initclip newpath clippath pathbbox % Get bounding rectangle + 72 div /pageTop exch def % Get top margin in inches + 72 div /pageRight exch def % Get right margin in inches + 72 div /pageBottom exch def % Get bottom margin in inches + 72 div /pageLeft exch def % Get left margin in inches + + /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft + /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom + + newpath % Clear bounding path + + % Create fonts... + /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold + pageWidth 4 mul scalefont def % size = pageWidth * 4 (nominally 34) + + /mediumFont /Helvetica findfont % mediumFont = Helvetica + pageWidth 2 mul scalefont def % size = pageWidth * 2 (nominally 17) + + % Offset page to account for lower-left margin... + pageLeft 72 mul + pageBottom 72 mul + translate + + % Draw the label at the top and bottom... + 0 setgray % Color + + pageWidth 36 mul % Center of page + pageHeight 72 mul % Top of page + pageWidth -9 mul add % - 1 line + moveto % Position text + bigFont setfont % Font + (Confidential) CENTER % Show text centered + + pageWidth 36 mul % Center of page + pageWidth 8 mul % Bottom of page + moveto % Position text + bigFont setfont % Font + (Confidential) CENTER % Show text centered + + % Job information box... + pageWidth 18 mul 9 add % x = pageWidth * 1/4 * 72 + 9 + pageHeight 27 mul 9 sub % y = pageHeight * 3/8 * 72 - 9 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + 0.5 setgray rectfill % Draw a shadow + + pageWidth 18 mul % x = pageWidth * 1/4 * 72 + pageHeight 27 mul % y = pageHeight * 3/8 * 72 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + + 4 copy 1 setgray rectfill % Clear the box to white + 0 setgray rectstroke % Draw a black box around it... + + % Job information text... + mediumFont setfont % Medium sized font + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 4 mul add % y += 2 lines + 2 copy % Copy X & Y + moveto + (Job ID: ) RIGHT + moveto + ({printer-name}-{job-id}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 1 mul add % y += 1 line + 2 copy % Copy X & Y + moveto + (Title: ) RIGHT + moveto + ({job-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -2 mul add % y -= 1 line + 2 copy % Copy X & Y + moveto + (Requesting User: ) RIGHT + moveto + ({job-originating-user-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -5 mul add % y -= 2 lines + 2 copy % Copy X & Y + moveto + (Billing Info: ) RIGHT + moveto + ({job-billing}) show + + % Then the CUPS logo.... + gsave + pageWidth 4 mul + pageWidth 6 mul + translate + pageWidth 9 mul CUPSLOGO + grestore + + % And the ESP logo.... + gsave + pageWidth 59 mul + pageWidth 6 mul + translate + pageWidth 6 mul ESPLOGO + grestore +% Show the page... +grestore +showpage +% +% End of "$Id: confidential 1075 2000-05-11 20:02:21Z mike $". +% +%%EOF diff --git a/data/cups.pam b/data/cups.pam new file mode 100644 index 0000000000..f38e70184a --- /dev/null +++ b/data/cups.pam @@ -0,0 +1,2 @@ +auth required /lib/security/pam_pwdb.so nullok shadow +account required /lib/security/pam_pwdb.so diff --git a/data/iso-8859-1 b/data/iso-8859-1 new file mode 100644 index 0000000000..057d8aee3d --- /dev/null +++ b/data/iso-8859-1 @@ -0,0 +1,251 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-1 +# (Latin1/West European) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 00A1 +A2 00A2 +A3 00A3 +A4 00A4 +A5 00A5 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AA 00AA +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00AF +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00B8 +B9 00B9 +BA 00BA +BB 00BB +BC 00BC +BD 00BD +BE 00BE +BF 00BF +C0 00C0 +C1 00C1 +C2 00C2 +C3 00C3 +C4 00C4 +C5 00C5 +C6 00C6 +C7 00C7 +C8 00C8 +C9 00C9 +CA 00CA +CB 00CB +CC 00CC +CD 00CD +CE 00CE +CF 00CF +D0 00D0 +D1 00D1 +D2 00D2 +D3 00D3 +D4 00D4 +D5 00D5 +D6 00D6 +D7 00D7 +D8 00D8 +D9 00D9 +DA 00DA +DB 00DB +DC 00DC +DD 00DD +DE 00DE +DF 00DF +E0 00E0 +E1 00E1 +E2 00E2 +E3 00E3 +E4 00E4 +E5 00E5 +E6 00E6 +E7 00E7 +E8 00E8 +E9 00E9 +EA 00EA +EB 00EB +EC 00EC +ED 00ED +EE 00EE +EF 00EF +F0 00F0 +F1 00F1 +F2 00F2 +F3 00F3 +F4 00F4 +F5 00F5 +F6 00F6 +F7 00F7 +F8 00F8 +F9 00F9 +FA 00FA +FB 00FB +FC 00FC +FD 00FD +FE 00FE +FF 00FF diff --git a/data/iso-8859-10 b/data/iso-8859-10 new file mode 100644 index 0000000000..31f55552ee --- /dev/null +++ b/data/iso-8859-10 @@ -0,0 +1,251 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-10 +# (Latin6/Nordic) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 0104 +A2 0112 +A3 0122 +A4 012A +A5 0128 +A6 0136 +A7 00A7 +A8 013B +A9 0110 +AA 0160 +AB 0166 +AC 017D +AD 00AD +AE 016A +AF 014A +B0 00B0 +B1 0105 +B2 0113 +B3 0123 +B4 012B +B5 0129 +B6 0137 +B7 00B7 +B8 013C +B9 0111 +BA 0161 +BB 0167 +BC 017E +BD 2015 +BE 016B +BF 014B +C0 0100 +C1 00C1 +C2 00C2 +C3 00C3 +C4 00C4 +C5 00C5 +C6 00C6 +C7 012E +C8 010C +C9 00C9 +CA 0118 +CB 00CB +CC 0116 +CD 00CD +CE 00CE +CF 00CF +D0 0110 +D1 0145 +D2 014C +D3 00D3 +D4 00D4 +D5 00D5 +D6 00D6 +D7 0168 +D8 00D8 +D9 0172 +DA 00DA +DB 00DB +DC 00DC +DD 00DD +DE 00DE +DF 00DF +E0 0101 +E1 00E1 +E2 00E2 +E3 00E3 +E4 00E4 +E5 00E5 +E6 00E6 +E7 012F +E8 010D +E9 00E9 +EA 0119 +EB 00EB +EC 0117 +ED 00ED +EE 00EE +EF 00EF +F0 00F0 +F1 0146 +F2 014D +F3 00F3 +F4 00F4 +F5 00F5 +F6 00F6 +F7 0169 +F8 00F8 +F9 0173 +FA 00FA +FB 00FB +FC 00FC +FD 00FD +FE 00FD +FF 0138 diff --git a/data/iso-8859-13 b/data/iso-8859-13 new file mode 100644 index 0000000000..dcfacca9d3 --- /dev/null +++ b/data/iso-8859-13 @@ -0,0 +1,251 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-13 +# (Latin7/Baltic Rim) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 201D +A2 00A2 +A3 00A3 +A4 00A4 +A5 201E +A6 00A6 +A7 00A7 +A8 00D8 +A9 00A9 +AA 0156 +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00C6 +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 201C +B5 00B5 +B6 00B6 +B7 00B7 +B8 00F8 +B9 00B9 +BA 0157 +BB 00BB +BC 00BC +BD 00BD +BE 00BE +BF 00E6 +C0 0104 +C1 012E +C2 0100 +C3 0106 +C4 00C4 +C5 00C5 +C6 0118 +C7 0112 +C8 010C +C9 00C9 +CA 0179 +CB 0116 +CC 0122 +CD 0136 +CE 012A +CF 013B +D0 0160 +D1 0143 +D2 0145 +D3 00D3 +D4 014C +D5 00D5 +D6 00D6 +D7 00D7 +D8 0172 +D9 0141 +DA 015A +DB 016A +DC 00DC +DD 017B +DE 017D +DF 00DF +E0 0105 +E1 012F +E2 0101 +E3 0107 +E4 00E4 +E5 00E5 +E6 0119 +E7 0113 +E8 010D +E9 00E9 +EA 017A +EB 0117 +EC 0123 +ED 0137 +EE 012B +EF 013C +F0 0161 +F1 0144 +F2 0146 +F3 00F3 +F4 014D +F5 00F5 +F6 00F6 +F7 00F7 +F8 0173 +F9 0142 +FA 015B +FB 016B +FC 00FC +FD 017C +FE 017E +FF 2019 diff --git a/data/iso-8859-14 b/data/iso-8859-14 new file mode 100644 index 0000000000..ca0097a47d --- /dev/null +++ b/data/iso-8859-14 @@ -0,0 +1,251 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-14 +# (Latin8/Celtic) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 1E02 +A2 1E03 +A3 00A3 +A4 010A +A5 010B +A6 1E0A +A7 00A7 +A8 1E80 +A9 00A9 +AA 1E82 +AB 1E0B +AC 1EF2 +AD 00AD +AE 00AE +AF 0178 +B0 1E1E +B1 1E1F +B2 0120 +B3 0121 +B4 1E40 +B5 1E41 +B6 00B6 +B7 1E56 +B8 1E81 +B9 1E57 +BA 1E83 +BB 1E60 +BC 1EF3 +BD 1E84 +BE 1E85 +BF 1E61 +C0 00C0 +C1 00C1 +C2 00C2 +C3 00C3 +C4 00C4 +C5 00C5 +C6 00C6 +C7 00C7 +C8 00C8 +C9 00C9 +CA 00CA +CB 00CB +CC 00CC +CD 00CD +CE 00CE +CF 00CF +D0 0174 +D1 00D1 +D2 00D2 +D3 00D3 +D4 00D4 +D5 00D5 +D6 00D6 +D7 1E6A +D8 00D8 +D9 00D9 +DA 00DA +DB 00DB +DC 00DC +DD 00DD +DE 0176 +DF 00DF +E0 00E0 +E1 00E1 +E2 00E2 +E3 00E3 +E4 00E4 +E5 00E5 +E6 00E6 +E7 00E7 +E8 00E8 +E9 00E9 +EA 00EA +EB 00EB +EC 00EC +ED 00ED +EE 00EE +EF 00EF +F0 0175 +F1 00F1 +F2 00F2 +F3 00F3 +F4 00F4 +F5 00F5 +F6 00F6 +F7 1E6B +F8 00F8 +F9 00F9 +FA 00FA +FB 00FB +FC 00FC +FD 00FD +FE 0177 +FF 00FF diff --git a/data/iso-8859-15 b/data/iso-8859-15 new file mode 100644 index 0000000000..334160f4f2 --- /dev/null +++ b/data/iso-8859-15 @@ -0,0 +1,251 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-15 +# (Latin9/West Europe + Euro) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 00A1 +A2 00A2 +A3 00A3 +A4 20AC +A5 00A5 +A6 0160 +A7 00A7 +A8 0161 +A9 00A9 +AA 00AA +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00AF +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 017D +B5 00B5 +B6 00B6 +B7 00B7 +B8 017E +B9 00B9 +BA 00BA +BB 00BB +BC 0152 +BD 0153 +BE 0178 +BF 00BF +C0 00C0 +C1 00C1 +C2 00C2 +C3 00C3 +C4 00C4 +C5 00C5 +C6 00C6 +C7 00C7 +C8 00C8 +C9 00C9 +CA 00CA +CB 00CB +CC 00CC +CD 00CD +CE 00CE +CF 00CF +D0 00D0 +D1 00D1 +D2 00D2 +D3 00D3 +D4 00D4 +D5 00D5 +D6 00D6 +D7 00D7 +D8 00D8 +D9 00D9 +DA 00DA +DB 00DB +DC 00DC +DD 00DD +DE 00DE +DF 00DF +E0 00E0 +E1 00E1 +E2 00E2 +E3 00E3 +E4 00E4 +E5 00E5 +E6 00E6 +E7 00E7 +E8 00E8 +E9 00E9 +EA 00EA +EB 00EB +EC 00EC +ED 00ED +EE 00EE +EF 00EF +F0 00F0 +F1 00F1 +F2 00F2 +F3 00F3 +F4 00F4 +F5 00F5 +F6 00F6 +F7 00F7 +F8 00F8 +F9 00F9 +FA 00FA +FB 00FB +FC 00FC +FD 00FD +FE 00FE +FF 00FF diff --git a/data/iso-8859-2 b/data/iso-8859-2 new file mode 100644 index 0000000000..19b77878d4 --- /dev/null +++ b/data/iso-8859-2 @@ -0,0 +1,253 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-2 +# (Latin2/East European) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +84 201E +85 2026 +86 2020 +87 2021 +89 2030 +8A 0160 +8B 2039 +8C 015A +8D 0164 +8E 017D +8F 0179 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +99 2122 +9A 0161 +9B 203A +8C 015B +8D 0165 +8E 017E +8F 017A +A0 00A0 +A1 0104 +A2 02D8 +A3 0141 +A4 00A4 +A5 013D +A6 015A +A7 00A7 +A8 00A8 +A9 0160 +AA 015E +AB 0164 +AC 0179 +AD 00AD +AE 017D +AF 017B +B0 00B0 +B1 0105 +B2 02DB +B3 0142 +B4 00B4 +B5 013E +B6 015B +B7 02C7 +B8 00B8 +B9 0161 +BA 015F +BB 0165 +BC 017A +BD 02DD +BE 017E +BF 017C +C0 0154 +C1 00C1 +C2 00C2 +C3 0102 +C4 00C4 +C5 0139 +C6 0106 +C7 00C7 +C8 010C +C9 00C9 +CA 0118 +CB 00CB +CC 011A +CD 00CD +CE 00CE +CF 010E +D0 0110 +D1 0143 +D2 0147 +D3 00D3 +D4 00D4 +D5 0150 +D6 00D6 +D7 00D7 +D8 0158 +D9 016E +DA 00DA +DB 0170 +DC 00DC +DD 00DD +DE 0162 +DF 00DF +E0 0155 +E1 00E1 +E2 00E2 +E3 0103 +E4 00E4 +E5 013A +E6 0107 +E7 00E7 +E8 010D +E9 00E9 +EA 0119 +EB 00EB +EC 011B +ED 00ED +EE 00EE +EF 010F +F0 0111 +F1 0144 +F2 0148 +F3 00F3 +F4 00F4 +F5 0151 +F6 00F6 +F7 00F7 +F8 0159 +F9 016F +FA 00FA +FB 0171 +FC 00FC +FD 00FD +FE 0163 +FF 02D9 diff --git a/data/iso-8859-3 b/data/iso-8859-3 new file mode 100644 index 0000000000..efc4529ed0 --- /dev/null +++ b/data/iso-8859-3 @@ -0,0 +1,244 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-3 +# (Latin3/South European) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 0126 +A2 02D8 +A3 00A3 +A4 00A4 +A6 0124 +A7 00A7 +A8 00A8 +A9 0130 +AA 015E +AB 011E +AC 0134 +AD 00AD +AF 017B +B0 00B0 +B1 0127 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 0125 +B7 00B7 +B8 00B8 +B9 0131 +BA 015F +BB 011F +BC 0135 +BD 00BD +BF 017C +C0 00C0 +C1 00C1 +C2 00C2 +C4 00C4 +C5 010A +C6 0108 +C7 00C7 +C8 00C8 +C9 00C9 +CA 00CA +CB 00CB +CC 00CC +CD 00CD +CE 00CE +CF 00CF +D1 00D1 +D2 00D2 +D3 00D3 +D4 00D4 +D5 0120 +D6 00D6 +D7 00D7 +D8 011C +D9 00D9 +DA 00DA +DB 00DB +DC 00DC +DD 016C +DE 015C +DF 00DF +E0 00E0 +E1 00E1 +E2 00E2 +E4 00E4 +E5 010B +E6 0109 +E7 00E7 +E8 00E8 +E9 00E9 +EA 00EA +EB 00EB +EC 00EC +ED 00ED +EE 00EE +EF 00EF +F1 00F1 +F2 00F2 +F3 00F3 +F4 00F4 +F5 0121 +F6 00F6 +F7 00F7 +F8 011D +F9 00F9 +FA 00FA +FB 00FB +FC 00FC +FD 016D +FE 015D +FF 02D9 diff --git a/data/iso-8859-4 b/data/iso-8859-4 new file mode 100644 index 0000000000..5c93156eb5 --- /dev/null +++ b/data/iso-8859-4 @@ -0,0 +1,251 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-4 +# (Latin4/North European) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 0104 +A2 0138 +A3 0156 +A4 00A4 +A5 0128 +A6 013B +A7 00A7 +A8 00A8 +A9 0160 +AA 0112 +AB 0122 +AC 0166 +AD 00AD +AE 017D +AF 00AF +B0 00B0 +B1 0105 +B2 02DB +B3 0157 +B4 00B4 +B5 0129 +B6 013C +B7 02C7 +B8 00B8 +B9 0161 +BA 0113 +BB 0123 +BC 0167 +BD 014A +BE 017E +BF 014B +C0 0100 +C1 00C1 +C2 00C2 +C3 00C3 +C4 00C4 +C5 00C5 +C6 00C6 +C7 012E +C8 010C +C9 00C9 +CA 0118 +CB 00CB +CC 0116 +CD 00CD +CE 00CE +CF 012A +D0 0110 +D1 0145 +D2 014C +D3 0136 +D4 00D4 +D5 00D5 +D6 00D6 +D7 00D7 +D8 00D8 +D9 0172 +DA 00DA +DB 00DB +DC 00DC +DD 0168 +DE 016A +DF 00DF +E0 0101 +E1 00E1 +E2 00E2 +E3 00E3 +E4 00E4 +E5 00E5 +E6 00E6 +E7 012F +E8 010D +E9 00E9 +EA 0119 +EB 00EB +EC 0117 +ED 00ED +EE 00EE +EF 012B +F0 0111 +F1 0146 +F2 014D +F3 0137 +F4 00F4 +F5 00F5 +F6 00F6 +F7 00F7 +F8 00F8 +F9 0173 +FA 00FA +FB 00FB +FC 00FC +FD 0169 +FE 016B +FF 02D9 diff --git a/data/iso-8859-5 b/data/iso-8859-5 new file mode 100644 index 0000000000..59ee84d57a --- /dev/null +++ b/data/iso-8859-5 @@ -0,0 +1,251 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-5 +# (Cyrillic) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 0401 +A2 0402 +A3 0403 +A4 0404 +A5 0405 +A6 0406 +A7 0407 +A8 0408 +A9 0409 +AA 040A +AB 040B +AC 040C +AD 00AD +AE 040E +AF 040F +B0 0410 +B1 0411 +B2 0412 +B3 0413 +B4 0414 +B5 0415 +B6 0416 +B7 0417 +B8 0418 +B9 0419 +BA 041A +BB 041B +BC 041C +BD 041D +BE 041E +BF 041F +C0 0420 +C1 0421 +C2 0422 +C3 0423 +C4 0424 +C5 0425 +C6 0426 +C7 0427 +C8 0428 +C9 0429 +CA 042A +CB 042B +CC 042C +CD 042D +CE 042E +CF 042F +D0 0430 +D1 0431 +D2 0432 +D3 0433 +D4 0434 +D5 0435 +D6 0436 +D7 0437 +D8 0438 +D9 0439 +DA 043A +DB 043B +DC 043C +DD 043D +DE 043E +DF 043F +E0 0440 +E1 0441 +E2 0442 +E3 0443 +E4 0444 +E5 0445 +E6 0446 +E7 0447 +E8 0448 +E9 0449 +EA 044A +EB 044B +EC 044C +ED 044D +EE 044E +EF 044F +F0 2116 +F1 0451 +F2 0452 +F3 0453 +F4 0454 +F5 0455 +F6 0456 +F7 0457 +F8 0458 +F9 0459 +FA 045A +FB 045B +FC 045C +FD 00A7 +FE 045E +FF 045F diff --git a/data/iso-8859-6 b/data/iso-8859-6 new file mode 100644 index 0000000000..356fe72e3b --- /dev/null +++ b/data/iso-8859-6 @@ -0,0 +1,206 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-6 +# (Arabic) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff rtol single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0660 +31 0661 +32 0662 +33 0663 +34 0664 +35 0665 +36 0666 +37 0667 +38 0668 +39 0669 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A4 00A4 +AC 060C +AD 00AD +BB 061B +BF 061F +C1 0621 +C2 0622 +C3 0623 +C4 0624 +C5 0625 +C6 0626 +C7 0627 +C8 0628 +C9 0629 +CA 062A +CB 062B +CC 062C +CD 062D +CE 062E +CF 062F +D0 0630 +D1 0631 +D2 0632 +D3 0633 +D4 0634 +D5 0635 +D6 0636 +D7 0637 +D8 0638 +D9 0639 +DA 063A +E0 0640 +E1 0641 +E2 0642 +E3 0643 +E4 0644 +E5 0645 +E6 0646 +E7 0647 +E8 0648 +E9 0649 +EA 064A +EB 064B +EC 064C +ED 064D +EE 064E +EF 064F +F0 0650 +F1 0651 +F2 0652 diff --git a/data/iso-8859-7 b/data/iso-8859-7 new file mode 100644 index 0000000000..57647841cf --- /dev/null +++ b/data/iso-8859-7 @@ -0,0 +1,246 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-7 +# (Greek) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 9f ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic +a0 ff ltor single Symbol + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 02BD +A2 02BC +A3 00A3 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AB 00AB +AC 00AC +AD 00AD +AF 2015 +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 0384 +B5 0385 +B6 0386 +B7 00B7 +B8 0388 +B9 0389 +BA 038A +BB 00BB +BC 038C +BD 00BD +BE 038E +BF 038F +C0 0390 +C1 0391 +C2 0392 +C3 0393 +C4 0394 +C5 0395 +C6 0396 +C7 0397 +C8 0398 +C9 0399 +CA 039A +CB 039B +CC 039C +CD 039D +CE 039E +CF 039F +D0 03A0 +D1 03A1 +D3 03A3 +D4 03A4 +D5 03A5 +D6 03A6 +D7 03A7 +D8 03A8 +D9 03A9 +DA 03AA +DB 03AB +DC 03AC +DD 03AD +DE 03AE +DF 03AF +E0 03B0 +E1 03B1 +E2 03B2 +E3 03B3 +E4 03B4 +E5 03B5 +E6 03B6 +E7 03B7 +E8 03B8 +E9 03B9 +EA 03BA +EB 03BB +EC 03BC +ED 03BD +EE 03BE +EF 03BF +F0 03C0 +F1 03C1 +F2 03C2 +F3 03C3 +F4 03C4 +F5 03C5 +F6 03C6 +F7 03C7 +F8 03C8 +F9 03C9 +FA 03CA +FB 03CB +FC 03CC +FD 03CD +FE 03CE diff --git a/data/iso-8859-8 b/data/iso-8859-8 new file mode 100644 index 0000000000..a64c598f13 --- /dev/null +++ b/data/iso-8859-8 @@ -0,0 +1,214 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-8 +# (Hebrew) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 7f ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic +80 ff rtol single Courier-Hebrew + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A2 00A2 +A3 00A3 +A4 00A4 +A5 00A5 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AA 00D7 +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 203E +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00B8 +B9 00B9 +BA 00F7 +BB 00BB +BC 00BC +BD 00BD +BE 00BE +DF 2017 +E0 05D0 +E1 05D1 +E2 05D2 +E3 05D3 +E4 05D4 +E5 05D5 +E6 05D6 +E7 05D7 +E8 05D8 +E9 05D9 +EA 05DA +EB 05DB +EC 05DC +ED 05DD +EE 05DE +EF 05DF +F0 05E0 +F1 05E1 +F2 05E2 +F3 05E3 +F4 05E4 +F5 05E5 +F6 05E6 +F7 05E7 +F8 05E8 +F9 05E9 +FA 05EA diff --git a/data/iso-8859-9 b/data/iso-8859-9 new file mode 100644 index 0000000000..83a661edc2 --- /dev/null +++ b/data/iso-8859-9 @@ -0,0 +1,251 @@ +charset 8bit + +# +# This file defines the font and character mappings used for ISO-8859-9 +# (Latin5/Turkish) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 00A1 +A2 00A2 +A3 00A3 +A4 00A4 +A5 00A5 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AA 00AA +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00AF +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00B8 +B9 00B9 +BA 00BA +BB 00BB +BC 00BC +BD 00BD +BE 00BE +BF 00BF +C0 00C0 +C1 00C1 +C2 00C2 +C3 00C3 +C4 00C4 +C5 00C5 +C6 00C6 +C7 00C7 +C8 00C8 +C9 00C9 +CA 00CA +CB 00CB +CC 00CC +CD 00CD +CE 00CE +CF 00CF +D0 011E +D1 00D1 +D2 00D2 +D3 00D3 +D4 00D4 +D5 00D5 +D6 00D6 +D7 00D7 +D8 00D8 +D9 00D9 +DA 00DA +DB 00DB +DC 00DC +DD 0130 +DE 015E +DF 00DF +E0 00E0 +E1 00E1 +E2 00E2 +E3 00E3 +E4 00E4 +E5 00E5 +E6 00E6 +E7 00E7 +E8 00E8 +E9 00E9 +EA 00EA +EB 00EB +EC 00EC +ED 00ED +EE 00EE +EF 00EF +F0 011F +F1 00F1 +F2 00F2 +F3 00F3 +F4 00F4 +F5 00F5 +F6 00F6 +F7 00F7 +F8 00F8 +F9 00F9 +FA 00FA +FB 00FB +FC 00FC +FD 0131 +FE 015F +FF 00FF diff --git a/data/psglyphs b/data/psglyphs new file mode 100644 index 0000000000..c4a902c66c --- /dev/null +++ b/data/psglyphs @@ -0,0 +1,1051 @@ +0020 space +0021 exclam +0022 quotedbl +0023 numbersign +0024 dollar +0025 percent +0026 ampersand +0027 quotesingle +0028 parenleft +0029 parenright +002a asterisk +002b plus +002c comma +002d minus +002e period +002f slash +0030 zero +0031 one +0032 two +0033 three +0034 four +0035 five +0036 six +0037 seven +0038 eight +0039 nine +003a colon +003b semicolon +003c less +003d equal +003e greater +003f question +0040 at +0041 A +0042 B +0043 C +0044 D +0045 E +0046 F +0047 G +0048 H +0049 I +004a J +004b K +004c L +004d M +004e N +004f O +0050 P +0051 Q +0052 R +0053 S +0054 T +0055 U +0056 V +0057 W +0058 X +0059 Y +005a Z +005b bracketleft +005c backslash +005d bracketright +005e asciicircum +005f underscore +0060 grave +0061 a +0062 b +0063 c +0064 d +0065 e +0066 f +0067 g +0068 h +0069 i +006a j +006b k +006c l +006d m +006e n +006f o +0070 p +0071 q +0072 r +0073 s +0074 t +0075 u +0076 v +0077 w +0078 x +0079 y +007a z +007b braceleft +007c bar +007d braceright +007e asciitilde +00a0 space +00a1 exclamdown +00a2 cent +00a3 sterling +00a4 currency +00a5 yen +00a6 brokenbar +00a7 section +00a8 dieresis +00a9 copyright +00aa ordfeminine +00ab guillemotleft +00ac logicalnot +00ad hyphen +00ae registered +00af macron +00b0 degree +00b1 plusminus +00b2 twosuperior +00b3 threesuperior +00b4 acute +00b5 mu +00b6 paragraph +00b7 periodcentered +00b8 cedilla +00b9 onesuperior +00ba ordmasculine +00bb guillemotright +00bc onequarter +00bd onehalf +00be threequarters +00bf questiondown +00c0 Agrave +00c1 Aacute +00c2 Acircumflex +00c3 Atilde +00c4 Adieresis +00c5 Aring +00c6 AE +00c7 Ccedilla +00c8 Egrave +00c9 Eacute +00ca Ecircumflex +00cb Edieresis +00cc Igrave +00cd Iacute +00ce Icircumflex +00cf Idieresis +00d0 Eth +00d1 Ntilde +00d2 Ograve +00d3 Oacute +00d4 Ocircumflex +00d5 Otilde +00d6 Odieresis +00d7 multiply +00d8 Oslash +00d9 Ugrave +00da Uacute +00db Ucircumflex +00dc Udieresis +00dd Yacute +00de Thorn +00df germandbls +00e0 agrave +00e1 aacute +00e2 acircumflex +00e3 atilde +00e4 adieresis +00e5 aring +00e6 ae +00e7 ccedilla +00e8 egrave +00e9 eacute +00ea ecircumflex +00eb edieresis +00ec igrave +00ed iacute +00ee icircumflex +00ef idieresis +00f0 eth +00f1 ntilde +00f2 ograve +00f3 oacute +00f4 ocircumflex +00f5 otilde +00f6 odieresis +00f7 divide +00f8 oslash +00f9 ugrave +00fa uacute +00fb ucircumflex +00fc udieresis +00fd yacute +00fe thorn +00ff ydieresis +0100 Amacron +0101 amacron +0102 Abreve +0103 abreve +0104 Aogonek +0105 aogonek +0106 Cacute +0107 cacute +0108 Ccircumflex +0109 ccircumflex +010a Cdotaccent +010b cdotaccent +010c Ccaron +010d ccaron +010e Dcaron +010f dcaron +0110 Dcroat +0111 dcroat +0112 Emacron +0113 emacron +0114 Ebreve +0115 ebreve +0116 Edotaccent +0117 edotaccent +0118 Eogonek +0119 eogonek +011a Ecaron +011b ecaron +011c Gcircumflex +011d gcircumflex +011e Gbreve +011f gbreve +0120 Gdotaccent +0121 gdotaccent +0122 Gcommaaccent +0123 gcommaaccent +0124 Hcircumflex +0125 hcircumflex +0126 Hbar +0127 hbar +0128 Itilde +0129 itilde +012a Imacron +012b imacron +012c Ibreve +012d ibreve +012e Iogonek +012f iogonek +0130 Idotaccent +0131 dotlessi +0132 IJ +0133 ij +0134 Jcircumflex +0135 jcircumflex +0136 Kcommaaccent +0137 kcommaaccent +0138 kgreenlandic +0139 Lacute +013a lacute +013b Lcommaaccent +013c lcommaaccent +013d Lcaron +013e lcaron +013f Ldot +0140 ldot +0141 Lslash +0142 lslash +0143 Nacute +0144 nacute +0145 Ncommaaccent +0146 ncommaaccent +0147 Ncaron +0148 ncaron +0149 napostrophe +014a Eng +014b eng +014c Omacron +014d omacron +014e Obreve +014f obreve +0150 Ohungarumlaut +0151 ohungarumlaut +0152 OE +0153 oe +0154 Racute +0155 racute +0156 Rcommaaccent +0157 rcommaaccent +0158 Rcaron +0159 rcaron +015a Sacute +015b sacute +015c Scircumflex +015d scircumflex +015e Scedilla +015f scedilla +0160 Scaron +0161 scaron +0162 Tcommaaccent +0163 tcommaaccent +0164 Tcaron +0165 tcaron +0166 Tbar +0167 tbar +0168 Utilde +0169 utilde +016a Umacron +016b umacron +016c Ubreve +016d ubreve +016e Uring +016f uring +0170 Uhungarumlaut +0171 uhungarumlaut +0172 Uogonek +0173 uogonek +0174 Wcircumflex +0175 wcircumflex +0176 Ycircumflex +0177 ycircumflex +0178 Ydieresis +0179 Zacute +017a zacute +017b Zdotaccent +017c zdotaccent +017d Zcaron +017e zcaron +017f longs +0192 florin +01a0 Ohorn +01a1 ohorn +01af Uhorn +01b0 uhorn +01e6 Gcaron +01e7 gcaron +01fa Aringacute +01fb aringacute +01fc AEacute +01fd aeacute +01fe Oslashacute +01ff oslashacute +0218 Scommaaccent +0219 scommaaccent +021a Tcommaaccent +021b tcommaaccent +02bc afii57929 +02bd afii64937 +02c6 circumflex +02c7 caron +02c9 macron +02d8 breve +02d9 dotaccent +02da ring +02db ogonek +02dc tilde +02dd hungarumlaut +0300 gravecomb +0301 acutecomb +0303 tildecomb +0309 hookabovecomb +0323 dotbelowcomb +0384 tonos +0385 dieresistonos +0386 Alphatonos +0387 anoteleia +0388 Epsilontonos +0389 Etatonos +038a Iotatonos +038c Omicrontonos +038e Upsilontonos +038f Omegatonos +0390 iotadieresistonos +0391 Alpha +0392 Beta +0393 Gamma +0394 Delta +0395 Epsilon +0396 Zeta +0397 Eta +0398 Theta +0399 Iota +039a Kappa +039b Lambda +039c Mu +039d Nu +039e Xi +039f Omicron +03a0 Pi +03a1 Rho +03a3 Sigma +03a4 Tau +03a5 Upsilon +03a6 Phi +03a7 Chi +03a8 Psi +03a9 Omega +03aa Iotadieresis +03ab Upsilondieresis +03ac alphatonos +03ad epsilontonos +03ae etatonos +03af iotatonos +03b0 upsilondieresistonos +03b1 alpha +03b2 beta +03b3 gamma +03b4 delta +03b5 epsilon +03b6 zeta +03b7 eta +03b8 theta +03b9 iota +03ba kappa +03bb lambda +03bc mu +03bd nu +03be xi +03bf omicron +03c0 pi +03c1 rho +03c2 sigma1 +03c3 sigma +03c4 tau +03c5 upsilon +03c6 phi +03c7 chi +03c8 psi +03c9 omega +03ca iotadieresis +03cb upsilondieresis +03cc omicrontonos +03cd upsilontonos +03ce omegatonos +03d1 theta1 +03d2 Upsilon1 +03d5 phi1 +03d6 omega1 +0401 afii10023 +0402 afii10051 +0403 afii10052 +0404 afii10053 +0405 afii10054 +0406 afii10055 +0407 afii10056 +0408 afii10057 +0409 afii10058 +040a afii10059 +040b afii10060 +040c afii10061 +040e afii10062 +040f afii10145 +0410 afii10017 +0411 afii10018 +0412 afii10019 +0413 afii10020 +0414 afii10021 +0415 afii10022 +0416 afii10024 +0417 afii10025 +0418 afii10026 +0419 afii10027 +041a afii10028 +041b afii10029 +041c afii10030 +041d afii10031 +041e afii10032 +041f afii10033 +0420 afii10034 +0421 afii10035 +0422 afii10036 +0423 afii10037 +0424 afii10038 +0425 afii10039 +0426 afii10040 +0427 afii10041 +0428 afii10042 +0429 afii10043 +042a afii10044 +042b afii10045 +042c afii10046 +042d afii10047 +042e afii10048 +042f afii10049 +0430 afii10065 +0431 afii10066 +0432 afii10067 +0433 afii10068 +0434 afii10069 +0435 afii10070 +0436 afii10072 +0437 afii10073 +0438 afii10074 +0439 afii10075 +043a afii10076 +043b afii10077 +043c afii10078 +043d afii10079 +043e afii10080 +043f afii10081 +0440 afii10082 +0441 afii10083 +0442 afii10084 +0443 afii10085 +0444 afii10086 +0445 afii10087 +0446 afii10088 +0447 afii10089 +0448 afii10090 +0449 afii10091 +044a afii10092 +044b afii10093 +044c afii10094 +044d afii10095 +044e afii10096 +044f afii10097 +0451 afii10071 +0452 afii10099 +0453 afii10100 +0454 afii10101 +0455 afii10102 +0456 afii10103 +0457 afii10104 +0458 afii10105 +0459 afii10106 +045a afii10107 +045b afii10108 +045c afii10109 +045e afii10110 +045f afii10193 +0462 afii10146 +0463 afii10194 +0472 afii10147 +0473 afii10195 +0474 afii10148 +0475 afii10196 +0490 afii10050 +0491 afii10098 +04d9 afii10846 +05b0 afii57799 +05b1 afii57801 +05b2 afii57800 +05b3 afii57802 +05b4 afii57793 +05b5 afii57794 +05b6 afii57795 +05b7 afii57798 +05b8 afii57797 +05b9 afii57806 +05bb afii57796 +05bc afii57807 +05bd afii57839 +05be afii57645 +05bf afii57841 +05c0 afii57842 +05c1 afii57804 +05c2 afii57803 +05c3 afii57658 +05d0 afii57664 +05d1 afii57665 +05d2 afii57666 +05d3 afii57667 +05d4 afii57668 +05d5 afii57669 +05d6 afii57670 +05d7 afii57671 +05d8 afii57672 +05d9 afii57673 +05da afii57674 +05db afii57675 +05dc afii57676 +05dd afii57677 +05de afii57678 +05df afii57679 +05e0 afii57680 +05e1 afii57681 +05e2 afii57682 +05e3 afii57683 +05e4 afii57684 +05e5 afii57685 +05e6 afii57686 +05e7 afii57687 +05e8 afii57688 +05e9 afii57689 +05ea afii57690 +05f0 afii57716 +05f1 afii57717 +05f2 afii57718 +060c afii57388 +061b afii57403 +061f afii57407 +0621 afii57409 +0622 afii57410 +0623 afii57411 +0624 afii57412 +0625 afii57413 +0626 afii57414 +0627 afii57415 +0628 afii57416 +0629 afii57417 +062a afii57418 +062b afii57419 +062c afii57420 +062d afii57421 +062e afii57422 +062f afii57423 +0630 afii57424 +0631 afii57425 +0632 afii57426 +0633 afii57427 +0634 afii57428 +0635 afii57429 +0636 afii57430 +0637 afii57431 +0638 afii57432 +0639 afii57433 +063a afii57434 +0640 afii57440 +0641 afii57441 +0642 afii57442 +0643 afii57443 +0644 afii57444 +0645 afii57445 +0646 afii57446 +0647 afii57470 +0648 afii57448 +0649 afii57449 +064a afii57450 +064b afii57451 +064c afii57452 +064d afii57453 +064e afii57454 +064f afii57455 +0650 afii57456 +0651 afii57457 +0652 afii57458 +0660 afii57392 +0661 afii57393 +0662 afii57394 +0663 afii57395 +0664 afii57396 +0665 afii57397 +0666 afii57398 +0667 afii57399 +0668 afii57400 +0669 afii57401 +066a afii57381 +066d afii63167 +0679 afii57511 +067e afii57506 +0686 afii57507 +0688 afii57512 +0691 afii57513 +0698 afii57508 +06a4 afii57505 +06af afii57509 +06ba afii57514 +06d2 afii57519 +06d5 afii57534 +1e80 Wgrave +1e81 wgrave +1e82 Wacute +1e83 wacute +1e84 Wdieresis +1e85 wdieresis +1ef2 Ygrave +1ef3 ygrave +200c afii61664 +200d afii301 +200e afii299 +200f afii300 +2012 figuredash +2013 endash +2014 emdash +2015 afii00208 +2017 underscoredbl +2018 quoteleft +2019 quoteright +201a quotesinglbase +201b quotereversed +201c quotedblleft +201d quotedblright +201e quotedblbase +2020 dagger +2021 daggerdbl +2022 bullet +2024 onedotenleader +2025 twodotenleader +2026 ellipsis +202c afii61573 +202d afii61574 +202e afii61575 +2030 perthousand +2032 minute +2033 second +2039 guilsinglleft +203a guilsinglright +203c exclamdbl +2044 fraction +2070 zerosuperior +2074 foursuperior +2075 fivesuperior +2076 sixsuperior +2077 sevensuperior +2078 eightsuperior +2079 ninesuperior +207d parenleftsuperior +207e parenrightsuperior +207f nsuperior +2080 zeroinferior +2081 oneinferior +2082 twoinferior +2083 threeinferior +2084 fourinferior +2085 fiveinferior +2086 sixinferior +2087 seveninferior +2088 eightinferior +2089 nineinferior +208d parenleftinferior +208e parenrightinferior +20a1 colonmonetary +20a3 franc +20a4 lira +20a7 peseta +20aa afii57636 +20ab dong +20ac Euro +2105 afii61248 +2111 Ifraktur +2113 afii61289 +2116 afii61352 +2118 weierstrass +211c Rfraktur +211e prescription +2122 trademark +2126 Omega +212e estimated +2135 aleph +2153 onethird +2154 twothirds +215b oneeighth +215c threeeighths +215d fiveeighths +215e seveneighths +2190 arrowleft +2191 arrowup +2192 arrowright +2193 arrowdown +2194 arrowboth +2195 arrowupdn +21a8 arrowupdnbse +21b5 carriagereturn +21d0 arrowdblleft +21d1 arrowdblup +21d2 arrowdblright +21d3 arrowdbldown +21d4 arrowdblboth +2200 universal +2202 partialdiff +2203 existential +2205 emptyset +2206 Delta +2207 gradient +2208 element +2209 notelement +220b suchthat +220f product +2211 summation +2212 minus +2215 fraction +2217 asteriskmath +2219 periodcentered +221a radical +221d proportional +221e infinity +221f orthogonal +2220 angle +2227 logicaland +2228 logicalor +2229 intersection +222a union +222b integral +2234 therefore +223c similar +2245 congruent +2248 approxequal +2260 notequal +2261 equivalence +2264 lessequal +2265 greaterequal +2282 propersubset +2283 propersuperset +2284 notsubset +2286 reflexsubset +2287 reflexsuperset +2295 circleplus +2297 circlemultiply +22a5 perpendicular +22c5 dotmath +2302 house +2310 revlogicalnot +2320 integraltp +2321 integralbt +2329 angleleft +232a angleright +2500 SF100000 +2502 SF110000 +250c SF010000 +2510 SF030000 +2514 SF020000 +2518 SF040000 +251c SF080000 +2524 SF090000 +252c SF060000 +2534 SF070000 +253c SF050000 +2550 SF430000 +2551 SF240000 +2552 SF510000 +2553 SF520000 +2554 SF390000 +2555 SF220000 +2556 SF210000 +2557 SF250000 +2558 SF500000 +2559 SF490000 +255a SF380000 +255b SF280000 +255c SF270000 +255d SF260000 +255e SF360000 +255f SF370000 +2560 SF420000 +2561 SF190000 +2562 SF200000 +2563 SF230000 +2564 SF470000 +2565 SF480000 +2566 SF410000 +2567 SF450000 +2568 SF460000 +2569 SF400000 +256a SF540000 +256b SF530000 +256c SF440000 +2580 upblock +2584 dnblock +2588 block +258c lfblock +2590 rtblock +2591 ltshade +2592 shade +2593 dkshade +25a0 filledbox +25a1 H22073 +25aa H18543 +25ab H18551 +25ac filledrect +25b2 triagup +25ba triagrt +25bc triagdn +25c4 triaglf +25ca lozenge +25cb circle +25cf H18533 +25d8 invbullet +25d9 invcircle +25e6 openbullet +263a smileface +263b invsmileface +263c sun +2640 female +2642 male +2660 spade +2663 club +2665 heart +2666 diamond +266a musicalnote +266b musicalnotedbl +f6be dotlessj +f6bf LL +f6c0 ll +f6c1 Scedilla +f6c2 scedilla +f6c3 commaaccent +f6c4 afii10063 +f6c5 afii10064 +f6c6 afii10192 +f6c7 afii10831 +f6c8 afii10832 +f6c9 Acute +f6ca Caron +f6cb Dieresis +f6cc DieresisAcute +f6cd DieresisGrave +f6ce Grave +f6cf Hungarumlaut +f6d0 Macron +f6d1 cyrBreve +f6d2 cyrFlex +f6d3 dblGrave +f6d4 cyrbreve +f6d5 cyrflex +f6d6 dblgrave +f6d7 dieresisacute +f6d8 dieresisgrave +f6d9 copyrightserif +f6da registerserif +f6db trademarkserif +f6dc onefitted +f6dd rupiah +f6de threequartersemdash +f6df centinferior +f6e0 centsuperior +f6e1 commainferior +f6e2 commasuperior +f6e3 dollarinferior +f6e4 dollarsuperior +f6e5 hypheninferior +f6e6 hyphensuperior +f6e7 periodinferior +f6e8 periodsuperior +f6e9 asuperior +f6ea bsuperior +f6eb dsuperior +f6ec esuperior +f6ed isuperior +f6ee lsuperior +f6ef msuperior +f6f0 osuperior +f6f1 rsuperior +f6f2 ssuperior +f6f3 tsuperior +f6f4 Brevesmall +f6f5 Caronsmall +f6f6 Circumflexsmall +f6f7 Dotaccentsmall +f6f8 Hungarumlautsmall +f6f9 Lslashsmall +f6fa OEsmall +f6fb Ogoneksmall +f6fc Ringsmall +f6fd Scaronsmall +f6fe Tildesmall +f6ff Zcaronsmall +f721 exclamsmall +f724 dollaroldstyle +f726 ampersandsmall +f730 zerooldstyle +f731 oneoldstyle +f732 twooldstyle +f733 threeoldstyle +f734 fouroldstyle +f735 fiveoldstyle +f736 sixoldstyle +f737 sevenoldstyle +f738 eightoldstyle +f739 nineoldstyle +f73f questionsmall +f760 Gravesmall +f761 Asmall +f762 Bsmall +f763 Csmall +f764 Dsmall +f765 Esmall +f766 Fsmall +f767 Gsmall +f768 Hsmall +f769 Ismall +f76a Jsmall +f76b Ksmall +f76c Lsmall +f76d Msmall +f76e Nsmall +f76f Osmall +f770 Psmall +f771 Qsmall +f772 Rsmall +f773 Ssmall +f774 Tsmall +f775 Usmall +f776 Vsmall +f777 Wsmall +f778 Xsmall +f779 Ysmall +f77a Zsmall +f7a1 exclamdownsmall +f7a2 centoldstyle +f7a8 Dieresissmall +f7af Macronsmall +f7b4 Acutesmall +f7b8 Cedillasmall +f7bf questiondownsmall +f7e0 Agravesmall +f7e1 Aacutesmall +f7e2 Acircumflexsmall +f7e3 Atildesmall +f7e4 Adieresissmall +f7e5 Aringsmall +f7e6 AEsmall +f7e7 Ccedillasmall +f7e8 Egravesmall +f7e9 Eacutesmall +f7ea Ecircumflexsmall +f7eb Edieresissmall +f7ec Igravesmall +f7ed Iacutesmall +f7ee Icircumflexsmall +f7ef Idieresissmall +f7f0 Ethsmall +f7f1 Ntildesmall +f7f2 Ogravesmall +f7f3 Oacutesmall +f7f4 Ocircumflexsmall +f7f5 Otildesmall +f7f6 Odieresissmall +f7f8 Oslashsmall +f7f9 Ugravesmall +f7fa Uacutesmall +f7fb Ucircumflexsmall +f7fc Udieresissmall +f7fd Yacutesmall +f7fe Thornsmall +f7ff Ydieresissmall +f8e5 radicalex +f8e6 arrowvertex +f8e7 arrowhorizex +f8e8 registersans +f8e9 copyrightsans +f8ea trademarksans +f8eb parenlefttp +f8ec parenleftex +f8ed parenleftbt +f8ee bracketlefttp +f8ef bracketleftex +f8f0 bracketleftbt +f8f1 bracelefttp +f8f2 braceleftmid +f8f3 braceleftbt +f8f4 braceex +f8f5 integralex +f8f6 parenrighttp +f8f7 parenrightex +f8f8 parenrightbt +f8f9 bracketrighttp +f8fa bracketrightex +f8fb bracketrightbt +f8fc bracerighttp +f8fd bracerightmid +f8fe bracerightbt +fb00 ff +fb01 fi +fb02 fl +fb03 ffi +fb04 ffl +fb1f afii57705 +fb2a afii57694 +fb2b afii57695 +fb35 afii57723 +fb4b afii57700 diff --git a/data/secret b/data/secret new file mode 100644 index 0000000000..b0259e0f3e --- /dev/null +++ b/data/secret @@ -0,0 +1,259 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 +%%Pages: 1 +%%LanguageLevel: 1 +%%DocumentData: Clean7Bit +%%DocumentSuppliedResources: procset bannerprint/1.0 +%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman +%%Creator: Michael Sweet, Easy Software Products +%%CreationDate: May 10, 2000 +%%Title: Test Page +%%EndComments +%%BeginProlog +%%BeginResource procset bannerprint 1.1 0 +% +% PostScript banner page for the Common UNIX Printing System ("CUPS"). +% +% Copyright 1993-2000 Easy Software Products +% +% These coded instructions, statements, and computer programs contain +% unpublished proprietary information of Easy Software Products, and +% are protected by Federal copyright law. They may not be disclosed +% to third parties or copied or duplicated in any form, in whole or +% in part, without the prior written consent of Easy Software Products. +% +/CENTER \{ % Draw centered text + % (name) CENTER - + dup stringwidth pop % Get the width of the string + 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance + show % Show the string +} bind def +/RIGHT \{ % Draw right-justified text + % (name) RIGHT - + dup stringwidth pop % Get the width of the string + neg 0 rmoveto % Shift left the entire distance + show % Show the string +} bind def +/NUMBER \{ % Draw a number + % power n NUMBER - + 1 index 1 eq \{ % power == 1? + round cvi exch pop % Convert "n" to integer + } \{ + 1 index mul round exch div % Truncate extra decimal places + } ifelse + 100 string cvs show % Convert to a string and show it... +} bind def +/CUPSLOGO \{ % Draw the CUPS logo + % height CUPSLOGO + % Start with a big C... + /Helvetica findfont 1 index scalefont setfont + 0 setgray + 0 0 moveto + (C) show + + % Then "UNIX Printing System" much smaller... + /Helvetica-Bold findfont 1 index 9 div scalefont setfont + 0.25 mul + dup dup 2.0 mul moveto + (UNIX) show + dup dup 1.6 mul moveto + (Printing) show + dup 1.2 mul moveto + (System) show +} bind def +/ESPLOGO \{ % Draw the ESP logo + % height ESPLOGO + % Compute the size of the logo... + 0 0 + 2 index 1.5 mul 3 index + + % Do the "metallic" fill from 10% black to 40% black... + 1 -0.001 0 \{ + dup % loopval + -0.15 mul % loopval * -0.15 + 0.9 add % 0.9 - loopval * 0.15 + setgray % set gray shade + + 0 % x + 1 index neg % loopval + 1 add % 1 - loopval + 3 index % height + mul % height * (1 - loopval) + moveto % starting point + + dup % loopval + 3 index % width + mul % loopval * width + 2 index % height + lineto % Next point + + 0 % x + 2 index % height + lineto % Next point + + closepath + fill + + dup % loopval + 0.15 mul % loopval * 0.15 + 0.6 add % 0.6 + loopval * 0.15 + setgray + + dup % loopval + neg 1 add % 1 - loopval + 3 index % width + mul % (1 - loopval) * width + 0 % y + moveto % Starting point + + 2 index % width + exch % loopval + 2 index % height + mul % loopval * height + lineto % Next point + + 1 index % width + 0 % y + lineto % Next point + + closepath + fill + } for + + 0 setgray rectstroke + + /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont + dup 40 div + + dup 4 mul 1 index 25 mul moveto (E) show + dup 10 mul 1 index 15 mul moveto (S) show + dup 16 mul 1 index 5 mul moveto (P) show + + /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont + dup 14 mul 1 index 29 mul moveto (asy) show + dup 20 mul 1 index 19 mul moveto (oftware) show + dup 26 mul 1 index 9 mul moveto (roducts) show + + pop +} bind def +%%EndResource +%%EndProlog +%%Page: 1 1 +gsave + + % Determine the imageable area and device resolution... + initclip newpath clippath pathbbox % Get bounding rectangle + 72 div /pageTop exch def % Get top margin in inches + 72 div /pageRight exch def % Get right margin in inches + 72 div /pageBottom exch def % Get bottom margin in inches + 72 div /pageLeft exch def % Get left margin in inches + + /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft + /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom + + newpath % Clear bounding path + + % Create fonts... + /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold + pageWidth 4 mul scalefont def % size = pageWidth * 4 (nominally 34) + + /mediumFont /Helvetica findfont % mediumFont = Helvetica + pageWidth 2 mul scalefont def % size = pageWidth * 2 (nominally 17) + + % Offset page to account for lower-left margin... + pageLeft 72 mul + pageBottom 72 mul + translate + + % Draw the label at the top and bottom... + 0 setgray % Color + + pageWidth 36 mul % Center of page + pageHeight 72 mul % Top of page + pageWidth -9 mul add % - 1 line + moveto % Position text + bigFont setfont % Font + (Secret) CENTER % Show text centered + + pageWidth 36 mul % Center of page + pageWidth 8 mul % Bottom of page + moveto % Position text + bigFont setfont % Font + (Secret) CENTER % Show text centered + + % Job information box... + pageWidth 18 mul 9 add % x = pageWidth * 1/4 * 72 + 9 + pageHeight 27 mul 9 sub % y = pageHeight * 3/8 * 72 - 9 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + 0.5 setgray rectfill % Draw a shadow + + pageWidth 18 mul % x = pageWidth * 1/4 * 72 + pageHeight 27 mul % y = pageHeight * 3/8 * 72 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + + 4 copy 1 setgray rectfill % Clear the box to white + 0 setgray rectstroke % Draw a black box around it... + + % Job information text... + mediumFont setfont % Medium sized font + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 4 mul add % y += 2 lines + 2 copy % Copy X & Y + moveto + (Job ID: ) RIGHT + moveto + ({printer-name}-{job-id}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 1 mul add % y += 1 line + 2 copy % Copy X & Y + moveto + (Title: ) RIGHT + moveto + ({job-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -2 mul add % y -= 1 line + 2 copy % Copy X & Y + moveto + (Requesting User: ) RIGHT + moveto + ({job-originating-user-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -5 mul add % y -= 2 lines + 2 copy % Copy X & Y + moveto + (Billing Info: ) RIGHT + moveto + ({job-billing}) show + + % Then the CUPS logo.... + gsave + pageWidth 4 mul + pageWidth 6 mul + translate + pageWidth 9 mul CUPSLOGO + grestore + + % And the ESP logo.... + gsave + pageWidth 59 mul + pageWidth 6 mul + translate + pageWidth 6 mul ESPLOGO + grestore +% Show the page... +grestore +showpage +% +% End of "$Id: secret 1075 2000-05-11 20:02:21Z mike $". +% +%%EOF diff --git a/data/standard b/data/standard new file mode 100644 index 0000000000..c80ede373d --- /dev/null +++ b/data/standard @@ -0,0 +1,259 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 +%%Pages: 1 +%%LanguageLevel: 1 +%%DocumentData: Clean7Bit +%%DocumentSuppliedResources: procset bannerprint/1.0 +%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman +%%Creator: Michael Sweet, Easy Software Products +%%CreationDate: May 10, 2000 +%%Title: Test Page +%%EndComments +%%BeginProlog +%%BeginResource procset bannerprint 1.1 0 +% +% PostScript banner page for the Common UNIX Printing System ("CUPS"). +% +% Copyright 1993-2000 Easy Software Products +% +% These coded instructions, statements, and computer programs contain +% unpublished proprietary information of Easy Software Products, and +% are protected by Federal copyright law. They may not be disclosed +% to third parties or copied or duplicated in any form, in whole or +% in part, without the prior written consent of Easy Software Products. +% +/CENTER \{ % Draw centered text + % (name) CENTER - + dup stringwidth pop % Get the width of the string + 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance + show % Show the string +} bind def +/RIGHT \{ % Draw right-justified text + % (name) RIGHT - + dup stringwidth pop % Get the width of the string + neg 0 rmoveto % Shift left the entire distance + show % Show the string +} bind def +/NUMBER \{ % Draw a number + % power n NUMBER - + 1 index 1 eq \{ % power == 1? + round cvi exch pop % Convert "n" to integer + } \{ + 1 index mul round exch div % Truncate extra decimal places + } ifelse + 100 string cvs show % Convert to a string and show it... +} bind def +/CUPSLOGO \{ % Draw the CUPS logo + % height CUPSLOGO + % Start with a big C... + /Helvetica findfont 1 index scalefont setfont + 0 setgray + 0 0 moveto + (C) show + + % Then "UNIX Printing System" much smaller... + /Helvetica-Bold findfont 1 index 9 div scalefont setfont + 0.25 mul + dup dup 2.0 mul moveto + (UNIX) show + dup dup 1.6 mul moveto + (Printing) show + dup 1.2 mul moveto + (System) show +} bind def +/ESPLOGO \{ % Draw the ESP logo + % height ESPLOGO + % Compute the size of the logo... + 0 0 + 2 index 1.5 mul 3 index + + % Do the "metallic" fill from 10% black to 40% black... + 1 -0.001 0 \{ + dup % loopval + -0.15 mul % loopval * -0.15 + 0.9 add % 0.9 - loopval * 0.15 + setgray % set gray shade + + 0 % x + 1 index neg % loopval + 1 add % 1 - loopval + 3 index % height + mul % height * (1 - loopval) + moveto % starting point + + dup % loopval + 3 index % width + mul % loopval * width + 2 index % height + lineto % Next point + + 0 % x + 2 index % height + lineto % Next point + + closepath + fill + + dup % loopval + 0.15 mul % loopval * 0.15 + 0.6 add % 0.6 + loopval * 0.15 + setgray + + dup % loopval + neg 1 add % 1 - loopval + 3 index % width + mul % (1 - loopval) * width + 0 % y + moveto % Starting point + + 2 index % width + exch % loopval + 2 index % height + mul % loopval * height + lineto % Next point + + 1 index % width + 0 % y + lineto % Next point + + closepath + fill + } for + + 0 setgray rectstroke + + /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont + dup 40 div + + dup 4 mul 1 index 25 mul moveto (E) show + dup 10 mul 1 index 15 mul moveto (S) show + dup 16 mul 1 index 5 mul moveto (P) show + + /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont + dup 14 mul 1 index 29 mul moveto (asy) show + dup 20 mul 1 index 19 mul moveto (oftware) show + dup 26 mul 1 index 9 mul moveto (roducts) show + + pop +} bind def +%%EndResource +%%EndProlog +%%Page: 1 1 +gsave + + % Determine the imageable area and device resolution... + initclip newpath clippath pathbbox % Get bounding rectangle + 72 div /pageTop exch def % Get top margin in inches + 72 div /pageRight exch def % Get right margin in inches + 72 div /pageBottom exch def % Get bottom margin in inches + 72 div /pageLeft exch def % Get left margin in inches + + /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft + /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom + + newpath % Clear bounding path + + % Create fonts... + /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold + pageWidth 4 mul scalefont def % size = pageWidth * 4 (nominally 34) + + /mediumFont /Helvetica findfont % mediumFont = Helvetica + pageWidth 2 mul scalefont def % size = pageWidth * 2 (nominally 17) + + % Offset page to account for lower-left margin... + pageLeft 72 mul + pageBottom 72 mul + translate + + % Draw the label at the top and bottom... + 0 setgray % Color + + pageWidth 36 mul % Center of page + pageHeight 72 mul % Top of page + pageWidth -9 mul add % - 1 line + moveto % Position text + bigFont setfont % Font + (Banner) CENTER % Show text centered + + pageWidth 36 mul % Center of page + pageWidth 8 mul % Bottom of page + moveto % Position text + bigFont setfont % Font + (Banner) CENTER % Show text centered + + % Job information box... + pageWidth 18 mul 9 add % x = pageWidth * 1/4 * 72 + 9 + pageHeight 27 mul 9 sub % y = pageHeight * 3/8 * 72 - 9 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + 0.5 setgray rectfill % Draw a shadow + + pageWidth 18 mul % x = pageWidth * 1/4 * 72 + pageHeight 27 mul % y = pageHeight * 3/8 * 72 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + + 4 copy 1 setgray rectfill % Clear the box to white + 0 setgray rectstroke % Draw a black box around it... + + % Job information text... + mediumFont setfont % Medium sized font + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 4 mul add % y += 2 lines + 2 copy % Copy X & Y + moveto + (Job ID: ) RIGHT + moveto + ({printer-name}-{job-id}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 1 mul add % y += 1 line + 2 copy % Copy X & Y + moveto + (Title: ) RIGHT + moveto + ({job-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -2 mul add % y -= 1 line + 2 copy % Copy X & Y + moveto + (Requesting User: ) RIGHT + moveto + ({job-originating-user-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -5 mul add % y -= 2 lines + 2 copy % Copy X & Y + moveto + (Billing Info: ) RIGHT + moveto + ({job-billing}) show + + % Then the CUPS logo.... + gsave + pageWidth 4 mul + pageWidth 6 mul + translate + pageWidth 9 mul CUPSLOGO + grestore + + % And the ESP logo.... + gsave + pageWidth 59 mul + pageWidth 6 mul + translate + pageWidth 6 mul ESPLOGO + grestore +% Show the page... +grestore +showpage +% +% End of "$Id: standard 1075 2000-05-11 20:02:21Z mike $". +% +%%EOF diff --git a/data/testprint.ps b/data/testprint.ps new file mode 100644 index 0000000000..9ebcff3b6f --- /dev/null +++ b/data/testprint.ps @@ -0,0 +1,505 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 +%%Pages: 1 +%%LanguageLevel: 1 +%%DocumentData: Clean7Bit +%%DocumentSuppliedResources: procset testprint/1.0 +%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman +%%Creator: Michael Sweet, Easy Software Products +%%CreationDate: May 11, 1999 +%%Title: Test Page +%%EndComments +%%BeginProlog +%%BeginResource procset testprint 1.1 0 +% +% PostScript test page for the Common UNIX Printing System ("CUPS"). +% +% Copyright 1993-2000 Easy Software Products +% +% These coded instructions, statements, and computer programs contain +% unpublished proprietary information of Easy Software Products, and +% are protected by Federal copyright law. They may not be disclosed +% to third parties or copied or duplicated in any form, in whole or +% in part, without the prior written consent of Easy Software Products. +% +/OCTANT { % Draw a color wheel OCTANT... + % (name) radius r g b OCTANT - + % Loop through 100 shades... + 0 0.010101 0.98 { + % Set the color... + 3 index 1 eq % R == 1? + 3 index 1 eq % G == 1? + 3 index 1 eq % B == 1? + and and { + 0 index 4 index mul % R * val + 1 index 4 index mul % G * val + 2 index 4 index mul % B * val + } { + 0 index 4 index mul % R * val + 1 index neg 1 add add % + (1 - val) + 1 index 4 index mul % G * val + 2 index neg 1 add add % + (1 - val) + 2 index 4 index mul % B * val + 3 index neg 1 add add % + (1 - val) + } ifelse + setrgbcolor + + % Draw a polygon... + dup 5 index mul dup 0 % x1, y1 + moveto + 0.707106781 mul dup lineto % x2, y2 + + 0.010101 add 4 index mul dup % x3 + 0.707106781 mul dup lineto % x3, y3 + 0 lineto % x4, y4 + closepath + fill + } for + + % Draw a line around the polygons... + pop pop pop dup + 0 setgray + 0 0 moveto + dup 0 lineto + 0.707106781 mul dup lineto + closepath + stroke + + % Draw the label... + 0 exch dup -9 div exch % text offset = 0, -radius/9 + dup 0.923879532 mul % x = radius * cos(22.5) + exch 0.382683432 mul % y = radius * cos(22.5) + moveto % position label + gsave + 22.5 rotate % rotate label + rmoveto % offset label + show % show label + grestore +} bind def +/CENTER { % Draw centered text + % (name) CENTER - + dup stringwidth pop % Get the width of the string + 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance + show % Show the string +} bind def +/RIGHT { % Draw right-justified text + % (name) RIGHT - + dup stringwidth pop % Get the width of the string + neg 0 rmoveto % Shift left the entire distance + show % Show the string +} bind def +/NUMBER { % Draw a number + % power n NUMBER - + 1 index 1 eq { % power == 1? + round cvi exch pop % Convert "n" to integer + } { + 1 index mul round exch div % Truncate extra decimal places + } ifelse + 100 string cvs show % Convert to a string and show it... +} bind def +/CUPSLOGO { % Draw the CUPS logo + % height CUPSLOGO + % Start with a big C... + /Helvetica findfont 1 index scalefont setfont + 0 setgray + 0 0 moveto + (C) show + + % Then "UNIX Printing System" much smaller... + /Helvetica-Bold findfont 1 index 9 div scalefont setfont + 0.25 mul + dup dup 2.0 mul moveto + (UNIX) show + dup dup 1.6 mul moveto + (Printing) show + dup 1.2 mul moveto + (System) show +} bind def +/ESPLOGO { % Draw the ESP logo + % height ESPLOGO + % Compute the size of the logo... + 0 0 + 2 index 1.5 mul 3 index + + % Do the "metallic" fill from 10% black to 40% black... + 1 -0.001 0 { + dup % loopval + -0.15 mul % loopval * -0.15 + 0.9 add % 0.9 - loopval * 0.15 + setgray % set gray shade + + 0 % x + 1 index neg % loopval + 1 add % 1 - loopval + 3 index % height + mul % height * (1 - loopval) + moveto % starting point + + dup % loopval + 3 index % width + mul % loopval * width + 2 index % height + lineto % Next point + + 0 % x + 2 index % height + lineto % Next point + + closepath + fill + + dup % loopval + 0.15 mul % loopval * 0.15 + 0.6 add % 0.6 + loopval * 0.15 + setgray + + dup % loopval + neg 1 add % 1 - loopval + 3 index % width + mul % (1 - loopval) * width + 0 % y + moveto % Starting point + + 2 index % width + exch % loopval + 2 index % height + mul % loopval * height + lineto % Next point + + 1 index % width + 0 % y + lineto % Next point + + closepath + fill + } for + + 0 setgray rectstroke + + /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont + dup 40 div + + dup 4 mul 1 index 25 mul moveto (E) show + dup 10 mul 1 index 15 mul moveto (S) show + dup 16 mul 1 index 5 mul moveto (P) show + + /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont + dup 14 mul 1 index 29 mul moveto (asy) show + dup 20 mul 1 index 19 mul moveto (oftware) show + dup 26 mul 1 index 9 mul moveto (roducts) show + + pop +} bind def +%%EndResource +%%EndProlog +%%Page: 1 1 +gsave + + % Determine the imageable area and device resolution... + initclip newpath clippath pathbbox % Get bounding rectangle + 72 div /pageTop exch def % Get top margin in inches + 72 div /pageRight exch def % Get right margin in inches + 72 div /pageBottom exch def % Get bottom margin in inches + 72 div /pageLeft exch def % Get left margin in inches + + 4 setlinewidth % Draw wide lines + 0 setgray closepath stroke % Draw a clipping rectangle + 1 setlinewidth % Draw normal lines + + /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft + /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom + + 72 72 dtransform % Get device resolution per inch + /yResolution exch abs def % yResolution = abs(yres) + /xResolution exch abs def % xResolution = abs(xres) + + % Create fonts... + /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold + pageWidth 4 mul scalefont def % size = pageWidth * 4 (nominally 34) + + /mediumFont /Helvetica findfont % mediumFont = Helvetica + pageWidth 2 mul scalefont def % size = pageWidth * 2 (nominally 17) + + /smallFont /Times-Roman findfont % smallFont = Times-Roman + pageWidth 1.5 mul scalefont def % size = pageWidth * 1.5 (nominally 13) + + % Offset page to account for lower-left margin... + pageLeft 72 mul + pageBottom 72 mul + translate + + % Draw the color wheel... + mediumFont setfont % Font + 0 setgray % Color + + gsave + % Position the wheel on the left side... + pageWidth 18 mul % x = pageWidth * 1/4 * 72 + pageHeight 54 mul % y = pageHeight * 3/4 * 72 + translate + + % Size the wheel... + pageWidth 9 mul % radius = pageWidth * 1/8 * 72 + + % Draw the colors... + dup (C) exch 0 1 1 OCTANT 45 rotate + dup (M) exch 1 0 1 OCTANT 45 rotate + dup (Y) exch 1 1 0 OCTANT 45 rotate + dup (K) exch 0 0 0 OCTANT 45 rotate + dup (R) exch 1 0 0 OCTANT 45 rotate + dup (G) exch 0 1 0 OCTANT 45 rotate + dup (B) exch 0 0 1 OCTANT 45 rotate + (W) exch 1 1 1 OCTANT 45 rotate + grestore + + % Label the color wheel... + pageWidth 18 mul % x = pageWidth * 1/4 * 72 + pageHeight 44 mul % y = pageHeight * 19/32 * 72 + moveto % Position the text + (Color Wheel) CENTER % Show the text centered + + % Draw radial lines... + gsave + 0 setlinewidth % 1 pixel lines + + % Position the lines on the left side... + pageWidth 54 mul % x = pageWidth * 3/4 * 72 + pageHeight 54 mul % y = pageHeight * 3/4 * 72 + translate + + % Size the wheel... + pageWidth 9 mul % radius = pageWidth * 1/8 * 72 + + % Loop at 1 degree increments + 0 1 359 { + pop % Discard angle - not used + 0 0 moveto % Start line at the center + dup 0 lineto % Draw to the radius + 1 rotate % Rotate 1 degree + } for + + pop % Discard radius - not needed anymore + stroke % Draw lines... + + grestore + + % Label the lines... + pageWidth 54 mul % x = pageWidth * 3/4 * 72 + pageHeight 44 mul % y = pageHeight * 19/32 * 72 + moveto % Position the text + (1 Degree Radial Lines) CENTER % Show the text centered + + % Imageable area... + pageWidth 19.5 mul % Height of imageable area + + pageWidth 4.5 mul % x = pageWidth * 1/16 * 72 + pageHeight 35.5 mul % y = pageHeight * 1/2 * 72 + 2 index sub % y -= height + pageWidth 28 mul % width = pageWidth * 1/4 * 72 + 3 index % height + 0.5 setgray rectfill % Draw a shadow + + pageWidth 4 mul % x = pageWidth * 1/16 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + 2 index sub % y -= height + pageWidth 28 mul % width = pageWidth * 3/8 * 72 + 3 index % height + 4 copy 1 setgray rectfill % Clear the box to white + 0 setgray rectstroke % Draw a black box around it... + + pop % Discard height + + % Label the imageable area... + pageWidth 4 mul % x = pageWidth * 1/16 * 72 + pageHeight 37 mul % y = pageHeight * 1/2 * 72 + moveto % Position the text + mediumFont setfont % Font + (Imageable Area) show % Show the text + + smallFont setfont % Font + pageWidth 14 mul % x = pageWidth * 3/16 * 72 + pageHeight 36 mul % y = pageWidth * 1/2 * 72 + pageWidth -3 mul add % y -= 2 * smallFont height + + % Page Size inches + 2 copy moveto % Move to x & y + (Page Size: ) RIGHT % Label + 100 pageWidth NUMBER % pageWidth + (x) show % "x" + 100 pageHeight NUMBER % pageHeight + (in) show % "in" + + % Page Size millimeters + pageWidth -1.5 mul add % Move down... + + 2 copy moveto % Move to x & y + 10 pageWidth 25.4 mul NUMBER % pageWidth + (x) show % "x" + 10 pageHeight 25.4 mul NUMBER % pageHeight + (mm) show % "mm" + + % Lower-left inches + pageWidth -3 mul add % Move down... + + 2 copy moveto % Move to x & y + (Lower-Left: ) RIGHT % Label + 100 pageLeft NUMBER % pageLeft + (x) show % "x" + 100 pageBottom NUMBER % pageBottom + (in) show % "in" + + % Lower-left millimeters + pageWidth -1.5 mul add % Move down... + + 2 copy moveto % Move to x & y + 10 pageLeft 25.4 mul NUMBER % pageLeft + (x) show % "x" + 10 pageBottom 25.4 mul NUMBER % pageBottom + (mm) show % "mm" + + % Upper-right inches + pageWidth -3 mul add % Move down... + + 2 copy moveto % Move to x & y + (Upper-Right: ) RIGHT % Label + 100 pageRight NUMBER % pageRight + (x) show % "x" + 100 pageTop NUMBER % pageTop + (in) show % "in" + + % Upper-right millimeters + pageWidth -1.5 mul add % Move down... + + 2 copy moveto % Move to x & y + 10 pageRight 25.4 mul NUMBER % pageRight + (x) show % "x" + 10 pageTop 25.4 mul NUMBER % pageTop + (mm) show % "mm" + + % Resolution dots-per-inch + pageWidth -3 mul add % Move down... + + 2 copy moveto % Move to x & y + (Resolution: ) RIGHT % Label + 1 xResolution NUMBER % xResolution + (x) show % "x" + 1 yResolution NUMBER % yResolution + (dpi) show % "dpi" + + % Resolution dots-per-meter + pageWidth -1.5 mul add % Move down... + + moveto % Move to x & y + 1 xResolution 39.27 mul NUMBER % xResolution + (x) show % "x" + 1 yResolution 39.27 mul NUMBER % yResolution + (dpm) show % "dpm" + + % Interpreter Information... + pageWidth 19.5 mul % Height of interpreter info + + pageWidth 40.5 mul % x = pageWidth * 9/16 * 72 + pageHeight 35.5 mul % y = pageHeight * 1/2 * 72 + 2 index sub % y -= height + pageWidth 28 mul % width = pageWidth * 1/4 * 72 + 3 index % height + 0.5 setgray rectfill % Draw a shadow + + pageWidth 40 mul % x = pageWidth * 9/16 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + 2 index sub % y -= height + pageWidth 28 mul % width = pageWidth * 3/8 * 72 + 3 index % height + 4 copy 1 setgray rectfill % Clear the box to white + 0 setgray rectstroke % Draw a black box around it... + + pop % Discard height + + % Label the interpreter info... + pageWidth 40 mul % x = pageWidth * 9/16 * 72 + pageHeight 37 mul % y = pageHeight * 1/2 * 72 + moveto % Position the text + mediumFont setfont % Font + (Interpreter Information) show % Show the text + + smallFont setfont % Font + pageWidth 49 mul % x = pageWidth * 11/16 * 72 + pageHeight 36 mul % y = pageWidth * 1/2 * 72 + pageWidth -3 mul add % y -= 2 * smallFont height + + % Language level + 2 copy moveto % Move to x & y + (PostScript: ) RIGHT % Label + (Level ) show % "Level " + 1 languagelevel NUMBER % Language level + + % Version + pageWidth -3 mul add % Move down... + 2 copy moveto % Move to x & y + (Version: ) RIGHT % Label + version show % Version + ( \() show % " (" + 1 revision NUMBER % Revision + (\)) show % ")" + + % Product + pageWidth -3 mul add % Move down... + 2 copy moveto % Move to x & y + (Product: ) RIGHT % Label + product show % Product name + + % Serial Number + pageWidth -3 mul add % Move down... + 2 copy moveto % Move to x & y + (Serial #: ) RIGHT % Label + 1 serialnumber NUMBER % S/N + + % Draw the label at the top... + pageWidth 36 mul % Center of page + pageHeight 68 mul % Top of page (15/16ths) + 2 copy moveto % Position text + bigFont setfont % Font + (Printer Test Page) CENTER % Show text centered + + % Draw the copyright notice at the bottom... + pageWidth 36 mul % Center of page + pageWidth 14 mul % Bottom of page + 2 copy moveto % Position text + (Printed Using CUPS v1.1) CENTER % Show text centered + + pageWidth 3 mul sub % Move down... + 2 copy moveto % Position text + smallFont setfont % Font + (Copyright 1993-2000 Easy Software Products, All Rights Reserved.) CENTER + pageWidth 1.5 mul sub % Move down... + 2 copy moveto % Position text + (CUPS, and the CUPS logo are the trademark property of) CENTER + pageWidth 1.5 mul sub % Move down... + 2 copy moveto % Position text + (Easy Software Products, 44141 Airport View Drive, Suite 204,) CENTER + pageWidth 1.5 mul sub % Move down... + 2 copy moveto % Position text + (Hollywood, Maryland, 20636-3111, USA.) CENTER + + % Then the CUPS logo.... + gsave + pageWidth 4 mul + pageWidth 6 mul + translate + pageWidth 9 mul CUPSLOGO + grestore + + % And the ESP logo.... + gsave + pageWidth 59 mul + pageWidth 6 mul + translate + pageWidth 6 mul ESPLOGO + grestore +% Show the page... +grestore +showpage +% +% End of "$Id: testprint.ps 985 2000-03-13 18:55:00Z mike $". +% +%%EOF diff --git a/data/topsecret b/data/topsecret new file mode 100644 index 0000000000..7845048b6e --- /dev/null +++ b/data/topsecret @@ -0,0 +1,259 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 +%%Pages: 1 +%%LanguageLevel: 1 +%%DocumentData: Clean7Bit +%%DocumentSuppliedResources: procset bannerprint/1.0 +%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman +%%Creator: Michael Sweet, Easy Software Products +%%CreationDate: May 10, 2000 +%%Title: Test Page +%%EndComments +%%BeginProlog +%%BeginResource procset bannerprint 1.1 0 +% +% PostScript banner page for the Common UNIX Printing System ("CUPS"). +% +% Copyright 1993-2000 Easy Software Products +% +% These coded instructions, statements, and computer programs contain +% unpublished proprietary information of Easy Software Products, and +% are protected by Federal copyright law. They may not be disclosed +% to third parties or copied or duplicated in any form, in whole or +% in part, without the prior written consent of Easy Software Products. +% +/CENTER \{ % Draw centered text + % (name) CENTER - + dup stringwidth pop % Get the width of the string + 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance + show % Show the string +} bind def +/RIGHT \{ % Draw right-justified text + % (name) RIGHT - + dup stringwidth pop % Get the width of the string + neg 0 rmoveto % Shift left the entire distance + show % Show the string +} bind def +/NUMBER \{ % Draw a number + % power n NUMBER - + 1 index 1 eq \{ % power == 1? + round cvi exch pop % Convert "n" to integer + } \{ + 1 index mul round exch div % Truncate extra decimal places + } ifelse + 100 string cvs show % Convert to a string and show it... +} bind def +/CUPSLOGO \{ % Draw the CUPS logo + % height CUPSLOGO + % Start with a big C... + /Helvetica findfont 1 index scalefont setfont + 0 setgray + 0 0 moveto + (C) show + + % Then "UNIX Printing System" much smaller... + /Helvetica-Bold findfont 1 index 9 div scalefont setfont + 0.25 mul + dup dup 2.0 mul moveto + (UNIX) show + dup dup 1.6 mul moveto + (Printing) show + dup 1.2 mul moveto + (System) show +} bind def +/ESPLOGO \{ % Draw the ESP logo + % height ESPLOGO + % Compute the size of the logo... + 0 0 + 2 index 1.5 mul 3 index + + % Do the "metallic" fill from 10% black to 40% black... + 1 -0.001 0 \{ + dup % loopval + -0.15 mul % loopval * -0.15 + 0.9 add % 0.9 - loopval * 0.15 + setgray % set gray shade + + 0 % x + 1 index neg % loopval + 1 add % 1 - loopval + 3 index % height + mul % height * (1 - loopval) + moveto % starting point + + dup % loopval + 3 index % width + mul % loopval * width + 2 index % height + lineto % Next point + + 0 % x + 2 index % height + lineto % Next point + + closepath + fill + + dup % loopval + 0.15 mul % loopval * 0.15 + 0.6 add % 0.6 + loopval * 0.15 + setgray + + dup % loopval + neg 1 add % 1 - loopval + 3 index % width + mul % (1 - loopval) * width + 0 % y + moveto % Starting point + + 2 index % width + exch % loopval + 2 index % height + mul % loopval * height + lineto % Next point + + 1 index % width + 0 % y + lineto % Next point + + closepath + fill + } for + + 0 setgray rectstroke + + /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont + dup 40 div + + dup 4 mul 1 index 25 mul moveto (E) show + dup 10 mul 1 index 15 mul moveto (S) show + dup 16 mul 1 index 5 mul moveto (P) show + + /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont + dup 14 mul 1 index 29 mul moveto (asy) show + dup 20 mul 1 index 19 mul moveto (oftware) show + dup 26 mul 1 index 9 mul moveto (roducts) show + + pop +} bind def +%%EndResource +%%EndProlog +%%Page: 1 1 +gsave + + % Determine the imageable area and device resolution... + initclip newpath clippath pathbbox % Get bounding rectangle + 72 div /pageTop exch def % Get top margin in inches + 72 div /pageRight exch def % Get right margin in inches + 72 div /pageBottom exch def % Get bottom margin in inches + 72 div /pageLeft exch def % Get left margin in inches + + /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft + /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom + + newpath % Clear bounding path + + % Create fonts... + /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold + pageWidth 4 mul scalefont def % size = pageWidth * 4 (nominally 34) + + /mediumFont /Helvetica findfont % mediumFont = Helvetica + pageWidth 2 mul scalefont def % size = pageWidth * 2 (nominally 17) + + % Offset page to account for lower-left margin... + pageLeft 72 mul + pageBottom 72 mul + translate + + % Draw the label at the top and bottom... + 0 setgray % Color + + pageWidth 36 mul % Center of page + pageHeight 72 mul % Top of page + pageWidth -9 mul add % - 1 line + moveto % Position text + bigFont setfont % Font + (Top Secret) CENTER % Show text centered + + pageWidth 36 mul % Center of page + pageWidth 8 mul % Bottom of page + moveto % Position text + bigFont setfont % Font + (Top Secret) CENTER % Show text centered + + % Job information box... + pageWidth 18 mul 9 add % x = pageWidth * 1/4 * 72 + 9 + pageHeight 27 mul 9 sub % y = pageHeight * 3/8 * 72 - 9 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + 0.5 setgray rectfill % Draw a shadow + + pageWidth 18 mul % x = pageWidth * 1/4 * 72 + pageHeight 27 mul % y = pageHeight * 3/8 * 72 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + + 4 copy 1 setgray rectfill % Clear the box to white + 0 setgray rectstroke % Draw a black box around it... + + % Job information text... + mediumFont setfont % Medium sized font + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 4 mul add % y += 2 lines + 2 copy % Copy X & Y + moveto + (Job ID: ) RIGHT + moveto + ({printer-name}-{job-id}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 1 mul add % y += 1 line + 2 copy % Copy X & Y + moveto + (Title: ) RIGHT + moveto + ({job-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -2 mul add % y -= 1 line + 2 copy % Copy X & Y + moveto + (Requesting User: ) RIGHT + moveto + ({job-originating-user-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -5 mul add % y -= 2 lines + 2 copy % Copy X & Y + moveto + (Billing Info: ) RIGHT + moveto + ({job-billing}) show + + % Then the CUPS logo.... + gsave + pageWidth 4 mul + pageWidth 6 mul + translate + pageWidth 9 mul CUPSLOGO + grestore + + % And the ESP logo.... + gsave + pageWidth 59 mul + pageWidth 6 mul + translate + pageWidth 6 mul ESPLOGO + grestore +% Show the page... +grestore +showpage +% +% End of "$Id: topsecret 1075 2000-05-11 20:02:21Z mike $". +% +%%EOF diff --git a/data/unclassified b/data/unclassified new file mode 100644 index 0000000000..a40af7e86b --- /dev/null +++ b/data/unclassified @@ -0,0 +1,259 @@ +%!PS-Adobe-3.0 +%%BoundingBox: 0 0 612 792 +%%Pages: 1 +%%LanguageLevel: 1 +%%DocumentData: Clean7Bit +%%DocumentSuppliedResources: procset bannerprint/1.0 +%%DocumentNeededResources: font Helvetica Helvetica-Bold Times-Roman +%%Creator: Michael Sweet, Easy Software Products +%%CreationDate: May 10, 2000 +%%Title: Test Page +%%EndComments +%%BeginProlog +%%BeginResource procset bannerprint 1.1 0 +% +% PostScript banner page for the Common UNIX Printing System ("CUPS"). +% +% Copyright 1993-2000 Easy Software Products +% +% These coded instructions, statements, and computer programs contain +% unpublished proprietary information of Easy Software Products, and +% are protected by Federal copyright law. They may not be disclosed +% to third parties or copied or duplicated in any form, in whole or +% in part, without the prior written consent of Easy Software Products. +% +/CENTER \{ % Draw centered text + % (name) CENTER - + dup stringwidth pop % Get the width of the string + 0.5 mul neg 0 rmoveto % Shift left 1/2 of the distance + show % Show the string +} bind def +/RIGHT \{ % Draw right-justified text + % (name) RIGHT - + dup stringwidth pop % Get the width of the string + neg 0 rmoveto % Shift left the entire distance + show % Show the string +} bind def +/NUMBER \{ % Draw a number + % power n NUMBER - + 1 index 1 eq \{ % power == 1? + round cvi exch pop % Convert "n" to integer + } \{ + 1 index mul round exch div % Truncate extra decimal places + } ifelse + 100 string cvs show % Convert to a string and show it... +} bind def +/CUPSLOGO \{ % Draw the CUPS logo + % height CUPSLOGO + % Start with a big C... + /Helvetica findfont 1 index scalefont setfont + 0 setgray + 0 0 moveto + (C) show + + % Then "UNIX Printing System" much smaller... + /Helvetica-Bold findfont 1 index 9 div scalefont setfont + 0.25 mul + dup dup 2.0 mul moveto + (UNIX) show + dup dup 1.6 mul moveto + (Printing) show + dup 1.2 mul moveto + (System) show +} bind def +/ESPLOGO \{ % Draw the ESP logo + % height ESPLOGO + % Compute the size of the logo... + 0 0 + 2 index 1.5 mul 3 index + + % Do the "metallic" fill from 10% black to 40% black... + 1 -0.001 0 \{ + dup % loopval + -0.15 mul % loopval * -0.15 + 0.9 add % 0.9 - loopval * 0.15 + setgray % set gray shade + + 0 % x + 1 index neg % loopval + 1 add % 1 - loopval + 3 index % height + mul % height * (1 - loopval) + moveto % starting point + + dup % loopval + 3 index % width + mul % loopval * width + 2 index % height + lineto % Next point + + 0 % x + 2 index % height + lineto % Next point + + closepath + fill + + dup % loopval + 0.15 mul % loopval * 0.15 + 0.6 add % 0.6 + loopval * 0.15 + setgray + + dup % loopval + neg 1 add % 1 - loopval + 3 index % width + mul % (1 - loopval) * width + 0 % y + moveto % Starting point + + 2 index % width + exch % loopval + 2 index % height + mul % loopval * height + lineto % Next point + + 1 index % width + 0 % y + lineto % Next point + + closepath + fill + } for + + 0 setgray rectstroke + + /Helvetica-BoldOblique findfont 1 index 3 div scalefont setfont + dup 40 div + + dup 4 mul 1 index 25 mul moveto (E) show + dup 10 mul 1 index 15 mul moveto (S) show + dup 16 mul 1 index 5 mul moveto (P) show + + /Helvetica-BoldOblique findfont 2 index 5 div scalefont setfont + dup 14 mul 1 index 29 mul moveto (asy) show + dup 20 mul 1 index 19 mul moveto (oftware) show + dup 26 mul 1 index 9 mul moveto (roducts) show + + pop +} bind def +%%EndResource +%%EndProlog +%%Page: 1 1 +gsave + + % Determine the imageable area and device resolution... + initclip newpath clippath pathbbox % Get bounding rectangle + 72 div /pageTop exch def % Get top margin in inches + 72 div /pageRight exch def % Get right margin in inches + 72 div /pageBottom exch def % Get bottom margin in inches + 72 div /pageLeft exch def % Get left margin in inches + + /pageWidth pageRight pageLeft sub def % pageWidth = pageRight - pageLeft + /pageHeight pageTop pageBottom sub def% pageHeight = pageTop - pageBottom + + newpath % Clear bounding path + + % Create fonts... + /bigFont /Helvetica-Bold findfont % bigFont = Helvetica-Bold + pageWidth 4 mul scalefont def % size = pageWidth * 4 (nominally 34) + + /mediumFont /Helvetica findfont % mediumFont = Helvetica + pageWidth 2 mul scalefont def % size = pageWidth * 2 (nominally 17) + + % Offset page to account for lower-left margin... + pageLeft 72 mul + pageBottom 72 mul + translate + + % Draw the label at the top and bottom... + 0 setgray % Color + + pageWidth 36 mul % Center of page + pageHeight 72 mul % Top of page + pageWidth -9 mul add % - 1 line + moveto % Position text + bigFont setfont % Font + (Unclassified) CENTER % Show text centered + + pageWidth 36 mul % Center of page + pageWidth 8 mul % Bottom of page + moveto % Position text + bigFont setfont % Font + (Unclassified) CENTER % Show text centered + + % Job information box... + pageWidth 18 mul 9 add % x = pageWidth * 1/4 * 72 + 9 + pageHeight 27 mul 9 sub % y = pageHeight * 3/8 * 72 - 9 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + 0.5 setgray rectfill % Draw a shadow + + pageWidth 18 mul % x = pageWidth * 1/4 * 72 + pageHeight 27 mul % y = pageHeight * 3/8 * 72 + pageWidth 36 mul % w = pageWidth * 1/2 * 72 + pageHeight 18 mul % h = pageHeight * 1/4 * 72 + + 4 copy 1 setgray rectfill % Clear the box to white + 0 setgray rectstroke % Draw a black box around it... + + % Job information text... + mediumFont setfont % Medium sized font + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 4 mul add % y += 2 lines + 2 copy % Copy X & Y + moveto + (Job ID: ) RIGHT + moveto + ({printer-name}-{job-id}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth 1 mul add % y += 1 line + 2 copy % Copy X & Y + moveto + (Title: ) RIGHT + moveto + ({job-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -2 mul add % y -= 1 line + 2 copy % Copy X & Y + moveto + (Requesting User: ) RIGHT + moveto + ({job-originating-user-name}) show + + pageWidth 36 mul % x = pageWidth * 1/2 * 72 + pageHeight 36 mul % y = pageHeight * 1/2 * 72 + pageWidth -5 mul add % y -= 2 lines + 2 copy % Copy X & Y + moveto + (Billing Info: ) RIGHT + moveto + ({job-billing}) show + + % Then the CUPS logo.... + gsave + pageWidth 4 mul + pageWidth 6 mul + translate + pageWidth 9 mul CUPSLOGO + grestore + + % And the ESP logo.... + gsave + pageWidth 59 mul + pageWidth 6 mul + translate + pageWidth 6 mul ESPLOGO + grestore +% Show the page... +grestore +showpage +% +% End of "$Id: unclassified 1075 2000-05-11 20:02:21Z mike $". +% +%%EOF diff --git a/data/utf-8 b/data/utf-8 new file mode 100644 index 0000000000..e808223a06 --- /dev/null +++ b/data/utf-8 @@ -0,0 +1,38 @@ +charset utf8 + +# +# This file defines the font mappings used for Unicode/UTF-8 text printing. +# +# Each line consists of: +# +# first last direction width normal bold italic bold-italic +# +# First and last are the first and last glyphs in the font mapping +# that correspond to that font; a maximum of 256 characters can be +# mapped within each group, with a maximum of 256 mappings (this is a +# PostScript limitation.) The glyph values are hexadecimal. +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +0000 00FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic +0100 01FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic +0200 02FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic +0300 03FF ltor single Symbol +0400 04FF ltor single Courier-Cyrillic +1E00 1EFF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic +2000 20FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic +2100 21FF ltor single Courier Courier-Bold Courier-Italic Courier-Bold-Italic +2200 22FF ltor single Symbol +2300 23FF ltor single Symbol diff --git a/data/windows-1250 b/data/windows-1250 new file mode 100644 index 0000000000..afcc62ed5f --- /dev/null +++ b/data/windows-1250 @@ -0,0 +1,254 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 1250 (WinLatin2) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 20AC +82 201A +84 201E +85 2026 +86 2020 +87 2021 +89 2030 +8A 0160 +8B 2039 +8C 015A +8D 0164 +8E 017D +8F 0179 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +99 2122 +9A 0161 +9B 203A +9C 015B +9D 0165 +9E 017E +9F 017A +A0 00A0 +A1 02C7 +A2 02D8 +A3 0141 +A4 00A4 +A5 0104 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AA 015E +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 017B +B0 00B0 +B1 00B1 +B2 02DB +B3 0142 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00B8 +B9 0105 +BA 015F +BB 00BB +BC 013D +BD 02DD +BE 013E +BF 017C +C0 0154 +C1 00C1 +C2 00C2 +C3 0102 +C4 00C4 +C5 0139 +C6 0106 +C7 00C7 +C8 010C +C9 00C9 +CA 0118 +CB 00CB +CC 011A +CD 00CD +CE 00CE +CF 010E +D0 0110 +D1 0143 +D2 0147 +D3 00D3 +D4 00D4 +D5 0150 +D6 00D6 +D7 00D7 +D8 0158 +D9 016E +DA 00DA +DB 0170 +DC 00DC +DD 00DD +DE 0162 +DF 00DF +E0 0155 +E1 00E1 +E2 00E2 +E3 0103 +E4 00E4 +E5 013A +E6 0107 +E7 00E7 +E8 010D +E9 00E9 +EA 0119 +EB 00EB +EC 011B +ED 00ED +EE 00EE +EF 010F +F0 0111 +F1 0144 +F2 0148 +F3 00F3 +F4 00F4 +F5 0151 +F6 00F6 +F7 00F7 +F8 0159 +F9 016F +FA 00FA +FB 0171 +FC 00FC +FD 00FD +FE 0163 +FF 02D9 diff --git a/data/windows-1251 b/data/windows-1251 new file mode 100644 index 0000000000..6d31dee09c --- /dev/null +++ b/data/windows-1251 @@ -0,0 +1,258 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 1251 (WinCyrillic) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 0402 +81 0403 +82 201A +83 0453 +84 201E +85 2026 +86 2020 +87 2021 +88 20AC +89 2030 +8A 0409 +8B 2039 +8C 040A +8D 040C +8E 040B +8F 040F +90 0452 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +99 2122 +9A 0459 +9B 203A +9C 045A +9D 045C +9E 045B +9F 045F +A0 00A0 +A1 040E +A2 045E +A3 0408 +A4 00A4 +A5 0490 +A6 00A6 +A7 00A7 +A8 0401 +A9 00A9 +AA 0404 +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 0407 +B0 00B0 +B1 00B1 +B2 0406 +B3 0456 +B4 0491 +B5 00B5 +B6 00B6 +B7 00B7 +B8 0451 +B9 2116 +BA 0454 +BB 00BB +BC 0458 +BD 0405 +BE 0455 +BF 0457 +C0 0410 +C1 0411 +C2 0412 +C3 0413 +C4 0414 +C5 0415 +C6 0416 +C7 0417 +C8 0418 +C9 0419 +CA 041A +CB 041B +CC 041C +CD 041D +CE 041E +CF 041F +D0 0420 +D1 0421 +D2 0422 +D3 0423 +D4 0424 +D5 0425 +D6 0426 +D7 0427 +D8 0428 +D9 0429 +DA 042A +DB 042B +DC 042C +DD 042D +DE 042E +DF 042F +E0 0430 +E1 0431 +E2 0432 +E3 0433 +E4 0434 +E5 0435 +E6 0436 +E7 0437 +E8 0438 +E9 0439 +EA 043A +EB 043B +EC 043C +ED 043D +EE 043E +EF 043F +F0 0440 +F1 0441 +F2 0442 +F3 0443 +F4 0444 +F5 0445 +F6 0446 +F7 0447 +F8 0448 +F9 0449 +FA 044A +FB 044B +FC 044C +FD 044D +FE 044E +FF 044F diff --git a/data/windows-1252 b/data/windows-1252 new file mode 100644 index 0000000000..a98595874d --- /dev/null +++ b/data/windows-1252 @@ -0,0 +1,254 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 1252 (WinLatin1) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +8E 017D +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9E 017E +9F 0178 +A0 00A0 +A1 00A1 +A2 00A2 +A3 00A3 +A4 00A4 +A5 00A5 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AA 00AA +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00AF +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00B8 +B9 00B9 +BA 00BA +BB 00BB +BC 00BC +BD 00BD +BE 00BE +BF 00BF +C0 00C0 +C1 00C1 +C2 00C2 +C3 00C3 +C4 00C4 +C5 00C5 +C6 00C6 +C7 00C7 +C8 00C8 +C9 00C9 +CA 00CA +CB 00CB +CC 00CC +CD 00CD +CE 00CE +CF 00CF +D0 00D0 +D1 00D1 +D2 00D2 +D3 00D3 +D4 00D4 +D5 00D5 +D6 00D6 +D7 00D7 +D8 00D8 +D9 00D9 +DA 00DA +DB 00DB +DC 00DC +DD 00DD +DE 00DE +DF 00DF +E0 00E0 +E1 00E1 +E2 00E2 +E3 00E3 +E4 00E4 +E5 00E5 +E6 00E6 +E7 00E7 +E8 00E8 +E9 00E9 +EA 00EA +EB 00EB +EC 00EC +ED 00ED +EE 00EE +EF 00EF +F0 00F0 +F1 00F1 +F2 00F2 +F3 00F3 +F4 00F4 +F5 00F5 +F6 00F6 +F7 00F7 +F8 00F8 +F9 00F9 +FA 00FA +FB 00FB +FC 00FC +FD 00FD +FE 00FE +FF 00FF diff --git a/data/windows-1253 b/data/windows-1253 new file mode 100644 index 0000000000..c736ecd6c8 --- /dev/null +++ b/data/windows-1253 @@ -0,0 +1,243 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 1253 (WinGreek) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 9f ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic +a0 ff ltor single Symbol + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +89 2030 +8B 2039 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +99 2122 +9B 203A +A0 00A0 +A1 0385 +A2 0386 +A3 00A3 +A4 00A4 +A5 00A5 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 2015 +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 0384 +B5 00B5 +B6 00B6 +B7 00B7 +B8 0388 +B9 0389 +BA 038A +BB 00BB +BC 038C +BD 00BD +BE 038E +BF 038F +C0 0390 +C1 0391 +C2 0392 +C3 0393 +C4 0394 +C5 0395 +C6 0396 +C7 0397 +C8 0398 +C9 0399 +CA 039A +CB 039B +CC 039C +CD 039D +CE 039E +CF 039F +D0 03A0 +D1 03A1 +D3 03A3 +D4 03A4 +D5 03A5 +D6 03A6 +D7 03A7 +D8 03A8 +D9 03A9 +DA 03AA +DB 03AB +DC 03AC +DD 03AD +DE 03AE +DF 03AF +E0 03B0 +E1 03B1 +E2 03B2 +E3 03B3 +E4 03B4 +E5 03B5 +E6 03B6 +E7 03B7 +E8 03B8 +E9 03B9 +EA 03BA +EB 03BB +EC 03BC +ED 03BD +EE 03BE +EF 03BF +F0 03C0 +F1 03C1 +F2 03C2 +F3 03C3 +F4 03C4 +F5 03C5 +F6 03C6 +F7 03C7 +F8 03C8 +F9 03C9 +FA 03CA +FB 03CB +FC 03CC +FD 03CD +FE 03CE diff --git a/data/windows-1254 b/data/windows-1254 new file mode 100644 index 0000000000..87fff2db7e --- /dev/null +++ b/data/windows-1254 @@ -0,0 +1,252 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 1254 (WinTurkish) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0160 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9A 0161 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 00A1 +A2 00A2 +A3 00A3 +A4 00A4 +A5 00A5 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AA 00AA +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00AF +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00B8 +B9 00B9 +BA 00BA +BB 00BB +BC 00BC +BD 00BD +BE 00BE +BF 00BF +C0 00C0 +C1 00C1 +C2 00C2 +C3 00C3 +C4 00C4 +C5 00C5 +C6 00C6 +C7 00C7 +C8 00C8 +C9 00C9 +CA 00CA +CB 00CB +CC 00CC +CD 00CD +CE 00CE +CF 00CF +D0 011E +D1 00D1 +D2 00D2 +D3 00D3 +D4 00D4 +D5 00D5 +D6 00D6 +D7 00D7 +D8 00D8 +D9 00D9 +DA 00DA +DB 00DB +DC 00DC +DD 0130 +DE 015E +DF 00DF +E0 00E0 +E1 00E1 +E2 00E2 +E3 00E3 +E4 00E4 +E5 00E5 +E6 00E6 +E7 00E7 +E8 00E8 +E9 00E9 +EA 00EA +EB 00EB +EC 00EC +ED 00ED +EE 00EE +EF 00EF +F0 011F +F1 00F1 +F2 00F2 +F3 00F3 +F4 00F4 +F5 00F5 +F6 00F6 +F7 00F7 +F8 00F8 +F9 00F9 +FA 00FA +FB 00FB +FC 00FC +FD 0131 +FE 015F +FF 00FF diff --git a/data/windows-1255 b/data/windows-1255 new file mode 100644 index 0000000000..a8b26a85d9 --- /dev/null +++ b/data/windows-1255 @@ -0,0 +1,236 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 1255 (WinHebrew) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff rtol single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8B 2039 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9B 203A +A0 00A0 +A1 00A1 +A2 00A2 +A3 00A3 +A4 20AA +A5 00A5 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AA 00D7 +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00AF +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00B8 +B9 00B9 +BA 00F7 +BB 00BB +BC 00BC +BD 00BD +BE 00BE +BF 00BF +C0 05B0 +C1 05B1 +C2 05B2 +C3 05B3 +C4 05B4 +C5 05B5 +C6 05B6 +C7 05B7 +C8 05B8 +C9 05B9 +CB 05BB +CC 05BC +CD 05BD +CE 05BE +CF 05BF +D0 05C0 +D1 05C1 +D2 05C2 +D3 05C3 +D4 05F0 +D5 05F1 +D6 05F2 +D7 05F3 +D8 05F4 +E0 05D0 +E1 05D1 +E2 05D2 +E3 05D3 +E4 05D4 +E5 05D5 +E6 05D6 +E7 05D7 +E8 05D8 +E9 05D9 +EA 05DA +EB 05DB +EC 05DC +ED 05DD +EE 05DE +EF 05DF +F0 05E0 +F1 05E1 +F2 05E2 +F3 05E3 +F4 05E4 +F5 05E5 +F6 05E6 +F7 05E7 +F8 05E8 +F9 05E9 +FA 05EA +FD 200E +FE 200F diff --git a/data/windows-1256 b/data/windows-1256 new file mode 100644 index 0000000000..6908f1eb5a --- /dev/null +++ b/data/windows-1256 @@ -0,0 +1,259 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 1256 (WinArabic) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff rtol single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 20AC +81 067E +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8A 0679 +8B 2039 +8C 0152 +8D 0686 +8E 0698 +8F 0688 +90 06AF +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 06A9 +99 2122 +9A 0691 +9B 203A +9C 0153 +9D 200C +9E 200D +9F 06BA +A0 00A0 +A1 060C +A2 00A2 +A3 00A3 +A4 00A4 +A5 00A5 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AA 06BE +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00AF +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00B8 +B9 00B9 +BA 061B +BB 00BB +BC 00BC +BD 00BD +BE 00BE +BF 061F +C0 06C1 +C1 0621 +C2 0622 +C3 0623 +C4 0624 +C5 0625 +C6 0626 +C7 0627 +C8 0628 +C9 0629 +CA 062A +CB 062B +CC 062C +CD 062D +CE 062E +CF 062F +D0 0630 +D1 0631 +D2 0632 +D3 0633 +D4 0634 +D5 0635 +D6 0636 +D7 00D7 +D8 0637 +D9 0638 +DA 0639 +DB 063A +DC 0640 +DD 0641 +DE 0642 +DF 0643 +E0 00E0 +E1 0644 +E2 00E2 +E3 0645 +E4 0646 +E5 0647 +E6 0648 +E7 00E7 +E8 00E8 +E9 00E9 +EA 00EA +EB 00EB +EC 0649 +ED 064A +EE 00EE +EF 00EF +F0 064B +F1 064C +F2 064D +F3 064E +F4 00F4 +F5 064F +F6 0650 +F7 00F7 +F8 0651 +F9 00F9 +FA 0652 +FB 00FB +FC 00FC +FD 200E +FE 200F +FF 06D2 diff --git a/data/windows-1257 b/data/windows-1257 new file mode 100644 index 0000000000..ac5f8e0b7c --- /dev/null +++ b/data/windows-1257 @@ -0,0 +1,247 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 1257 (WinBaltic) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 20AC +82 201A +84 201E +85 2026 +86 2020 +87 2021 +89 2030 +8B 2039 +8D 00A8 +8E 02C7 +8F 00B8 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +99 2122 +9B 203A +9D 00AF +9E 02DB +A0 00A0 +A2 00A2 +A3 00A3 +A4 00A4 +A6 00A6 +A7 00A7 +A8 00D8 +A9 00A9 +AA 0156 +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00C6 +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00F8 +B9 00B9 +BA 0157 +BB 00BB +BC 00BC +BD 00BD +BE 00BE +BF 00E6 +C0 0104 +C1 012E +C2 0100 +C3 0106 +C4 00C4 +C5 00C5 +C6 0118 +C7 0112 +C8 010C +C9 00C9 +CA 0179 +CB 0116 +CC 0122 +CD 0136 +CE 012A +CF 013B +D0 0160 +D1 0143 +D2 0145 +D3 00D3 +D4 014C +D5 00D5 +D6 00D6 +D7 00D7 +D8 0172 +D9 0141 +DA 015A +DB 016A +DC 00DC +DD 017B +DE 017D +DF 00DF +E0 0105 +E1 012F +E2 0101 +E3 0107 +E4 00E4 +E5 00E5 +E6 0119 +E7 0113 +E8 010D +E9 00E9 +EA 017A +EB 0117 +EC 0123 +ED 0137 +EE 012B +EF 013C +F0 0161 +F1 0144 +F2 0146 +F3 00F3 +F4 014D +F5 00F5 +F6 00F6 +F7 00F7 +F8 0173 +F9 0142 +FA 015B +FB 016B +FC 00FC +FD 017C +FE 017E +FF 02D9 diff --git a/data/windows-1258 b/data/windows-1258 new file mode 100644 index 0000000000..f7721c51b1 --- /dev/null +++ b/data/windows-1258 @@ -0,0 +1,250 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 1258 (WinVietnamese) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 20AC +82 201A +83 0192 +84 201E +85 2026 +86 2020 +87 2021 +88 02C6 +89 2030 +8B 2039 +8C 0152 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +98 02DC +99 2122 +9B 203A +9C 0153 +9F 0178 +A0 00A0 +A1 00A1 +A2 00A2 +A3 00A3 +A4 00A4 +A5 00A5 +A6 00A6 +A7 00A7 +A8 00A8 +A9 00A9 +AA 00AA +AB 00AB +AC 00AC +AD 00AD +AE 00AE +AF 00AF +B0 00B0 +B1 00B1 +B2 00B2 +B3 00B3 +B4 00B4 +B5 00B5 +B6 00B6 +B7 00B7 +B8 00B8 +B9 00B9 +BA 00BA +BB 00BB +BC 00BC +BD 00BD +BE 00BE +BF 00BF +C0 00C0 +C1 00C1 +C2 00C2 +C3 0102 +C4 00C4 +C5 00C5 +C6 00C6 +C7 00C7 +C8 00C8 +C9 00C9 +CA 00CA +CB 00CB +CC 0300 +CD 00CD +CE 00CE +CF 00CF +D0 0110 +D1 00D1 +D2 0309 +D3 00D3 +D4 00D4 +D5 01A0 +D6 00D6 +D7 00D7 +D8 00D8 +D9 00D9 +DA 00DA +DB 00DB +DC 00DC +DD 01AF +DE 0303 +DF 00DF +E0 00E0 +E1 00E1 +E2 00E2 +E3 0103 +E4 00E4 +E5 00E5 +E6 00E6 +E7 00E7 +E8 00E8 +E9 00E9 +EA 00EA +EB 00EB +EC 0301 +ED 00ED +EE 00EE +EF 00EF +F0 0111 +F1 00F1 +F2 0323 +F3 00F3 +F4 00F4 +F5 01A1 +F6 00F6 +F7 00F7 +F8 00F8 +F9 00F9 +FA 00FA +FB 00FB +FC 00FC +FD 01B0 +FE 20AB +FF 00FF diff --git a/data/windows-874 b/data/windows-874 new file mode 100644 index 0000000000..886e46a4b4 --- /dev/null +++ b/data/windows-874 @@ -0,0 +1,228 @@ +charset 8bit + +# +# This file defines the font and character mappings used for Windows +# Code Page 874 (Thai) text printing. +# +# The first line consists of: +# +# direction width normal bold italic bold-italic +# +# Direction is the string "ltor" or "rtol", indicating left-to-right or +# right-to-left text. +# +# Width is the string "single" or "double"; double means that the glyphs +# are twice as wide as ASCII characters in the Courier typeface. +# +# "Normal", "bold", "italic", and "bold-italic" are the typefaces to use +# for each presentation. If characters are only available in a single +# style then only one typeface should be listed (e.g. "Symbol") +# +# Each font that is listed will be used (and downloaded if needed) when +# printing. +# + +00 ff ltor single Courier Courier-Bold Courier-Italic Courier-BoldItalic + +# +# The following lines define the mapping from the 8-bit character set to +# the Unicode glyphs for each character: +# +# char glyph +# +# "Char" and "glyph" are hexadecimal values. +# + +20 0020 +21 0021 +22 0022 +23 0023 +24 0024 +25 0025 +26 0026 +27 0027 +28 0028 +29 0029 +2A 002A +2B 002B +2C 002C +2D 002D +2E 002E +2F 002F +30 0030 +31 0031 +32 0032 +33 0033 +34 0034 +35 0035 +36 0036 +37 0037 +38 0038 +39 0039 +3A 003A +3B 003B +3C 003C +3D 003D +3E 003E +3F 003F +40 0040 +41 0041 +42 0042 +43 0043 +44 0044 +45 0045 +46 0046 +47 0047 +48 0048 +49 0049 +4A 004A +4B 004B +4C 004C +4D 004D +4E 004E +4F 004F +50 0050 +51 0051 +52 0052 +53 0053 +54 0054 +55 0055 +56 0056 +57 0057 +58 0058 +59 0059 +5A 005A +5B 005B +5C 005C +5D 005D +5E 005E +5F 005F +60 0060 +61 0061 +62 0062 +63 0063 +64 0064 +65 0065 +66 0066 +67 0067 +68 0068 +69 0069 +6A 006A +6B 006B +6C 006C +6D 006D +6E 006E +6F 006F +70 0070 +71 0071 +72 0072 +73 0073 +74 0074 +75 0075 +76 0076 +77 0077 +78 0078 +79 0079 +7A 007A +7B 007B +7C 007C +7D 007D +7E 007E +7F 007F +80 20AC +85 2026 +91 2018 +92 2019 +93 201C +94 201D +95 2022 +96 2013 +97 2014 +A0 00A0 +A1 0E01 +A2 0E02 +A3 0E03 +A4 0E04 +A5 0E05 +A6 0E06 +A7 0E07 +A8 0E08 +A9 0E09 +AA 0E0A +AB 0E0B +AC 0E0C +AD 0E0D +AE 0E0E +AF 0E0F +B0 0E10 +B1 0E11 +B2 0E12 +B3 0E13 +B4 0E14 +B5 0E15 +B6 0E16 +B7 0E17 +B8 0E18 +B9 0E19 +BA 0E1A +BB 0E1B +BC 0E1C +BD 0E1D +BE 0E1E +BF 0E1F +C0 0E20 +C1 0E21 +C2 0E22 +C3 0E23 +C4 0E24 +C5 0E25 +C6 0E26 +C7 0E27 +C8 0E28 +C9 0E29 +CA 0E2A +CB 0E2B +CC 0E2C +CD 0E2D +CE 0E2E +CF 0E2F +D0 0E30 +D1 0E31 +D2 0E32 +D3 0E33 +D4 0E34 +D5 0E35 +D6 0E36 +D7 0E37 +D8 0E38 +D9 0E39 +DA 0E3A +DF 0E3F +E0 0E40 +E1 0E41 +E2 0E42 +E3 0E43 +E4 0E44 +E5 0E45 +E6 0E46 +E7 0E47 +E8 0E48 +E9 0E49 +EA 0E4A +EB 0E4B +EC 0E4C +ED 0E4D +EE 0E4E +EF 0E4F +F0 0E50 +F1 0E51 +F2 0E52 +F3 0E53 +F4 0E54 +F5 0E55 +F6 0E56 +F7 0E57 +F8 0E58 +F9 0E59 +FA 0E5A +FB 0E5B diff --git a/doc/Makefile b/doc/Makefile new file mode 100644 index 0000000000..8c5beb1300 --- /dev/null +++ b/doc/Makefile @@ -0,0 +1,225 @@ +# +# "$Id$" +# +# Documentation makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1993-2000 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +# +# HTMLDOC generation rules... +# + +.SUFFIXES: .html .pdf .ps .shtml +.shtml.html: + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --numbered -f $@ $< +.shtml.pdf: + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --compression=9 \ + --numbered --jpeg -f $@ $< +.shtml.ps: + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --numbered \ + --jpeg -f $@ $< + + +# +# Document files... +# + +DOCUMENTS = cmp.shtml idd.shtml ipp.shtml sam.shtml sdd.shtml \ + spm.shtml ssr.shtml stp.shtml sum.shtml svd.shtml +DOCIMAGES = images/cups-block-diagram.gif images/cups-large.gif \ + images/cups-medium.gif images/cups-small.gif +WEBPAGES = cups.css cupsdoc.css index.html documentation.html +WEBIMAGES = images/accept-jobs.gif \ + images/add-class.gif \ + images/add-printer.gif \ + images/cancel-job.gif \ + images/cancel-jobs.gif \ + images/cancel.gif \ + images/classes.gif \ + images/config-printer.gif \ + images/continue.gif \ + images/delete-class.gif \ + images/delete-printer.gif \ + images/draft.gif \ + images/hold-job.gif \ + images/left.gif \ + images/logo.gif \ + images/manage-classes.gif \ + images/manage-jobs.gif \ + images/manage-printers.gif \ + images/modify-class.gif \ + images/modify-printer.gif \ + images/navbar.gif \ + images/print-test-page.gif \ + images/printer-idle.gif \ + images/printer-processing.gif \ + images/printer-stopped.gif \ + images/reject-jobs.gif \ + images/release-job.gif \ + images/right.gif \ + images/show-active.gif \ + images/show-completed.gif \ + images/start-class.gif \ + images/start-printer.gif \ + images/stop-class.gif \ + images/stop-printer.gif + + +# +# Make all documents... +# + +all: $(DOCUMENTS:.shtml=.pdf) $(DOCUMENTS:.shtml=.html) overview.pdf + + +# +# Make PS files... +# + +ps: $(DOCUMENTS:.shtml=.ps) overview.ps + + +# +# Make manuals for printing... +# + +print: sam-7x8.pdf spm-7x8.pdf sum-7x8.pdf \ + sam-7x8.ps spm-7x8.ps sum-7x8.ps + + +# +# Remove all generated files... +# + +clean: + $(RM) $(DOCUMENTS:.shtml=.pdf) + $(RM) $(DOCUMENTS:.shtml=.html) + $(RM) overview.pdf + + +# +# Install all documentation files... +# + +install: + -$(MKDIR) $(DOCDIR) + $(CHMOD) ugo+rx $(DOCDIR) + $(INSTALL_MAN) $(WEBPAGES) $(DOCDIR) + $(INSTALL_MAN) overview.html overview.pdf $(DOCDIR) + $(INSTALL_MAN) $(DOCUMENTS:.shtml=.html) $(DOCDIR) + $(INSTALL_MAN) $(DOCUMENTS:.shtml=.pdf) $(DOCDIR) + -$(MKDIR) $(DOCDIR)/images + $(CHMOD) ugo+rx $(DOCDIR)/images + $(INSTALL_MAN) $(WEBIMAGES) $(DOCDIR)/images + $(INSTALL_MAN) $(DOCIMAGES) $(DOCDIR)/images + + +# +# The overview, admin manual, programmers manual, and users manual get +# special attention... +# + +overview.pdf: overview.html + echo Formatting $@... + htmldoc --duplex --compression=9 --jpeg --webpage -f overview.pdf overview.html +overview.ps: overview.html + echo Formatting $@... + htmldoc --duplex --jpeg --webpage -f overview.ps overview.html + +sam.html: sam.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif -f $@ $< +sam.pdf: sam.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --compression=9 \ + --jpeg -f $@ $< +sam.ps: sam.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --jpeg -f $@ $< + +spm.html: spm.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif -f $@ $< +spm.pdf: spm.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --compression=9 \ + --jpeg -f $@ $< +spm.ps: spm.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --jpeg -f $@ $< + +sum.html: sum.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif -f $@ $< +sum.pdf: sum.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --compression=9 \ + --jpeg -f $@ $< +sum.ps: sum.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --jpeg -f $@ $< + +sam-7x8.pdf: sam.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --compression=9 \ + --pagelayout tworight --pagemode document \ + --jpeg --size 7x8.5in --left 0.5in --right 0.25in \ + --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ sam.shtml +sam-7x8.ps: sam.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --jpeg \ + --size 7x8.5in --left 0.5in --right 0.25in \ + --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ sam.shtml +spm-7x8.pdf: spm.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --compression=9 \ + --pagelayout tworight --pagemode document \ + --jpeg --size 7x8.5in --left 0.5in --right 0.25in \ + --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ spm.shtml +spm-7x8.ps: spm.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --jpeg \ + --size 7x8.5in --left 0.5in --right 0.25in \ + --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ spm.shtml +sum-7x8.pdf: sum.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --compression=9 \ + --pagelayout tworight --pagemode document \ + --jpeg --size 7x8.5in --left 0.5in --right 0.25in \ + --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ sum.shtml +sum-7x8.ps: sum.shtml + echo Formatting $@... + htmldoc --titleimage images/cups-large.gif --duplex --jpeg \ + --size 7x8.5in --left 0.5in --right 0.25in \ + --top 0.25in --bottom 0.25in --fontsize 10 --headfootsize 10 -f $@ sum.shtml + +$(DOCUMENTS): glossary.shtml printing-overview.shtml \ + references.shtml system-overview.shtml \ + ../LICENSE.html + + +# +# End of Makefile. +# diff --git a/doc/cmp.html b/doc/cmp.html new file mode 100644 index 0000000000..43251321ff --- /dev/null +++ b/doc/cmp.html @@ -0,0 +1,680 @@ + + + + CUPS Configuration Management Plan + + + + + + + +

+

CUPS Configuration Management Plan


+CUPS-CMP-1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
1 Scope + +2 References + +3 File Management + +4 Trouble Report Processing + +5 Software Releases + +A Glossary + +B Coding Requirements + +C Software Trouble Report Form
+

1 Scope

+

1.1 Identification

+ This configuration management plan document provides the guidelines +for development and maintenance of the Common UNIX Printing System +("CUPS") Version 1.1 software. +

1.2 System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+

1.3 Document Overview

+ This configuration management document is organized into the following +sections: +
    +
  • 1 - Scope
  • +
  • 2 - References
  • +
  • 3 - File Management
  • +
  • 4 - Trouble Report Processing
  • +
  • 5 - Software Releases
  • +
  • A - Glossary
  • +
  • B - Coding Requirements
  • +
+

2 References

+

2.1 CUPS Documentation

+

The following CUPS documentation is referenced by this document:

+
    +
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • +
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • +
  • CUPS-IPP-1.1: CUPS Implmentation of IPP
  • +
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • +
  • CUPS-SDD-1.1: CUPS Software Design Description
  • +
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual
  • +
  • CUPS-SSR-1.1: CUPS Software Security Report
  • +
  • CUPS-STP-1.1: CUPS Software Test Plan
  • +
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • +
  • CUPS-SVD-1.1.x: CUPS Software Version Description
  • +
+

2.2 Other Documents

+

The following non-CUPS documents are referenced by this document:

+ +

3 File Management

+

3.1 Directory Structure

+ Each source file shall be placed a sub-directory corresponding to the +software sub-system it belongs to ("scheduler", "cups", etc.) To remain +compatible with older UNIX filesystems, directory names shall not +exceed 16 characters in length. +

3.2 Source Files

+ Source files shall be documented and formatted as described in +Appendix B, Coding Requirements. +

3.3 Configuration Management

+ Source files shall be placed under the control of the Concurrent +Versions System ("CVS") software. Source files shall be "checked in" +with each change so that modifications can be tracked. +

Documentation on the CVS software is included with the whitepaper, +"CVS II: Parallelizing Software Development".

+

4 Trouble Report Processing

+ A Software Trouble Report ("STR") shall be submitted every time a user +or vendor experiences a problem with the CUPS software. Trouble reports +are maintained in a database with one of the following states: +
    +
  1. STR is closed with complete resolution
  2. +
  3. STR is closed without resolution
  4. +
  5. STR is active
  6. +
  7. STR is pending (new STR or additional information available)
  8. +
+ Trouble reports shall be processed using the following steps. +

4.1 Classification

+ When a trouble report is received it must be classified at one of the +following levels: +
    +
  1. Request for enhancement
  2. +
  3. Documentation error
  4. +
  5. Unable to print a file
  6. +
  7. Unable to print to a printer
  8. +
  9. Unable to print at all
  10. +
+ The scope of the problem should also be determined as: +
    +
  1. Specific to a machine
  2. +
  3. Specific to an operating system
  4. +
  5. Applies to all machines and operating systems
  6. +
+

4.2 Identification

+ Once the level and scope of the trouble report is determined the +software sub-system(s) involved with the problem are determined. This +may involve additional communication with the user or vendor to isolate +the problem to a specific cause. +

When the sub-system(s) involved have been identified, an engineer +will then determine the change(s) needed and estimate the time required +for the change(s).

+

4.3 Correction

+ Corrections are scheduled based upon the severity and complexity of +the problem. Once all changes have been made, documented, and tested +successfully a new software release snapshot is generated. Additional +tests are added as necessary for proper testing of the changes. +

4.4 Notification

+ The user or vendor is notified when the fix is available or if the +problem was caused by user error. +

5 Software Releases

+

5.1 Version Numbering

+ CUPS uses a three-part version number separated by periods to +represent the major, minor, and patch release numbers: +
    +
    +major.minor.patch
    +1.1.0
    +
    +
+ Beta-test releases are indentified by appending the letter B followed +by the build number: +
    +
    +major.minor.patchbbuild
    +1.1.0b1
    +
    +
+ A CVS snapshot is generated for every beta and final release and uses +the version number preceded by the letter "v" and with the decimal +points replaced by underscores: +
    +
    +v1_0_0b1
    +v1_0_0
    +
    +
+ Each change that corrects a fault in a software sub-system increments +the patch release number. If a change affects the software design of +CUPS then the minor release number will be incremented and the patch +release number reset to 0. If CUPS is completely redesigned the major +release number will be incremented and the minor and patch release +numbers reset to 0: +
    +
    +1.1.0b1    First beta release
    +1.1.0b2    Second beta release
    +1.1.0      First production release
    +1.1.1b1    First beta of 1.1.1
    +1.1.1      Production release of 1.1.1
    +1.1.1b1    First beta of 1.1.1
    +1.1.1      Production release of 1.1.1
    +2.0.0b1    First beta of 2.0.0
    +2.0.0      Production release of 2.0.0
    +
    +
+

5.2 Generation

+ Software releases shall be generated for each successfully completed +software trouble report. All object and executable files shall be +deleted prior to performing a full build to ensure that source files +are recompiled. +

5.3 Testing

+ Software testing shall be conducted according to the CUPS Software +Test Plan, CUPS-STP-1.1. Failed tests cause STRs to be generated to +correct the problems found. +

5.4 Release

+ When testing has been completed successfully a new distribution image +is created from the current CVS code "snapshot". No production release +shall contain software that has not passed the appropriate software +tests. +

A Glossary

+

A.1 Terms

+
+
C
+
A computer language.
+
parallel
+
Sending or receiving data more than 1 bit at a time.
+
pipe
+
A one-way communications channel between two programs.
+
serial
+
Sending or receiving data 1 bit at a time.
+
socket
+
A two-way network communications channel.
+
+

A.2 Acronyms

+
+
ASCII
+
American Standard Code for Information Interchange
+
CUPS
+
Common UNIX Printing System
+
ESC/P
+
EPSON Standard Code for Printers
+
FTP
+
File Transfer Protocol
+
HP-GL
+
Hewlett-Packard Graphics Language
+
HP-PCL
+
Hewlett-Packard Printer Control Language
+
HP-PJL
+
Hewlett-Packard Printer Job Language
+
IETF
+
Internet Engineering Task Force
+
IPP
+
Internet Printing Protocol
+
ISO
+
International Standards Organization
+
LPD
+
Line Printer Daemon
+
MIME
+
Multimedia Internet Mail Exchange
+
PCL
+
Page Control Language
+
PPD
+
PostScript Printer Description
+
SMB
+
Server Message Block
+
TFTP
+
Trivial File Transfer Protocol
+
+

B Coding Requirements

+ These coding requirements provide detailed information on source file +formatting and documentation content. These guidelines shall be applied +to all C and C++ source files provided with CUPS. +

B.1 Source Files

+

B.1.1 Naming

+ All source files names shall be 16 characters or less in length to +ensure compatibility with older UNIX filesystems. Source files +containing functions shall have an extension of ".c" for ANSI C and +".cxx" for C++ source files. All other "include" files shall have an +extension of ".h". +

B.1.2 Documentation

+ The top of each source file shall contain a header giving the name of +the file, the purpose or nature of the source file, the copyright and +licensing notice, and the functions contained in the file. The file +name and revision information is provided by the CVS "$Id$" tag: +
    +
    +/*
    + * "36;Id$"
    + *
    + *   Description of file contents.
    + *
    + *   Copyright 1997-2000 by Easy Software Products, all rights
    + *   reserved.
    + *
    + *   These coded instructions, statements, and computer programs are
    + *   the property of Easy Software Products and are protected by
    + *   Federal copyright law.  Distribution and use rights are outlined
    + *   in the file "LICENSE.txt" which should have been included with
    + *   this file.  If this file is missing or damaged please contact
    + *   Easy Software Products at:
    + *
    + *       Attn: CUPS Licensing Information
    + *       Easy Software Products
    + *       44141 Airport View Drive, Suite 204
    + *       Hollywood, Maryland 20636-3111 USA
    + *
    + *       Voice: (301) 373-9603
    + *       EMail: cups-info@cups.org
    + *         WWW: http://www.cups.org
    + *
    + * Contents:
    + *
    + *   function1() - Description 1.
    + *   function2() - Description 2.
    + *   function3() - Description 3.
    + */
    +
    +
+ The bottom of each source file shall contain a trailer giving the name +of the file using the CVS "$Id$" tag. The primary purpose of this is to +mark the end of a source file; if the trailer is missing it is possible +that code has been lost near the end of the file: +
    +
    +/*
    + * End of "36;Id$".
    + */
    +
    +
+

B.2 Functions

+

B.2.1 Naming

+ Functions with a global scope shall be capitalized ("DoThis", +"DoThat", "DoSomethingElse", etc.) The only exception to this rule +shall be the CUPS interface library functions which may begin with a +prefix word in lowercase ("cupsDoThis", "cupsDoThat", etc.) +

Functions with a local scope shall be declared "static" and be +lowercase with underscores between words ("do_this", "do_that", +"do_something_else", etc.)

+

B.2.2 Documentation

+ Each function shall begin with a comment header describing what the +function does, the possible input limits (if any), and the possible +output values (if any), and any special information needed: +
    +
    +/*
    + * 'do_this()' - Compute y = this(x).
    + *
    + * Notes: none.
    + */
    +
    +static float     /* O - Inverse power value, 0.0 <= y <= 1.1 */
    +do_this(float x) /* I - Power value (0.0 <= x <= 1.1) */
    +{
    +  ...
    +  return (y);
    +}
    +
    +
+

B.3 Methods

+

B.3.1 Naming

+ Methods shall be in lowercase with underscores between words +("do_this", "do_that", "do_something_else", etc.) +

B.3.2 Documentation

+ Each method shall begin with a comment header describing what the +method does, the possible input limits (if any), and the possible +output values (if any), and any special information needed: +
    +
    +/*
    + * 'class::do_this()' - Compute y = this(x).
    + *
    + * Notes: none.
    + */
    +
    +float                   /* O - Inverse power value, 0.0 <= y <= 1.0 */
    +class::do_this(float x) /* I - Power value (0.0 <= x <= 1.0) */
    +{
    +  ...
    +  return (y);
    +}
    +
    +
+

B.4 Variables

+

B.4.1 Naming

+ Variables with a global scope shall be capitalized ("ThisVariable", +"ThatVariable", "ThisStateVariable", etc.) The only exception to this +rule shall be the CUPS interface library global variables which must +begin with the prefix "cups" ("cupsThisVariable", "cupsThatVariable", +etc.) Global variables shall be replaced by function arguments whenever +possible. +

Variables with a local scope shall be lowercase with underscores +between words ("this_variable", "that_variable", etc.) Any local +variables shared by functions within a source file shall be declared +"static".

+

B.4.2 Documentation

+ Each variable shall be declared on a separate line and shall be +immediately followed by a comment block describing the variable: +
    +
    +int this_variable;   /* The current state of this */
    +int that_variable;   /* The current state of that */
    +
    +
+

B.5 Types

+

B.5.1 Naming

+ All type names shall be lowercase with underscores between words and +"_t" appended to the end of the name ("this_type_t", "that_type_t", +etc.) +

B.5.2 Documentation

+ Each type shall have a comment block immediately before the typedef: +
    +
    +/*
    + * This type is for CUPS foobar options.
    + */
    +typedef int cups_this_type_t;
    +
    +
+

B.6 Structures

+

B.6.1 Naming

+ All structure names shall be lowercase with underscores between words +and "_str" appended to the end of the name ("this_struct_str", +"that_struct_str", etc.) +

B.6.2 Documentation

+ Each structure shall have a comment block immediately before the +struct and each member shall be documented in accordance with the +variable naming policy above: +
    +
    +/*
    + * This structure is for CUPS foobar options.
    + */
    +struct cups_this_struct_str
    +{
    +  int this_member;   /* Current state for this */
    +  int that_member;   /* Current state for that */
    +};
    +
    +
+

B.7 Classes

+

B.7.1 Naming

+ All class names shall be lowercase with underscores between words +("this_class", "that_class", etc.) +

B.7.2 Documentation

+ Each class shall have a comment block immediately before the class and +each member shall be documented in accordance with the variable naming +policy above: +
    +
    +/*
    + * This class is for CUPS foobar options.
    + */
    +class cups_this_class
    +{
    +  int this_member;   /* Current state for this */
    +  int that_member;   /* Current state for that */
    +};
    +
    +
+

B.8 Constants

+

B.8.1 Naming

+ All constant names shall be uppercase with underscored between words +("THIS_CONSTANT", "THAT_CONSTANT", etc.) Constants defined for the CUPS +interface library must begin with an uppercase prefix +("CUPS_THIS_CONSTANT", "CUPS_THAT_CONSTANT", etc.) +

Typed enumerations shall be used whenever possible to allow for +type checking by the compiler.

+

B.8.2 Documentation

+ Comment blocks shall immediately follow each constant: +
    +
    +enum
    +{
    +  CUPS_THIS_TRAY,   /* This tray */
    +  CUPS_THAT_TRAY    /* That tray */
    +};
    +
    +
+

B.9 Code

+

B.9.1 Documentation

+ All source code shall utilize block comments within functions to +describe the operations being performed by a group of statements: +
    +
    +/*
    + * Clear the state array before we begin...
    + */
    +
    +for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
    +  array[i] = STATE_IDLE;
    +
    +/*
    + * Wait for state changes...
    + */
    +
    +do
    +{
    +  for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
    +    if (array[i] != STATE_IDLE)
    +      break;
    +
    +  if (i == (sizeof(array) / sizeof(array[0])))
    +    sleep(1);
    +} while (i == (sizeof(array) / sizeof(array[0])));
    +
    +
+

B.9.2 Style

+

B.9.2.a Indentation

+ All code blocks enclosed by brackets shall begin with the opening +brace on a new line. The code then follows starting on a new line after +the brace and is indented 2 spaces. The closing brace is then placed on +a new line following the code at the original indentation: +
    +
    +{
    +  int i; /* Looping var */
    +
    + /*
    +  * Process foobar values from 0 to 999...
    +  */
    +
    +  for (i = 0; i < 1000; i ++)
    +  {
    +    do_this(i);
    +    do_that(i);
    +  }
    +}
    +
    +
+ Single-line statements following "do", "else", "for", "if", and +"while" shall be indented 2 spaces as well. Blocks of code in a +"switch" block shall be indented 4 spaces after each "case" and +"default" case: +
    +
    +switch (array[i])
    +{
    +  case STATE_IDLE :
    +      do_this(i);
    +      do_that(i);
    +      break;
    +  default :
    +      do_nothing(i);
    +      break;
    +}
    +
    +
+

B.9.2.b Spacing

+ A space shall follow each reserved word ("if", "while", etc.) Spaces +shall not be inserted between a function name and the arguments in +parenthesis. +

B.9.2.c Return Values

+ Parenthesis shall surround values returned from a function using +"return": +
    +
    +return (STATE_IDLE);
    +
    +
+

B.9.2.d Loops

+ Whenever convenient loops should count downward to zero to improve +program performance: +
    +
    +for (i = sizeof(array) / sizeof(array[0]) - 1; i >= 0; i --)
    +  array[i] = STATE_IDLE;
    +
    +
+

C Software Trouble Report Form

+
+ + + + + +
Summary of Problem: + ________________________________________
Problem Severity: __1=RFE +
__2=Documentation-Error +
__3=Unable-to-Print-a-File +
__4=Unable-to-Print-to-a-Printer +
__5=Unable-to-Print-at-All
Problem Scope: __1=Machine +__2=Operating-System __3=All
Detailed Description of Problem: ________________________________________ +
________________________________________ +
________________________________________ +
________________________________________ +
________________________________________ +
________________________________________
+
+ + diff --git a/doc/cmp.pdf b/doc/cmp.pdf new file mode 100644 index 0000000000..56e20e37f0 --- /dev/null +++ b/doc/cmp.pdf @@ -0,0 +1,830 @@ +%PDF-1.2 +%âãÏÓ +1 0 obj<>endobj +2 0 obj<>endobj +3 0 obj<>endobj +4 0 obj<>endobj +5 0 obj<>endobj +6 0 obj<>endobj +7 0 obj<>endobj +8 0 obj<>endobj +9 0 obj<>endobj +10 0 obj<>endobj +11 0 obj<>endobj +12 0 obj<>endobj +13 0 obj<>endobj +14 0 obj[11 0 R +13 0 R +]endobj +15 0 obj<>endobj +16 0 obj<>endobj +17 0 obj<>endobj +18 0 obj<>endobj +19 0 obj<>endobj +20 0 obj<>endobj +21 0 obj<>endobj +22 0 obj<>endobj +23 0 obj<>endobj +24 0 obj<>endobj +25 0 obj<>endobj +26 0 obj<>endobj +27 0 obj<>endobj +28 0 obj<>endobj +29 0 obj<>endobj +30 0 obj<>endobj +31 0 obj<>endobj +32 0 obj<>endobj +33 0 obj<>endobj +34 0 obj<>endobj +35 0 obj<>endobj +36 0 obj<>endobj +37 0 obj[16 0 R +18 0 R +20 0 R +22 0 R +24 0 R +26 0 R +28 0 R +30 0 R +32 0 R +34 0 R +36 0 R +]endobj +38 0 obj<>endobj +39 0 obj<>endobj +40 0 obj<>endobj +41 0 obj<>endobj +42 0 obj<>endobj +43 0 obj<>endobj +44 0 obj<>endobj +45 0 obj<>endobj +46 0 obj<>endobj +47 0 obj<>endobj +48 0 obj<>endobj +49 0 obj<>endobj +50 0 obj<>endobj +51 0 obj<>endobj +52 0 obj<>endobj +53 0 obj<>endobj +54 0 obj<>endobj +55 0 obj<>endobj +56 0 obj<>endobj +57 0 obj<>endobj +58 0 obj<>endobj +59 0 obj<>endobj +60 0 obj<>endobj +61 0 obj<>endobj +62 0 obj<>endobj +63 0 obj<>endobj +64 0 obj<>endobj +65 0 obj<>endobj +66 0 obj<>endobj +67 0 obj<>endobj +68 0 obj<>endobj +69 0 obj<>endobj +70 0 obj<>endobj +71 0 obj<>endobj +72 0 obj<>endobj +73 0 obj<>endobj +74 0 obj<>endobj +75 0 obj<>endobj +76 0 obj<>endobj +77 0 obj<>endobj +78 0 obj<>endobj +79 0 obj[38 0 R +39 0 R +40 0 R +41 0 R +42 0 R +43 0 R +44 0 R +45 0 R +46 0 R +47 0 R +48 0 R +49 0 R +50 0 R +51 0 R +52 0 R +53 0 R +54 0 R +55 0 R +56 0 R +57 0 R +58 0 R +59 0 R +60 0 R +61 0 R +62 0 R +63 0 R +64 0 R +65 0 R +66 0 R +67 0 R +68 0 R +69 0 R +70 0 R +71 0 R +72 0 R +73 0 R +74 0 R +75 0 R +76 0 R +77 0 R +78 0 R +]endobj +80 0 obj<>endobj +81 0 obj<>endobj +82 0 obj<>endobj +83 0 obj<>endobj +84 0 obj<>endobj +85 0 obj<>endobj +86 0 obj<>endobj +87 0 obj<>endobj +88 0 obj<>endobj +89 0 obj<>endobj +90 0 obj<>endobj +91 0 obj<>endobj +92 0 obj[80 0 R +81 0 R +82 0 R +83 0 R +84 0 R +85 0 R +86 0 R +87 0 R +88 0 R +89 0 R +90 0 R +91 0 R +]endobj +93 0 obj<>endobj +94 0 obj<>endobj +95 0 obj<>endobj +96 0 obj<>endobj +97 0 obj<>endobj +98 0 obj<>endobj +99 0 obj<>endobj +100 0 obj<>endobj +101 0 obj<>endobj +102 0 obj<>endobj +103 0 obj<>endobj +104 0 obj<>endobj +105 0 obj<>endobj +106 0 obj<>endobj +107 0 obj<>endobj +108 0 obj<>endobj +109 0 obj<>endobj +110 0 obj<>endobj +111 0 obj<>endobj +112 0 obj<>endobj +113 0 obj<>endobj +114 0 obj<>endobj +115 0 obj<>endobj +116 0 obj<>endobj +117 0 obj<>endobj +118 0 obj<>endobj +119 0 obj<>endobj +120 0 obj<>endobj +121 0 obj<>endobj +122 0 obj<>endobj +123 0 obj<>endobj +124 0 obj<>endobj +125 0 obj<>endobj +126 0 obj<>endobj +127 0 obj<>endobj +128 0 obj<>endobj +129 0 obj<>endobj +130 0 obj<>endobj +131 0 obj<>endobj +132 0 obj<>endobj +133 0 obj<>endobj +134 0 obj<>endobj +135 0 obj<>endobj +136 0 obj<>endobj +137 0 obj<>endobj +138 0 obj<>endobj +139 0 obj<>endobj +140 0 obj<>endobj +141 0 obj<>endobj +142 0 obj<>endobj +143 0 obj<>endobj +144 0 obj<>endobj +145 0 obj<>endobj +146 0 obj<>endobj +147 0 obj<>endobj +148 0 obj<>endobj +149 0 obj<>endobj +150 0 obj<>endobj +151 0 obj<>>>>>endobj +152 0 obj<>stream +xÚìÏsë8rÇIŠºÌ‰öŒî´üt§çyšÝ­ÚJñÙfvçÖ$ÁÊ!•S*Ç6•üÿ±~X"H€èn$è5¦jêÙE|ˆÆ·@ƒúÇOßòýÛßò?=å¿ýžÿçÿô,~*ÅOÿÈÛÿù×?þøÛï¿ÿºÏÿü—_Ÿò§§§·kýñõ¥ù÷¯|­ÿöœþº?•ßNå÷SùË©¼œÊ¿žÊ¿üÇ×?òÿýŸÿû¯¯ÿ–ÿíÛ׿ç‡oß¾>ÃKþ=ÿãõ§öcøä²+âõi»Ý>ÜËÛ?¶ß_—Î%^¶wY¤*w÷¯ËäOj¤Üöû¸ē‰é½Ü?–KáÂC]о/ëå!"—x[ÎõœE¼r˜ë‰KåÒ!˜¾rÛg޹^òȾü\ÆÕÊÏ3s=GžJRÎÉõ-òVâÃl\ŽuЄõV¾ÌÂ%²( + ‚B¹ü29×$X,0X –€Åƒ %ƒ/° ¬(ÚMÄåÝoÙ9h6×ÄXo`å\ûhò’LÀõ#𡬼sÕÑ,åÏ\M6A!|…gi,A +Ú Ñ ê£s5Ѭåà‹+›— 9Ä`™ãÅ`ž‹,öD.1?V{àÊàŠRç\uD98æY\‰c®}HÙ8媣`Jé++D91WT蚐°ŒÒË TÔ  LÔ‹Š4ðZåªBÃ2t,OãQ ÔxŒsÆq‰±FãzX¢Æ#F,Ï%£FL×]w÷Ûí—×cy>|ðÛa0IwÅ÷_†ƒüxÂ[‡ÿîŠG’þÅ˃ŸßÝuoœ*=[ í,¸ö~ºªÛk[ça=xì.Bú±àæØ\ìPƒ–.Î$[q¹¸¡==·aMJ&³»XéԜ.K™\¬@ž› É貘ÇUùÑv‡]¶cqeSÙà՛eN¤ܯjؤ½s’  ®|²¡ÅϼJé\Í Xd°˜ÎEùØÍÉÜZ9ƹfÂ"‚­¨\Õ FÈ1ŒȕυEÛи'’ –Y¹0p7ñú¥uZj+Cg‘¼c,Òé« …«rÎX•½ÅÍÁ‘jÄ¥{.B J<—°ÒlKÃ7D=Ì:¸ÎåÛÁÉ %i=•œkˆàBf½ .Ú`Ø`¹Š¹2O”,Á W­Ç’ó ìÍПR4q‡ãÚa…„–¤8®´&1Š«žÙ#3ì€á«aÚz/8 [c¸²0Dƒ¢õ ‚«æfóuXiæ*B J‡íÌ\Y OjOjäªÃê.d‡%F®"°îBú°ÒĕÖ]È'½1p5Á¸dZ“RW\wá¢ÄÄÀ•6ºÐRVŽr‰» 7æw£\u€Ý…[FJG¹*OŠ…²¢d”+ (2$*ÇVå'ÆB ÃRåÓ©¹Z’ Wå“s! q5ÂÀÚÛ=W¢È£­ÔrAˆ"v@;-W¨jàLi­ã¡ªnè¯t\5-4”=Ùí§ž±¿ÿ.Ï´’T¹Æúù=¾aÀ +¢6(®–KH·Kh%ºÖRÕÓbQ®•–ër›®Îa‡Àà ¯Çé¹ £^ >ÜÌіœáµCrí´\MçùÖ 1£$UsÑys¥Z®³í%·NH)}¢æÊ‰Îkœ+ÑsÝ´BPf=ègŒàp‡åz7.×MÛk¼b”¾Tq5ÔÊÀµÑrÝD° ¬•T؇ô¹WŠçZ鹊÷G”Q&ß V<זByW¤çª/ŸÕPÌ1PRWF4C#×NËu¾×úü+ü’QØV +.A5C#WªçڟòáªÕr[¬àª©fhäŠõ\盽§5Rì•K,×êZ[Éu6Ž;êÊ12BªWNZ,×:{—'%WG¤(³ÔgO@• ž«x j®Š5K5†ˆëWC6Ãq®ZÂp ÖbI…Ó5 ÊFÒâ¹Ä»Y¨¹®&EZ,ip-â\9%pžê¹*֚Nè(; +\n£á¬5;c+\ŒôÅq®æ" +®K‰kvª‰@“¤¥pµ¥×qgéB™ÐdcMãº(½Ž«àôWòD@“ë¢ô:®Œ3¾êÙwCÅuQz WÍÛÃÈ0’ ¤h#!r]”^ÃUðûMÏ%s Æð2r•^Õñ6g +ÌÃ’lì¨\g¥Ws5Ì]Œ +㘁´¶ÑR¹ÎJ¯æ½ØER2WÁ^f®“Ò«¹rfæŽÀ8f DQ)ëd݅~^¹e¢IàkSYŽ­\§Öç*®³Ý Fȑ#š ”(ªT?º²k ±ÌukDŸ+?krN7Ä="àVÌµë>š>h¸Þ;а›‚]†Yw¹k6+IlºŠšô¸ Wuáiè†X!dr¸Ñ˜ÄjøCýsȵèÝJ´§•¸rŽlH[âã‹:\…’K\[°'¢@Ø¢C­I¤€]Ÿ«VrU×Ê=öEèà£ÃDïû¯´ùÖṌŸêsí¯#èùVž«áxåÛ-â;^WÈ\OÌɱonn0¾d=äª\ÝT”‚lˆ{ó€¼0ÚT¹WWojò$ ð\{–l lbÕ¹.¶*qeÝKž„‰×ñÒáÊY²Ñ˜×Ó{Šyq—KΈÚ{ÈhzªX¯üPy8Å:F—« »òúh9ÔNþnï5ùÒ*¹Ä€+“,¯ñª è¨Wo'ÍéŧñýGH©\SßËy°†ÇeŽæãvQ°2Ÿ,’+çEQÁse¼(*t.a#‡s5–r*W͍çª>š^¸ +vt6מ͕4™¿peM/\œ¥ùp‰'óg®úÃÉ<–k2ߝÎ-‡͋ó·•Ü:\[æ»uîªßFwÒ²ßmµwpœOm›.Ò,²Î-ï\·u›þà,•\×FÍÕI¿\¹r¶ûRãkT§×ćk¥äjÔûËÛ}©4fÜkbÄኔ\¹z߁¿h£¶W]nj¯‰;×NÁU UPn9Ár­4áËNŕr¸RW6|ŒŽ¹Î«Ëë51áp%C®wшﲫÝÊ-§h®š+Vqõó¡¸g¯r~ô'/ÙÅlp\ëQ®Ó¿^òHjÁZv,¥Šk£tEr<Џ¨ëdÞ7ÛnlÌ\—᯻?"éx@·‰+×à¢Zr—Ûj{‡àꤥÈ]|Ëíé71âp .’7.y<€ +£®[‘"K~­lâŽÃÕ¿(—óM +-áðì8—Ðpz®”ÃÕ¿¨7RNf™*Œj1\·Ùÿj®˜ÃÕ»¨ðTà¹b\Šã|f.ÅEußÁnßÊ#`ÂÃĞk¨Šã|f.ÝÀT5_ŽÜp ×^­óŠã|®áE…ÒÁ&ŒJ[=Ì®9·r‡Çù\Ër¥#Bq­Q\µÚ՚8JqœÁ5¼HËU;â*”ñÆË- é5qxœÁ5¼(S:"×Ã%¢"ÎSÇù0\ƒ‹´\?Œê´áò;ô¼RqœÃ5¸¨[ývGסµœm”MçÃp .Òr?ŒjÕ£YU4ñ"Ú4®þE\-š+Uý6.5MìçCqõ/Òr¹ê^,ÕMìçCqõ/Òríùáa«68Íòþ ‰ýã|(®þEY/Mõʕ;ãŠK W'T•šØ;·ãê]ÄçJ\ñ®óۋ_¾,{lÔMìçÃqõ.Ê;Š-qen¸:ù‡Ýxã¼ì‘ª›Ø;·ãê]4ˆ£*,WÚâæ)­Š«ó~(EO¢Må’/Ú÷#¢âÂùåªÇ¸äã|H.ÅÀn÷X®µW£‹ç¯AeNä’/ªúC%;s Ï\BsŠCqœÉ%_T÷$[DX®W;Ê.é"Ñ Í« ¸—|Q&°üÂeÎ=Üy䒎óa¹ä‹ +E2þW=/WÁá’.ªn»Ê·EÞÙ¹j—t‘è¶²¾Æ6ÓJ\‚Ã%_”ßö¿ž#W铫{œÍ%_T ö+Càª8\òE½H0?qÙL—Q\Ù8WÃá’/’gÆé>®Îq>ès¥”ºór=ŸÞa?bšK©;3×Cÿøšü²¡ÎæuÕ»ꝪHqPJÛ:k®|¾!çéw·§†u\y1Ô׏áŒF~™WsÛìø9QeäÚÉÔ—Pì(É/4¬®KüuòÈȵ™‚ TSë¼;Àz齺 ®u+ M?\™j« ºã “Òdúu\©l)^¸š÷§»nÝî«ko»õʺ ®Dºµ®êºQ(¾unڑÀ[v…².Ÿ«öÉUtv¬÷7ïÒqY·äsM]Õ2¿ú®òöNå“+ª›v^Ȭ©K㊯ۧoƒ8ñƕu—áòžÒߌ§©KãJ®£0qÙÄóҟá¦×VËIÚªº$®Õõq¼=™t®êöÓ5ä$mU]WÚ}tk;.CúáõÏÍÝ[ÙtĪ윑Ò×%qÏ]ÓÆ+W¢ûѧ“T<¶ÔçÊ/ƒô8„wÞ¸2]:ÎeO¹éÀd#©;x®ýåóŽŸ|ðÆuŽš¸1‘†‘¶.‰«¸ÈÐÑÒKo\—½Îûƒ:À:eR¼Ë¹¶.‰ nÙ¯qëë¢Z{þ⇬ã‹õu•\ÃÄÎEu¯G÷叫“Òkmñîm®¾X_—ÂU_ `ü`;®±}½n=é½ÄÕ0‹V[—ÂÕ\~<ºeK®±}ØByŽCš—ƺ.]_ˆ¾ç²Ú_ÚÌÒ|Õ¢¯Kàj/Žùô[\½,Ú¸ôdЍKá:;æ“[öÉÕyіL¡ú’9]] +×Ù1×'ï“ëý ì —J•l:ZÇuvÌõ©¾—1ïë9Sš\ùPÔuñ~ùäËãÿc—‹|¶—‡á¤¦ÒLrTu \ÕÉOnÙ?×­µ«^(u@Õ%póÉ-OÁõ. +‰vЌÕ%póÉ-[raß-Z‹ÁX]—x÷b멸n‰×f®^]×Ù1ŸEr”Ë&ûø*™ìе\cu)\o&˜4·õS/\²{ãb§®.…ëM2âúì-¹JÜú¡k¬.…ëØÓUt}Q7®D²­x”KW—Âçð±‰ËæÜM.ý9Õù±º®ê|²&±çڍO¿6ÝyÈJË5V—ÂUߜº7®ªÛŸûÞmz«Kájn³Q.›sˆçkãï·M­–k¬®!ž—Þ¶%ä]A ®qö¶ ©Ÿ,ŽÕ¥puÞ ë«™«õ¹F꒸r—Õ¹ìf¤jŸk¤.ƒ«´çZãÒmú¡ÿ VÑ×%qƒßxàjô +3àj¸ëQ2\ŸÊ(—Õû7䵘_ÚQ.}]—îý¬n¹:}l \Úº$®úêÓǹ¬²Þè!Ón”ØÔµ*–ïí¹Ê×ëMóU|–ïY +¶X¾ë“kz.ó떗ÉUüÓr•‹ä2/pÉe3aþ䚞Ëjb¹h®õ"¹Ä?-WºH.ólõA¹’ere0ðµü>ŽO®¸ö0ðÅ}Ïn‘\ðA¹ª Z~¯Ù\Åô²×å÷ÐÍULMÞá¾70¸@ªrÃ\ e’ºÒò{9ç*Š+[\Àa +%°ß{ZÀ‘›ì ù=Å¡­´e&=@~¯thG„â‚¥Âèo‘ßoXÀQã¸÷}ô•±mç˜Á8lc®Á9æ½Qæ#/Á9°Üè–ã‚s`™±Åš3‡}€²×ÀXcV@éK`3Ëڬހò9°ÊÜX@=€ÀXa6.@l`3°½9êT˜ËÍ"8á Kèmœ£ Jè„m®gƒú¡€S˜ „A:àª%ô¢©€ìڐ„>G˜ ‡bH}fv_ï\bAB/0Ò -Vè׋‘Ã]‡+_Ž V˜Ȑ+ A,0 +-V裥ÈaÜ媗#ˆ(Â-ôDˆ *âƒ-ôéBäpÝåB} Â(»‚-ôÇ¥€VÏP„#C̾:\ÕB")£œ· Å }ºÙHd.„Ð'‹TæB,Ýċu+_†pd8üƒ"âȇxà B8j¤—Â!Gl#´A `1Û¨«>BðÌØå +h)‚¸xí\Åú,(ÖCéÑg­¡% ÇÜ ýŽhIÂ1ó3?ú•‚+~€áï€d¼s°=z @KŽy>r’s˜y€Õø©bå™a÷H*:sˆH؇–(30Ê&ÐúyÖ9eˆιÈQDs‘ƒ²Ôā9£Ò7”AОQéI+Ò@½t>¥Ï)Mª’ζÚ&HšÔ¡9›!"li¥åڇkˆ´åhél¨vc! »ô™ ±¢g83âžö¼nų¢ †®@žâÌcˆñqCË`3Ĉ9qx@Ë`iˆf(Í4€ó`¦Ÿ¬Tԇ -g€M>kΩj-k€MœdY“½´¬6± +ÈcX]>±rz‹€5D'VFÔ +œéöÔ1GNÀY™8樼A:©ÔgB©œÇ Üϙ.H,8ޏÃtºc wàÊêd†kÍÁ…Tú‰:,c=càÔ4Æ €?R§é°ŒÖÛNÓaә_‚& :C¢Åqí±`»0ºk…äªé0‘qƒph­ ±÷UKó„ªY.´v†èuâ,øV­!zÕzìÓÝ ¹ð†èQ:j ›ÖÖãrfWŠØ ¬OKüñÍPË%¢¹-±±’.h­ ѓ&æV>¬­'BõÊXZ?Þ¹±´°öõ^†˜È,e \<1÷3–½í#×½{&ܸ¥rU¤s©ÍJÉ\"š LdöܹK0‘;¸)82‡i\o\´;¼•Ÿ'–‘P¬.t¬Â^¿¹1p1_uFÃÒÇàd}¡ãNSbé¥ +\EiW°/)áøf08Ô&[õ cœFwžÿf<[l2êR6W›qÀúßtŽ*OôÛø\‹+Š¿S;‹añcq€‰‹ÙaQt_zî¬ñ¹‘‘«ˆ¸ÿ¥ó/9k·6\"â—{”56¼OßYqYtØqœ=šÌñ…Ie˜>˜¹l:ìŒöªÿ짌ý¹K.ê4Li¯ƒ~/ÛÌæqµ¶\Mä¦ÜÝo·Û/¯oåe»}È,?mcÍå¢ÃœSþ#†KȵqÀe'‰³tŽ+¼Û9á +®ÃÌK_8.±´îBrvm¦(ˆ=$W›…ÄupÇU/«»Ð\¬•O_ºäj‚áÚ´.¹‚ÑzÜöžKdKÑxw gÑ q!Øý^ +—XŒÒ¸°DôÖ!‰kvKÄgиš…X!•kæø—°MäšÕ)¹/T®9½3eû‰Ê5c`OJš#sÍ6Ähi/t®™†1±ŒÁ5Ï#îí2¸fbÔ,%=pÍ`sM®ôT9×ÄÚÁÈdr‰<\)´ášRY©Ã\®éÀx™dl.FÚÏ$ŽËšk¢Éóā×þ9椰áòoŠü,M+.ß`ɧv\~UÑ&Yؒ˧ƒ¶Ê¶åòf—ŒoÍEΡö41qÏåcÚb™®î†Ë½,ڟ›pÂÕ +·¶øhß"7\o¶è®Ë’CW+Âé,—\ŽºìþІÆÕŠ'küâª-.¹ø©ÕªGw-qËe‘^Hݞ“‹Kæ–ʇìþ‹ë6øà"æÅÇ[ï¹ðÃõV^qÙññýw/·÷Æuê5ƒAÞm_}ÝÛ'ש۞¶wê~z|õy_ß\çŽ;žpØ>ÜËývûøúêý–“pÍPàÿÿÿârõä +äÿÿMÌA‚0Ð=§˜¥&¶ò±",•莵 ‘‚lM©n/uåfóçýŒ–‡I Ù`ò ”‰)e=Cq©Î(¬iºöå”ï¬A©ŒjõCªWf.ï +œDÆ0ZM9ùÀYQVŒ8…!#Á ,I¹ç½Fœmã?ÊiTÎÖ¯«~C±âéßû]×Þ<(Ï7,‰ãxmßãÊ'=h÷Öu {£/;“òendstream +endobj +153 0 obj +6289 +endobj +154 0 obj<>>>endobj +155 0 obj<>stream +xÚ+ä2T0BCc3JÎår +ár á +äHÉHendstream +endobj +156 0 obj +31 +endobj +157 0 obj<>>>/Annots 14 0 R>>endobj +158 0 obj<>stream +xڝVMoÛ8½çW zJ€µjɟÙ[§Y/šTk9Å|¡%ÊfC‰ +IÙpýΐtì¸éb³„â ç½7Ã<_ÄÐşF ô†W“ÅÅÇÏאtaQâÎp4†EqC–«†_-¾»Ýxäw;½~”¸ý(†YÁk+J‘3+TíCûÇ!4EC +]l„\Õ¥X·Ú…BÅj¶æ¦C#Y …Ê[¿Òj+ +nÀn8¬[üSŠ—¥ÒPð-—ªqq¬.ðQ[^³:ç J*EãžÇGù7ªª°ØãÃìoH5‹z ÙÞX^ÁòòÃÍcš}X^Á7® "JF•vÇ4~&žD}O<9œñuËõVðÅÞ..ºQ¥¥_1ýšßAGcô“¨ ôDŽͯ$d^ø£^ƒ~Î'TG4J[¶’¿’í¹vгe2vVÌð°_¤/†ÐD0³°aVœ×ý0pµ'×kÀz —·ÌìI0HÆH É$Ñ ,ˆË܏Œã—ÔÀœ–ב³Z4Ç©¢Í­y­{ÀV‘0•²u1=ÀtqÔÅ(Ù:w‘4LJßø-¯ ¥sLk°Õ¼’ø ߄ö~s9®Ÿ¸ä{tp…¶-:dH çé’åÜDá€dèýáÇBÞÂ3Š«¹=úIZ•+Iœ¥)ùXl¢ðNw׃‚7ø®VÿsË[¬ Œþ‚0ΰ»h)ãä{,ð%R }Šßï¹1xí`"UþDÛÙý·sgjš ?#Ôå%‹ž"ÁŸÜN…æ¹Å#š`§˜4ꬸi²*ºk'ì4ÇVâ¢l뜚¤°û =+ +(ÊNé'OÁ­´ÚâL`Rel–kÑá¸>«6åÆm Ï3õ<ý5x1„rû†|Ð!,&;XWž„µuÁý]z³—ÄûËÖ_ȼ5VUâVچɡJ¸{x„» Âö¸TÞj£Jî,Uþ5ˆÝåÕ7g¢¨¨W¥À«?Ÿ¥èfö-vB©VuçD¯ 'º$cUƒÉ…„ÓëÔÉ{›f_Ϊò\@·ðU±"Ô84î왎=˜†ùé|ü/ÃË£€AJ¯Yí4G”Ê]—RI©vîâsg1ó»/”‡B8n’c/—Ép¯‘à#×9}æò#ƒ*oeá¡0ç%Çîæ~~üçÔ¦~¦ŽÞ¿Ð|W~óZµô̹k?ÎDA7ç]' ˆúaðÎqÀ¡GßÇåžp'޽WâoTA›óç' 銏CT't•œý?Òw£k,B_Ã[õ×Å?/¥Õendstream +endobj +159 0 obj +990 +endobj +160 0 obj<>>>>>endobj +161 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS041Ó3V072PIÑPp VpÎÏKËL/-J,ÉÌÏSðMÌKLOÍMÍ+QÈIÌÓ Éâ҅h҅ê2‰™…ÌÀ|C…àäü‚T¨kW _)!rendstream +endobj +162 0 obj +117 +endobj +163 0 obj<>>>/Annots 37 0 R>>endobj +164 0 obj<>stream +xÚµ˜KSãH Çï| +ÙªÄãGâ7 À°5Ylæ´ãt‚·b;k;ÅðíGêöCYB;¶¨ +ÕÉÏjEú·¤Î¿'˜øggƒãB’\D'ß®°Mˆ–ø‰ëù-NmxKQŠ<ÕÑ?±<…Œ‰aKȰàòq¬H¶™Èë¸N‹\á°¬·=Ã%ÂþnXZë_ŽpþŽëó²X•q–‘´Žö;|Øçw(’m™Ö¯x$6EYa7šï³‰êXᅏï„ᱟIÜÏÙ~³?Ñ*)îMîÚª0VÇѱÕq´qñ£~eWªËB^äãÒP9ðéºp˜†‰µ^,zy¸Á +h˜àø:’ëc9S‹5„{hd¸™oøZܲ\ÎOyFdXížÈÛ¶áéyF ?õ0NZž8¶9à'w­p:SßpzÞ›ìØ¿x“¯r½~°w9þD è|Q »—–g‰”tÏ º`$YÏ-QÇ "wjøLFØ"ïã͆òü$ê!r¸›Ï¤bp–ér_}}›ZòN¢²-:94´Ê¶†fÕ8‡*†çõ²AÞã¼m ñœPéÕ»Ï J¯CéíøÒ;µÕ}M¦×µÜ|Åñº¿j5ãxßeÆcøErdýú;~?²ª….Á ­ò§¡@#«GÒàœ Ôp†jXñ´<'T“Ñûɬ9Zž4ܸT:þA8A?£ p¸¡ŒÃù‹=]Kd9ƒ‹¸JyìgéŠ~3;OQUïu‹ÝÇUgð[¥à¶ãnßÿþÈ=ñMü +&}ä4úëä7ö2Uhendstream +endobj +165 0 obj +1330 +endobj +166 0 obj<>>>>>endobj +167 0 obj<>stream +xÚ-‹Á‚0DïûsÔȖ¦z–È͵~@ƒ[‚‘% þ¿VÍÌeÞäMÄ(>a”.µhïiSïÀ ÁÖå%¶¦€¿­P]› ªQcß½æ°ô£â4t2ˆ.hA×þNÙOÊþ–MÌξÛà,QfÑVžé:x:Ñr#vendstream +endobj +168 0 obj +122 +endobj +169 0 obj<>>>>>endobj +170 0 obj<>stream +xڍ“OoÓ@Åïù#ŸZ)5±’”mZ)`qèe³Û ë]wÿ–OÏìÚ`)UŠ¥hå7ûf~oü8Ë`A¿ 69,×À»ÙM9{s ùʚެ7[(«‹%Ü ‰ð)Ö`‡Ê]–ߣ.Û º«å*Í£2Í`' r§Í3Îxî¼ÁA¿‚,õù&]ýã-Xí G¨ƒ‡m™”pDè%ãXëWÕß+¹6m¯U%TNƒk©H×îÄ F­}¶;Žn‘Z5–TÁŸ\³åÐåÃEby‹•—h’9$Ü÷–þÑñôáJ ;&™u=sâH}„kAË + |ý¸ÿ›œì¦öëЎC(íÎ|ñ‰#͔ê–Æ ä#Q5®M_RÍÓÕ@5‡b€‚°¯â,&’vBYiîCj§ª Ö¦c.ž,Th¹G:Pïû ìÜÌáVGÂ_ðÑÓt¡Üþ«Á%¨Z4Þ0­^ìÊ7;æîU@ÂåZ9£%è:Ɇ{Úåà@øÈËB1DN±ÞŠ„"ü³éˆí,‡3˄vÿˆ’!h kI©&,ù2©ãYàL…RG)Re:äëÇn$>° 'v~(¦M!x.}E¶Ñ2(N­pس -eï÷ïàmŠ”(ůG1^p6ÑÒ²÷Á3cÚNÄW!°W>ãÕv‘^“ˆÞ¿ ç»röyöUDK­endstream +endobj +171 0 obj +540 +endobj +172 0 obj<>>>>>endobj +173 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS041Ó3V072PIÑPp VpÎÏKËL/-J,ÉÌÏSðMÌKLOÍMÍ+QÈIÌÓ Éâ҅h҅ê2‰[éY*€ùÆ +n™9©HAò®!\\ÍZ%endstream +endobj +174 0 obj +119 +endobj +175 0 obj<>>>>>endobj +176 0 obj<>stream +xڍVMsÛ6½ëWìä$ÏĬõËîÍuۙ^ÚÔV&] ri¢ JÖ¿ï[”,*t2¶G\¼Ý÷öíÂß&3ºÁόVsZÜRZN~[O~ùóžæ7´ÎñävuGëlº¤µ³ÍÖ0=qm] ÏΦ콮^®ÖÿáĒf³öÄõü.™Ë™z¶yØ+ÇÃÛé‡çõӇÍùBC[&ßlKgÄ;v +ºdRÔxvdí¸Êð¯5;ÍRãaí,@K)ig‹6í^‡‚BÁôøåó3ù®„äXƒ‹5à<ê*•®þVW@ÌTP[å™"ˆ­˜l±rkŒÝƒ-ù û_%éüÈÞ&KÉ:KH¾š‚iO©± &µem8HfoM´­%ÏGÛ&Œ[œSiÐ;Ä,Ïcjè(,6ӊ÷$_BU•eZà• +¹u¥’O¤vJÉ6Wq-t{Ø¡˜Ç>Ö­/P~#渏kŸ´Ž¹§ÙªsÌbފ¸Lfôhl•ëTõŒÏ͵Jn%ôkÁÒ°pV‡0tœ2d@C•RTÚaâ[¾ßVۙñ¶>ñ·†–‹ «BÁ%Wa¤¿Û´‘Ç­Žìœu#­ûR‰À,„ƒÁ(×f¬‡Ã`¼Qí[âÃǯ1—í„>µõQ˜n´ÐWÛ¨f¼!3ØØ•q^ÔI¬å85§ÒÁ¶ÀR¥NŒYþmlE(ÁA5±Êf)Gd{¨k£±ä|×¥ÀTÙ„?·[ä}2ܜþÊЩî´e Es‰“Û*}ÔkÀ3ªWªŒ?RÖí—VCØ ü‘Ö7©ìÞ¼1I6üÑtŽ ËÅæ+Uc¨£A_¸’Q/=­3È*Ð-I¸+Ž=p%‹Â%-ڂ.– 3×1ëx¼§ô’þ¶?1wëKÛ¢ôʶ¢}o½\¿ÆK°¿´$^Ÿ/³=ŠþEŸ-hÜÍ]•w§ä÷‹Ÿø§gyw“Ü#‘+ùüÇzòïäd)ú´endstream +endobj +177 0 obj +930 +endobj +178 0 obj<>>>>>endobj +179 0 obj<>stream +xÚ-‹A‚0D÷ÿ³ÔJm¬%º3Aý bij Õ÷—ª™ÙÌ˼7 äKd‘Ú´gÚ+î T±‘(w9ø±B}k®¨ƒïœ£ž\ð8i¯­ŒŸÐôÚ¯ùIÙOÊþV•˜T%¾Kc˜ï½ÁżB\¬Z3ŽÎÛô;0é#Õ(Óendstream +endobj +180 0 obj +131 +endobj +181 0 obj<>>>>>endobj +182 0 obj<>stream +xÚµVMsÛ6½ëWìøÔÎDŒ()þè-Îĝ^2n¤¦Ç .-zH€@»þ÷} P¦$gr¨}°I,Þ¾}ûÅ&9Íð›Ó՜—¤ÛÉízòþî†æ3ZW8¹¼º¦uùËZÙ*<+Çô•Vžý¯ëÇh™_%Ëéb™Í£m–Ó7v¾¶†¾ômÁ®6ÉzIy>Xϯ²K±þô×ýŠzà‘¢°qÌÓN¹@O€‰äoUà’Šê€hKOÁ’ãαgp—©UÖ½£¶6òG™’:ôV‘²p€ç|‘x&hÿ[¢6£a¦óe¶ƒ—E´,mfY%Ïòlö:°i¼»å ¦}غG„¯6%èÖUbQ]Ǧ„@1€†C@´·TÙ¦±ÏÉDоnÊAŒŸ \Ä{§hùYâéÓ·y£:¿±jOl8©_YGŒÜ¼Pð¢ÄUmT³1¾‰ÙÖ£$"UšË]P£t ±_<]Dç:l"Hɺnᡳµ ^2Þ(@zhé¼¶(ó¢<åßg߇xTH¯ÏŠðY¡nôF™ ^@?H™Vªo ‹Á¿~Û¾/¦þÅnq ·,d…ÿ«¤Èè +·þHUUяÜÝÁ—ìëC¶¢Ø/83©â%×#pH×4ÈϞÔIØœl’† +Ò\³H3:DhÛvÈ7/°H|¸Ü·ÝO¹M1uëäøœOòPӄŸ»Ú¡çbyŽÂ|Uÿs±]±¶ðû#c¢=pçlÙë e}þF~D™‹§Œüýð›—þWólvBNǃSÆoyØ]Ú¯‹Øi‹a]Ìé÷4`pïìžØíŸÝ4õ•Jl4ž¤s}¯5{_õ Êu[¹å¾Ÿ‚³}ÑXg]Èè#lñˆÆ“B(ÿ˺J쫺9ô\rÂí°œ”(V8´2Ï1'z±Š“Gl|ï†aâmïô-%$ñXfÇ{užjüC¶ 5öÉ[Ût§RH†{ªRèHt¡Æ,K+ÇÆþ¾»).è¾Qæ]<˜®Ö÷S©ºSÂ/"û‘BZaæÓjý5.åW)Áó0:Óüq:¶©Âô~+ØåöKãl°Ç)8ºQŽñâ ۇE Èð3•µ®.úX¢X+˜î2Ú§òq¶,uÆø¨E¨m9žXÛåx‘Ñ{b$ ²Có °'öe'ɦ‹µSÞ_΢ˆÀâÀX„ºÞG¿¸Lџù$[^ϲØÁâFž?¯'Nþû¦Yendstream +endobj +183 0 obj +947 +endobj +184 0 obj<>>>>>endobj +185 0 obj<>stream +xÚ-‹A‚0D÷ÿ³ÔØo-²–èÎ¥àG Á@¡ÆëkÕ̬^Þ{C}ÆÐEúu¤¥Õ¡3l Þ¹Æv­`o T—ºA|ÛwÏIb<Žâ¥s£óõ ~iï”ý¢ì_±JP—&7øƒ&´ñ%“ÃÙ Nf7'coéDoC¦&Kendstream +endobj +186 0 obj +128 +endobj +187 0 obj<>>>>>endobj +188 0 obj<>stream +xڝ•ÁrÚ0†ï<ÅÛnl ÇÄ1‰3¨cg¦WEÞ8*²D%JŸ¾kCi2S+$ƒ‡ÁÖòíþ«_럃ÎèÃ4ÑD3¸(_æ_!9ƒò‘V&Ó”Õ§s¸RÆ9nwŸË]@<Ý Gã(éB¢J´ÛGL ŽÉ4š´é~e|X¡|Ãxtø3Ó¬7-(®ë ¯1z; _s˕BÕ,PWR×`,X(ŸÛ›Š{±þ‰kRý =pºÀË&œP®1T½Ñ8Üò]«¢Ùh)¸—F;”F£‚ô[D ~k`mMmyãBéZÉ?¤îšœ+ô!UTn§JSùÆ®zÔE¯-Ñå%ÑxoŠ΅5zðÅy‘æy Ž†º!h¿ +ÏuÅm©©I|®é»éÊ¡ß䞶¤¢Ó{Vô§JI ¡îoóïÀ¬Ô¾ík±s›3+Ò/¬š±âîö?Åw кy^¸s©J˵{Ėf¼Fh×lxµèç]ãV¡÷CÆÅª-ôÊòõ“‡F³ôìƒvj†öÖ¨SSÜ| ōy8Ÿgå¼ޙ‹Ždº–ɐdŒ’»̍A.c'`f;aóâî-bw"¸:šÎÁ­¹–¿»…{Á.ûÙ R~lë%Ç&ˆZæË¬ŸµÜ¨v>U’ñ K.d¿Þ<ÃA§1Úæ÷؊…3ã|!¬\ûºÑuÂ},–¡émŸ‰´Dz¡R±Šq€U§@iiúÓV‡¦Áì%6™ýï/_éãé8šÑP¦…8ndåàÛàfØ9endstream +endobj +189 0 obj +602 +endobj +190 0 obj<>>>>>endobj +191 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS041Ó3V072PIÑPp VpÎÏKËL/-J,ÉÌÏSðMÌKLOÍMÍ+QÈIÌÓ Éâ҅h҅ê24 šë)€Üsò‹‹‹*A®!\\í€#endstream +endobj +192 0 obj +122 +endobj +193 0 obj<>>>>>endobj +194 0 obj<>stream +xڍV[sÚ:~çWì0}H[0¾ ÎK)I¦Ì´™žIÎC^„-°ZÛr%¿ïJ2Ä;C FÚë·»ßúOÇÿ=ù !Ê:_—ÁÝ|–k¼Ž®a_}…Y¾ÿ蟒 šÑ\ɏË_(‚çYÙ¾íøZz™PI!²¢¦…à[Sˆ©",¥1°|ÍEFã9àGòRDÖxöBi$!æQ©Xوç +8:ôìuϛ}¤,§dBÒVHQ¤ *údflÎ>®»<ÆΩf?ŽÍr Þ¨Ê2ðÐ`âx°°ÊwZù(]gX ¢è=É0•sÌFZdŠ!’“¬½‡µIˆ ‘¢B€2ÁÃï|ƒ‘bV4—¥Ð¨gB´b)S{›Oc*àá~þÿ´Œ«½T4“Î!ë^ÃKX®±_—y¤!?D“-¢™}ÁHS·5t¨« ÓûżÏ^^ì)âüÆu=Ytú\%e—åQZÆ´[ò®Ï¤ëœîÕAO7õ¦iÁ{ñ+´IJ¢ä¤­û + P¢±Ü°­†#6…ÒªúY«ôÌSQŠ‚c'bî9Qº.V¤«ñb/Ø&QÁ”E:]ô”s…Ï=sj<‹RÅfFé„ËêÉÆ‡jo< ºeÈú²Ú¬öÆÚìqÝóøCÙL,„.Œ5‚H}?´p>¸Ža øT靝Ÿ ÜP V¨ª´&òjÄ¥s‘…Ù9o<õ}×uu·Dî±µ×jG°?ËHɞá#.›Œ d±¥ñe®tgŠ •(mmz ±ñ,óÙÒéá,q„5ÌA2 U“IÓC‚Tà# Íi›úEEnÐek2wG±kIZk¯”석a´lUܵ±±°»¼TšFã&›µvƒî÷ùìö~që¨Յ]Âô%¼Lc;º+Ju§™É¶Üڜ46 m_˜¯_ê¾Ì˜4ƒ€“ŒlÐL‘R"m› /6lCMM.ª«þ›*•OÌ"€ïÇiœ¿ÎL›^³ë6é0ôB¦ IC(xdt7‚mqà%S·qئú§é~Çy܃DìS]EßÃ~à!Ñ=,¦çúÈ1à <_®÷ü‚QÐÝ 5ŸÂ'•…ìkù¢Ÿ.6m +OOOH”*&ƒÁn·sZ5ÎMÌ*6¸¬t~ôž¯0“þ ¿xÎ{~ƒ†ÿ®FРœk N×Oß°çð°€V\)ž]´ƒ”ЯNï.!œãÃÕ)7¼/!y° ;çugU£‡|­À«ßÆÅÆÂ+Rí`Öé!¦Ú¤2eö Ç_+ŒH%DŽ|AB¤¥‡”K9%¢îíPµx®_ww8ªö|ۛi8 +zWËx¦‡o—;QQJ-endstream +endobj +195 0 obj +1072 +endobj +196 0 obj<>>>>>endobj +197 0 obj<>stream +xÚÕV]oÚ0}çW\¡J-„| (l}i RÚu*{CªŒsC<%6‹6í¿ï: В~îeZ@ÈØ÷ßs|áG×^}ûæiãlÚèN\Â4²3ý…GÝãÖô{Ŏç:'vŽa,CP4.æS[ïڙîdÞÀbu¬øvíÌña’Kn„’zÕ³Q„¸N¿Šr<¸f©‹2¨žWù²ab`°HԜ% ¹Z"è˜% Ì8[ +ÃñC˜5/Ô4ºÙ†bÄL9ºU)š˜ö'i + wf-˜ÆJ&ë ½À)(àŠãÒn F¥iÈòäі†ÒοÝ܂³ˆq„DÌ3–­!Ú CÊ֔±rCb™a$V𠲐Ò÷6NÔfœi´Lx¾Ô;6›o£²ü*Ùï;½gõJ¯Ë"OXFZ5µaFð&0:iZØí]¤ç2Čr3Ô´jeQ´Þ+™ + ՝©ª,†¥è4ÔÕïð±ìµ¦ð‡%Û>\(ž§(muJ¾ÐcFÚn´Þ’{$3W©Å€ñ ֚gbN¥Ð¹0Sœà6=T¨ÛÅÔRi-ætÔB.sC‡š +S',"Òl=kµ éžä©ÜØÄ{–ä¤Û~( A/‘ :!#•¥Gˆ!†£’ëΝ¿Wêòœ?+ÕgG³Ö!tà\¥´3ÂN¡œ_ÍZußց®•A=©$¾`s«ºWÚ¶ìˆE"Ú§{ _h÷KyOÝb… &*é·Áu\ø|JчGnߢmð·J<*Øâ]Þ͇T¬€V…Õ ~í—ŽS£š<“„HGòioõ÷+7ZWÔÈ*|í> ÞºÏ*ˆ©[ßk:øˆÍöo³·L|ÄtiÁâ/-W%ÿŸ†£{SëÑèŸøng¸§ÏûíçÖ=³OèC.t·.ìNNªNñ9€þ0(U,#ϕŒÄ"ÏJ寘d ,úä&aE§u¼^ŸÒ:ßµY^ÏNö¼¡3÷Ù?ãiãkã‘m•Äendstream +endobj +198 0 obj +767 +endobj +199 0 obj<>>>>>endobj +200 0 obj<>stream +xÚ¥UÁrÚ0½ó;>%™b°“4§$Mzj'Ðž2“‘å5¨µ-W–Ii§ÿޕ„ÁBÓépÀ’vßîÛ}Z}ï0¤_ÓFð¼w=ë î†p³ÔìDçô•œü:}í ¡ ýs³ð}oO¡®U'«ÇÓËÎéo³Ü]@05Ð}ÂîBsríá S‚ÅV«±±"ÿÑЏÖV~Y.й3C¬Â©1ـÀ³Ð `0ÏdÌ2¨¸,ªË2ˆ8+…f™ø‰ ¥êÍ¢j<½7@k¦w×¢zÐLck5÷O†#ßò˜-d‘­p,µh šÜAÕY+M†7Ÿï@UÊ8B&bÅÔªÉx¹e²|y]iòœ‹ÂQ#„NðRa*~€Çë²ò -óÑ¥æövè9&ð¾w“¬Â2£ ˆWÖ7¼:±™š×9Úd‹.QA)«JP£‘0¢&jQ&ù~‡2ùŒŠ³ +U]$¨ÈD‘[Œú‘Ê URž¦¾OË ¡NjtÌtë¸á{U¬Ö¡w(«]ž.K*:ƒJ֊ú”Šv#ä™õñ*ˆàž¿'ßðÂ7ò áä¶R¬©âß2jx“ՁXÒ¦ƒ%S¤INÀŠdk(òAg¤ÄTf¦––.sbbþ­S¨+®DL—Ëʳ‰ÿÖ%¹ýpì‘va§ö—08s x­” dªBw"u—àlÐ ¢ÕŸãL¯!^˜"˜­Ê£dò· rE%ÔËۗàՂ4ðž´¬,‘¬7háX8ìNõ›ØäMWÕÖe³ÜΛÄ5ùqY†ŽÛ‚-±«ŒŘM›·qK0}Yƒ³î‹`zI·韠ÜàK%ÒNÉjï!ÙSÊ:´˜`†ØS«Z—G$ÁƒV5§Wé¨.¢×è¢jþS„sLe˜X›1çR°Dv¶Ú29_sƑ?‚h2Y×ÖÖÿF©˜×ÊJ>°‚ÍÑ +à>cV:}ç֟†ÃƒOôx:&<{LÌÆí¬÷©÷?ðendstream +endobj +201 0 obj +789 +endobj +202 0 obj<>>>>>endobj +203 0 obj<>stream +xÚՖMoÚ@†ïüЧ$ +2МMÕš¦{¨ ­×vc{ÝÝu(ªúß;»kdò©J•*"×óξ3óŒ”ôña˜?žwÎÃNÿÝ ü1„+zLéG|tîÞÞ +^åXh¦SQ‡ß)r ¾ï"{ɉ¼`<¥eÅu%T² v‡À€‹ÜÈ!Ê¿…”â”i̶áJP´N°Ö+b@“+Çä«Î4 –á¶$gXÐH»€û=Rôj“`w´/¥P*5Øk 6®ÒOßšUˆ¶náD^¦Jï‰ÍŸ¾póûޘÛ_ô•°fìj7Ó~| M¥Ï®Æ®©á—ù·SG¶]V-Ùö¡eØ5Ü( Qù{Šþ»i]OÊ3ߪ-„Ë*]Wnð‘l¶ð«ŒÙÞôüq@¢Þd80*?0‡£é˜ÎOüßpv>wþK†Œ-endstream +endobj +204 0 obj +729 +endobj +205 0 obj<>>>>>endobj +206 0 obj<>stream +xÚµUßoÚ0~ç¯ø–§Ò¤ÊØÖ_R¥MêT¦=Œi2‰^ÍâPÔMýßw¶C) LÛÄøî|÷Ýùûì­}b œô‘.ZgãV÷*ÂãÜZú§ô/;zµÇßÉ1D<°ž¹:'‰u…CœëŒ?ôl@Dî(ìWaŒ ®\•¬ZùØ⸊M6ò”0zU¤)e„™3²¬J!ÅOŽ©Ôé96ÁZ”s¡¯TjS”7i!¦åœC/yÁ¼kʅšÖ¹.<ÃôÁ" ºñIèš`˜zµ„Îa"w%^{˜Ûat’^سáÝãÍþ(<µã\rV¸Â.XQ°ªL%9ÖŸÏ„ +ð±³[Y’ØÏ‹6`r$ðÑoha¨OŽ\ÎI]l,;ž/Ñ×I{Ò¶»^¾œ´ë•<¤/â+¥¾¿_~»¾x9ª•ß×Ûg&JX\¾µtÎԌ›¿i&Óµ_ Tÿ¯_@äØÄRÛ/ž÷½7˜œÝÕgR%"Œoÿˆî9ª½ùä|99Š tÍûˆõ\HþïUF»ÂsÊL†á%¸-äVœ»‚s!õÊK³ï9oÅéTéthÀU*µqb¢¡±ôŽ“(½b՝@7BTV6ŠV + Н!…â!ÆóJìIjÖR굩©“XW”6ÃÎ^°¼ä^q>3S„pͰfIvS!´[ç +.%­²Ýĵê“ÝZn°²Ò7Vj”ɪ¤›ßáK£É|¡JˆºÇx¯õÒV¸§+¤¡!4%Iš¼)4õfhdzJ»î™\qZzA§Fwáp8Ü#Ð=ٛŒ£(:(ª_{héotJÒ$ö“Ÿ•üu)ìrÐ3Úa½¥IÞq§¿½§±=¡ ÓÁ+\n©3û#rú¶ìœÆ‚'š6¹F/ —2¬‘à̓žÞGaù¢x:ª—©™´÷”Ô1•³tŽ e„Í£ÉxÎV² `m‡‰ãË<»Èü©t¯N« Å4¹ûTW=ÿtsKo²ÊÅlåŸ@|`ŠÍܸp#™Sy'îõi[gDõw¼7èQ*gŽÖp9n}lýJÈVªendstream +endobj +207 0 obj +817 +endobj +208 0 obj<>>>>>endobj +209 0 obj<>stream +xڕRmo›0þί8åS" ¥I«Nj»TšÔIÙ¶£ª8‚7°3¿µÓþû΁-­¢T lŸŸ{ûéEÒA)uy ìóÕV)i)ünïI’%^*Ù<ˬ¦ »œw!ƒçO’.D b†­ïç+M*àNÊí鼿V(p‡ +r)v(8‰€Úy +ië‚ì–L…lE˨UFÂ*éVÞl•Ü!УX[T¥T 9žARÀá4BYfC¦{¤f_Z¾…÷dô!ºo/!t«ïg££îàüž8•éë2ëG!NÎz§›ÏËÜHQòUl߆L° ºeÍöÃäGɔÜü³Iè¼¢™3&qL$á¿ÃÊ<Öèn©÷Ñû¡¦7nendstream +endobj +210 0 obj +534 +endobj +211 0 obj<>>>>>endobj +212 0 obj<>stream +xÚíSËNÃ0¼ç+ö›Øqí© Í QH8W&u!¨‰ÃÖõﱛ¤ñ¸c_,kfggÇ~‰Ä~3P e]ÑY6C±¦RÊ@ªŠåÉävåÞ4(ÐnÖîLkÑAf±>-ž=qŒ"Q‚ށ$"¡Uàô¦5è]6$ßmœ§_C)6’!Ø£ÖÔ8í.aj6%VmÓ7!ïÉ +y8“ÞçãO±pÓ$Ä¢º'ýó_þ‡¦]l.fEt½ 4ïendstream +endobj +213 0 obj +345 +endobj +214 0 obj<>>>>>endobj +215 0 obj<>stream +xÚ-‹A ÷ÿo©‹V(Úº–؝IµxThj +(¡ñúŠš÷V“™'q°Ï8Du´S´j·àʂ¯ëR ©ÔmyîzÈàí8ÌQ§1x´×ƒqÆ't“öKu§âÿªbŠª)7ø‰>ØôÒÑ@Å0_&ƒ“y„˜Ð†è²¼Wt¤7%*Oendstream +endobj +216 0 obj +135 +endobj +217 0 obj<>>>/Annots 79 0 R>>endobj +218 0 obj<>stream +xÚ՛MsÛ6†ïþ<¶‡2Ä óQgzh’ÆjîŠB;êXbBIÉøßw]€Fr3ìÌØ‚W|,¾Ä¾ b™ïW¬éàkވ¾Ùì®^­®^\›†wÍê¶aÊ4ý ›Õ—ßVëÏ÷c3Ý6¯§ýqÜ¿¯þ»úsuÕµì7f¿}|kM/T«›]£[N¯ï›Ë>{û|×¼¸V cö¯ÙÃzx+ü5Ö<ŠÈ]ã~$|Œåf3}-ˆ+€Ã/Úê¿Ø£ç 'qÞöp⊷Štâ/®%É×±ç"VÇ6£dÙÁ±Ìj#)N¨¿¾ÀUßÞn7ëãvÚ[¨àˆŠt-iיV.Ú¹¨UŒu­DÅxI1âè„I8ö¤›‡ÃqÜe&r8älùˆ~*»¸§½ÿ1Î?¶ãO‹“¬5U_P\™Ô$ÅqWf€±S\÷ÖÙùœ€(N¨7Óæ´ƒiú8/FPJP7ú71‘ÃïžXv–µ]՛ÅvñõâÁdÕС=ò¼Éz˜20š‹zÊÇñvœÇýftAšv¨ÜkEaÒª>X,.Y¬Rú"/Z¬'jŠ%D +éõ¿n2—$ Wuö¢Ä,ŠËgÂbÖ}ÿ´—¥¤ºÁœqY…KS§uɜ=Gwà* ‡ÂDzü:αÃá֛­'0Š̋í3€W‘"ol€ïdîõ%«`.ÅEÁ(Å5ä~¨c\oaùø(&:t×'wÌ¡°ý½Þ¯ïF+·[ƒ˜¶Êµ*L÷N ·ºIéM¦“h²¢l2D„Â%S"…‰ôf;›ã4?<΋vòVûHqÞçÓæxšÝB[XûyúËQP_š.X<‚ÙHÃÐBEÑlà¢K õMYø2…Y«t0F\ª)ÂíõØËP¬)žëT–)L¤Oã|È.¿"€Ýë¬ð1Žâ„{wÚ}çPÐ+Øl*I/UpXD†(QðRMò»A)SÅ õv܏óºf‹-)&xd±n)&ú¢*Ö$ρۧ3…‰´GšQBT¹yYŒ·ÆÓrƒH0Þ¡\ŊDÝۂS0ŒòÂg)–-GÜP¿«ƒ³ÄÁ…zÄ u½^æZ ÁI/R…‰óö~:ÖóƒÓÍ´¬ö~$+´vø@Í4 ¥— + +×Ô¾z™-(ÓO,x?ý\ؓVã¼s•˜×Y‰ËÒõÔs§Õ§]1ÞSãée¶ „CíL¶˜DqÚÌÓþE“²¶Õ#Ë·´¸À.³Ë\ÊWIݨWÙ|e –g8 {Îëé ”„̆ÆÁì}õ ãré‘}?mçqéôª­gïŽZ3œSCÌN\LuN­§W…T Ñu¸"…‡_Ü7 ÇÛ b–wÐZ´oÚÖ´sšÑn@à”¶¡Œ]ã€Îoà0¦¨žÓ=:wͺEq‚½[ï–Q Kì¢D]ç¬Ï "‰:†>h%â%‰ˆÄz»šNPgé£Qƒõ©”*%0ÓØWsɅƒPp˜Fß,”±PŒ½éJ(Æ6ßiïvwµ<0q®•ÌÏ$6PÍ^l„™d{^­b²y&[‚¢8ÁªK¶’D=6ªð,ú¨Oe%꙯¼˜lž„É– (Î}šáɒM’M~a,h%›ÔÞ­E)݈cìT¡°ïGÇ¯Óܚê+|ö¦8›„ ֍ƒh6 å­[”ŽH”p1Šâ{v DZمgÁ£^—•ˆ/Ӎ8”n1ˆâü¹%[G­2—]ÔײÉÖiïÖ²”lÄ1¶›p(L¤OëykŸƒ>Ðm¼¬-ݘÊO%#ƒu™8·QÞ¸e1Õƒ™s0J¤êò¬ Žfa­Y²ÌÖÜû¶,¦a0ËbFyúÌX YVxp£×~¿Bàëè±iãýYRŒ Ú.Ÿc ³zø†¹ÅU¥‘–æRÁªÝë0‡¥—*¦A0½b +FŸerIÖՒ%ËjɽO«br“+æ`”HÏ(¹¸Ž6WtòÀ7ޑû҆Šö¶n ³<¨Wí½™“*œb·ü!MÛLÒî°õ†v‚÷Àtú”Wx<«ùp¿Þc~hPáû[RòŸ«ÿ=džýendstream +endobj +219 0 obj +1953 +endobj +220 0 obj<>>>/Annots 92 0 R>>endobj +221 0 obj<>stream +xÚ՗ώ›0Æï<…í!Ä6þƒ¯›6=µÚnè°»$JBKˆª¾}Çö8˜H‰ÕS’ÝÒìÀæó|cø1BᗑBÙ¿·6{ª²ùÒNIµ&L¢´ Õû‡ª~Ý5¤[“E·šýpøXýÌ>WÍ)ìÙÃË¢yN‰*d^’–˜2WìÈÊÒÏ.è7d¾„1{?Íá\砟r•3rñ.¸%¬§{âm0°ou»Ýo,¬(r Ãÿòþ0™sxü Ÿ °.+/ F‰xJ"$1¥r1EaaŸº·c [Ûno™pÁ”bêbM°  5PKK¤È °$èaÅh.¼:ú²6Ñ¥-)õ9ǧi±«‡Æu|Á@ñ›·Ïÿ(æúIÛ)ØO>ûI ±W,i¹@ò–› 0°»³\J¢²€cÈ‘Deh©¤áÇn¼x0»Ieܔu¦ðÁh7©i˜×eÂn¢§Ÿ$ØaC[Œàwg¸d'I5oD$uÞeÚlHB³Å(Ì#ìáÌ& +7y}.ˆ$"Lð2m7$¡ÝbæöH†+¨›±Þ.ˆ ç¶ §ŽI9ÚvɄƒi$-º÷ƒàåÀÜáæfӉ~b:Þ.ˆú‰á€2iÃ!»)a¾¼·^J)C‹ñEÜ‘2Tä'm’NCã¶m&(Ì#l5üݹ~bænúéŠLqS„Â:úK›/%~œØ³J|!¼,UDKÐe‚Ã4rVÝzøS÷͏XCû²5ÁaqUßíWÚåuvSá§ÊÃ:ú<â^š_]?\)5N–çO'Œ´e×·nÈțµ3öÆBèé´Ä5ž¹õá‚ùm•,~<¯ìïz»9öÎíäk½¯7u?yÞÕÎý3&Ìә殲í%ûžý†(´endstream +endobj +222 0 obj +700 +endobj +223 0 obj<>endobj +224 0 obj<>endobj +225 0 obj<>endobj +226 0 obj<>endobj +227 0 obj<>endobj +228 0 obj<>endobj +229 0 obj<>endobj +230 0 obj<>endobj +231 0 obj<>endobj +232 0 obj<>endobj +233 0 obj<>endobj +234 0 obj<>endobj +235 0 obj<>endobj +236 0 obj<>endobj +237 0 obj<>endobj +238 0 obj<>endobj +239 0 obj<>endobj +240 0 obj<>endobj +241 0 obj<>endobj +242 0 obj<>endobj +243 0 obj<>endobj +244 0 obj<>endobj +245 0 obj<>endobj +246 0 obj<>endobj +247 0 obj<>endobj +248 0 obj<>endobj +249 0 obj<>endobj +250 0 obj<>endobj +251 0 obj<>endobj +252 0 obj<>endobj +253 0 obj<>endobj +254 0 obj<>endobj +255 0 obj<>endobj +256 0 obj<>endobj +257 0 obj<>endobj +258 0 obj<>endobj +259 0 obj<>endobj +260 0 obj<>endobj +261 0 obj<>endobj +262 0 obj<>endobj +263 0 obj<>endobj +264 0 obj<>endobj +265 0 obj<>endobj +266 0 obj<>endobj +267 0 obj<>endobj +268 0 obj<>endobj +269 0 obj<>endobj +270 0 obj<>endobj +271 0 obj<>endobj +272 0 obj<>endobj +273 0 obj<>endobj +274 0 obj<>endobj +275 0 obj<>endobj +276 0 obj<>endobj +277 0 obj<>endobj +278 0 obj<>1<>2<>4<>]>>>>endobj +xref +0 279 +0000000000 65535 f +0000000015 00000 n +0000000228 00000 n +0000001794 00000 n +0000001868 00000 n +0000001946 00000 n +0000002023 00000 n +0000002102 00000 n +0000002178 00000 n +0000002259 00000 n +0000002317 00000 n +0000002369 00000 n +0000002454 00000 n +0000002506 00000 n +0000002590 00000 n +0000002621 00000 n +0000002722 00000 n +0000002807 00000 n +0000002908 00000 n +0000002993 00000 n +0000003094 00000 n +0000003179 00000 n +0000003266 00000 n +0000003351 00000 n +0000003438 00000 n +0000003523 00000 n +0000003589 00000 n +0000003674 00000 n +0000003740 00000 n +0000003825 00000 n +0000003891 00000 n +0000003976 00000 n +0000004042 00000 n +0000004127 00000 n +0000004193 00000 n +0000004278 00000 n +0000004344 00000 n +0000004429 00000 n +0000004523 00000 n +0000004627 00000 n +0000004732 00000 n +0000004837 00000 n +0000004942 00000 n +0000005046 00000 n +0000005151 00000 n +0000005256 00000 n +0000005360 00000 n +0000005465 00000 n +0000005570 00000 n +0000005675 00000 n +0000005779 00000 n +0000005884 00000 n +0000005989 00000 n +0000006094 00000 n +0000006199 00000 n +0000006303 00000 n +0000006408 00000 n +0000006513 00000 n +0000006618 00000 n +0000006723 00000 n +0000006827 00000 n +0000006932 00000 n +0000007037 00000 n +0000007141 00000 n +0000007246 00000 n +0000007351 00000 n +0000007456 00000 n +0000007561 00000 n +0000007666 00000 n +0000007771 00000 n +0000007876 00000 n +0000007981 00000 n +0000008086 00000 n +0000008191 00000 n +0000008296 00000 n +0000008401 00000 n +0000008506 00000 n +0000008610 00000 n +0000008713 00000 n +0000008816 00000 n +0000009120 00000 n +0000009225 00000 n +0000009330 00000 n +0000009434 00000 n +0000009539 00000 n +0000009644 00000 n +0000009748 00000 n +0000009853 00000 n +0000009958 00000 n +0000010062 00000 n +0000010167 00000 n +0000010272 00000 n +0000010376 00000 n +0000010477 00000 n +0000010509 00000 n +0000010541 00000 n +0000011261 00000 n +0000011309 00000 n +0000011357 00000 n +0000011405 00000 n +0000011453 00000 n +0000011502 00000 n +0000011551 00000 n +0000011600 00000 n +0000011649 00000 n +0000011698 00000 n +0000011747 00000 n +0000011796 00000 n +0000011845 00000 n +0000011894 00000 n +0000011943 00000 n +0000011992 00000 n +0000012041 00000 n +0000012090 00000 n +0000012139 00000 n +0000012188 00000 n +0000012237 00000 n +0000012286 00000 n +0000012335 00000 n +0000012384 00000 n +0000012433 00000 n +0000012482 00000 n +0000012531 00000 n +0000012580 00000 n +0000012629 00000 n +0000012678 00000 n +0000012727 00000 n +0000012776 00000 n +0000012825 00000 n +0000012874 00000 n +0000012923 00000 n +0000012972 00000 n +0000013021 00000 n +0000013070 00000 n +0000013119 00000 n +0000013168 00000 n +0000013217 00000 n +0000013266 00000 n +0000013315 00000 n +0000013364 00000 n +0000013413 00000 n +0000013462 00000 n +0000013511 00000 n +0000013560 00000 n +0000013609 00000 n +0000013658 00000 n +0000013707 00000 n +0000013756 00000 n +0000013805 00000 n +0000013854 00000 n +0000013903 00000 n +0000014164 00000 n +0000014316 00000 n +0000020676 00000 n +0000020698 00000 n +0000020793 00000 n +0000020895 00000 n +0000020915 00000 n +0000021069 00000 n +0000022130 00000 n +0000022151 00000 n +0000022264 00000 n +0000022452 00000 n +0000022473 00000 n +0000022627 00000 n +0000024028 00000 n +0000024050 00000 n +0000024163 00000 n +0000024356 00000 n +0000024377 00000 n +0000024508 00000 n +0000025119 00000 n +0000025140 00000 n +0000025253 00000 n +0000025443 00000 n +0000025464 00000 n +0000025595 00000 n +0000026596 00000 n +0000026617 00000 n +0000026730 00000 n +0000026932 00000 n +0000026953 00000 n +0000027093 00000 n +0000028111 00000 n +0000028132 00000 n +0000028245 00000 n +0000028444 00000 n +0000028465 00000 n +0000028605 00000 n +0000029278 00000 n +0000029299 00000 n +0000029412 00000 n +0000029605 00000 n +0000029626 00000 n +0000029766 00000 n +0000030909 00000 n +0000030931 00000 n +0000031071 00000 n +0000031909 00000 n +0000031930 00000 n +0000032070 00000 n +0000032930 00000 n +0000032951 00000 n +0000033091 00000 n +0000033891 00000 n +0000033912 00000 n +0000034052 00000 n +0000034940 00000 n +0000034961 00000 n +0000035101 00000 n +0000035706 00000 n +0000035727 00000 n +0000035867 00000 n +0000036283 00000 n +0000036304 00000 n +0000036417 00000 n +0000036623 00000 n +0000036644 00000 n +0000036798 00000 n +0000038822 00000 n +0000038844 00000 n +0000038998 00000 n +0000039769 00000 n +0000039790 00000 n +0000039845 00000 n +0000039950 00000 n +0000040094 00000 n +0000040200 00000 n +0000040320 00000 n +0000040429 00000 n +0000040578 00000 n +0000040688 00000 n +0000040795 00000 n +0000040949 00000 n +0000041060 00000 n +0000041177 00000 n +0000041293 00000 n +0000041457 00000 n +0000041563 00000 n +0000041682 00000 n +0000041797 00000 n +0000041901 00000 n +0000042057 00000 n +0000042166 00000 n +0000042281 00000 n +0000042393 00000 n +0000042492 00000 n +0000042639 00000 n +0000042736 00000 n +0000042836 00000 n +0000042994 00000 n +0000043134 00000 n +0000043234 00000 n +0000043341 00000 n +0000043491 00000 n +0000043591 00000 n +0000043698 00000 n +0000043846 00000 n +0000043946 00000 n +0000044053 00000 n +0000044203 00000 n +0000044303 00000 n +0000044410 00000 n +0000044556 00000 n +0000044656 00000 n +0000044763 00000 n +0000044914 00000 n +0000045014 00000 n +0000045121 00000 n +0000045269 00000 n +0000045369 00000 n +0000045476 00000 n +0000045626 00000 n +0000045726 00000 n +0000045833 00000 n +0000045965 00000 n +0000046072 00000 n +0000046171 00000 n +0000046289 00000 n +trailer +<<49d7086a07a26d8f7455139812a43056>]>> +startxref +46516 +%%EOF diff --git a/doc/cmp.shtml b/doc/cmp.shtml new file mode 100644 index 0000000000..38c592d467 --- /dev/null +++ b/doc/cmp.shtml @@ -0,0 +1,595 @@ + + + + + + CUPS Configuration Management Plan + + + +

Scope

+ +

Identification

+ +This configuration management plan document provides the guidelines for +development and maintenance of the Common UNIX Printing System ("CUPS") +Version 1.1 software. + + + +

Document Overview

+ +This configuration management document is organized into the following +sections: + +
    +
  • 1 - Scope
  • +
  • 2 - References
  • +
  • 3 - File Management
  • +
  • 4 - Trouble Report Processing
  • +
  • 5 - Software Releases
  • +
  • A - Glossary
  • +
  • B - Coding Requirements
  • +
+ + + +

File Management

+ +

Directory Structure

+ +Each source file shall be placed a sub-directory corresponding to the software +sub-system it belongs to ("scheduler", "cups", etc.) To remain compatible +with older UNIX filesystems, directory names shall not exceed 16 characters +in length. + +

Source Files

+ +Source files shall be documented and formatted as described in Appendix +B, Coding Requirements. + +

Configuration Management

+ +Source files shall be placed under the control of the Concurrent Versions +System ("CVS") software. Source files shall be "checked in" with each change +so that modifications can be tracked. + +

Documentation on the CVS software is included with the whitepaper, "CVS +II: Parallelizing Software Development". + +

Trouble Report Processing

+ +A Software Trouble Report ("STR") shall be submitted every time a user +or vendor experiences a problem with the CUPS software. Trouble reports +are maintained in a database with one of the following states: + +
    +
  1. STR is closed with complete resolution
  2. +
  3. STR is closed without resolution
  4. +
  5. STR is active
  6. +
  7. STR is pending (new STR or additional information available)
  8. +
+ +Trouble reports shall be processed using the following steps. + +

Classification

+ +When a trouble report is received it must be classified at one of the following +levels: + +
    +
  1. Request for enhancement
  2. +
  3. Documentation error
  4. +
  5. Unable to print a file
  6. +
  7. Unable to print to a printer
  8. +
  9. Unable to print at all
  10. +
+ +The scope of the problem should also be determined as: + +
    +
  1. Specific to a machine
  2. +
  3. Specific to an operating system
  4. +
  5. Applies to all machines and operating systems
  6. +
+ +

Identification

+ +Once the level and scope of the trouble report is determined the software +sub-system(s) involved with the problem are determined. This may involve +additional communication with the user or vendor to isolate the problem +to a specific cause. + +

When the sub-system(s) involved have been identified, an engineer will +then determine the change(s) needed and estimate the time required for +the change(s). + +

Correction

+ +Corrections are scheduled based upon the severity and complexity of the +problem. Once all changes have been made, documented, and tested successfully +a new software release snapshot is generated. Additional tests are added +as necessary for proper testing of the changes. + +

Notification

+ +The user or vendor is notified when the fix is available or if the problem +was caused by user error. + +

Software Releases

+ +

Version Numbering

+ +CUPS uses a three-part version number separated by periods to represent +the major, minor, and patch release numbers: + +
    +
    +major.minor.patch
    +1.1.0
    +
    +
+ +Beta-test releases are indentified by appending the letter B followed by +the build number: + +
    +
    +major.minor.patchbbuild
    +1.1.0b1
    +
    +
+ +A CVS snapshot is generated for every beta and final release and uses +the version number preceded by the letter "v" and with the decimal +points replaced by underscores: + +
    +
    +v1_0_0b1
    +v1_0_0
    +
    +
+ +Each change that corrects a fault in a software sub-system increments the +patch release number. If a change affects the software design of CUPS then +the minor release number will be incremented and the patch release number +reset to 0. If CUPS is completely redesigned the major release number will +be incremented and the minor and patch release numbers reset to 0: + +
    +
    +1.1.0b1    First beta release
    +1.1.0b2    Second beta release
    +1.1.0      First production release
    +1.1.1b1    First beta of 1.1.1
    +1.1.1      Production release of 1.1.1
    +1.1.1b1    First beta of 1.1.1
    +1.1.1      Production release of 1.1.1
    +2.0.0b1    First beta of 2.0.0
    +2.0.0      Production release of 2.0.0
    +
    +
+ +

Generation

+ +Software releases shall be generated for each successfully completed software +trouble report. All object and executable files shall be deleted prior +to performing a full build to ensure that source files are recompiled. + +

Testing

+ +Software testing shall be conducted according to the CUPS Software Test +Plan, CUPS-STP-1.1. Failed tests cause STRs to be generated to correct +the problems found. + +

Release

+ +When testing has been completed successfully a new distribution image is +created from the current CVS code "snapshot". No production release shall +contain software that has not passed the appropriate software tests. + + + +

Coding Requirements

+ +These coding requirements provide detailed information on source file +formatting and documentation content. These guidelines shall be applied +to all C and C++ source files provided with CUPS. + +

Source Files

+ +

Naming

+ +All source files names shall be 16 characters or less in length to +ensure compatibility with older UNIX filesystems. Source files +containing functions shall have an extension of ".c" for ANSI C and +".cxx" for C++ source files. All other "include" files shall have an +extension of ".h". + +

Documentation

+ +The top of each source file shall contain a header giving the name of the +file, the purpose or nature of the source file, the copyright and licensing +notice, and the functions contained in the file. The file name and revision +information is provided by the CVS "$Id$" tag: + +
    +
    +/*
    + * "$Id$"
    + *
    + *   Description of file contents.
    + *
    + *   Copyright 1997-2000 by Easy Software Products, all rights
    + *   reserved.
    + *
    + *   These coded instructions, statements, and computer programs are
    + *   the property of Easy Software Products and are protected by
    + *   Federal copyright law.  Distribution and use rights are outlined
    + *   in the file "LICENSE.txt" which should have been included with
    + *   this file.  If this file is missing or damaged please contact
    + *   Easy Software Products at:
    + *
    + *       Attn: CUPS Licensing Information
    + *       Easy Software Products
    + *       44141 Airport View Drive, Suite 204
    + *       Hollywood, Maryland 20636-3111 USA
    + *
    + *       Voice: (301) 373-9603
    + *       EMail: cups-info@cups.org
    + *         WWW: http://www.cups.org
    + *
    + * Contents:
    + *
    + *   function1() - Description 1.
    + *   function2() - Description 2.
    + *   function3() - Description 3.
    + */
    +
    +
+ +The bottom of each source file shall contain a trailer giving the name +of the file using the CVS "$Id$" tag. The primary purpose of this is to +mark the end of a source file; if the trailer is missing it is possible +that code has been lost near the end of the file: + +
    +
    +/*
    + * End of "$Id$".
    + */
    +
    +
+ +

Functions

+ +

Naming

+ +Functions with a global scope shall be capitalized ("DoThis", "DoThat", +"DoSomethingElse", etc.) The only exception to this rule shall be the +CUPS interface library functions which may begin with a prefix word in +lowercase ("cupsDoThis", "cupsDoThat", etc.) + +

Functions with a local scope shall be declared "static" and be lowercase +with underscores between words ("do_this", "do_that", "do_something_else", +etc.) + +

Documentation

+ +Each function shall begin with a comment header describing what the function +does, the possible input limits (if any), and the possible output values +(if any), and any special information needed: + +
    +
    +/*
    + * 'do_this()' - Compute y = this(x).
    + *
    + * Notes: none.
    + */
    +
    +static float     /* O - Inverse power value, 0.0 <= y <= 1.1 */
    +do_this(float x) /* I - Power value (0.0 <= x <= 1.1) */
    +{
    +  ...
    +  return (y);
    +}
    +
    +
+ +

Methods

+ +

Naming

+ +Methods shall be in lowercase with underscores between words ("do_this", +"do_that", "do_something_else", etc.) + +

Documentation

+ +Each method shall begin with a comment header describing what the method +does, the possible input limits (if any), and the possible output values +(if any), and any special information needed: + +
    +
    +/*
    + * 'class::do_this()' - Compute y = this(x).
    + *
    + * Notes: none.
    + */
    +
    +float                   /* O - Inverse power value, 0.0 <= y <= 1.0 */
    +class::do_this(float x) /* I - Power value (0.0 <= x <= 1.0) */
    +{
    +  ...
    +  return (y);
    +}
    +
    +
+ +

Variables

+ +

Naming

+ +Variables with a global scope shall be capitalized ("ThisVariable", +"ThatVariable", "ThisStateVariable", etc.) The only exception to this +rule shall be the CUPS interface library global variables which must +begin with the prefix "cups" ("cupsThisVariable", "cupsThatVariable", +etc.) Global variables shall be replaced by function arguments whenever +possible. + +

Variables with a local scope shall be lowercase with underscores between +words ("this_variable", "that_variable", etc.) Any local variables shared +by functions within a source file shall be declared "static". + +

Documentation

+ +Each variable shall be declared on a separate line and shall be immediately +followed by a comment block describing the variable: + +
    +int this_variable;   /* The current state of this */
    +int that_variable;   /* The current state of that */
    +
+ +

Types

+ +

Naming

+ +All type names shall be lowercase with underscores between words and +"_t" appended to the end of the name ("this_type_t", "that_type_t", +etc.) + +

Documentation

+ +Each type shall have a comment block immediately before the typedef: + +
    +
    +/*
    + * This type is for CUPS foobar options.
    + */
    +typedef int cups_this_type_t;
    +
    +
+ +

Structures

+ +

Naming

+ +All structure names shall be lowercase with underscores between words and +"_str" appended to the end of the name ("this_struct_str", "that_struct_str", +etc.) + +

Documentation

+ +Each structure shall have a comment block immediately before the struct +and each member shall be documented in accordance with the variable naming +policy above: + +
    +
    +/*
    + * This structure is for CUPS foobar options.
    + */
    +struct cups_this_struct_str
    +{
    +  int this_member;   /* Current state for this */
    +  int that_member;   /* Current state for that */
    +};
    +
    +
+ +

Classes

+ +

Naming

+ +All class names shall be lowercase with underscores between words +("this_class", "that_class", etc.) + +

Documentation

+ +Each class shall have a comment block immediately before the class +and each member shall be documented in accordance with the variable naming +policy above: + +
    +
    +/*
    + * This class is for CUPS foobar options.
    + */
    +class cups_this_class
    +{
    +  int this_member;   /* Current state for this */
    +  int that_member;   /* Current state for that */
    +};
    +
    +
+ +

Constants

+ +

Naming

+ +All constant names shall be uppercase with underscored between words +("THIS_CONSTANT", "THAT_CONSTANT", etc.) Constants defined for the CUPS +interface library must begin with an uppercase prefix +("CUPS_THIS_CONSTANT", "CUPS_THAT_CONSTANT", etc.) + +

Typed enumerations shall be used whenever possible to allow for type +checking by the compiler. + +

Documentation

+ +Comment blocks shall immediately follow each constant: + +
    +
    +enum
    +{
    +  CUPS_THIS_TRAY,   /* This tray */
    +  CUPS_THAT_TRAY    /* That tray */
    +};
    +
    +
+ +

Code

+ +

Documentation

+ +All source code shall utilize block comments within functions to describe +the operations being performed by a group of statements: + +
    +
    +/*
    + * Clear the state array before we begin...
    + */
    +
    +for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
    +  array[i] = STATE_IDLE;
    +
    +/*
    + * Wait for state changes...
    + */
    +
    +do
    +{
    +  for (i = 0; i < (sizeof(array) / sizeof(sizeof(array[0])); i ++)
    +    if (array[i] != STATE_IDLE)
    +      break;
    +
    +  if (i == (sizeof(array) / sizeof(array[0])))
    +    sleep(1);
    +} while (i == (sizeof(array) / sizeof(array[0])));
    +
    +
+ +

Style

+ +

Indentation

+ +All code blocks enclosed by brackets shall begin with the opening brace +on a new line. The code then follows starting on a new line after the brace +and is indented 2 spaces. The closing brace is then placed on a new line +following the code at the original indentation: + +
    +
    +{
    +  int i; /* Looping var */
    +
    + /*
    +  * Process foobar values from 0 to 999...
    +  */
    +
    +  for (i = 0; i < 1000; i ++)
    +  {
    +    do_this(i);
    +    do_that(i);
    +  }
    +}
    +
    +
+ +Single-line statements following "do", "else", "for", "if", and "while" +shall be indented 2 spaces as well. Blocks of code in a "switch" block +shall be indented 4 spaces after each "case" and "default" case: + +
    +
    +switch (array[i])
    +{
    +  case STATE_IDLE :
    +      do_this(i);
    +      do_that(i);
    +      break;
    +  default :
    +      do_nothing(i);
    +      break;
    +}
    +
    +
+ +

Spacing

+ +A space shall follow each reserved word ("if", "while", etc.) Spaces shall +not be inserted between a function name and the arguments in parenthesis. + +

Return Values

+ +Parenthesis shall surround values returned from a function using "return": + +
    +
    +return (STATE_IDLE);
    +
    +
+ +

Loops

+ +Whenever convenient loops should count downward to zero to improve program +performance: + +
    +
    +for (i = sizeof(array) / sizeof(array[0]) - 1; i >= 0; i --)
    +  array[i] = STATE_IDLE;
    +
    +
+ +

Software Trouble Report Form

+ +
+ + + + + + + + + + + + + + + + + + + +
Summary of Problem:________________________________________
Problem Severity:__1=RFE +
__2=Documentation-Error +
__3=Unable-to-Print-a-File +
__4=Unable-to-Print-to-a-Printer +
__5=Unable-to-Print-at-All
Problem Scope:__1=Machine __2=Operating-System __3=All
Detailed Description of Problem:________________________________________ +
________________________________________ +
________________________________________ +
________________________________________ +
________________________________________ +
________________________________________
+ + + diff --git a/doc/cups.css b/doc/cups.css new file mode 100644 index 0000000000..9285a5b5ee --- /dev/null +++ b/doc/cups.css @@ -0,0 +1,4 @@ +H1 { font-family: sans-serif } +H2 { font-family: sans-serif } +TH { text-align: left } + diff --git a/doc/cupsdoc.css b/doc/cupsdoc.css new file mode 100644 index 0000000000..333f20144d --- /dev/null +++ b/doc/cupsdoc.css @@ -0,0 +1,9 @@ +H1 { font-family: sans-serif } +H2 { font-family: sans-serif } +H3 { font-family: sans-serif } +H4 { font-family: sans-serif } +H5 { font-family: sans-serif } +H6 { font-family: sans-serif } +SUP { font-family: sans-serif; font-size: 6pt } +PRE { margin-left: 2em } +CODE { font-weight: bold } diff --git a/doc/documentation.html b/doc/documentation.html new file mode 100644 index 0000000000..e69721336a --- /dev/null +++ b/doc/documentation.html @@ -0,0 +1,77 @@ + + + Documentation - Common UNIX Printing System + + + Easy Software Products Home Page + Do Administration Tasks + Manage Printer Classes Status + On-Line Help + Manage Jobs + Manage Printers + Download the Current CUPS Software + + + + +
+Common UNIX Printing System +
+ +

Documentation

+ +The following documentation for CUPS is available on this server: + +
    + +
  • Whitepaper - An Overview of the Common UNIX Printing System ( + HTML | + PDF ) + +
  • Software Users Manual ( + HTML | + PDF ) + +
  • Software Administrators Manual ( + HTML | + PDF ) + +
  • Software Programmers Manual ( + HTML | + PDF ) + +
  • Configuration Management Plan ( + HTML | + PDF ) + +
  • CUPS Implementation of IPP ( + HTML | + PDF ) + +
  • Interface Design Description ( + HTML | + PDF ) + +
  • Software Design Description ( + HTML | + PDF ) + +
  • Software Version Description ( + HTML | + PDF ) + +
  • Software Security Report ( + HTML | + PDF ) + +
+ +
+ +

The Common UNIX Printing System, CUPS, and the CUPS logo are the +trademark property of Easy Software +Products. CUPS is copyright 1997-2000 by Easy Software Products, +All Rights Reserved. + + + diff --git a/doc/figures.sc b/doc/figures.sc new file mode 100644 index 0000000000000000000000000000000000000000..13baeacea402d2f88991f6c5c267095bcae792ae GIT binary patch literal 51728 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 literal 0 Hc-jL100001 diff --git a/doc/glossary.shtml b/doc/glossary.shtml new file mode 100644 index 0000000000..2cc0c1c893 --- /dev/null +++ b/doc/glossary.shtml @@ -0,0 +1,73 @@ +

Glossary

+ +

Terms

+ +
+ +
C +
A computer language. + +
parallel +
Sending or receiving data more than 1 bit at a time. + +
pipe +
A one-way communications channel between two programs. + +
serial +
Sending or receiving data 1 bit at a time. + +
socket +
A two-way network communications channel. + +
+ +

Acronyms

+ +
+ +
ASCII +
American Standard Code for Information Interchange + +
CUPS +
Common UNIX Printing System + +
ESC/P +
EPSON Standard Code for Printers + +
FTP +
File Transfer Protocol + +
HP-GL +
Hewlett-Packard Graphics Language + +
HP-PCL +
Hewlett-Packard Page Control Language + +
HP-PJL +
Hewlett-Packard Printer Job Language + +
IETF +
Internet Engineering Task Force + +
IPP +
Internet Printing Protocol + +
ISO +
International Standards Organization + +
LPD +
Line Printer Daemon + +
MIME +
Multimedia Internet Mail Exchange + +
PPD +
PostScript Printer Description + +
SMB +
Server Message Block + +
TFTP +
Trivial File Transfer Protocol + +
diff --git a/doc/idd.html b/doc/idd.html new file mode 100644 index 0000000000..b01a2229fb --- /dev/null +++ b/doc/idd.html @@ -0,0 +1,1094 @@ + + + + CUPS Interface Design Description + + + + + + + +

+

CUPS Interface Design Description


+CUPS-IDD-1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
1 Scope + +2 References + +3 Internal Interfaces + +4 External Interfaces + +5 Directories +
+
A Glossary + +
+

1 Scope

+

1.1 Identification

+

This interface design description document provides detailed file +formats, message formats, and program conventions for the Common UNIX +Printing System ("CUPS") Version 1.1.

+

1.2 System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+

1.3 Document Overview

+

This interface design description document is organized into the +following sections:

+
    +
  • 1 - Scope
  • +
  • 2 - References
  • +
  • 3 - Internal Interfaces
  • +
  • 4 - External Interfaces
  • +
  • 5 - Directories
  • +
  • A - Glossary
  • +
+

2 References

+

2.1 CUPS Documentation

+

The following CUPS documentation is referenced by this document:

+
    +
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • +
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • +
  • CUPS-IPP-1.1: CUPS Implmentation of IPP
  • +
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • +
  • CUPS-SDD-1.1: CUPS Software Design Description
  • +
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual
  • +
  • CUPS-SSR-1.1: CUPS Software Security Report
  • +
  • CUPS-STP-1.1: CUPS Software Test Plan
  • +
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • +
  • CUPS-SVD-1.1.x: CUPS Software Version Description
  • +
+

2.2 Other Documents

+

The following non-CUPS documents are referenced by this document:

+ +

3 Internal Interfaces

+

3.1 Character Set Files

+

The character set files define a mapping between 8-bit characters +and the Unicode character set, or between Unicode and printer fonts. +They are named using the IETF charset names defined in RFCnnnn. These +files are ASCII text, the content of which is described below. Comments +can be included by using the # character in the first column +of a line.

+

3.1.1 8-Bit Character Set Files

+

8-bit character set files start with a line reading:

+
    +
    +charset 8bit
    +
    +
+

Following this are lines that define the font information:

+
    +
    +first last direction width normal bold italic bold-italic
    +
    +
+

First and last are the first and last glyphs +in the font mapping that correspond to that font; a maximum of 256 +characters can be mapped within each group, with a maximum of 256 +mappings (this is a PostScript limitation.) The glyph values are +hexadecimal.

+

Direction is the string "ltor", "rtol", or "rtola" +indicating left-to-right, right-to-left, or right-to-left Arabic text.

+

Width is the string "single" or "double"; double means +that the glyphs are twice as wide as ASCII characters in the Courier +typeface.

+

Normal, bold, italic, and bold-italic are the +typefaces to use for each presentation. If characters are only +available in a single style then only one typeface should be listed +(e.g. "Symbol".) Each font that is listed will be used (and downloaded +if needed) when printing.

+

The remaining lines define a character to Unicode glyph mapping for +the character set. The character and glyph values are hexadecimal:

+
    +
    +xx yyyy
    +
    +
+

3.1.2 Unicode Character Set Files

+

Unicode character set files start with a line reading:

+
    +
    +charset encoding
    +
    +
+

Encoding is the encoding to use for the text; currently +only the string "utf8" is supported.

+

Following this are lines defining the font information:

+
    +
    +first last direction width normal bold italic bold-italic
    +
    +
+

First and last are the first and last glyphs +in the font mapping that correspond to that font; a maximum of 256 +characters can be mapped within each group, with a maximum of 256 +mappings (this is a PostScript limitation.) The glyph values are +hexadecimal.

+

Direction is the string "ltor", "rtol", or "rtola" +indicating left-to-right, right-to-left, or right-to-left Arabic text.

+

Width is the string "single" or "double"; double means +that the glyphs are twice as wide as ASCII characters in the Courier +typeface.

+

Normal, bold, italic, and bold-italic are the +typefaces to use for each presentation. If characters are only +available in a single style then only one typeface should be listed +(e.g. "Symbol".) Each font that is listed will be used (and downloaded +if needed) when printing.

+

3.2 Language Files

+

The language files define the default character set and a +collection of text messages in that language. They are named by +prefixing the string "cups_" to the front of the language specifier +(e.g. "cups_en", "cups_fr", etc.) Each file consists of two or more +lines of ASCII text.

+

The first line identifies the character set to be used for the +messages. The currently recognized values are:

+
    +
  • iso-8859-1
  • +
  • iso-8859-2
  • +
  • iso-8859-3
  • +
  • iso-8859-4
  • +
  • iso-8859-5
  • +
  • iso-8859-6
  • +
  • iso-8859-7
  • +
  • iso-8859-8
  • +
  • iso-8859-9
  • +
  • iso-8859-10
  • +
  • iso-8859-13
  • +
  • iso-8859-14
  • +
  • iso-8859-15
  • +
  • us-ascii
  • +
  • utf-8
  • +
  • windows-874
  • +
  • windows-1250
  • +
  • windows-1251
  • +
  • windows-1252
  • +
  • windows-1253
  • +
  • windows-1254
  • +
  • windows-1255
  • +
  • windows-1256
  • +
  • windows-1257
  • +
  • windows-1258
  • +
+

The second and succeeding lines define text messages. If the +message text is preceded by a number, then the current message number +is updated and the text after the number is used.

+

3.3 MIME Files

+

CUPS uses two MIME files in its standard configuration.

+

3.3.1 mime.types

+

The mime.types file defines the recognized file types and consists +of 1 or more lines of ASCII text. Comment lines start with the pound +("#") character. The backslash ("\") character can be used at the end +of a line to continue that line to the next.

+

Each non-blank line starts with a MIME type identifier +("super/type") as registered with the IANA. All text following the MIME +type is treated as a series of type recognition rules:

+
    +
    +mime-type := super "/" type { SP rule }*
    +super := { "a-z" | "A-Z" }*
    +type := { "a-z" | "A-Z" | "-" | "." | "0-9" }*
    +rule := { extension | match | operator | "(" rule ")" }*
    +extension := { "a-z" | "A-Z" | "0-9" }*
    +match := "match(" regexp ")" |
    +         "ascii(" offset "," length ")" |
    +	 "printable(" offset "," length ")" |
    +	 "string(" offset "," string ")" |
    +	 "contains(" offset "," length "," string ")" |
    +	 "char(" offset "," value ")" |
    +	 "short(" offset "," value ")" |
    +	 "int(" offset "," value ")" |
    +	 "locale(" string ")"
    +operator := "+" |	[ logical AND ]
    +            "," | SP    [ logical OR ]
    +	    "!"         [ unary NOT ]
    +
    +
+

The int and short rules match look for +integers in network byte order (a.k.a. big-endian) with the +most-significant byte first.

+

3.3.2 mime.convs

+

The mime.types file defines the recognized file filters and +consists of 1 or more lines of ASCII text. Comment lines start with the +pound ("#") character.

+

Each non-blank line starts with two MIME type identifiers +("super/type") representing the source and destination types. Following +the MIME types are a cost value (0 to 100) and the filter program to +use. If the filter program is not specified using the full path then it +must reside in the CUPS filter directory:

+
    +
    +super/type SP super/type2 SP cost SP program
    +
    +
+

3.4 Option Files

+

CUPS maintains user-defined printer and option files for each +printer and user on the system. The printers and options defined in the +system option file (/etc/cups/lpoptions) are loaded first, +followed by the user option file ($HOME/.lpoptions). +Options in the user file replace those defined in the system file for +the same destination. Each line in the files can be one of the +following:

+
    +
    +Dest name option=value option=value ... option=value
    +Dest name/instance option=value option=value ... option=value
    +Default name option=value option=value ... option=value
    +Default name/instance option=value option=value ... option=value
    +
    +
+

The line beginning with "Default" indicates the default destination +for print jobs; a default line in the user option file overrides the +default defined in the system option file.

+

Name is the name of a printer known to the local server.

+

Instance can be any string of letters, numbers, and the +underscore up to 127 characters in length.

+

The remainder of the line contains a list of space-separated +options and their values.

+

3.5 PostScript Printer Description Files

+

PostScript Printer Description ("PPD") files describe the +capabilities of each printer and are used by CUPS to support +printer-specific features and intelligent filtering.

+

3.5.1 PPD Specification

+

The PPD file format is described in + Adobe TechNote #5003: PostScript Printer Description File Format +Specification Version 4.3.

+

3.5.2 CUPS Extensions to PPD Files

+

CUPS adds several new attributes that are described below.

+

3.5.2.1 cupsFilter

+

This string attribute provides a conversion rule of the form:

+
    +
    +source/type cost program
    +
    +
+

The destination type is assumed to the printer's type. If a printer +supports the source type directly the special filter program "-" may be +specified.

+

3.5.2.2 cupsManualCopies

+

This boolean attribute notifies the RIP filters that the +destination printer does not support copy generation in hardware. The +default value is false.

+

3.5.2.3 cupsModelNumber

+

This integer attribute specifies a printer-specific model number. +This number can be used by a filter program to adjust the output for a +specific model of printer.

+

3.5.2.4 cupsProfile

+

This string attribute specifies a color profile of the form:

+
    +
    +resolution/type density gamma m00 m01 m02 m10 m11 m12 m20 m21 m22
    +
    +
+

The resolution and type values may be "-" to act as a +wildcard. Otherwise they must match one of the Resolution + or MediaType attributes defined in the PPD file.

+

The density and gamma values define gamma and density +adjustment function such that:

+
    +
    +f(x) = density * xgamma
    +
    +
+

The m00 through m22 values define a 3x3 +transformation matrix for the CMY color values. The density function is +applied after the CMY transformation.

+

3.5.2.5 cupsVersion

+

This required attribute describes which version of the CUPS IDD was +used for the PPD file extensions. Currently it must be the string "1.0" +or "1.1".

+

3.6 Scheduler Configuration Files

+

The scheduler reads three configuration files that define the +available printers, classes, and services:

+
+
classes.conf
+
This file defines all of the printer classes known to the system.
+
cupsd.conf
+
This file defines the files, directories, passwords, etc. used by +the scheduler.
+
printers.conf
+
This file defines all of the printers known to the system.
+
+

3.6.1 classes.conf

+

The classes.conf file consists of 1 or more lines of ASCII text. + Comment lines start with the pound ("#") character.

+

Each non-blank line starts with the name of a configuration +directive followed by its value. The following directives are +understood: +

+ + + + + + + + + + + + + + +
Directive Description
<Class name> +
</Class>
Surrounds a class definition.
<DefaultClass name> +
</Class>
Surrounds a class definition for the default +destination.
Accepting Specifies whether the class is accepting +new jobs. May be the names "Yes" or "No".
AllowUsers Specifies a list of users that are allowed +to access the class.
BannerStart Specifies the banner that is printed +before other files in a job.
BannerEnd Specifies the banner that is printed after +other files in a job.
DenyUsers Specifies a list of users that are not +allowed to access the class.
Info A textual description of the class.
Location A textual location of the class.
Printer Specifies a printer that is a member of the +class.
State Specifies the initial state of the class; can +be "Idle" or "Stopped".
StateMessage Specifies a textual message for the +current class state.
+
+

+

3.6.2 cupsd.conf

+

The cupsd.conf file consists of 1 or more lines of ASCII text. + Comment lines start with the pound ("#") character.

+

Each non-blank line starts with the name of a configuration +directive followed by its value. The following directives are +understood: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Directive Default Description
AccessLog access_log Specifies the location +of the access log file. The special name "syslog" can be used to send +access log information to the system log.
Allow - Allows connections from the +specified host, network, or domain.
AuthClass - Specifies what level of +authentication is required; may be "User", "System", or "Group".
AuthType None Specifies the type of +authentication to perform; may be "None", "Basic", or "Digest".
BrowseAddress 255.255.255.255 Specifies a +broadcast address to send CUPS browsing packets to.
BrowseAllow - Specifies hosts or addresses +from which browsing information should be used.
BrowseDeny - Specifies hosts or addresses +from which browsing information should not be used.
BrowseInterval 30 Specifies the number of +seconds between browsing updates. A browse interval of 0 seconds +disables outgoing packets.
BrowseOrder Allow,Deny Specifies the order +of BrowseAllow and BrowseDeny directive processing; can be +"Deny,Allow" to implicitly deny hosts unless they are allowed by a +BrowseAllow line, or "Allow,Deny" to implicitly allow hosts unless +they are denied by a BrowseDeny line.
BrowsePoll - Specifies a server to poll for +available printers and classes.
BrowsePort 631 Specifies the UDP port number +to use for browse packets.
BrowseRelay - Specifies a source and +destination address for relaying browser information from one subnet +to another.
BrowseShortNames yes Specifies whether or +not to provide short names (without the "@server" part) for remote +printers.
BrowseTimeout 300 Specifies the number of +seconds to wait until remote destinations are removed from the local +destination list.
Browsing On Specifies whether or not printer +and class browsing is enabled; can be "On" or "Off".
DataDir /usr/share/cups Specifies the +directory where CUPS data files are stored.
DefaultCharset iso-8859-1 Specifies the +default character set.
DefaultLanguage current locale Specifies the +default language.
Deny - Refuses connections from the +specified host, network, or domain.
DocumentRoot /usr/share/doc/cups Specifies +the document data root directory.
ErrorLog error_log Specifies the error log +file location. The special name "syslog" can be used to send error log +information to the system log.
Group root, sys, system Specifies the group +name or ID that is used when running external programs.
HostNameLookups Off Specifies whether or not +to perform reverse IP address lookups to get the actual hostname; may +be "On" or "Off". Hostname lookups can significantly degrade the +performance of the CUPS server if one or more DNS servers is not +functioning properly.
ImplicitClasses On Specifies whether or not +to automatically create printer classes when more than one printer or +class of the same name is detected on the network; may be "On" or +"Off".
KeepAlive On Specifies whether or not to use +the HTTP Keep-Alive feature; may be "On" or "Off".
KeepAliveTimeout 30 Specifies the amount of +time to keep the HTTP connection alive before closing it.
<Location path> +
</Location>
- Specifies a location to restrict +access to.
LogLevel info Controls the amount of +information that is logged in the error log file. Can be one of +"debug", "info", "warn", "error", or "none", in decreasing order or +verbosity.
MaxClients 100 Specifies the maximum number +of simultaneous active clients. This value is internally limited to +1/3 of the total number of available file descriptors.
MaxLogSize 0 Specifies the maximum size of +the access, error, and page log files in bytes. If set to 0 then no +maximum size is set. Log files are rotated automatically when this +size is exceeded.
MaxRequestSize 0 Specifies the maximum size +of HTTP requests in bytes. If set to 0 then there is no maximum.
Order Allow,Deny Specifies the order of +Allow and Deny directive processing; can be "Deny,Allow" to implicitly +deny hosts unless they are allowed by an Allow line, or "Allow,Deny" +to implicitly allow hosts unless they are denied by a Deny line.
PageLog page_log Specifies the location of +the page log file. The special name "syslog" can be used to send page +log information to the system log.
Port 631 Specifies a port number to listen +to for HTTP connections.
Printcap /etc/printcap Specifies the +location of a Berkeley printcap file to update with a list of current +printers and classes. If no filename is supplied then this automatic +generation is disabled.
RequestRoot /var/spool/cups Specifies the +location of request files.
RIPCache 8m Specifies the size of the memory +cache in bytes that is used by RIP filters.
ServerAdmin root@ServerName Specifies the +person to contact with problems.
ServerName hostname Specifies the hostname +that is supplied to HTTP clients. This is also used to determine the +default CUPS server for the CUPS IPP client applications.
ServerRoot /etc/cups Specifies the root +directory for server configuration files.
SystemGroup root, sys, system Specifies the +group name used for System class authentication.
TempDir /var/tmp Specifies the temporary +directory to use.
Timeout 300 The timeout in seconds before +client connections are closed in the middle of a request.
User lp Specifies the user that is used when +running external programs.
+
+

+

3.6.3 printers.conf

+

The printers.conf file consists of 1 or more lines of ASCII text. + Comment lines start with the pound ("#") character.

+

Each non-blank line starts with the name of a configuration +directive followed by its value. The following directives are +understood: +

+ + + + + + + + + + + + + + +
Directive Description
Accepting Specifies whether the printer is accepting +new jobs. May be the names "Yes" or "No".
<DefaultPrinter name> +
</Printer>
Surrounds the printer definition for a default +destination.
AllowUsers Specifies a list of users that are allowed +to access the printer.
BannerStart Specifies the banner that is printed +before other files in a job.
BannerEnd Specifies the banner that is printed after +other files in a job.
DenyUsers Specifies a list of users that are not +allowed to access the printer.
DeviceURI Specifies the device-uri attribute for the +printer.
Info A textual description of the printer.
Location A textual location of the printer.
<Printer name> +
</Printer>
Surrounds the printer definition.
State Specifies the initial state of the printer; can +be "Idle" or "Stopped".
StateMessage Specifies a textual message for the +current printer state.
+
+

+

4 External Interfaces

+

4.1 AppSocket Protocol

+

The AppSocket protocol is an 8-bit clean TCP/IP socket connection. +The default IP service port is 9100. The URI method name is "socket".

+

The AppSocket protocol is used by the Hewlett Packard JetDirect +network interfaces and print servers, as well as many other vendors' +products. See the CUPS Software Administrators Manual for a list of +supported products.

+

4.2 CUPS Browsing Protocol

+

The CUPS Browsing Protocol is a UDP/IP-based broadcast service. By +default this service operates on IP service port 631.

+

Each broadcast packet describes the state of a single printer or +class and is an ASCII text string of up to 1450 bytes ending with a +newline (0x0a). The string is formatted as follows:

+
    +
    +type SP state SP uri SP "location" SP "info" SP "make-and-model" NL
    +
    +
+

State, uri, location, info, and make-and-model +, correspond to the IPP printer-state, +printer-uri-supported, printer-location, +printer-info, and printer-make-and-model + attributes.

+

Type is a hexadecimal number string representing +capability/type bits: +

+ + + + + + + + + + + + + + + + + + +
Bit Description
0 0 = printer +
1 = class
1 0 = local +
1 = remote +
(always 1)
2 1 = can print B
3 1 = can print color
4 1 = can duplex
5 1 = can staple
6 1 = can do fast copies
7 1 = can do fast collating
8 1 = can punch holes
9 1 = can cover
10 1 = can bind
11 1 = can sort
12 1 = can print up to 9x14 inches
13 1 = can print up to 18x24 inches
14 1 = can print up to 36x48 inches
15 1 = can print variable sizes
+
+

+

4.3 CUPS Form File

+

CUPS Form files are XML files used by the CUPS formtops + filter to produce dynamic banner pages and support preprinted forms.

+

The MIME type for CUPS Form files is application/vnd.cups-form +.

+

4.3.1 CUPS Form DTD

+

The following DTD describes the available elements and attributes +in a CUPS Form file: +

+ + +
+
+<!ENTITY % Angle "CDATA" -- angle in degrees -->
+
+<!ENTITY % Color "CDATA" -- a color using sRGB: #RRGGBB as Hex values -->
+
+<!ENTITY % Length "CDATA" -- nn for pixels or nn% for percentage length -->
+
+<!ENTITY % Lengths "CDATA" -- comma-separated Length values -->
+
+<!ENTITY % Text "CDATA">
+
+<!ENTITY % heading "H1|H2|H3|H4|H5|H6">
+
+<!ENTITY % preformatted "PRE">
+
+<!ENTITY % i18n
+ "lang        %LanguageCode; #IMPLIED  -- language code --
+  dir         (ltr|rtl)      #IMPLIED  -- direction for weak/neutral text --"
+  >
+
+<!ENTITY % attrs "%i18n;">
+
+<!ENTITY % fontstyle
+ "B | FONT | I | TT">
+
+<!ENTITY % graphics
+ "BOX | RECT | LINE | POLY | ARC | PIE | TEXT">
+
+<!ENTITY % insert
+ "IMG | VAR">
+
+<!-- %inline; covers inline or "text-level" elements -->
+<!ENTITY % inline "#PCDATA | %fontstyle; | %graphics; | %insert;">
+
+<!ELEMENT (%fontstyle;) - - (%inline;)*>
+<!ATTLIST (%fontstyle;)
+  %attrs;                              -- %i18n --
+  >
+
+<!ELEMENT BR - O EMPTY                 -- forced line break -->
+<!ATTLIST BR
+  %attrs;                              -- %i18n --
+  >
+
+<!ENTITY % block
+     "P | %heading; | %preformatted;">
+
+<!ENTITY % flow "%block; | %inline;">
+
+<!ELEMENT PAGE O O (%flow;)+           -- document body -->
+<!ATTLIST PAGE
+  %attrs;                              -- %i18n --
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  valign      (top|middle|center|bottom) #IMPLIED -- vertical alignment --
+  >
+
+<!ELEMENT P - O (%inline;)*            -- paragraph -->
+<!ATTLIST P
+  %attrs;                              -- %i18n --
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  >
+
+<!ELEMENT (%heading;)  - - (%inline;)* -- heading -->
+<!ATTLIST (%heading;)
+  %attrs;                              -- %i18n --
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  >
+
+<!ELEMENT PRE - - (%inline;)*          -- preformatted text -->
+<!ATTLIST PRE
+  %attrs;                              -- %i18n --
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  >
+
+<!ELEMENT BOX - O EMPTY                -- unfilled box -->
+<!ATTLIST BOX
+  color       %Color;        #IMPLIED  -- override color --
+  height      %Length;       #REQUIRED -- height of box --
+  thickness   %Length;       #IMPLIED  -- override line thickness --
+  width       %Length;       #REQUIRED -- width of box --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+<!ELEMENT RECT - O EMPTY               -- filled box -->
+<!ATTLIST RECT
+  color       %Color;        #IMPLIED  -- override color --
+  height      %Length;       #REQUIRED -- height of box --
+  width       %Length;       #REQUIRED -- width of box --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+<!ELEMENT LINE - O EMPTY               -- polyline -->
+<!ATTLIST LINE
+  color       %Color;        #IMPLIED  -- override color --
+  thickness   %Length;       #IMPLIED  -- override line thickness --
+  x           %Lengths;      #REQUIRED -- horizontal positions --
+  y           %Lengths;      #REQUIRED -- vertical positions --
+  >
+
+<!ELEMENT POLY - O EMPTY               -- polygon (filled) -->
+<!ATTLIST POLY
+  color       %Color;        #IMPLIED  -- override color --
+  x           %Lengths;      #REQUIRED -- horizontal positions --
+  y           %Lengths;      #REQUIRED -- vertical positions --
+  >
+
+<!ELEMENT ARC - O EMPTY                -- unfilled arc -->
+<!ATTLIST ARC
+  color       %Color;        #IMPLIED  -- override color --
+  end         %Angle;        #IMPLIED  -- override end angle --
+  height      %Length;       #REQUIRED -- height of arc --
+  start       %Angle;        #IMPLIED  -- override start angle --
+  thickness   %Length;       #IMPLIED  -- override line thickness --
+  width       %Length;       #REQUIRED -- width of arc --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+<!ELEMENT PIE - O EMPTY                -- filled arc -->
+<!ATTLIST PIE
+  color       %Color;        #IMPLIED  -- override color --
+  end         %Angle;        #IMPLIED  -- override end angle --
+  height      %Length;       #REQUIRED -- height of arc --
+  start       %Angle;        #IMPLIED  -- override start angle --
+  width       %Length;       #REQUIRED -- width of arc --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+<!ELEMENT TEXT - - (%flow;)*           -- text box -->
+<!ATTLIST RECT
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  height      %Length;       #REQUIRED -- height of box --
+  valign      (top|middle|center|bottom) #IMPLIED -- vertical alignment --
+  width       %Length;       #REQUIRED -- width of box --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+
+<!ELEMENT IMG - O EMPTY                -- Embedded image -->
+<!ATTLIST IMG
+  %attrs;                              -- %coreattrs, %i18n, %events --
+  src         %URI;          #REQUIRED -- URI of image to embed --
+  height      %Length;       #IMPLIED  -- override height --
+  width       %Length;       #IMPLIED  -- override width --
+  >
+
+<!ELEMENT HEAD O O (DEFVAR)*           -- document head -->
+<!ATTLIST HEAD
+  %i18n;                               -- lang, dir --
+  >
+
+<!ELEMENT DEFVAR - O EMPTY             -- variable definition -->
+<!ATTLIST DEFVAR
+  name        CDATA          #REQUIRED -- name
+  value       CDATA          #REQUIRED -- value
+  >
+
+
+<!ENTITY % html.content "HEAD, PAGE">
+
+<!ELEMENT CUPSFORM - - (HEAD) (PAGE)+  -- document root element -->
+<!ATTLIST CUPSFORM
+  %i18n;                               -- lang, dir --
+  >
+
+
+
+

+

4.4 CUPS PostScript File

+

CUPS PostScript files are device-dependent Adobe PostScript program +files. The PostScript language is described in the + Adobe PostScript Language Reference Manual, Third Edition.

+

The MIME type for CUPS PostScript files is +application/vnd.cups-postscript.

+

4.5 CUPS Raster File

+

CUPS raster files are device-dependent raster image files that +contain a PostScript page device dictionary and device-dependent raster +imagery for each page in the document. These files are used to transfer +raster data from the PostScript and image file RIPs to device-dependent +filters that convert the raster data to a printable format.

+

A raster file begins with a four byte synchronization word: +0x52615374 ("RaSt") for big-endian architectures and 0x74536152 +("tSaR") for little-endian architectures. The writer of the raster +file will use the native word order, and the reader is responsible for +detecting a reversed word order file and swapping bytes as needed. The +CUPS Image Library raster functions perform this function +automatically.

+

Following the synchronization word are a series of raster pages. + Each page starts with a page device dictionary header and is followed +immediately by the raster data for that page. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Bytes Description + Values
0-63 MediaClass Nul-terminated ASCII string
64-127 MediaColor Nul-terminated ASCII string
128-191 MediaType Nul-terminated ASCII string
192-255 OutputType Nul-terminated ASCII +string
256-259 AdvanceDistance 0 to 232 + - 1 points
260-263 AdvanceMedia 0 = Never advance roll +
1 = Advance roll after file +
2 = Advance roll after job +
3 = Advance roll after set +
4 = Advance roll after page
264-267 Collate 0 = do not collate copies +
1 = collate copies
268-271 CutMedia 0 = Never cut media +
1 = Cut roll after file +
2 = Cut roll after job +
3 = Cut roll after set +
4 = Cut roll after page
272-275 Duplex 0 = Print single-sided +
1 = Print double-sided
276-283 HWResolution Horizontal and vertical +resolution in dots-per-inch.
284-299 ImagingBoundingBox Four integers +giving the left, bottom, right, and top positions of the page bounding +box in points
300-303 InsertSheet 0 = Do not insert +separator sheets +
1 = Insert separator sheets
304-307 Jog 0 = Do no jog pages +
1 = Jog pages after file +
2 = Jog pages after job +
3 = Jog pages after set
308-311 LeadingEdge 0 = Top edge is first +
1 = Right edge is first +
2 = Bottom edge is first +
3 = Left edge is first
312-319 Margins Left and bottom origin of +image in points
320-323 ManualFeed 0 = Do not manually feed +media +
1 = Manually feed media
324-327 MediaPosition Input slot position +from 0 to N
328-331 MediaWeight Media weight in grams +per meter squared
332-335 MirrorPrint 0 = Do not mirror prints +
1 = Mirror prints
336-339 NegativePrint 0 = Do not invert +prints +
1 = Invert prints
340-343 NumCopies 1 to 232 - 1
344-347 Orientation 0 = Do not rotate page +
1 = Rotate page counter-clockwise +
2 = Turn page upside down +
3 = Rotate page clockwise
348-351 OutputFaceUp 0 = Output face down +
1 = Output face up
352-359 PageSize Width and length in points
360-363 Separations 0 = Print composite image +
1 = Print color separations
364-367 TraySwitch 0 = Do not change trays +if selected tray is empty +
1 = Change trays if selected tray is empty
368-371 Tumble 0 = Do not rotate even pages +when duplexing +
1 = Rotate even pages when duplexing
372-375 cupsWidth Width of page image in +pixels
376-379 cupsHeight Height of page image in +pixels
380-383 cupsMediaType Driver-specific 0 to 2 +32 - 1
384-387 cupsBitsPerColor 1, 2, 4, 8 bits
388-391 cupsBitsPerPixel 1 to 32 bits
392-395 cupsBytesPerLine 1 to 232 + - 1 bytes
396-399 cupsColorOrder 0 = chunky pixels +(CMYK CMYK CMYK) +
1 = banded pixels (CCC MMM YYY KKK) +
2 = planar pixels (CCC... MMM... YYY... KKK...)
400-403 cupsColorSpace 0 = white +
1 = RGB +
2 = RGBA +
3 = black +
4 = CMY +
5 = YMC +
6 = CMYK +
7 = YMCK +
8 = KCMY +
9 = KCMYcm
404-407 cupsCompression Driver-specific 0 to +232 - 1
408-411 cupsRowCount Driver-specific 0 to 2 +32 - 1
412-415 cupsRowFeed Driver-specific 0 to 2 +32 - 1
416-419 cupsRowStep Driver-specific 0 to 2 +32 - 1
+
+

+

The MIME type for CUPS Raster files is +application/vnd.cups-raster.

+

4.6 CUPS Raw Files

+

Raw files are printer-dependent print files that are in a format +suitable to the destination printer (e.g. HP-PCL, HP-RTL, etc.) The +MIME type for CUPS Raw files is application/vnd.cups-raw.

+

4.7 Internet Printing Protocol

+

The Internet Printing Protocol and the CUPS extensions to it are +described in the CUPS Implementation of IPP document.

+

4.8 Line Printer Daemon Protocol

+

The Line Printer Daemon (LPD) protocol is described by +RFC 1179: Line Printer Daemon Protocol.

+

The URI method name for LPD is "lpd".

+

4.9 Server Message Block Protocol

+

The Server Message Block (SMB) and related Common Internet File +System (CIFS) protocols are described at +http://anu.samba.org/cifs.

+

The URI method name for SMB is "smb". Support for this protocol is +provided via the SAMBA smbspool(1) program provided with +SAMBA 2.0.6 and higher.

+

5 Directories

+
+
/etc/cups
+
The scheduler configuration and MIME files reside here.
+
/etc/cups/certs
+
The authentication certificates reside here.
+
/etc/cups/interfaces
+
System V interface scripts reside here.
+
/etc/cups/ppd
+
This directory contains PPD files for each printer.
+
/usr/bin
+
The cancel, lp, lpq, + lpr, lprm, and lpstat commands + reside here.
+
/usr/lib, /usr/lib32
+
The shared libraries (DSOs) reside here.
+
/usr/lib/cups/backend
+
The backend filters reside here.
+
/usr/lib/cups/cgi-bin
+
The CGI programs reside here.
+
/usr/lib/cups/daemon
+
The polling and LPD daemons reside here.
+
/usr/lib/cups/filter
+
The file filters reside here.
+
/usr/sbin
+
The accept, cupsd, lpadmin +, lpc, and reject commands reside here.
+
/usr/share/cups
+
This is the root directory of the CUPS static data.
+
/usr/share/cups/charsets
+
The character set files reside here.
+
/usr/share/cups/data
+
The filter data files reside here.
+
/usr/share/cups/fonts
+
The pstoraster font files reside here.
+
/usr/share/cups/model
+
The sample PPD files reside here.
+
/usr/share/cups/pstoraster
+
The pstoraster data files reside here.
+
/usr/share/doc/cups
+
The scheduler documentation files reside here.
+
/var/log/cups
+
The access_log, error_log, and + page_log files reside here.
+
/var/spool/cups
+
This directory contains print job files.
+
+

A Glossary

+

A.1 Terms

+
+
C
+
A computer language.
+
parallel
+
Sending or receiving data more than 1 bit at a time.
+
pipe
+
A one-way communications channel between two programs.
+
serial
+
Sending or receiving data 1 bit at a time.
+
socket
+
A two-way network communications channel.
+
+

A.2 Acronyms

+
+
ASCII
+
American Standard Code for Information Interchange
+
CUPS
+
Common UNIX Printing System
+
ESC/P
+
EPSON Standard Code for Printers
+
FTP
+
File Transfer Protocol
+
HP-GL
+
Hewlett-Packard Graphics Language
+
HP-PCL
+
Hewlett-Packard Printer Control Language
+
HP-PJL
+
Hewlett-Packard Printer Job Language
+
IETF
+
Internet Engineering Task Force
+
IPP
+
Internet Printing Protocol
+
ISO
+
International Standards Organization
+
LPD
+
Line Printer Daemon
+
MIME
+
Multimedia Internet Mail Exchange
+
PCL
+
Page Control Language
+
PPD
+
PostScript Printer Description
+
SMB
+
Server Message Block
+
TFTP
+
Trivial File Transfer Protocol
+
+ + diff --git a/doc/idd.pdf b/doc/idd.pdf new file mode 100644 index 0000000000..faf4eedbd4 --- /dev/null +++ b/doc/idd.pdf @@ -0,0 +1,936 @@ +%PDF-1.2 +%âãÏÓ +1 0 obj<>endobj +2 0 obj<>endobj +3 0 obj<>endobj +4 0 obj<>endobj +5 0 obj<>endobj +6 0 obj<>endobj +7 0 obj<>endobj +8 0 obj<>endobj +9 0 obj<>endobj +10 0 obj<>endobj +11 0 obj<>endobj +12 0 obj<>endobj +13 0 obj<>endobj +14 0 obj<>endobj +15 0 obj[12 0 R +14 0 R +]endobj +16 0 obj<>endobj +17 0 obj<>endobj +18 0 obj<>endobj +19 0 obj<>endobj +20 0 obj<>endobj +21 0 obj<>endobj +22 0 obj<>endobj +23 0 obj<>endobj +24 0 obj<>endobj +25 0 obj<>endobj +26 0 obj<>endobj +27 0 obj<>endobj +28 0 obj<>endobj +29 0 obj<>endobj +30 0 obj<>endobj +31 0 obj<>endobj +32 0 obj<>endobj +33 0 obj<>endobj +34 0 obj<>endobj +35 0 obj<>endobj +36 0 obj<>endobj +37 0 obj<>endobj +38 0 obj<>endobj +39 0 obj<>endobj +40 0 obj<>endobj +41 0 obj<>endobj +42 0 obj<>endobj +43 0 obj<>endobj +44 0 obj<>endobj +45 0 obj<>endobj +46 0 obj<>endobj +47 0 obj<>endobj +48 0 obj<>endobj +49 0 obj<>endobj +50 0 obj<>endobj +51 0 obj<>endobj +52 0 obj<>endobj +53 0 obj<>endobj +54 0 obj[17 0 R +19 0 R +21 0 R +23 0 R +25 0 R +27 0 R +29 0 R +31 0 R +33 0 R +35 0 R +37 0 R +39 0 R +41 0 R +43 0 R +45 0 R +47 0 R +49 0 R +51 0 R +53 0 R +]endobj +55 0 obj<>endobj +56 0 obj<>endobj +57 0 obj<>endobj +58 0 obj<>endobj +59 0 obj<>endobj +60 0 obj<>endobj +61 0 obj[56 0 R +58 0 R +60 0 R +]endobj +62 0 obj<>endobj +63 0 obj<>endobj +64 0 obj<>endobj +65 0 obj<>endobj +66 0 obj[63 0 R +65 0 R +]endobj +67 0 obj<>endobj +68 0 obj<>endobj +69 0 obj<>endobj +70 0 obj<>endobj +71 0 obj[68 0 R +70 0 R +]endobj +72 0 obj<>endobj +73 0 obj<>endobj +74 0 obj<>endobj +75 0 obj<>endobj +76 0 obj<>endobj +77 0 obj<>endobj +78 0 obj<>endobj +79 0 obj<>endobj +80 0 obj<>endobj +81 0 obj<>endobj +82 0 obj<>endobj +83 0 obj<>endobj +84 0 obj<>endobj +85 0 obj<>endobj +86 0 obj<>endobj +87 0 obj<>endobj +88 0 obj<>endobj +89 0 obj<>endobj +90 0 obj<>endobj +91 0 obj<>endobj +92 0 obj<>endobj +93 0 obj<>endobj +94 0 obj<>endobj +95 0 obj<>endobj +96 0 obj<>endobj +97 0 obj<>endobj +98 0 obj<>endobj +99 0 obj<>endobj +100 0 obj<>endobj +101 0 obj<>endobj +102 0 obj<>endobj +103 0 obj<>endobj +104 0 obj<>endobj +105 0 obj<>endobj +106 0 obj<>endobj +107 0 obj<>endobj +108 0 obj<>endobj +109 0 obj<>endobj +110 0 obj[72 0 R +73 0 R +74 0 R +75 0 R +76 0 R +77 0 R +78 0 R +79 0 R +80 0 R +81 0 R +82 0 R +83 0 R +84 0 R +85 0 R +86 0 R +87 0 R +88 0 R +89 0 R +90 0 R +91 0 R +92 0 R +93 0 R +94 0 R +95 0 R +96 0 R +97 0 R +98 0 R +99 0 R +100 0 R +101 0 R +102 0 R +103 0 R +104 0 R +105 0 R +106 0 R +107 0 R +108 0 R +109 0 R +]endobj +111 0 obj<>endobj +112 0 obj<>endobj +113 0 obj<>endobj +114 0 obj<>endobj +115 0 obj<>endobj +116 0 obj<>endobj +117 0 obj<>endobj +118 0 obj<>endobj +119 0 obj<>endobj +120 0 obj<>endobj +121 0 obj<>endobj +122 0 obj<>endobj +123 0 obj<>endobj +124 0 obj<>endobj +125 0 obj<>endobj +126 0 obj<>endobj +127 0 obj<>endobj +128 0 obj<>endobj +129 0 obj<>endobj +130 0 obj<>endobj +131 0 obj<>endobj +132 0 obj<>endobj +133 0 obj<>endobj +134 0 obj<>endobj +135 0 obj<>endobj +136 0 obj<>endobj +137 0 obj<>endobj +138 0 obj<>endobj +139 0 obj<>endobj +140 0 obj<>endobj +141 0 obj<>endobj +142 0 obj<>endobj +143 0 obj<>endobj +144 0 obj<>endobj +145 0 obj<>endobj +146 0 obj<>endobj +147 0 obj<>endobj +148 0 obj<>endobj +149 0 obj<>endobj +150 0 obj<>endobj +151 0 obj<>endobj +152 0 obj<>endobj +153 0 obj<>endobj +154 0 obj<>>>>>endobj +155 0 obj<>stream +xÚìÏsë8rÇIŠºÌ‰öŒî´üt§çyšÝ­ÚJñÙfvçÖ$ÁÊ!•S*Ç6•üÿ±~X"H€èn$è5¦jêÙE|ˆÆ·@ƒúÇOßòýÛßò?=å¿ýžÿçÿô,~*ÅOÿÈÛÿù×?þøÛï¿ÿºÏÿü—_Ÿò§§§·kýñõ¥ù÷¯|­ÿöœþº?•ßNå÷SùË©¼œÊ¿žÊ¿üÇ×?òÿýŸÿû¯¯ÿ–ÿíÛ׿ç‡oß¾>ÃKþ=ÿãõ§öcøä²+âõi»Ý>ÜËÛ?¶ß_—Î%^¶wY¤*w÷¯ËäOj¤Üöû¸ē‰é½Ü?–KáÂC]о/ëå!"—x[ÎõœE¼r˜ë‰KåÒ!˜¾rÛg޹^òȾü\ÆÕÊÏ3s=GžJRÎÉõ-òVâÃl\ŽuЄõV¾ÌÂ%²( + ‚B¹ü29×$X,0X –€Åƒ %ƒ/° ¬(ÚMÄåÝoÙ9h6×ÄXo`å\ûhò’LÀõ#𡬼sÕÑ,åÏ\M6A!|…gi,A +Ú Ñ ê£s5Ѭåà‹+›— 9Ä`™ãÅ`ž‹,öD.1?V{àÊàŠRç\uD98æY\‰c®}HÙ8媣`Jé++D91WT蚐°ŒÒË TÔ  LÔ‹Š4ðZåªBÃ2t,OãQ ÔxŒsÆq‰±FãzX¢Æ#F,Ï%£FL×]w÷Ûí—×cy>|ðÛa0IwÅ÷_†ƒüxÂ[‡ÿîŠG’þÅ˃ŸßÝuoœ*=[ í,¸ö~ºªÛk[ça=xì.Bú±àæØ\ìPƒ–.Î$[q¹¸¡==·aMJ&³»XéԜ.K™\¬@ž› É貘ÇUùÑv‡]¶cqeSÙà՛eN¤ܯjؤ½s’  ®|²¡ÅϼJé\Í Xd°˜ÎEùØÍÉÜZ9ƹfÂ"‚­¨\Õ FÈ1ŒȕυEÛи'’ –Y¹0p7ñú¥uZj+Cg‘¼c,Òé« …«rÎX•½ÅÍÁ‘jÄ¥{.B J<—°ÒlKÃ7D=Ì:¸ÎåÛÁÉ %i=•œkˆàBf½ .Ú`Ø`¹Š¹2O”,Á W­Ç’ó ìÍПR4q‡ãÚa…„–¤8®´&1Š«žÙ#3ì€á«aÚz/8 [c¸²0Dƒ¢õ ‚«æfóuXiæ*B J‡íÌ\Y OjOjäªÃê.d‡%F®"°îBú°ÒĕÖ]È'½1p5Á¸dZ“RW\wá¢ÄÄÀ•6ºÐRVŽr‰» 7æw£\u€Ý…[FJG¹*OŠ…²¢d”+ (2$*ÇVå'ÆB ÃRåÓ©¹Z’ Wå“s! q5ÂÀÚÛ=W¢È£­ÔrAˆ"v@;-W¨jàLi­ã¡ªnè¯t\5-4”=Ùí§ž±¿ÿ.Ï´’T¹Æúù=¾aÀ +¢6(®–KH·Kh%ºÖRÕÓbQ®•–ër›®Îa‡Àà ¯Çé¹ £^ >ÜÌіœáµCrí´\MçùÖ 1£$UsÑys¥Z®³í%·NH)}¢æÊ‰Îkœ+ÑsÝ´BPf=ègŒàp‡åz7.×MÛk¼b”¾Tq5ÔÊÀµÑrÝD° ¬•T؇ô¹WŠçZ鹊÷G”Q&ß V<זByW¤çª/ŸÕPÌ1PRWF4C#×NËu¾×úü+ü’QØV +.A5C#WªçڟòáªÕr[¬àª©fhäŠõ\盽§5Rì•K,×êZ[Éu6Ž;êÊ12BªWNZ,×:{—'%WG¤(³ÔgO@• ž«x j®Š5K5†ˆëWC6Ãq®ZÂp ÖbI…Ó5 ÊFÒâ¹Ä»Y¨¹®&EZ,ip-â\9%pžê¹*֚Nè(; +\n£á¬5;c+\ŒôÅq®æ" +®K‰kvª‰@“¤¥pµ¥×qgéB™ÐdcMãº(½Ž«àôWòD@“ë¢ô:®Œ3¾êÙwCÅuQz WÍÛÃÈ0’ ¤h#!r]”^ÃUðûMÏ%s Æð2r•^Õñ6g +ÌÃ’lì¨\g¥Ws5Ì]Œ +㘁´¶ÑR¹ÎJ¯æ½ØER2WÁ^f®“Ò«¹rfæŽÀ8f DQ)ëd݅~^¹e¢IàkSYŽ­\§Öç*®³Ý Fȑ#š ”(ªT?º²k ±ÌukDŸ+?krN7Ä="àVÌµë>š>h¸Þ;а›‚]†Yw¹k6+IlºŠšô¸ Wuáiè†X!dr¸Ñ˜ÄjøCýsȵèÝJ´§•¸rŽlH[âã‹:\…’K\[°'¢@Ø¢C­I¤€]Ÿ«VrU×Ê=öEèà£ÃDïû¯´ùÖṌŸêsí¯#èùVž«áxåÛ-â;^WÈ\OÌɱonn0¾d=äª\ÝT”‚lˆ{ó€¼0ÚT¹WWojò$ ð\{–l lbÕ¹.¶*qeÝKž„‰×ñÒáÊY²Ñ˜×Ó{Šyq—KΈÚ{ÈhzªX¯üPy8Å:F—« »òúh9ÔNþnï5ùÒ*¹Ä€+“,¯ñª è¨Wo'ÍéŧñýGH©\SßËy°†ÇeŽæãvQ°2Ÿ,’+çEQÁse¼(*t.a#‡s5–r*W͍çª>š^¸ +vt6מ͕4™¿peM/\œ¥ùp‰'óg®úÃÉ<–k2ߝÎ-‡͋ó·•Ü:\[æ»uîªßFwÒ²ßmµwpœOm›.Ò,²Î-ï\·u›þà,•\×FÍÕI¿\¹r¶ûRãkT§×ćk¥äjÔûËÛ}©4fÜkbÄኔ\¹z߁¿h£¶W]nj¯‰;×NÁU UPn9Ár­4áËNŕr¸RW6|ŒŽ¹Î«Ëë51áp%C®wшﲫÝÊ-§h®š+Vqõó¡¸g¯r~ô'/ÙÅlp\ëQ®Ó¿^òHjÁZv,¥Šk£tEr<Џ¨ëdÞ7ÛnlÌ\—᯻?"éx@·‰+×à¢Zr—Ûj{‡àꤥÈ]|Ëíé71âp .’7.y<€ +£®[‘"K~­lâŽÃÕ¿(—óM +-áðì8—Ðpz®”ÃÕ¿¨7RNf™*Œj1\·Ùÿj®˜ÃÕ»¨ðTà¹b\Šã|f.ÅEußÁnßÊ#`ÂÃĞk¨Šã|f.ÝÀT5_ŽÜp ×^­óŠã|®áE…ÒÁ&ŒJ[=Ì®9·r‡Çù\Ër¥#Bq­Q\µÚ՚8JqœÁ5¼HËU;â*”ñÆË- é5qxœÁ5¼(S:"×Ã%¢"ÎSÇù0\ƒ‹´\?Œê´áò;ô¼RqœÃ5¸¨[ývGסµœm”MçÃp .Òr?ŒjÕ£YU4ñ"Ú4®þE\-š+Uý6.5MìçCqõ/Òr¹ê^,ÕMìçCqõ/Òríùáa«68Íòþ ‰ýã|(®þEY/Mõʕ;ãŠK W'T•šØ;·ãê]ÄçJ\ñ®óۋ_¾,{lÔMìçÃqõ.Ê;Š-qen¸:ù‡Ýxã¼ì‘ª›Ø;·ãê]4ˆ£*,WÚâæ)­Š«ó~(EO¢Må’/Ú÷#¢âÂùåªÇ¸äã|H.ÅÀn÷X®µW£‹ç¯AeNä’/ªúC%;s Ï\BsŠCqœÉ%_T÷$[DX®W;Ê.é"Ñ Í« ¸—|Q&°üÂeÎ=Üy䒎óa¹ä‹ +E2þW=/WÁá’.ªn»Ê·EÞÙ¹j—t‘è¶²¾Æ6ÓJ\‚Ã%_”ßö¿ž#W铫{œÍ%_T ö+Càª8\òE½H0?qÙL—Q\Ù8WÃá’/’gÆé>®Îq>ès¥”ºór=ŸÞa?bšK©;3×Cÿøšü²¡ÎæuÕ»ꝪHqPJÛ:k®|¾!çéw·§†u\y1Ô׏áŒF~™WsÛìø9QeäÚÉÔ—Pì(É/4¬®KüuòÈȵ™‚ TSë¼;Àz齺 ®u+ M?\™j« ºã “Òdúu\©l)^¸š÷§»nÝî«ko»õʺ ®Dºµ®êºQ(¾unڑÀ[v…².Ÿ«öÉUtv¬÷7ïÒqY·äsM]Õ2¿ú®òöNå“+ª›v^Ȭ©K㊯ۧoƒ8ñƕu—áòžÒߌ§©KãJ®£0qÙÄóҟá¦×VËIÚªº$®Õõq¼=™t®êöÓ5ä$mU]WÚ}tk;.CúáõÏÍÝ[ÙtĪ윑Ò×%qÏ]ÓÆ+W¢ûѧ“T<¶ÔçÊ/ƒô8„wÞ¸2]:ÎeO¹éÀd#©;x®ýåóŽŸ|ðÆuŽš¸1‘†‘¶.‰«¸ÈÐÑÒKo\—½Îûƒ:À:eR¼Ë¹¶.‰ nÙ¯qëë¢Z{þ⇬ã‹õu•\ÃÄÎEu¯G÷叫“Òkmñîm®¾X_—ÂU_ `ü`;®±}½n=é½ÄÕ0‹V[—ÂÕ\~<ºeK®±}ØByŽCš—ƺ.]_ˆ¾ç²Ú_ÚÌÒ|Õ¢¯Kàj/Žùô[\½,Ú¸ôdЍKá:;æ“[öÉÕyіL¡ú’9]] +×Ù1×'ï“ëý ì —J•l:ZÇuvÌõ©¾—1ïë9Sš\ùPÔuñ~ùäËãÿc—‹|¶—‡á¤¦ÒLrTu \ÕÉOnÙ?×­µ«^(u@Õ%póÉ-OÁõ. +‰vЌÕ%póÉ-[raß-Z‹ÁX]—x÷b멸n‰×f®^]×Ù1ŸEr”Ë&ûø*™ìе\cu)\o&˜4·õS/\²{ãb§®.…ëM2âúì-¹JÜú¡k¬.…ëØÓUt}Q7®D²­x”KW—Âçð±‰ËæÜM.ý9Õù±º®ê|²&±çڍO¿6ÝyÈJË5V—ÂUߜº7®ªÛŸûÞmz«Kájn³Q.›sˆçkãï·M­–k¬®!ž—Þ¶%ä]A ®qö¶ ©Ÿ,ŽÕ¥puÞ ë«™«õ¹F꒸r—Õ¹ìf¤jŸk¤.ƒ«´çZãÒmú¡ÿ VÑ×%qƒßxàjô +3àj¸ëQ2\ŸÊ(—Õû7䵘_ÚQ.}]—îý¬n¹:}l \Úº$®úêÓǹ¬²Þè!Ón”ØÔµ*–ïí¹Ê×ëMóU|–ïY +¶X¾ë“kz.ó떗ÉUüÓr•‹ä2/pÉe3aþ䚞Ëjb¹h®õ"¹Ä?-WºH.ólõA¹’ere0ðµü>ŽO®¸ö0ðÅ}Ïn‘\ðA¹ª Z~¯Ù\Åô²×å÷ÐÍULMÞá¾70¸@ªrÃ\ e’ºÒò{9ç*Š+[\Àa +%°ß{ZÀ‘›ì ù=Å¡­´e&=@~¯thG„â‚¥Âèo‘ßoXÀQã¸÷}ô•±mç˜Á8lc®Á9æ½Qæ#/Á9°Üè–ã‚s`™±Åš3‡}€²×ÀXcV@éK`3Ëڬހò9°ÊÜX@=€ÀXa6.@l`3°½9êT˜ËÍ"8á Kèmœ£ Jè„m®gƒú¡€S˜ „A:àª%ô¢©€ìڐ„>G˜ ‡bH}fv_ï\bAB/0Ò -Vè׋‘Ã]‡+_Ž V˜Ȑ+ A,0 +-V裥ÈaÜ媗#ˆ(Â-ôDˆ *âƒ-ôéBäpÝåB} Â(»‚-ôÇ¥€VÏP„#C̾:\ÕB")£œ· Å }ºÙHd.„Ð'‹TæB,Ýċu+_†pd8üƒ"âȇxà B8j¤—Â!Gl#´A `1Û¨«>BðÌØå +h)‚¸xí\Åú,(ÖCéÑg­¡% ÇÜ ýŽhIÂ1ó3?ú•‚+~€áï€d¼s°=z @KŽy>r’s˜y€Õø©bå™a÷H*:sˆH؇–(30Ê&ÐúyÖ9eˆιÈQDs‘ƒ²Ôā9£Ò7”AОQéI+Ò@½t>¥Ï)Mª’ζÚ&HšÔ¡9›!"li¥åڇkˆ´åhél¨vc! »ô™ ±¢g83âžö¼nų¢ †®@žâÌcˆñqCË`3Ĉ9qx@Ë`iˆf(Í4€ó`¦Ÿ¬Tԇ -g€M>kΩj-k€MœdY“½´¬6± +ÈcX]>±rz‹€5D'VFÔ +œéöÔ1GNÀY™8樼A:©ÔgB©œÇ Üϙ.H,8ޏÃtºc wàÊêd†kÍÁ…Tú‰:,c=càÔ4Æ €?R§é°ŒÖÛNÓaә_‚& :C¢Åqí±`»0ºk…äªé0‘qƒph­ ±÷UKó„ªY.´v†èuâ,øV­!zÕzìÓÝ ¹ð†èQ:j ›ÖÖãrfWŠØ ¬OKüñÍPË%¢¹-±±’.h­ ѓ&æV>¬­'BõÊXZ?Þ¹±´°öõ^†˜È,e \<1÷3–½í#×½{&ܸ¥rU¤s©ÍJÉ\"š LdöܹK0‘;¸)82‡i\o\´;¼•Ÿ'–‘P¬.t¬Â^¿¹1p1_uFÃÒÇàd}¡ãNSbé¥ +\EiW°/)áøf08Ô&[õ cœFwžÿf<[l2êR6W›qÀúßtŽ*OôÛø\‹+Š¿S;‹añcq€‰‹ÙaQt_zî¬ñ¹‘‘«ˆ¸ÿ¥ó/9k·6\"â—{”56¼OßYqYtØqœ=šÌñ…Ie˜>˜¹l:ìŒöªÿ짌ý¹K.ê4Li¯ƒ~/ÛÌæqµ¶\Mä¦ÜÝo·Û/¯oåe»}È,?mcÍå¢ÃœSþ#†KȵqÀe'‰³tŽ+¼Û9á +®ÃÌK_8.±´îBrvm¦(ˆ=$W›…ÄupÇU/«»Ð\¬•O_ºäj‚áÚ´.¹‚ÑzÜöžKdKÑxw gÑ q!Øý^ +—XŒÒ¸°DôÖ!‰kvKÄgиš…X!•kæø—°MäšÕ)¹/T®9½3eû‰Ê5c`OJš#sÍ6Ähi/t®™†1±ŒÁ5Ï#îí2¸fbÔ,%=pÍ`sM®ôT9×ÄÚÁÈdr‰<\)´ášRY©Ã\®éÀx™dl.FÚÏ$ŽËšk¢Éóā×þ9椰áòoŠü,M+.ß`ɧv\~UÑ&Yؒ˧ƒ¶Ê¶åòf—ŒoÍEΡö41qÏåcÚb™®î†Ë½,ڟ›pÂÕ +·¶øhß"7\o¶è®Ë’CW+Âé,—\ŽºìþІÆÕŠ'küâª-.¹ø©ÕªGw-qËe‘^Hݞ“‹Kæ–ʇìþ‹ë6øà"æÅÇ[ï¹ðÃõV^qÙññýw/·÷Æuê5ƒAÞm_}ÝÛ'ש۞¶wê~z|õy_ß\çŽ;žpØ>ÜËývûøúêý–“pÍPàÿÿÿârõä +äÿÿEÎË‚0Ð=_q—šØÚi냥 +&î|Ô PC€´UãßkݸšäÎ=“Ùšd¾O!L•æKÐZó5L5Áîz¼àÐëꢴȬo›>ŽÒµch‡~jî_­A5)É).#š²Œ§Xd´à)˜\r×yá߸ uxÎâè†êQÿ+jõ}ãgß®mn”¦+&…3lºçzœ­·îi«Hs“œ’!@ñ endstream +endobj +156 0 obj +6290 +endobj +157 0 obj<>>>endobj +158 0 obj<>stream +xÚ+ä2T0BCc3JÎår +ár á +äHÉHendstream +endobj +159 0 obj +31 +endobj +160 0 obj<>>>/Annots 15 0 R>>endobj +161 0 obj<>stream +xÚ¥UMsÛ6½ëWìädÏT¬HQî-Ž\WÄaM9Ӄ. JˆA‚@©ê¯ï.…²âvšÉx†±_oß>,¿ bá_ ³ÆS(êÁíjðó¯7Œ`U¡e:›Ãª¼Š!/T˯WŸ5žyëpœF‰³G1,KÞXQ‰‚Y¡ïšB×dMÉuµDc¹®XÁ¡äFlúWhÑR$”ªèjÌ­V{´Z&$/¡Â'TJ×̚Ÿ æÆ°íÙkJ +ÚjVS}¬=ÀB5{‚§Cî`wÞ©ºÆrOË?!ÓI4[ȏÆòÖWoÞ=eù›õ5|âÚ,ì1ú–€$J=É)ôãžë½àò½[ FÑ)¦GLÇ{H§q4‡IšD#¨!Dÿ&!÷èy›¤cÊO`z>´J[¶A2ÚpɎ\»Þ¨¡u2™7Ì g87͜‹qMK ;f`Ã91¿ç}JØÁ±ö°ÞÂÕ3Çm_`’̱%l&‰&á…zy¥÷Þ¡†yü54tN¯7‘“\®*{`šãhTÙÖ¼Ä6:a«ˆ˜ZY޼‹`ºìy1JvNVD “ÒÏÅP*mœb:ƒŽàÅò!¹„ñ~r1·\?sɏP ˆð`(EÃ{Y›($H¦^.92NyKòk¸íe‡MZU(IÂ[féŽy_¢ðšÅ:lKή7ø¬6ÿ—ŽwXVèýa\`w5P ÆIîXà}¶ 9êÏ?„[t+UñLæüÃ-šýmzÛ¶9#Ôõ‹ž#ÁïÜ.„æ…Åm€@pRLuQÜt-IÕuvšã(éwMACaRØc ž•¥$å ô³oÁm´:ê™ÀdÊØÜ­ M]T[œml$ó}úkðUªõkuÐ!,&‡XWž¹uMÉý]zu–Ô+됝¿Eg¬ªÅßXi†ªàþá îwÛãBPE§5."y °Tõ­×$šŒÖ×½¬Q»G{ðq™¡B˜uÜw”쬥F5Ã3¾Ÿ¨’œÕ-—ZN'¬ß2Gï]–|¸¨zŠs5B»¥¯ŠI Æ¡q¹ÿc;ŽaqÚêçûñG¿è¨ô–5Žw QîÊTJJup—Ÿ;™™_|±"Փôó\'Ó¼Dƒ¼áù'¯èQž˜y- +“Â#¯8N¸ð;䇎1Ô¯&ý·G¾+GŠ9îþú±Ì᯷Òâ;cßbì½T¸NôћæÁ4 Œ§“ èÙMç£èSÓqøÈü1øøF•@endstream +endobj +162 0 obj +957 +endobj +163 0 obj<>>>>>endobj +164 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Ó3T072PIÑPp VðÌ+I-JKLNUpI-ÎLÏQÉE™%™ùyš!Y\º=ºPMF 1c=30ßPA!89¿ $ìÂÈJm!endstream +endobj +165 0 obj +116 +endobj +166 0 obj<>>>/Annots 54 0 R>>endobj +167 0 obj<>stream +xÚµ˜MSã8†ïü +ÙªÄcɉ?¸†-¨Éb3§½G ފí¬íÿŸnɝ…È!°EU(%[J÷«W­ü{™ œy‚9.K²“‹èäÛuÀ„Í¢%|âz>‹§‚=È¥,ežÈêè…pO#cgb Yœ]>ÎC6+’m&ó:®Ó"×ø„qÞà³\Ä£gɖÅz]¼¤ùJ?¸ ²´be;ë‚=½²úÞj™38i 1®5ÁØ ×c»3Ÿâ ãËûù˜[üLÏwYäËtµ-õ|÷q¯$ÆfóuœïƇ…sGϽÁog3<|­j™±Û¼–å2N$›É*]åø/)ÓMŸ›M1§ë¿Í6ë>_ŒÁǏžßcLëW»ðbY¿Ä¥dç‹,ÍÓª†üe…ùÙÆë#â殮þéç{–>/‹UgJëèu‡ï­;”ɶLëWØ›¢¬ˆÍߋÉêXᅏ{ÒðXÉÏîçìý°?!**îMíZWëíè½ ~Ôϲ쬡:Ðò"ïXCÅpŸö…«èĶlð>|áøòphÙÌñXHÆ<Ûò›Áš…ïЮ~×Ҝû8ç.å'ƒ˜{O àÀššyBïamzþ€jz\ïØ7Õ¼‹óÕÎé¾#±è9-ìj‘b-q?8FÏØŸÅ‹óE'ŸPÖìÇFêf¡ú›B¼oÊñ¯ò¤X ¯a਌óêÃGH Õ­ ÅßlӅ<.Î}±kµ Pfq^§É_Πp{¢jî*Á¨Áû™*…4´ïu¾O÷ƒ=€SÝV þL°»Ü¦]aT˜ºÞ¨í¢oŠx]AßTÂFÖWŽ\6'ÚÍÿ§#ȘÝéH L:jh-M¨´‘fœ¨#¯›kŸŽ<²î:°—%ðtUª5ñ„ÞÅîÖÈx:OJ`¯·[ÜtêD¥þˆ=¨C3^K%Q¸ °°.·I½…^®­øF ™Åzڅ0Ëü3¢v±ùlE­&Q7´Ö¬&šcÿì>s¤Ñ94„™'ðÞ½ŒY ¶"ž‘§„>dÌë¡DÖìF#Oln\t£Ž?@NÐ·Ä hn°âì| f×u†œ±‹¸Jµígé +3;OYUûN‹ÝÇõÉà·JiÇݼ‚ýçWî‰oÃw°ñ3§QÐ_'¿Ý7UXendstream +endobj +168 0 obj +1339 +endobj +169 0 obj<>>>>>endobj +170 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Ó3T072PIÑPp VðÌ+I-JKLNUpI-ÎLÏQÉE™%™ùyš!Y\º=ºPM& 1C =S0ßHA!(5-µ(5/9µ$çÂÈþî#(endstream +endobj +171 0 obj +121 +endobj +172 0 obj<>>>>>endobj +173 0 obj<>stream +xÚ½VM"7½ó+J +AgøX2§]2H\¢l†h/s1ÝnڑÛîØîþ}ªì64=Ãf¥H™‘À4õñüêU&ð€ÿxœÂlY5ø¼ü¼YÁôv~³x\Â.Î`«7ŠÉp(XÆí‡Ý_Þvòldzy:õÖéÖ%3,CSxá6BFû9L&­ýô1]ý®ä]ì-Úd9/„âÀ bu-ÔöÜ9W°ºX`*‡QþT"Óy/Ú´‰®„3Ofi´'ÿÚºZ9›‚:3«x%”cû¼Ûø”¾Œ@s +þجþyËÃEzI)觗õv ŽŸÍ0)WtÇRd%Šj3#öwÏ¥>¦°ÖU…F2¦ð¦Ëd“Ó÷ç¾@óCKóð§[ڇWnz°<¹ÂXäV˦R‡Ä»¥—bÏcñVé¼-6–{9þŒù±¢“W¯‚¢[njƒ£pe› g9^î—x±EBµŽ§ó!c‰1o󍽙ÙFK$1„äR(ºÅÌE©y°Hm¡MŜÐê~Þ@•dø’ Ã3²Fä9BWä-a¯%ªÂ1)2‡sˆÈÞIû#qÞz )ç3Ã;$'ì Ïui!V—.ÛÉß<ÓÆp[kê ‘Ñ“o»“¨šŠT0ý¸èÉ¥Ó}­),Š‘J‡Ù8CŒnêQ¬æm¼ÃÂëЗ„ª¿kë^Pöµë哢BòˆâôõuW¸|c²á¡ž%?±œg™Oo #Ý-BÑ~•êó'¬gÈ:CÜ$Òi“Œ 1NËďd R™‹ ‘ •ä…;=6âPb'û7úLϽÏÍødØ>T¿s1÷á~%9ý Tj}ɏ1×ÍÏOPq¦Z»ÈY`ËE†“Ï’bý{˜I׺¾?Öº1;֝kNkà>ôß|Œ¼ðGÐUþå&£÷Äý¦QÞj<&·¤Ù†æ,ÞÝ+®F1㌠Bmq³%Ð[+yîÏãoLHFdá6‘ܳôɔ÷Á—kZ°¥n$Íeœ!Ö¡è_‡<=¤¼œ+„ŸDŸ Žï7Ï>Ö¬µ= +){0ނ¹>*©MvQ€âOðHXü–B„i!’M axńòºô“í²?¯séŠ;/´OœD ëïa¿Å:\ø÷zðþà<àŒ·;%ŒÁUÜ)Ó Ðß*ï®ÿÿ¾W¸Â¨hywl?ß¼éÓèß«W1vþd `å¼Äð¥Û؍+– E±M]kƒâé—ýîVóµ? þ·•¶ìr3[¥íÇ{¿çˇt…åC£ôùy7ø2øöïR—endstream +endobj +174 0 obj +1017 +endobj +175 0 obj<>>>>>endobj +176 0 obj<>stream +xڝWÛnã6}÷W üä,גãKºOÛìP[ÄE_4EÙ,(R%©uܯï )ù¢f[„HbÑԜá̙ 'r˜ãO‹ýòzôÓvôÃ#ƒ<‡m…oV›5lËÉ£´ÎØþ‰ïîºw`º„¸×ËO{CÌ +ðé ’‚½:5RǗF{¨YÓH½Ç æk…k Ê{·Hè#0”{•u[ƒ© X®è¼9dùbV©üÀ,ã^Xœi؉ V”p”þ€§ ư·¦m¦aë_úz3¼L&:”ùjœæV6~pž’µôÌK£g/`‹¾ÏàS­pÁûƒxe¥à²fjvKê)V³;ÒóYZÁI͐?<žrÞ7cåOal½Qø46.Ù©,%GKPJ‰ÊgÞdVî~ +áAßi?`nvà“e;ÉŽyñê¿oîï²ô‡ÿ1Õá§ã`ciÚ®?B\@-˜v1¬¾ç,²å’ `£S†ç§ç‡§'¸Äu`g—A¦µRXð§FTŒ‹ï›þ‹±‰)ìŒ*§€ÁSÑ÷+O¦o%7ÉgoŠŸs¼?ÜQζŽòÚÆŒk0™…+Úhu8ƾ1©‘….2ˆl"¹'Óƒ—cÁL«JJz%Ç¤™ˆÙ~ãçSæ)E¿9¡Þû³Nö(•˜€ŠÐ RC|”樕ÁT.AV …À*<’- †œR¯£ýòuGû¢ˆ´“ÊŸ™Þ·l/àQ*ánY¤­g+¥*R½hE¢PŠJêH2.Y«ü…Ap"6†]C©XFT͔˜iў®Õ Ç½æUë‰Øx­Y.îN´J¾Æ–tIkÞ6îqìJhž%*é°k£]ƒõ^Q>ö(¡©tò¢*žcHÇÇ¡×èvÔ Rm,W‹°Kã\©WI¾=w\,% +ô–:ô¤4å+ ô¤Ž€·Ø‹µÇlÃeöZþ¢—÷c $ïYlЏ³!/Åj ƒz‘Îd›Íò>Ëo‘W$ü'¬Hƒ-Ò`wi°el•[§Á6i°û4X>OÄ%F.O ]þ¾Øµ.cŽKù>¯ÞÉþ/xstÙf}—„Ë‹å<˜§‹Tà"˜LÎ2¸J®S!q²ÛFKÚa{¦{ÿ\Ë9ÞÐa ×Eƒ^߉a¹ê÷ñ-ŽxóqºÞéd Ûz'ì4Nø1¹ãõpVÅIM۔ŒF 2(ÌG¤žUtñÐ×+A¼|ºÑaÓù›/W³¼ÿ~ûú O‘aÐù,œÜkz„™¼›³ˆÉÖŜ@!.‹û9ò3ï'7F/Ûѯ£  ³—endstream +endobj +177 0 obj +1016 +endobj +178 0 obj<>>>>>endobj +179 0 obj<>stream +xÚ­WKsÛ6¾ûWlٜքV$+39¨Ž=ÕÁvZ«—Æ=@$(¡&ã(qÿ{wR’Ɏ=•fH‘ø¾}aÐǃtñۃQއ¿Î:çcè`–áÊð¤³ôð˜ÃÅôâ Îe.ì«Ù?@¯@qĆ;ýóý5TVXpw:2"€T ë¸J¹I!Ñ*“‹Êp'µbA*4òÆlP«e=(d!˜[•;l¶[ ¯R‘IE†àš‰^(ùE¤a-ÀвÃJ‹–é ƒ  ÚÈ=_M®O§Spâ³cpª‹B(G& âÞ1ë“êE¿Œƒ;é–^_©+”}sýݼ‚dÉ Oœ0 ÈÐ9OnmÎí’77psA!L;/L (4…{«Àé–聓ªÂ•%jŒ'*2»F÷‡! g†;˜Š¡Þ!hCßmÊnõA2"ÿËë ñ¹ Zî[ph>·‰”×Yf…ƒè(‚\¨îùÌÒHåø</b[‡ôE‹^>E¥¢àRÙ=z¿_fKÆ'žWâIӗڸ—1^/¡å:á!Ê[~µÐë£ø…%|>@®ù0¹|ïÓAjŽˆ…eô€uõÇ㤢õïP)nVpy5 œM/}›nޔxX<”¡ïnà‡¾{·P>êmœou•åZßB†!@y˜úÆÏ%%pV™[˜¯œÀ úvÇÙ-ã ærcÿ•\aÏkº\«­ÚºØJlQÆC¹ (“ƺÇ[?Ì,ÌÕOÿ×`Ë#·ž7ÚZՃž5ڞ9gÖǃ֤±ßŽ#J#,êÉaueA>¶ O…E?R„Ïà|÷ÌÁa,8ÆÈººÂn»48{Ý.7ô‘!žP½0¼ uœÌ ¦ÙŽ=z7ñ^Û¶ÎÊѺòŽû!+pUúø}Ç9¯à2tY +ЉC^¦à›>M1ÔAX8Rá ʋmQA—í +ÏE8%ÕÛ +òF¨…F¡Üfo«Ä=muˆŽpI'©JÛÉËZL«_ÐæS™hžú¢Â*>‚prÁçùjÇÆSûÓoWg¶_'«Ãng¼L/ Ó?ç ï´{|µ¯MË0à±Ö…ÁÀ—¦/ÈZH؝úä©ñ½ÎÂû¦vögÝ; ŠTÏކZzðÀ{ð";©ïõ»xÂŽ_דÃg֔¶>#¯QvVº%Fz!D{¯‡ÈŠGýnóç¤õïdpÒecð«#z>›ü~ð‹ãØÞendstream +endobj +180 0 obj +1192 +endobj +181 0 obj<>>>/Annots 61 0 R>>endobj +182 0 obj<>stream +xÚ­VMsÛ6½ûW쨇:3MR_V:=´IÜñ¡5V{Ê"! . °hGÿ¾oR¢åXr;Ë@.v÷íÇ[ü}‘PŒ¿„FSþdåÅ/ˋ«›˜æ´\ó“é5VùåGiiQÊ+¥­:“d*§ŒþéQÍÑ&Š¢gÞ-.b&qtt­ESuÿ–ÿêÔÕ͘’„‘u˜NYñr+©PZÒJn”ÖJoèI¹- Z‹R:W™pҒƒlÞ:’#DJ ¶@kSSU+íèÁ¬ì$öR^³ÒþdceÝ¡E)ÒZpÿQÖµÊ_˜YCEÞé°;ëdI½sQ@&Zd1ãŠÆ¬ü¡zû’TÐr±†£ÞmYÓ_Ú<Á„ñ¯ “‰‚à.\z]ÿm›…c™Ð& ½#ëj(,ÒÁŒýtS®üBè<„EçØg¦Æ²b’tFÙVÔ"㌼zã¶Q¼Î>g®–¥P¬€m¸.•™Ñ-ð +•Œw¶™ZYA¯C¾¼óiµ\`x‡@2¬LTb¥ +åގÙvŸ;Æ j_`9­vôáÅ=yTk¶©*S»îÔÐV2Sk•ÑZ +×Ô2Ăß…ÚH3ü€ xʸÃ4ß%J~Ó}«ÎwËZ^ÄQ ºá¯„¿>ÿJÉäÁ'×8^R2á7ì +ºdtˆÜ8™2Í6|Ÿ ÙJḒ»ùîxÝä<î™LGSÊÁäKù¾äg1ž”ïI”4Âïiù¾ä'q4;-ߓ(iÏøß—€|:>£¿/ùÉuþ,%GGêÍ>‹mz~Î Êt)³íq’¾›Äñèý[z…n|._M6€3Aý–4åA6߯Ñ(iÎþŸ’î  “”S²gÐØNCã<«lúœÄ¿ãhäl¯9nƒsyº[ÒОŸ¾:©­§ P÷käÁý‘ç¤ N9kùD^WM˜Lh æ€CO¬daž¾³·÷¨³¦²7¾Ñ_ÚÞ-š­¥ò½MðˆyôãJ0ß>¶a©›Bv\̝ú>h=Ü0†(7¯Õš¦Îä•ÛULؖ‰ÉljQžœÔý©ëOÂ3amSp;¼Z~ûÞzˆnûc®%Á0ƒAO®j™¹b^pÆEqD ;7i0P)v<êZ*•ù¹p§>Ü¿ ݈⃩ԷÞúʘBbœ¢®cKÀçÛEKÒm¸£u°sƒ8ÚáGÀ«äQK^Pé#°˜¿ù +*¢eï6îVpl- ++Ï¡´&—ŝŸú§Á²«g{°]\í!ƒ‡±U²Þö:Á^BCØtn +zž¹#¤(‘?46DÏ4®jœ¿Ñ :²…²n½8‡|ì‘/jÃë_öUtf +µ4á†ø–¶Â 7EÃI ­•3Í8$[”¥ UÆ þÁ{ ÖpªL°N±N±NÓ ùºu7IyºMç“p äuË1XãBŌ®6ºOì||˜`Š$4œA+]ó³*fw7©7_¥0~¿øÃPÁòendstream +endobj +183 0 obj +1199 +endobj +184 0 obj<>>>>>endobj +185 0 obj<>stream +xÚ­WßsÚ8~Ï_±Ã½›âúèôn&%i'¹Ëz3É‹°å Ö–¨$‡ðßßJ² ˜8¡¹Nfˆ±v¥ïÛývWü8 ÀÇ¿Æ!D1$ÅهÅÙۏCXd¸OưHû‹…óÅ7\Š«¥¾¤Jä¥f‚»…Ú§„§mc½]Ó¶ÙÉKª  [XRè z DQ@`Ãò4!2õào½¢rÃ|ØBQ*N:YàDf^»½ýö ˆ¼Ðÿ܉RH8ôêßД‘ÅH‰Ö’-KhSš1NS`Ü ··—±œzƏ coد”rÅôö„`ݓ¢ Ñrçƒ5±¾Õ¶@Òo˜‚r YÉÃT‰AÒ+¢ßÕL§f3Lô : Ù]ÿñîþhöùkãIšÝ!î Zø~¼^IQÞ¯Ž,Ãðyš¢Ç´$\eBbÒ +ü'Ù#à ›‚ÙÍWHDŽßœ¯Ó^´÷ÔÐD†¡ÄÖëœÑ£à“LSyŒßsˆÄsfӝêêôGÞÈ ½$åZýK¥:’߁TŒ¤?J&M#5d |Ä`lV óøàö©³/·s¸¾¼„ –K©ÐµH­I ÚDApåµâ0+¥D¥ä[`ÚÔÒV(<ßC/ðüž©|z;žã +{ÖXæ„·»}ÕncN +;©HKÝ.ƒìS*ò\l\ʺÚ^æZ™[²l!jœ1H¡cäµi%úQ¼Ñ؛ ܉ƒ{Y{£÷Š0ºæ½m7ëzR^-Î|ÏÇ»AóñùØ¡†–pàOÍç¡àÙó'Œƒ(ò¦•u„§÷¬.6¡?qáý̤×FìÏá÷oíš}íΏÏۙI¹7Xu8m²¦Iw³ &”ÛÍvµgÙ8kÇfgl,‡`W@/iFÊ\ÿb*M‡OÝöfDhÆÉ)4G1ŠàdšÖº“f4v$.’„¢`œ0Y¬iÂ2fg5×7 Ûñ1£·vN7ðM,qh߸k`]-vr ö"ÖûJ•I‰ÞKlÝç©l­u'Û p…saªð µ£ë’%Xý8K±ÐKcçÆ–©MR·½àâXR»x¼DÅ5ú|¹ÚœõÕf©LCÊ„s*ç¦GuR1ø–ÖαÀ¬¹æŽŠf¦½ +›W7Ÿñ6LL_ 3‰=ÿd.Ö¸‹Ê8Ú¹âékh؋ÞkXÄ»Rz™E¼«¤c£mïåÛW*‹ ý?Ô5ÿD+·Æ]T¢¡«ükž‰‹ ;zK’WWZ;cêÃ)(íè:yàLšbn͛I5oLw3?x-¸êmn-I(àd÷ZÓpà|•“½Þƒs½j.Ù&þæîÝ\|‡YiÅðŸ³ÿ'bQóendstream +endobj +186 0 obj +1291 +endobj +187 0 obj<>>>>>endobj +188 0 obj<>stream +xÚ½XÛnÛ8}ÏWޗˆU]}Ù>¥q[ØK¶qß +,h‰¶¹•H•¤’Íßï )YŠY + +,š + u8œ9s¥~\㉸“¶ï>Å$ÈvO…“Å*!ÛìÍo2¥†KñvûÏE௽ìƒå+bØ¿¦¢9Ék‘{bŽŒ¤9ÕÚCøÇí…ïùpÐéñå3 c”½\y+âÄk/$Š‘»ÀAyë…+oÙAƒÆNÏEoA¥[Ņaª§è]ÉR¾çLJJ‡5©!W +Vì`á5ª'V驪[ô êñÞ¢’†6¨8ªÆ7ØÖˆ|¢ï{’RAvŒÌn²œÍˆTdvgdY²l6fKìÃs²-=hK¸„gcËïLkz`g|фOád/•³©RŠ ãlsæŽY Ìd+,ú+Þ}Z“ Æð÷I²¶¦DÞiUêÌK¥Ø£m–ød.¶µj7 ²ç9ü-…æÚhtU€>)$”sÁìÒÕÝõ͍åÀ#ײ(Ðb÷,V†°ênš].\/pá²a{Z寮&qD¦SÅ˦& ÇE¼|M¦:ô:|/H1e8Œžß¢'54N"gâUšBœÿ&½Œ výïܽp§×\>Íÿ~•uaù`ãͺEÌ;ÞÐ(R̺z¦5 gMµ¨4xÖH¢ė“Ös&Êæò²p'O9†xòH^ÆQŒôXcãçù·hËÀ9pÍ¿;þ[tSŠâ ®YÇ(í1>?]×^ Ҙ£ò–ì•,œ­µ2r”Ú\öÌڞôU35»„Žd£ff¹š}V²*ǚS´XŸÊú8Y=‘,$+^בÖnË~ûC +6L†M/Ð T2… õ¾Ÿª ](éú@5Ok¶6üÀ´¥ ¬YM§Ë¢§ÒeÁƒtKgÃyÄ®²L±g&‰×ù?L%;%i–Rmu¢NUêúëí]/Ìvx&ô!RÒô;3ˆãɏO3Ïž,z*O<ÄS¸ŠÝœZó4¥6µ¼`ýÑ5)¬®RG½¾¡¡ÇN·z룬ò¬©ü#$…ËðTºÇIrè‰$9ð IIèJ·#iÃÄãÿϑf*OÑúÝ¡§ò­Ïô0ˆº<Ýàµæ³W‘?2Uˆª¹þh 0Ó`·y`L ±U• äÚ#Ww4 +ñOb2®é.gý‘BVæ ;é:Bo°~ÍáÐ'𠂏“©ªìÙ­ÒfïežÎ¥Ñs~%nEf:9O¨Èz´´ÁÞ¿K%q(¶š^o× 7\Z™3¬‘¼(sžr“ƒåÒ¡¹­¡GöØo:8¢ÓvƧO´ÄKöŸþ¡­åýC­¨i§‚~üé¡ÖxKè"ÃނÙXž,¯hi<±YìP JÝ~v+•é1²ˆ‚ósÒ×Í-ð×ݺ=Pt-;®ºôؘV5âø½+ާ·®8>Ó¹¢ åâ Ëépßzö)DËJ¥ ½‰¡ ®5ãÏÞ%á™.„ÕGÝð—ó-h +´e±è²”ÿ´\ר¦k[ëÐa?ÿYÁñ"œ +í[ÔûN:Ø«þª¾ê Y†Ö±vJ%¶!ï)xuÃ4?Òûj1w{æõ¦À6êØÇ8÷Û/O½OO]ü-›Žendstream +endobj +189 0 obj +1507 +endobj +190 0 obj<>>>>>endobj +191 0 obj<>stream +xÚ¥XÛnÛ8}ÏW~jø¢«m´(v›ô4Ûvï[-Q6·é%©¤þû!eÙfbKÙ¢€›(‡C͙ÙCÿ{ ü È4$QJ²êâíâbü>&A@ ÃÙ(%é,!‹ü…b%Ýr±"K%4S„‹BªŠ.)”¬ˆŒèz)˜!F¾\üs1!à …¸š +iÖLðñ»ÅÅd4ÛoHb’¦ lH¯Š‘»' Aæ=±a«£…寇SdçÙ¯\­,9vœ†½±‡q«£•øP|ø;ð§X³·¶Ðwk©ÌgZ1µ &sÜÿ¼uOæáhJ0*<ºÛ°Œœiò°fXo"ÊƒÈFÉ{žƒB0»€Ã‘|ñÀÍZր_32ø TvÏԀl¨2ß_äUIà †)Ý¥§#»wîQ‹¶ùôàЂÃ(=b¼ep2Ý3¸àƒ¤<ú¢É¤¥oGÀž?$@ÔÕ),ˆf™¹F(7¤†—>{ 59ӆ {,5¡ðVøüžåîŒbÜRf´ôÎçÁ*Rrm:ˆMfSÈÃe£|ÎëÐ6Ós`G¬;b÷è±I:k‰…fäqúEôVd£ BEN²’jíúZó€® tY²üɨ KPæ1À8ƒ/E1èb*Iž!A‡î)A>%Á$J×ÔÐk®<ªÆµVc½Œ³zsæ$£br®Xf¤Ú"‹°ËÕ__ïHqIÁKfe汦Íò.nÂp4ëύE÷寂Or[Z]³‚Ö¥¹4óO(×r8›%óaв3y‚‚dƒf()ˆÔ•ø$jO0ÆÎ'nÑ®Qœ7‰[°K|Þ%Ï'(Ü[ßR±ªéŠy™gµRL×)XŸìË&PGâñ ?û&îÐ=wà“‰§ñ®âbëe;ôÅÿµ†¡é +нí¤m÷ÔMþ9YKm.=݃ùyêÇ%¶‡\V”‹.F’_¸çpèžgÀO8š[>dVWPëoRšÓ-"—Ùq›xJ +M$×ÄÛ÷.¢}#è!‹¨m=díÁ²˜4%§”T·Ò( ÿ]ºçgFµÅÁqYنhÏ ÊfD;Å<š¸è€È@o5¬ì& È.Ç)¯Œ¥6¨?‘Œ7`­(·Ú° +±LG0]Ãރۡ{n>5¸£tê˜þ d½ñhF±\b—M&çÇÑ +CX ‰ÇìæRC`P[ú`D 1U Wöú³ %šÑ•¢U—Œ’øÊ¡{N>u8£ OxóÐcÐ|ßJù£9‡~§(Z¦ìº.ÎJö_­¹ùê_Óò\1ðB¥Û׬˜³ã0Ûj`›2ÿŠTt ’õ]è±7"x…®ùJÀ+¦Üúr•{îÙ¼/CŒ¬õp ¼sz)ÀÞxrýy‡Ó( d ¨…íæ(PD/»:S8Ûw¦)¶Ó³ +ph[Žs`§v +Ø£w +[á›jSòŒ›+´¨®`~7h͹òÓÚHì0ÔË-É£æQýv¾8sÚÓä…C&ì‘ Ê/€+”ƪÛÒû930àpbË«“VDþ<Ó`‡ð¹ É H8_!‹¶Œ7²`W¡=º­Ð$v'îc›ßK~ÏþÿmнËRóq±ðO%n0´;jV«öô=‹©`´®³»›9tÏnæÀ§ºY0 x:u!>ßõi%áÞkû¬GÊ~@À#Îe´7o„Zꖬ@g¥Ä[á]&=HæÏ¸¹9t_º,ø$]qêRx}Ûø²¡fýÆÏðõx÷÷7{*ꆧœmÍ 2ÍÞ(žèîö}#»H7ì?º/)|Š”¹=jàÐnav•þM Ñ£Nx%…Q²ôÅsäžß¾iÅòG6ë k7"WΩa#„hƒœ-ëÕà’ 0îàòÑ8| JàŸm˜½ ,†aƒœa¶z”*·ýÀ{ ˜_K¬éTéì]Ђ{6A‹=ÕãÀqýýyUr0ÿþ„ +:¿åªèO^ÕÕá·]ð{i¨€áÏ0!x”3·Úk¨Þ=-k;eìXv¸•¼âÆyé`ùUiF”‘Í~czOy‰_õ8Ÿ3)¾û‹îœAí­¶ÛT[pOOm±OXêñûYó}¤#üþÞ²íÜÑ ÒPPðL× ­þgÉ[&ܚa³(a»!x½ËGÐ5­¥Œ§hO] ƒ&ù?/þ¼)0`endstream +endobj +192 0 obj +1711 +endobj +193 0 obj<>>>>>endobj +194 0 obj<>stream +xڕXێÛ6}߯ ¶/ °+ëbËvûÒdséIëî:o +®DÛl$R!¥Íº_ߎ,Û²-)HàÒásæÌ…ú~0þ,Šño’_½]^>ŒY°åŠ…±7fñl–é«Ïüå“^?ÊÿÄëå¿W?÷bv̽¾ôñÙ<ô¦l÷䱉\IaY¹,ç/2¯rfa9Ó+÷Œ'‰°ö† c´¹A>Œ¼—s•²‚¯Ëôš­dv¤bOÛRXÝ¯˜%+5,)¦4.¿=X´¡´ˆ÷اÆ7‚]òR¤í•¼*uÎK™ð,Û²h¾Ü …Ú’xI„HEêáÂ÷Ë+ßóÂæçá# ÇÈZ4{DÓdœÀŽgÀAyóí쇐¸‡Qìùh…+À-)`â{%ly4ÿ8`1¡»ãõÇr¹€mœ5ŒD+Z—â?Ƒ¦ôÎdm~ ÑA£tÓæÐ΍.pM›m{ô޶I<…_ðå/“ +ÓbëM–é7ï„Ú6´¹E'¼i\Œ„¹ UŒ«X*HJù,ZÄFcHµþ%.Ø5.¸q믑J™™Ld bLëÊu£1"•U»#l¶9.)$ œ¡>L&•¸¶Žp½w®½Ÿ³ÂNv8ÉØŽ&ëýÈcÜ­'֓hÜÄzBT:cMhÇ}˜bM`ŠõÝÄڟ‘èPa (´¢u矌SM«=Žu¦(ZíêÙQ¹òØrÓ¶ÅåãxJݾ„³¹Øe =°ËøR— ãpse +ËQ:›±(ÕzXÅlEFjr@+¹®¨r·â0¤ˆ…ãýüџ „˜ ¾” aXϏnTúhtUœIÐ¥nêyª›¤5š )Îi Y"ãÔ1ÛWÙ +›bY+¨¦àgæB¥)èšKB?¢!c)òâ4çÚ\™]Å €‰›í‚J—=Nói“5ýu‹Ðë/Õ­`J.Ë\誝2‘rI^¢—ÆfdEja| ˆ]¹8BÛJp š‘Šº¢LÓLÐW}\œŸÈ#B/ $pE¼øbOîÇYѝ1 Óu—3©”‚«o‹%ñu[Á= ºÞÚðÞ®ÀY‡§ ¡‡2âÀg}KcüD†SiMLäÅ^ÔLÐVL<ùþs8Nw::ÂѰÿ³/Û ‡nê,GYáMÚ=zóxwYöRzìNç9Š^ڒ›zTpS„®`zÿúêú—믯Û=sà ÌÂxõ‹Ý‡Œ÷0™1¥ÕíSÆÕ7g˜ìÚ½aWóœXÚÁþóÔÂý— KŸyVÑe¸~uïf1}–ƒ£+¥Öé¯ÄÞ¬f/€{UÀâù˜–Õm9\ñD°wÂʵÂ#‹]—º¥U·ÓÐ 5ña4Ÿ€ü}ÌNƒrûûêÒµ”{endstream +endobj +195 0 obj +1584 +endobj +196 0 obj<>>>>>endobj +197 0 obj<>stream +xÚ­–]oÚ0†ïùG\m¤qâ| U•Úµ›Ö©+ôb—&9i]¥KL»ýûÛúAt¢øµó>9çøø×€OIa ÙÃàl68úc0+ J¼â4‚Yþá\֘iùˆg÷ƒ€…^HÍ}l²Z.´¬”¹˜ |ϧE×?×_!à‡8Ii5揽ØØ  F˜n³0ôÆ­: R/y¦¶îxë.ˆÍª‘$§Y†äBÝî)1}idºÀLxºC}‡5Ð,j©4]ËÄj*(|‚ûjÞxp)þÀ­R‰l̪>ŒˆÛ>mø›!T5 ¿WC¯œ£ÎRÐånp«và5;\Òpcàø ±,õU‹aLž£g.Úᓷ/eY×ÕRå͋—‘c!•4±„‚à„¹ažBÿ ½ aFúh÷üýi­º“Ög6´eY=Ý4X7 ÿed”²ÑP°4:‚-&Ì\ÌAW6ÌÍ Þ”hÌÈX§Þ’±%J’ç3¡ÖS-jÝIc,έ΁PŽ:Ç9å$¡²y\ȒÔR>emMŽ}i¬º“&\9š •¿‡E&çރm*j”hSQ[Px[Qç¨þ¼3ÉT¥ÿ-Ñ„líÍc՝<´bàxe†7ד¡É­j´¬%­k9_j´µ€{–®+~÷VÝéÞ·Íf¢Šê•íSÐø[/Eiö¢UÇ1±Øß(ҁœºË(O#WÏߪL¬šßV»e+8Ðk2> Zz»×xÜnúÇoºÅÿi},|“Þý-Á©»ZÛô¦TãÎÔ¶æ(Q¾zûŸ Ê4øá$/Ñuò©® ÌûÚ9Iw§îÌ"­Y.iÏ·¸c÷YeԃS®Ë4£ð ÒëÀXà> +ÿ Zð;Oci{c´Ëšs¤u Ÿo®¦01n +‘!Ð!QÞ*xuV¹9£vRè™d]Q4^V©ÂÈxb«•°°¥ú1ø |¿¿Vendstream +endobj +198 0 obj +752 +endobj +199 0 obj<>>>>>endobj +200 0 obj<>stream +xÚ-ŒÍ +Â0„ïûsÔCcרh¯þ7Åõ$&Á´¦}tUf`àcf^Ĩ?bX§öOZ Íö+0C"¸q†±œ×Û›ËñŒCC‰W° Cºg _R?¦.OåAÕoSýG¼PhÛÆ´økœ±@_’ Æw9je't¢7U%pendstream +endobj +201 0 obj +126 +endobj +202 0 obj<>>>>>endobj +203 0 obj<>stream +xڕ—]sê6†ïù;ܔÌÇ2þ¢3½8$iK§=Ã9»Ü[7²åÊr€ߕd“ÀÁ˜Nfˆ1¯VÏì\ü#y0 !ɳÕàá×)x.¬6øKŰJG><ï“å0/ðbCVÝ­þ1ZYíxâ;žQ;¾”åR$oLÁB +%Á­ÜB¹9¡–¯¶ì“¼läU@ ˆÇëLAÂ^¯óTV˜ˆ¢`‰ÊDထ² ­¹­`ò=K”B*gJ\׈4ÎL&ôåûr¦¶"…‚æLK‡6úÐi¤^èø×!능°>€BÅïlǙœiòFe +0õ”I¤„‚©oˇ٥o^&«{ ÕáŽqŽw!§ÅN!ᝩÕO"­U9°dÌLÿø²XÂRlԎJÄMó¬È*%©B=üE‹û·(p¼bU]ê"±ôlÞcì›ìقè^›ùfR쪬øû¶F_bš /Oº¿ã55•‚¦ ­TÛMf‡c“ÕG´m%ñ¢¢ÀîŸerâ…pBÎûL“í§ÉJjœ²*‘ÙcêºV +ÃërQÐØœÙ¾a3°˜ §•m¦uì—åã|Ší‘\I%¬KPˆ¸gxëƒǖjá.S[œ£@eƒ×‘»wéëõw 'ÁæTaÓ´36‚s¬æÏ¶ê.LuÑq-=ß&¨%ƒå¢I/j™éC.ª—ÏÐ|ˊ°W9}ccÌgœ‹”ñ!|ýÓÆ¦MGÇ&ºéèRǼ×ï¡ w:Ô© F÷¦@§qF§ý0"R²ª8k§û0_, Í³‘5›ìÎCœjOìmG!øød œtLÕ&z«¾«½tWëèthöqNëúy×Âޟ3KmËö4eI–ãŽPÔù­ÜøK²«Î +¥¿$´¤ëŒgêð`l„{që´  HM=öb;ã,Sú÷(›®¾ñdVRÙìy5pãÇ÷ßp]„xdxÓ)îhdŠÃq [^GÚØVLÂÐ >©ÍéÕ¦JüXG †Yw&vh7#~iWñْ$ø‹YÔ}¼¡NÒÄ4›âu^#¶¼jäm(}b¦>R¶0SŽ_€”,êüL{Q¾£‡ +Èë]_i îxu=#¶ |¨?pc[W{,&îŠö ›õ¹º4·ZÀˆ/XÀ‘xj-9¹F„‡=T$ž´î§²ânªÈm’.S¥uÉÙ¾(ô÷f #î +Œó‚Ë8¸­"OŽï;ñÍ8F܍ƒ'´yä ;ê#`£ÏéD”ë[¡Ä nßQ¬¸ŒxÖàQçTož}lnx»Õ­¸“m:±N;œ^øŒ³¼·`qt»ÑãèšÏ£æ]`z)ï¬oمñí&7ÚN˜ 0s»—Y֙=‹¯ `”› n´(“ÀڛŽ‡"½çäÿ9&»NÉøø´àÚ7¼®W>>>>>endobj +206 0 obj<>stream +xڍVkoêFýߘ!%•ìàgভÄ<$H(q«\)_{·fík.©øñYہ!ð2»ž9sæÌ¬wT4¨ã[揷¬´ÝÊm×MwšÙP5°¸þµ¦ß¸ÿTô†j áwð˜€8 D«²š̈́@x ž’±ãVêj#¼ÿLzjè]Cm€DӚª ‡çSÆw¦jƚm«Öž5R-ÚÞ&JÆ×µÆF¿”£ÕTí‹9JãÏ9"¢-9™_s4ìÙ¸£YÇà—r”ÆŸsÔïð6q²Îq\³$`ӐCü÷5?]Ã8—ò“Æ'øÝv›hB-Y«©';Ÿ¡%Kè!'&»Þ­ƒ‚éHÉwf34K!ìËhXŒV)÷aúقç€9N½À¹ž¡cÅéGøkòÎxB劓È_yü7Á–S&މٜ‚ Ÿ<‘Žf`FH']Åq”dèÆ¥ žb¤ja§Ûy\$4ŒÈÞbN&p˜H’eq˂HÜ®…¯z«8Uý€½šQU³«™GE]±l»Hîà aK~³( £Ÿ˜“ø<õ’`ŠÌHL¶fA(…‡|ÉE&Ŗeh³Êˆ¿vÔ·2¡&Å2,äò.Èo¿8îÀý5h‰9âV;-·UEAdš@@ŸÏŽØŠòG©§–·Áž{' +QÎ}wðäÔ*¥\ÒI¯ý ®&“^¯Ý–BŸo°íÃÕW¸C.æÙbXY¹8Øð0ü'D-Ÿá‰‡š`@˜{]€œîC{Ñrɔ”Ç,aÔDEðKxº|“•PgÌœù¤Gµ¯mûú¶olûæ¶omûö9/ìkê8¬3’ªŽ'Î9ã@kˆr}Ôó§8TC¬&¯Ú+”©ùü®£ñpà<)·P +ŸãÄ!øARâÀëu˜%Û$ _oò‰PhÉ=Z6²8?9û÷VðU–°2KQªGègÒ¢&ÇbÕ(½ûsùÏ"\Ù[þôú B¶Ð}ztñ2À¯ëžƒ™',^^zŒòô‚ΧC8ÃÁ£ƒ—ñÓð;^Z“ 4å:/gñ‘ò$;BŒzèüwkrÂE­" V͋Ö<¡õNCZUU ùš‡ÕÝãa׳eˆ¤sõj,ûãÖÞÅ»§Q©ä„OJ?tFŠý°ç=¡àç +ʯ7¿si¹îpð|äzÔ5Yþ{8û’ú`{œêÛÏY·'Hó œÑE9‰ÝëᲓRMlãRԓ{´AÏz]Wå ˜ý~²C›–¡6/´•°¦E¶ËÂ1…åvÞ(O˜îtyÌÈ·‚îˆÉŒá~úÀÓ`.肻JL‹“Qr¥pÒlš4žêåÁàÄÉóÿ³ò?ª'Юendstream +endobj +207 0 obj +1045 +endobj +208 0 obj<>>>>>endobj +209 0 obj<>stream +xÚå—mo¢@Çßû)æÚè]à@­ÚxiÒlHlµ”&ׄ7‹ìYºl[½øáoÐZEô’ë s’ âÌogþ3» Ï T~hЮC£î¤raU¾÷T8ˇƉ¢A«ÓË«þørnY}ãނ ³fýª¨ kªÒHc4éBéG–AÂZ'″üN]SZÙhú­eX Á($îӆÿ aR€G㮸Ž)ò ð`×=*aú!yƒ#)E§ž8 +q„ +}úú ÷ƒáùµ~ØUI¸wíÚ·ÉyÄ}™ ˆÁˆx3~ãl-èwëßkè„xåvv5D>›»<Dçf×àØ¸ö ýJ`Bño1'ÌÓÈ ¨¯+X»ÊH<Ÿ`Ï Ñ‚="Œ‘ÉüQ†Ý]è±AΔÎëb×¾®©;ÔS'ʅ>•·KÁEX´8gs]ä5]Ä(™A©8‡/ËÐÔ ´øÐ!+‹04eåbê‡/ÊÅàg:qô›!_æ6}‰|†\Ž™–ªÁAú$$4gI—âÇR™ebÂ'?ÅÊ +È>'õQ4fÁulêw†™ ’Ù?wÄì>E(I +@…!‰FYñ*@¾a°;¶Ìn{hÓåKs|/zLÌ0)ì¤Ùž¸åÂ[ÛÞ@¦~imí Žß³}æúçÿ.v߸Õˊ“p–N˜²R È'–úfxA±kü®b%{V«·Q­ä/w¼AÿqW¹Æ¼ìj6Kùî’N·*ª¢òçüåɼ†Fƒ?Û×ëJzZí?S÷¦Í“†rZh›¾,t@ÓÄۂvÒRċ„šfrù0¼Clv¾ã"¸B‰Ø ù—Kq,Ò‘É™œ;5•dŽ=¾sC‡HX5ÛM.Oj¡µó„î*¾ã1(endstream +endobj +210 0 obj +694 +endobj +211 0 obj<>>>>>endobj +212 0 obj<>stream +xÚíWmo›0þž_qk) + ¡ISuªÄÒ!%mJÝi•ò…€¼Όû²©?~6¦)„mû0mNÂÜ=~îîñ!«iÐ? ôŽü»aíª½4áÐ ô¶ªA§{ Èk¼c 4´®Œ/‡·èK­ ŠÖT»ò%€KÊ õž|8͞`ߍ‡–ÙP ÷˜1âáÌAQrH°õ!ŽæÜ3¬}Û¼º±l%|ÊÈq'€ '4Š‹ð¾ïˆ'ˆqânC;ËfZšÚIÓb͑yÀ°{ À%˜£1º…WCàßE3؇¹âùìô*¿è¦GÞ*F4ð$éàH»"4“¹Ïג»„[/VjGgYô9 ˜;ŒW¡•:l$Æ}â~p+Ä H„_x@>û°=ÖÔns¨/ÎY^à;ê».§ïjò[f©¼w·€ù/î_÷¿­Dd~FBŠ +LõY@N'o×µÈñ#‡)},U¢möPnU' ó(š4<ãO.Ž8fOLÖxr°*Øz^ÇP˜þ!¥äs@÷/øMœ.žBây^’œRÎiøŠåsºK9VÖÔŠƒ¦ô–z´®)kt^ÚÝÌpŠ=Oô7:s\ª+•[¸îpÎâS(b™ºKNl¡N´n$nø^T¬ðƒ‹]ýœ›Ûz¿–ñJ,¥Î)`LUö©Ì¡¢œ +¡R‡Jà£iôEÍ.ÅV蛃O†kuïÁûØñJ«&±òe“%ØR5¹L :õ!x„U㟒ޠ;©i‡g*>ž‘h©êÍ1¤x9‘â%j¯o cƒL¤]QǹÃ;8'v»l¸ d‰Hëàó0P]Ñdyödúalœ›{‰‰jMµ)Ž&Ïût]GZ-5™ÎqG\†ëÓ£¶®žÚ&ç›.hš<àh펀>>>/Annots 66 0 R>>endobj +215 0 obj<>stream +xÚ­XÛnÛ8}ÏWÌX ÅVЍ«µ7ÀMn€¤ÍÚÞ}ê -Ñ6 Yr)*©÷ëwHJ¶,ۊšŽ%ÎÌ9s!•oWü%¹à…l®Þϯnîˆa¾/° „£æéõï?M&“Os¸ýçiv÷yúþ~¹þk2þðå-~yœ|yû €eAZ$ՆåDQH`Ó–õçÛù×+,âØ#cu<Ÿ?ÜÏV;€Ÿ9å¿AÿºÌh¾z)xqbDûÌ¯ÛA¾ûéGð<ÅÑ!oÛ.³3P?ðìx ¶evs´0C¸Ö8)‘ÉÈUœ¾íkà©(å,|+áŽgLsç!fåFfA¼Dp cJÙ3O˜•²-ËS¥ý8-¬ÝŠb%èÆ¬±a¾>zªÔ¬èŠ/O¤#5ÇÈÅxƒ(Ô‰¡æªæèàed2²í.X +<‰®.%Žo«»¿ÊŽ„Þã[ÄÇJÊ^| ±×03}ø6ñ£Àvúñ-Ä<â©rŠo#ïûGñ¿?‘H¬ÝkiOûФnʖL°Tq<Þ?N@î¶ –…€ó•ÇK0µêÔµzM·ÛŒ'Tù»yÎS;©¶¥µÅu¥^w\ÙÆw»5,Ï5¨¢Ð>§´”L h a€=-Q#øF‰eprM%$E.)Ö)=j2&pÈ$Š»fÐx˜CtLó´ßØiõMÖÆbÝͼÔ}X²VÔU‰M# ‚æ%æ³6×qœRIa)Š¶Ö +[Et Óû§RY; Ÿ¢ÕƒÏLHm«Ž^;À…´ãx+8еÈtUl¨´ëçMåŒÛy€[ñ¼„.ר,v’A¹Ë“µ(rþŸ®x)Dú+8ß7$ù¸»¼™Ò™|ƒÒoÁWÎ)&I$k.Y"+ÁÊ3ép¾G8~ь«ŒÈ6F2.eÆÎÚ1ãðEpy±l ¡y¼ð,S™ÑrŒù™é˜;þñït´FSU%~+·E^òZ7L‡òÌóª"j¯’® ‚6aœ*3å 6”Â)Ù°@JÈKYjw<«ðuÜëÜ?ð…ÀjÝs¨r]À%l™PyÃð0ªæ6ÐJ˜KìÛ,Ûu3zWdYñ¢bPœÎeN×-…’ Ž1¢|µ[Uð(íd_ü¥¤BîË¡ÕaÝêÞ÷¬†º¬1b‹ÚU6†i”,Û¡4'…«4֕­|ÔC&¨çFÛ²v +ª±ì¨[˜™UõÈ$#§Œ~ò/Í*V^^8Vè©`ýȄÿ¨$»Íh©)·úÁ§*³P» ÇÒFqdzÛû{L¶úªŸ¬«q=Œ¬Á%kÐgÈŠQlÒúq£S’EVˆF2Re9¤Æ&©ÑI†ŽiâŽ,“–sܜÉÀW'Üa$5v0I¾HÒ'šbìZn´)~®ä¶’?”£çc<9jì`Ž}‘£KÌÑÍ Bd·YŽÓgŠ'¶gcžt©:j v›sÏHµ¸«ÞÑ<õÐsD#<=é· ßï¶îÓ¯Œ*—ƒG•ÁÖC£/éA𸫠+·ïŒº¾b4{‘À'µ_58|ß̲ÎîA4n=ºl6òÒ=üZ,ô™¸…ôÎ#K&;&ýó@µõ'ƒø^“ <‹;½É0X#MØ$àM2è}2\ߤÂÇTMR¢vØ! a½­ Å´€¼PG Á¿[n6F«“ˆSD¸ÁՃV¿ôJ ±&®>p-F èF‚¨iÏp„¯Gsö¶’¯–bRIØ4 }\? ;¨ õ×A¯½èõºóâFóWËNC‡VŸ)º›»Q=¯H`,i¡ëÓkŽA/)öÂø*‡ÎYÌ2k¬z‘úÿÉÅ ø‘šÉŽÙ]j þ¾ú×âó\endstream +endobj +216 0 obj +1530 +endobj +217 0 obj<>>>>>endobj +218 0 obj<>stream +xÚ¥X]s›8}ϯÐãîLq‘_ûҦ٦ӏlìNŸ –±ºQIÓ_ß+ lƒùPv'™ØG {tïѹü¸ÂȅŒ¼@ý¦‡«7›«×7aŒ6;仫‘6Û?HHún¾_Ñ9Á*P£×M™³Ÿj»Á +£vØE¡;ɋU¼ÈræT|˶ +æ"{+¢@øڊæáônså®\XÙñÏý߈Fj1O áÊEYQ$Z`cÿˆ5뚯¢M¼`埡C‚OLd$ y- ®zÿížU"oj.Š撐ü—(ê$GI±ELÖ<…äqâ„_WNɤËt¿Z €°6MށÇY4Ö,gܠц€úH £ˆ¨Câøœ€ÛC’Á6¿M±ÕŸ— q# ¡Ö,c²Bª÷ ålW¿B¢®Åá’<ÛÿŠ«Z”ê.ÎY”¢âг +‰ž\&ƒ¹æ±ðå§b³ðœjEL@Ë4ÒXë4Òè©4òc +CŠçºŽçöÒ趨 =Ö{ÆêÑzº¨5D¨`¨be"“ZHT©Ր+U\·ÓÐijü[W˜ÁÚRcГÔÀÓ#C jÂsj>ˆìD äfÔã}™N…jD`>t×P²«™D;ž³ŒŒÀ¾‹‡!£Þ¬2{5Ã&!°Zͦ¯â›eScMsà–M6lžÐ›4v —‘ãa|ÎåG–¨jy·ÍØ8§Q"W¯€-YÕ#¬Þ«:½D9Vß貞½›bõ#hÀ%hšT«w‘Tƒµ%Õ 'Iõ±^2&@jO?%°¨¿ŽKi™‘7‡ ”xñƒR.K±¢”v9´(ùk+ù=%ù”øí+âõ.š$¿a漞ҪƒFåÏh@t`[žŒéÔ§qØ #˜t‡à¢F¬­Fô”FyqÜÊ7"=ú¤–}מPƒD¸-Êt8Jº3 í$d„ Çú<¬+ªì¶ß`m·ß §¶ß‹ÜnûAD<|ì7¦T`ª¾‚žô%•à™LsûªóG“È%—ç…Ç_9<¸EÈá©ÀGBö»ãك÷ü^È\J!µ_My C¥ìêú"ه€¨ýQl°¶inГiN̾{ÐÓ¹Ï,KjþÈià…òºgQ^X“ÁõܸËÿe4֚žbÄA›ÿäöäïssx+JΆŠU=5¨š¨HõP ¢°SGÝÓ]EÈÑãÈAxž»Öõ`°¶õ`ÐSõ@ü°£ôŽöôî‹ä ›¾Ú]x³I cÕnjÄé*JÁȃD8i.ÒŸxÅÆ,Ŧ‘…7¥ê¡yz*F>>>/Annots 71 0 R>>endobj +221 0 obj<>stream +xÚŗKoâHÇï|ŠRNŒ?Ú¯‘ö0a%hY`‘r1¦oüZ»I&ß~ªÜ61`ˆçEÂq÷¿ì®_UWµÿïé áŸŽ¦ AÜ.{ƒ1]‡å,MuÀv-X®û¦ËÓu¾,ÿë1mp(ØgÅ0Ōç£4JsšÓ5[Õå´~ Æ-°[pa…*šý¾ìiª†¯<üÌsé-Ž«ºÀWã©ä-ZÏ:h囮‰ MGT¦­Z 5ú)½³-œ-ýsÓÓ/ø7 ñèÔ?)˜Fç,Oµ»:Wj;;Wª/:Çlœ%ç<³Îœ{œ¼{ÞæœAƒ”.eƒaá¤Y>î0!óÄ¥SiEý€ÓT֕G©íÌ£T_ä¡3*yØÈÃ;åQfñ?ùš7RY7¥‰A°Û'ÏoQ2ðÔMïáðóô…¬4PjMV~²æë†ÉhÓéáþþÜÆ@›,ò??²QU•Ì肖tAc¼Hûˤ-ÕۊY˜ ×HK­ôúšX’–jIú]]“¶ ã€þ0MS˜f¶’^d~ÐÈ;LeV“~݅‚·àœÿ¶ÃÑo'Ã&±üà™Æ•Æà ŒÖ‰ÜÂÑÇéèdԖÚû“aGŠO‡]¾?´W ñõP1Ë>T@ÓÅßk±’â:C¯¨e°¤¼Úïò:ZŒ™²2a´œóhÅY΋"L““2q—‡/`c: ¨Ôv-R}©`0ƒÉÊ4WaúYw˜§¯£tŸˆO¢¢»Ë¨Ôv¦Rª/RѬjsëR±Z¨Œ9_,ë¸ÞnP¤¶+©¾ÅtíªÀè6BñZ ,Ï> Š«Qè¥Ôv†Rª[ h`ZÕÑj¹ã0L¿ƒxË8lÒF?g ˜û…à9lˆ Ó*çú~–Eaà ,:ƒ—d­D%/mŽ1ôUyïîÐ=Ö^³î>¸{«w½Â˜^tlŠRÑ;œr)>ºåa‚/RÖ<ãØÀ!G*…Øù¢”… øäPŒ÷Å>þ*âA¯y!¤\ý8ìå\ݪ' âï™2=Ü^çK¼r`_‡‹Ô^ÿÙëðr`B+M¸€-:L¶øO*Ò .²£¥^6<•DÊõó_‚'ÔI +JŽÈ*ÈԐèA:‰³ˆÇ_BL7'à&³¬Ó`O’k>¹@\¹0 Ïc|\Ó«££× n1JjF¥0á¶)ï"™âM:«N/Ä¢íuOý‡Ù†5«©`øÞÝ^½Áåu4Þƒ©Ñ®z_ǹ¾©@½Aા¡@½­S£¸¦o(blúR»¾©@½y¼žá™Ëùö€¾b:´ã}ý0'e +%³]‘OT û=J?爹إkHüXn1Œæ&ÊÖ7×RʃϱrÏEþ–Ã0Jƒçn;¥Õò©¿˜1=h¯ä<ò&»È¿Ã΢‹7¬€1}LƋF>Çéb6ée§OâtC£³>ÝÔ¡d^m¬hÇ@ëØôwBd_?Ù«…¯|5Í·l_ŵh³G%û"^ݨ°ØgYš‹rFìp¼¹qðÿ—¾«^B¿¬‹oSù 0»uÝ¢f{Õ'pURˆå?;àŽá6¡ ËDu´U¤•âZÝ?Zs¨¨” +£î¼ÿö~jé<endstream +endobj +222 0 obj +1286 +endobj +223 0 obj<>>>>>endobj +224 0 obj<>stream +xÚ-Í‚0„ï}Š=J ® ’x0Q©7/ +Ôðg!òú¶Bv“IfçÛù ¾³[t(åh—‡¯Ì…Åðҙº×4CûtÈÓuùÛdÂ-ãÀ¨‡Z‹ÎêW•²„EÍ äÉ%M€b3} ª©ñ +ÇLö ›òÀvÀáqÍáÜÏRW¢p”“ª{+…V㬆޲ފxõ-D©5ƒ8ÀüÐÔ­ŸîbLµr²‰G7ô¿£@3endstream +endobj +225 0 obj +185 +endobj +226 0 obj<>>>>>endobj +227 0 obj<>stream +xÚ­–]oÚ0†ïùç’J…@ ÀnWº©Òª15ÛU¥ÉØ'‰Y§¶3©ÿ~Ç$íJ` \$ñk?öñùzLaB¿),}˜-€§ƒÁÀûôü !,–+ÄðÖR#·JK4WÁŽ4 ˜NKÍÈ_}§òÐry¥˜W +Zx4•’ F0C’iœ‹éŒe¶¦$û¥)‰Ï¿%g°Dn¯áõiæ·DAÌ4 + ¥f.ªài¸~üjž®º"KçØ2þ 3Ñ̬DÎ!ÈL?ä¨Õ5n?ߓŸ©H³´'F0LU %WI"³h­_ÈÑË9=¥Qš.’zYÏt &Æ9æ¶ÍÉÝÆE{$0‘Öñ§düœxѸ£ó_âe­ƒòý)oƒVʾËq*ܽý¾yғXÖëqz4ØV5œŠqºs mÇêTº ¶º˜#9áe¨J€éäs” •fæ( +†àÖºl7©õÚp”YšSxý­X=Qÿ:FïÓ_tBuë‰H_¤Ô£”J7êoFùLEgðNdc~Òܶ,Z+}Rx"Wä,ÂÚ§2¹RÉ9©âD ´ïw`§¶%·b­Y7e›[ïsçËùxE=. ú3÷á.|ü‹"ðendstream +endobj +228 0 obj +614 +endobj +229 0 obj<>>>>>endobj +230 0 obj<>stream +xÚ-‹Á +Â0DïûsÔCk7¶Õ³VÁ›âú·eSMóÿhTf`à ïEŒêƲÍõÚ-ök0CzpӖŒ•« ·¶—㇐4öW¯èt²!äñÑžÉÆ0—;?§øK®Î°v®tø‚è,ªOc4ò¹:ÑE„#Ðendstream +endobj +231 0 obj +122 +endobj +232 0 obj<>>>>>endobj +233 0 obj<>stream +xڝ•ÁrÚ0†ï<ÅÛNl(Ð#qLâ $êØ™éU±GE–¨$BéÓwm(Mfj2xl-ßî¿úµþÙ á’>!Œ#Œ ¨{Wyïbö¢Kȗ´2O /?MáFjk¹Ù}δáxÐ ƒ¨ BÈÑÔv1‚0ƒ}ÐNÍPÎhyjŠ»¤¸ÓO§àÓ$ŸuÃ[sÑ1€DUB!’Œ‘s»‚™6…—ËØ Ø£ÙNØÆ4{xØž.¦³ð`*®ÄïvÁÞ³ënöœ”Ûzͱö¢é"éf-6²™O¥àpl‚ ɯwϰ×iŒ¶ù[1Ÿb¦­Ë +#ÖîŸn´í³Å•oz›"-^¨T앤AìaåÞ)šþ´Õ¾i0y&Çû›wúp< &4•i%úÒ>>>>>endobj +236 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Ó3T072PIÑPp VðÌ+I-JKLNUpI-ÎLÏQÉE™%™ùyš!Y\º=ºPMFf Ac=#°€£‚‚{N~qqbQ%HÆ5„+ Ø="´endstream +endobj +237 0 obj +120 +endobj +238 0 obj<>>>/Annots 110 0 R>>endobj +239 0 obj<>stream +xÚ՛Qs7€ßý+øØ>TYrÉÝå£'Ì4S7r€*¯ÝIZ$'— ,ÁMªµtíŒG4È/"@‚ ÿçJŠÊý/E«D݈åæêíÝ՛V¨JÜ=iìLЦÕâîþ§»Å_ë^ âݰ=öÛãáç»]½¿»ªf•cÀ ?>ÿ + ÑÔf։èf +?¯Åè“îûGñæƒR¿Ã×ÕýkR¼ˆÈ¨»™IùAŠ1_»Hªu¿©àw³KÿO¾8s7-§"¥f›ºQ0ußÀ©¿ù Q‘ƍª49Ëè’A6n¬ž"QŽ(ññÞ~õ°Z.Ž«a Ô¦r.G¯%ÝUv¦GÝùN4&«™S%!Lj„ÄDóï‡c¿y™ÆNÿuíi‚ rÂýþµß]õß§åÌ^‚â 7¶qÚD‡FÔ¸±­k{×GV £„rD‰›aù´qËôe g8¢†‘ ‘: 2Q»r¿;¯ÚeÖñšÆŽŽ7|½Ct³¦­‚ƒTy7K°F9%4/%ŠøÜ?ôû~»ìý¡à rѾ¶.,ZÓDϹXcÚàUÑű3S"Š‘$Þýy;ÏØÄ0–45X…ÃPŽ0Ú ÑY7g5KI뺎Î94˜«Ð:ø@UtÎÄéêšèšHâ÷ã—~ŸQv;øf•Òº:²HÕ~ýk{vQзw²u?ÑQøÏÏ9 +é7x]pˆ2ÞMpV'ñхûíb5_=¬ÂPìiö°@£ÛKó7¦°Öý CkÝ7žõ0•¶.{$Ê +œr‚D9¢Ä»/‹ýbyÌ-}¸J‚¤Ȝ÷¹ã– ‡dÇù ; ìÃj¬ªªKØG/[²Un&څhà-\9B§åîTÚÊàŠýrdƒ†Ü]E§(”#Lt¿¼]åÎ羦MqÔy§,qÈÎÎÚ ; 2¿ ØðPT“°ÂÆ!íë%³·m¸xËø3{ۅcÌ®JfGl “¢PŽ0ñçvµîûŒb¬dÆ/JŠÅH<Åð âlUÉét]‡̚v(j‚¢‹~@¾Š(¸lÝèx“ žèƄ»B] Oˆ#Ýlu +B9¢Äo‹íãÓâ1gpÆÇ¡@œHÉw’½”#³)èÝH +. 6˜Þ j½t$Jׂ›â•úøé}&։ƒÁ~ $(”ÿ ê梢“¶àÙêÖÔÁùøóluGI]>А$ $‰Ê&6«M?;~ßÑýñ¼ú*)HivâûS2tâ×e׏$¸ÉU) +å +ZÛ¯AAúÌÉ̶°e¥Œ7¹Ð`[V*:uiÓ"§ëfMÊA±¢›Ü®¸™ÎVãw¤äjrðÈîr¼ä)z¯m¨Ðˆz¯­¥#ÊôNȃ©„rD‰Ûápœ/÷«]!ݦ"³6N© “: ôv¿Úæc†p@[SÜЁ7ýÁÅìᘔê ÔVɽû«y«.ï—jª¡_ +è—ê½’)ºmâ@8¡SʃOº½½ÉÝAâ`EáHPÔ!\vý2yVðI­×ßy% ·2¡Á4Ü*:MÑóI*;E¡\Ñm=›äペ'4ꀸ÷ÿ=öۃSò!òWœi!»™2±2CnWÅѰ«Ì¨ÅqW…ÈÊ®)>ÜÁœËÓ)Ìuˆ(¶Eÿá•Ô¼²éb694˜W6–Ⅶ䕑#+5R¯L(1_~éïŸÖù b_M6Íô»¹‘ønØ>¬Ÿö‹‚eX§Pì`'{U½~@c {]›xÁ ¶×uC1LSö§H’>™ PŽ0±\/‡þÞÃEÄy%Õʟ–a¾Átä3樣¢?D<ƙ…r„‰åÓîp?jèì©vYT$-;”}ƒ©HU¤ º¤ äHË'y@‰]žØjÏù'Uö BÙPyaVøüÌ„²X~ ó¯s»¦MiAJE pÞ!"!äi&<”#pò¡/ìº?“…Ä–jYQDh<÷¡:¬BÐÅ·"ʪq'@‚ rB‰ëÝn>,ÿÍ38Èn%Hì@ÌÛýp–À>D8«1ŠÊoX}DhÄà@5X ‹YEâøà„ƒb*8ၙX²–ã7äÌ#ìí~øvXmsW5É&)›Î9ºè:D^bºó<éíåS5d/ß`ö2¸AJÙH¢ur +ŠõɶB’”G'(”‡”ưßä^èâàp'Q)Š:ŒéWƒ¼„ +¤&«ÚÆ[[hÄ#Xi¬aÑ'$4‰.U *È vÒ­m¤8þv \Ázl<<÷ÙqÎD ˆvsws¾'YÈö+ÅJoBƒí/…•-º˜:$NØjZp3’NÚcȂ å;)Æ !5Þ¤HêÐÆ;’7—q6<ãn“¶`8ɪwBƒNjŠJ¹GâÍÊiõÎH:ÉpȒ r„}^òG×ÇQ=Ó£]@¹hºªb1ˆo0ÓU’bR‚‚8A·œƒbù7bdÉ +^ƒÊöyñ-;ÆÑ£Ûæ,ê 'i]5 ç?ÛT¡ºR,c4Ñr²Ãƒ­-؍(nÝ ż~+ª3ìÈÊ»1Ë_ˆ#bÇÖM$ÁQ‡î‡Øñly“¢ÁZV÷Ì`­¦X¤+™ 9-\mŠ©Øë·Õ6S?À†‡w1›ÂPްòà #„³m£¼Yô›l>Ñ$¼î‡ÉR‡ñ žóêW´}SÅÐ&4˜íI¡-Ù9]‚sPLebó~ÿ5[à¡ê̦8”#îS8ä‹Q¬ßŽsfeg6ß®ÝÍ?gü–)MZ¸U¥8þ]bzóºÛ_å+òeÊsüê­YqOrÁ“¥?‚L>ÉE°ÊíZRíÐÍjß/Ã~õÿQ’¯òµÊ²ÂJ’ +VdÅ +I*Æûݝ‹Æqnÿ™‘8F^LÕ(¿®·Ô÷ßñÏl.ýïÆT!ea5¥Emøü\vÏb¥Éu6¹7"|×%¸ ¤‚•»~¿ñ+¯®.-z’Ò:¬`IuiK‡e"×Ù¤Ü80”Q˜„¤T½r½ÜÛï¬d¿ˆÀsª¨8Ájü«ÍW„pS'ê1'.núÃêq+X †_ +þpó—6¼Z¬P\ý{Ô endstream +endobj +240 0 obj +2418 +endobj +241 0 obj<>>>>>endobj +242 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Ó3T072PIÑPp VðÌ+I-JKLNUpI-ÎLÏQÉE™%™ùyš!Y\º=ºPM™™ A×®@.¯µendstream +endobj +243 0 obj +99 +endobj +244 0 obj<>endobj +245 0 obj<>endobj +246 0 obj<>endobj +247 0 obj<>endobj +248 0 obj<>endobj +249 0 obj<>endobj +250 0 obj<>endobj +251 0 obj<>endobj +252 0 obj<>endobj +253 0 obj<>endobj +254 0 obj<>endobj +255 0 obj<>endobj +256 0 obj<>endobj +257 0 obj<>endobj +258 0 obj<>endobj +259 0 obj<>endobj +260 0 obj<>endobj +261 0 obj<>endobj +262 0 obj<>endobj +263 0 obj<>endobj +264 0 obj<>endobj +265 0 obj<>endobj +266 0 obj<>endobj +267 0 obj<>endobj +268 0 obj<>endobj +269 0 obj<>endobj +270 0 obj<>endobj +271 0 obj<>endobj +272 0 obj<>endobj +273 0 obj<>endobj +274 0 obj<>endobj +275 0 obj<>endobj +276 0 obj<>endobj +277 0 obj<>endobj +278 0 obj<>endobj +279 0 obj<>endobj +280 0 obj<>endobj +281 0 obj<>endobj +282 0 obj<>endobj +283 0 obj<>endobj +284 0 obj<>1<>2<>4<>]>>>>endobj +xref +0 285 +0000000000 65535 f +0000000015 00000 n +0000000227 00000 n +0000001793 00000 n +0000001867 00000 n +0000001945 00000 n +0000002022 00000 n +0000002101 00000 n +0000002177 00000 n +0000002258 00000 n +0000002342 00000 n +0000002401 00000 n +0000002453 00000 n +0000002538 00000 n +0000002590 00000 n +0000002674 00000 n +0000002705 00000 n +0000002806 00000 n +0000002891 00000 n +0000002992 00000 n +0000003077 00000 n +0000003178 00000 n +0000003263 00000 n +0000003364 00000 n +0000003449 00000 n +0000003536 00000 n +0000003621 00000 n +0000003708 00000 n +0000003793 00000 n +0000003880 00000 n +0000003965 00000 n +0000004031 00000 n +0000004116 00000 n +0000004182 00000 n +0000004267 00000 n +0000004333 00000 n +0000004418 00000 n +0000004484 00000 n +0000004569 00000 n +0000004635 00000 n +0000004720 00000 n +0000004786 00000 n +0000004871 00000 n +0000004937 00000 n +0000005022 00000 n +0000005088 00000 n +0000005173 00000 n +0000005239 00000 n +0000005324 00000 n +0000005390 00000 n +0000005475 00000 n +0000005541 00000 n +0000005626 00000 n +0000005692 00000 n +0000005777 00000 n +0000005927 00000 n +0000006028 00000 n +0000006113 00000 n +0000006214 00000 n +0000006299 00000 n +0000006400 00000 n +0000006484 00000 n +0000006522 00000 n +0000006609 00000 n +0000006694 00000 n +0000006781 00000 n +0000006866 00000 n +0000006897 00000 n +0000006963 00000 n +0000007048 00000 n +0000007104 00000 n +0000007186 00000 n +0000007217 00000 n +0000007321 00000 n +0000007426 00000 n +0000007531 00000 n +0000007636 00000 n +0000007740 00000 n +0000007845 00000 n +0000007950 00000 n +0000008054 00000 n +0000008159 00000 n +0000008264 00000 n +0000008369 00000 n +0000008474 00000 n +0000008579 00000 n +0000008684 00000 n +0000008789 00000 n +0000008894 00000 n +0000008999 00000 n +0000009104 00000 n +0000009209 00000 n +0000009314 00000 n +0000009419 00000 n +0000009524 00000 n +0000009629 00000 n +0000009733 00000 n +0000009838 00000 n +0000009943 00000 n +0000010048 00000 n +0000010153 00000 n +0000010259 00000 n +0000010365 00000 n +0000010471 00000 n +0000010577 00000 n +0000010683 00000 n +0000010789 00000 n +0000010894 00000 n +0000010999 00000 n +0000011105 00000 n +0000011211 00000 n +0000011505 00000 n +0000011539 00000 n +0000011573 00000 n +0000012106 00000 n +0000012155 00000 n +0000012204 00000 n +0000012253 00000 n +0000012302 00000 n +0000012351 00000 n +0000012400 00000 n +0000012449 00000 n +0000012498 00000 n +0000012547 00000 n +0000012596 00000 n +0000012645 00000 n +0000012694 00000 n +0000012743 00000 n +0000012792 00000 n +0000012841 00000 n +0000012890 00000 n +0000012939 00000 n +0000012988 00000 n +0000013037 00000 n +0000013086 00000 n +0000013135 00000 n +0000013184 00000 n +0000013233 00000 n +0000013282 00000 n +0000013331 00000 n +0000013380 00000 n +0000013429 00000 n +0000013478 00000 n +0000013527 00000 n +0000013576 00000 n +0000013625 00000 n +0000013674 00000 n +0000013723 00000 n +0000013772 00000 n +0000013821 00000 n +0000013870 00000 n +0000013919 00000 n +0000013968 00000 n +0000014017 00000 n +0000014326 00000 n +0000014478 00000 n +0000020839 00000 n +0000020861 00000 n +0000020956 00000 n +0000021058 00000 n +0000021078 00000 n +0000021233 00000 n +0000022261 00000 n +0000022282 00000 n +0000022395 00000 n +0000022582 00000 n +0000022603 00000 n +0000022758 00000 n +0000024168 00000 n +0000024190 00000 n +0000024303 00000 n +0000024495 00000 n +0000024516 00000 n +0000024665 00000 n +0000025753 00000 n +0000025775 00000 n +0000025925 00000 n +0000027012 00000 n +0000027034 00000 n +0000027174 00000 n +0000028437 00000 n +0000028459 00000 n +0000028622 00000 n +0000029892 00000 n +0000029914 00000 n +0000030072 00000 n +0000031434 00000 n +0000031456 00000 n +0000031596 00000 n +0000033174 00000 n +0000033196 00000 n +0000033318 00000 n +0000035100 00000 n +0000035122 00000 n +0000035253 00000 n +0000036908 00000 n +0000036930 00000 n +0000037061 00000 n +0000037884 00000 n +0000037905 00000 n +0000038018 00000 n +0000038215 00000 n +0000038236 00000 n +0000038394 00000 n +0000039597 00000 n +0000039619 00000 n +0000039759 00000 n +0000040875 00000 n +0000040897 00000 n +0000041019 00000 n +0000041784 00000 n +0000041805 00000 n +0000041927 00000 n +0000042776 00000 n +0000042797 00000 n +0000042960 00000 n +0000044561 00000 n +0000044583 00000 n +0000044705 00000 n +0000046279 00000 n +0000046301 00000 n +0000046455 00000 n +0000047812 00000 n +0000047834 00000 n +0000047965 00000 n +0000048221 00000 n +0000048242 00000 n +0000048391 00000 n +0000049076 00000 n +0000049097 00000 n +0000049210 00000 n +0000049403 00000 n +0000049424 00000 n +0000049564 00000 n +0000050237 00000 n +0000050258 00000 n +0000050371 00000 n +0000050562 00000 n +0000050583 00000 n +0000050738 00000 n +0000053227 00000 n +0000053249 00000 n +0000053362 00000 n +0000053532 00000 n +0000053552 00000 n +0000053607 00000 n +0000053712 00000 n +0000053857 00000 n +0000053964 00000 n +0000054085 00000 n +0000054195 00000 n +0000054345 00000 n +0000054456 00000 n +0000054564 00000 n +0000054723 00000 n +0000054871 00000 n +0000054991 00000 n +0000055113 00000 n +0000055233 00000 n +0000055385 00000 n +0000055490 00000 n +0000055595 00000 n +0000055713 00000 n +0000055891 00000 n +0000056003 00000 n +0000056126 00000 n +0000056284 00000 n +0000056391 00000 n +0000056509 00000 n +0000056617 00000 n +0000056776 00000 n +0000056887 00000 n +0000057015 00000 n +0000057171 00000 n +0000057266 00000 n +0000057392 00000 n +0000057514 00000 n +0000057634 00000 n +0000057766 00000 n +0000057900 00000 n +0000058022 00000 n +0000058137 00000 n +0000058272 00000 n +0000058370 00000 n +0000058471 00000 n +trailer +<<39db518cea6fdf0052f603ca5012c045>]>> +startxref +58699 +%%EOF diff --git a/doc/idd.shtml b/doc/idd.shtml new file mode 100644 index 0000000000..2f156a27d3 --- /dev/null +++ b/doc/idd.shtml @@ -0,0 +1,1429 @@ + + + + + + CUPS Interface Design Description + + + +

Scope

+ +

Identification

+ +

This interface design description document provides detailed file +formats, message formats, and program conventions for the Common UNIX +Printing System ("CUPS") Version 1.1. + + + +

Document Overview

+ +

This interface design description document is organized into the following +sections: + +

    +
  • 1 - Scope +
  • 2 - References +
  • 3 - Internal Interfaces +
  • 4 - External Interfaces +
  • 5 - Directories +
  • A - Glossary +
+ + + +

Internal Interfaces

+ +

Character Set Files

+ +

The character set files define a mapping between 8-bit characters +and the Unicode character set, or between Unicode and printer fonts. +They are named using the IETF charset names defined in RFCnnnn. These +files are ASCII text, the content of which is described below. Comments +can be included by using the # character in the first column +of a line. + +

8-Bit Character Set Files

+ +

8-bit character set files start with a line reading: + +

    +charset 8bit
    +
+ +

Following this are lines that define the font information: + +

    +first last direction width normal bold italic bold-italic
    +
+ +

First and last are the first and last glyphs +in the font mapping that correspond to that font; a maximum of 256 +characters can be mapped within each group, with a maximum of 256 +mappings (this is a PostScript limitation.) The glyph values are +hexadecimal. + +

Direction is the string "ltor", "rtol", or "rtola" indicating +left-to-right, right-to-left, or right-to-left Arabic text. + +

Width is the string "single" or "double"; double means that the +glyphs are twice as wide as ASCII characters in the Courier typeface. + +

Normal, bold, italic, and bold-italic are the +typefaces to use for each presentation. If characters are only available in +a single style then only one typeface should be listed (e.g. "Symbol".) +Each font that is listed will be used (and downloaded if needed) when +printing. + +

The remaining lines define a character to Unicode glyph mapping for the +character set. The character and glyph values are hexadecimal: + +

    +xx yyyy
    +
+ +

Unicode Character Set Files

+ +

Unicode character set files start with a line reading: + +

    +charset encoding
    +
+ +

Encoding is the encoding to use for the text; currently only +the string "utf8" is supported. + +

Following this are lines defining the font information: + +

    +first last direction width normal bold italic bold-italic
    +
+ +

First and last are the first and last glyphs +in the font mapping that correspond to that font; a maximum of 256 +characters can be mapped within each group, with a maximum of 256 +mappings (this is a PostScript limitation.) The glyph values are +hexadecimal. + +

Direction is the string "ltor", "rtol", or "rtola" indicating +left-to-right, right-to-left, or right-to-left Arabic text. + +

Width is the string "single" or "double"; double means that the +glyphs are twice as wide as ASCII characters in the Courier typeface. + +

Normal, bold, italic, and bold-italic are the +typefaces to use for each presentation. If characters are only available in +a single style then only one typeface should be listed (e.g. "Symbol".) +Each font that is listed will be used (and downloaded if needed) when +printing. + +

Language Files

+ +

The language files define the default character set and a collection of +text messages in that language. They are named by prefixing the string "cups_" +to the front of the language specifier (e.g. "cups_en", "cups_fr", etc.) Each +file consists of two or more lines of ASCII text. + +

The first line identifies the character set to be used for the messages. +The currently recognized values are: + +

    +
  • iso-8859-1 +
  • iso-8859-2 +
  • iso-8859-3 +
  • iso-8859-4 +
  • iso-8859-5 +
  • iso-8859-6 +
  • iso-8859-7 +
  • iso-8859-8 +
  • iso-8859-9 +
  • iso-8859-10 +
  • iso-8859-13 +
  • iso-8859-14 +
  • iso-8859-15 +
  • us-ascii +
  • utf-8 +
  • windows-874 +
  • windows-1250 +
  • windows-1251 +
  • windows-1252 +
  • windows-1253 +
  • windows-1254 +
  • windows-1255 +
  • windows-1256 +
  • windows-1257 +
  • windows-1258 +
+ +

The second and succeeding lines define text messages. If the message text +is preceded by a number, then the current message number is updated and the +text after the number is used. + +

MIME Files

+ +

CUPS uses two MIME files in its standard configuration. + +

mime.types

+ +

The mime.types file defines the recognized file types and consists +of 1 or more lines of ASCII text. Comment lines start with the pound +("#") character. The backslash ("\") character can be used at the end +of a line to continue that line to the next. + +

Each non-blank line starts with a MIME type identifier ("super/type") +as registered with the IANA. All text following the MIME type is treated as +a series of type recognition rules: + +

    +mime-type := super "/" type { SP rule }*
    +super := { "a-z" | "A-Z" }*
    +type := { "a-z" | "A-Z" | "-" | "." | "0-9" }*
    +rule := { extension | match | operator | "(" rule ")" }*
    +extension := { "a-z" | "A-Z" | "0-9" }*
    +match := "match(" regexp ")" |
    +         "ascii(" offset "," length ")" |
    +	 "printable(" offset "," length ")" |
    +	 "string(" offset "," string ")" |
    +	 "contains(" offset "," length "," string ")" |
    +	 "char(" offset "," value ")" |
    +	 "short(" offset "," value ")" |
    +	 "int(" offset "," value ")" |
    +	 "locale(" string ")"
    +operator := "+" |	[ logical AND ]
    +            "," | SP    [ logical OR ]
    +	    "!"         [ unary NOT ]
    +
+ +

The int and short rules match look for integers +in network byte order (a.k.a. big-endian) with the most-significant byte first. + +

mime.convs

+ +

The mime.types file defines the recognized file filters and consists +of 1 or more lines of ASCII text. Comment lines start with the pound +("#") character. + +

Each non-blank line starts with two MIME type identifiers ("super/type") +representing the source and destination types. Following the MIME types are +a cost value (0 to 100) and the filter program to use. If the filter program +is not specified using the full path then it must reside in the CUPS filter +directory: + +

    +super/type SP super/type2 SP cost SP program
    +
+ +

Option Files

+ +

CUPS maintains user-defined printer and option files for each +printer and user on the system. The printers and options defined in the +system option file (/etc/cups/lpoptions) are loaded first, +followed by the user option file ($HOME/.lpoptions). +Options in the user file replace those defined in the system file for +the same destination. Each line in the files can be one of the +following: + +

    +Dest name option=value option=value ... option=value
    +Dest name/instance option=value option=value ... option=value
    +Default name option=value option=value ... option=value
    +Default name/instance option=value option=value ... option=value
    +
+ +

The line beginning with "Default" indicates the default destination for +print jobs; a default line in the user option file overrides the default +defined in the system option file. + +

Name is the name of a printer known to the local server. + +

Instance can be any string of letters, numbers, and the underscore +up to 127 characters in length. + +

The remainder of the line contains a list of space-separated options +and their values. + +

PostScript Printer Description Files

+ +

PostScript Printer Description ("PPD") files describe the capabilities +of each printer and are used by CUPS to support printer-specific features +and intelligent filtering. + +

PPD Specification

+ +

The PPD file format is described in + +Adobe TechNote #5003: PostScript Printer Description File Format +Specification Version 4.3. + +

CUPS Extensions to PPD Files

+ +

CUPS adds several new attributes that are described below. + +

cupsFilter

+ +

This string attribute provides a conversion rule of the form: + +

    +source/type cost program
    +
+ +

The destination type is assumed to the printer's type. If a printer +supports the source type directly the special filter program "-" may be +specified. + +

cupsManualCopies

+ +

This boolean attribute notifies the RIP filters that the destination printer +does not support copy generation in hardware. The default value is false. + +

cupsModelNumber

+ +

This integer attribute specifies a printer-specific model number. This number +can be used by a filter program to adjust the output for a specific model of +printer. + +

cupsProfile

+ +

This string attribute specifies a color profile of the form: + +

    +resolution/type density gamma m00 m01 m02 m10 m11 m12 m20 m21 m22
    +
+ +

The resolution and type values may be "-" to act as a +wildcard. Otherwise they must match one of the Resolution or +MediaType attributes defined in the PPD file. + +

The density and gamma values define gamma and density +adjustment function such that: + +

    +f(x) = density * xgamma
    +
+ +

The m00 through m22 values define a 3x3 transformation +matrix for the CMY color values. The density function is applied after +the CMY transformation. + +

cupsVersion

+ +

This required attribute describes which version of the CUPS IDD was used +for the PPD file extensions. Currently it must be the string "1.0" or "1.1". + +

Scheduler Configuration Files

+ +

The scheduler reads three configuration files that define the available +printers, classes, and services: + +

+ +
classes.conf +
This file defines all of the printer classes known to the + system. + +
cupsd.conf +
This file defines the files, directories, passwords, etc. + used by the scheduler. + +
printers.conf +
This file defines all of the printers known to the system. + +
+ +

classes.conf

+ +

The classes.conf file consists of 1 or more lines of ASCII text. +Comment lines start with the pound ("#") character. + +

Each non-blank line starts with the name of a configuration directive +followed by its value. The following directives are understood: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectiveDescription
<Class name>
+ </Class>
Surrounds a class definition.
<DefaultClass name>
+ </Class>
Surrounds a class definition for the default destination.
AcceptingSpecifies whether the class is accepting new jobs. May be + the names "Yes" or "No".
AllowUsersSpecifies a list of users that are allowed to access the class.
BannerStartSpecifies the banner that is printed before other files in a + job.
BannerEndSpecifies the banner that is printed after other files in a + job.
DenyUsersSpecifies a list of users that are not allowed to access the + class.
InfoA textual description of the class.
LocationA textual location of the class.
PrinterSpecifies a printer that is a member of the class.
StateSpecifies the initial state of the class; can be "Idle" or + "Stopped".
StateMessageSpecifies a textual message for the current class state.
+ +

cupsd.conf

+ +

The cupsd.conf file consists of 1 or more lines of ASCII text. +Comment lines start with the pound ("#") character. + +

Each non-blank line starts with the name of a configuration directive +followed by its value. The following directives are understood: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectiveDefaultDescription
AccessLogaccess_logSpecifies the location of the access log file. The special name + "syslog" can be used to send access log information to the system + log.
Allow-Allows connections from the specified host, network, or + domain.
AuthClass-Specifies what level of authentication is required; may be + "User", "System", or "Group".
AuthTypeNoneSpecifies the type of authentication to perform; may be + "None", "Basic", or "Digest".
BrowseAddress255.255.255.255Specifies a broadcast address to send CUPS browsing packets to.
BrowseAllow-Specifies hosts or addresses from which browsing information + should be used.
BrowseDeny-Specifies hosts or addresses from which browsing information + should not be used.
BrowseInterval30Specifies the number of seconds between browsing updates. A + browse interval of 0 seconds disables outgoing packets.
BrowseOrderAllow,DenySpecifies the order of BrowseAllow and BrowseDeny directive + processing; can be "Deny,Allow" to implicitly deny hosts unless + they are allowed by a BrowseAllow line, or "Allow,Deny" to + implicitly allow hosts unless they are denied by a BrowseDeny + line.
BrowsePoll-Specifies a server to poll for available printers and classes.
BrowsePort631Specifies the UDP port number to use for browse packets.
BrowseRelay-Specifies a source and destination address for relaying browser + information from one subnet to another.
BrowseShortNamesyesSpecifies whether or not to provide short names (without the + "@server" part) for remote printers.
BrowseTimeout300Specifies the number of seconds to wait until remote destinations + are removed from the local destination list.
BrowsingOnSpecifies whether or not printer and class browsing is enabled; can + be "On" or "Off".
DataDir/usr/share/cupsSpecifies the directory where CUPS data files are stored.
DefaultCharsetiso-8859-1Specifies the default character set.
DefaultLanguagecurrent localeSpecifies the default language.
Deny-Refuses connections from the specified host, network, or + domain.
DocumentRoot/usr/share/doc/cupsSpecifies the document data root directory.
ErrorLogerror_logSpecifies the error log file location. The special name + "syslog" can be used to send error log information to the system + log.
Grouproot, sys, systemSpecifies the group name or ID that is used when running + external programs.
HostNameLookupsOffSpecifies whether or not to perform reverse IP address lookups to + get the actual hostname; may be "On" or "Off". Hostname lookups can + significantly degrade the performance of the CUPS server if one or + more DNS servers is not functioning properly.
ImplicitClassesOnSpecifies whether or not to automatically create printer classes + when more than one printer or class of the same name is detected on + the network; may be "On" or "Off".
KeepAliveOnSpecifies whether or not to use the HTTP Keep-Alive feature; may + be "On" or "Off".
KeepAliveTimeout30Specifies the amount of time to keep the HTTP connection alive + before closing it.
<Location path>
+ </Location>
-Specifies a location to restrict access to.
LogLevelinfoControls the amount of information that is logged in the + error log file. Can be one of "debug", "info", "warn", "error", + or "none", in decreasing order or verbosity.
MaxClients100Specifies the maximum number of simultaneous active clients. + This value is internally limited to 1/3 of the total number of + available file descriptors.
MaxLogSize0Specifies the maximum size of the access, error, and page + log files in bytes. If set to 0 then no maximum size is set. + Log files are rotated automatically when this size is + exceeded.
MaxRequestSize0Specifies the maximum size of HTTP requests in bytes. If set to 0 + then there is no maximum.
OrderAllow,DenySpecifies the order of Allow and Deny directive processing; can + be "Deny,Allow" to implicitly deny hosts unless they are allowed by + an Allow line, or "Allow,Deny" to implicitly allow hosts unless they + are denied by a Deny line.
PageLogpage_logSpecifies the location of the page log file. The special name + "syslog" can be used to send page log information to the system + log.
Port631Specifies a port number to listen to for HTTP connections.
Printcap/etc/printcapSpecifies the location of a Berkeley printcap file to update + with a list of current printers and classes. If no filename is + supplied then this automatic generation is disabled.
RequestRoot/var/spool/cupsSpecifies the location of request files.
RIPCache8mSpecifies the size of the memory cache in bytes that is used by + RIP filters.
ServerAdminroot@ServerNameSpecifies the person to contact with problems.
ServerNamehostnameSpecifies the hostname that is supplied to HTTP clients. This + is also used to determine the default CUPS server for the CUPS IPP + client applications.
ServerRoot/etc/cupsSpecifies the root directory for server configuration files.
SystemGrouproot, sys, systemSpecifies the group name used for System class authentication.
TempDir/var/tmpSpecifies the temporary directory to use.
Timeout300The timeout in seconds before client connections are closed + in the middle of a request.
UserlpSpecifies the user that is used when running external programs.
+ +

printers.conf

+ +

The printers.conf file consists of 1 or more lines of ASCII text. +Comment lines start with the pound ("#") character. + +

Each non-blank line starts with the name of a configuration directive +followed by its value. The following directives are understood: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
DirectiveDescription
AcceptingSpecifies whether the printer is accepting new jobs. May be + the names "Yes" or "No".
<DefaultPrinter name>
+ </Printer>
Surrounds the printer definition for a default destination.
AllowUsersSpecifies a list of users that are allowed to access the printer.
BannerStartSpecifies the banner that is printed before other files in a + job.
BannerEndSpecifies the banner that is printed after other files in a + job.
DenyUsersSpecifies a list of users that are not allowed to access the + printer.
DeviceURISpecifies the device-uri attribute for the printer.
InfoA textual description of the printer.
LocationA textual location of the printer.
<Printer name>
+ </Printer>
Surrounds the printer definition.
StateSpecifies the initial state of the printer; can be "Idle" or + "Stopped".
StateMessageSpecifies a textual message for the current printer state.
+ +

External Interfaces

+ +

AppSocket Protocol

+ +

The AppSocket protocol is an 8-bit clean TCP/IP socket connection. +The default IP service port is 9100. The URI method name is "socket". + +

The AppSocket protocol is used by the Hewlett Packard JetDirect +network interfaces and print servers, as well as many other vendors' +products. See the CUPS Software Administrators Manual for a list of +supported products. + +

CUPS Browsing Protocol

+ +

The CUPS Browsing Protocol is a UDP/IP-based broadcast service. By default +this service operates on IP service port 631. + +

Each broadcast packet describes the state of a single printer or class and +is an ASCII text string of up to 1450 bytes ending with a newline (0x0a). The +string is formatted as follows: + +

    +type SP state SP uri SP "location" SP "info" SP "make-and-model" NL
    +
+ +

State, uri, location, info, and make-and-model, +correspond to the IPP printer-state, +printer-uri-supported, printer-location, +printer-info, and printer-make-and-model +attributes. + +

Type is a hexadecimal number string representing +capability/type bits: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitDescription
00 = printer
+ 1 = class
10 = local
+ 1 = remote
+ (always 1)
21 = can print B&W
31 = can print color
41 = can duplex
51 = can staple
61 = can do fast copies
71 = can do fast collating
81 = can punch holes
91 = can cover
101 = can bind
111 = can sort
121 = can print up to 9x14 inches
131 = can print up to 18x24 inches
141 = can print up to 36x48 inches
151 = can print variable sizes
+ +

CUPS Form File

+ +

CUPS Form files are XML files used by the CUPS formtops +filter to produce dynamic banner pages and support preprinted forms. + +

The MIME type for CUPS Form files is +application/vnd.cups-form. + +

CUPS Form DTD

+ +

The following DTD describes the available elements and attributes in +a CUPS Form file: + +

+ + + +
+<!ENTITY % Angle "CDATA" -- angle in degrees -->
+
+<!ENTITY % Color "CDATA" -- a color using sRGB: #RRGGBB as Hex values -->
+
+<!ENTITY % Length "CDATA" -- nn for pixels or nn% for percentage length -->
+
+<!ENTITY % Lengths "CDATA" -- comma-separated Length values -->
+
+<!ENTITY % Text "CDATA">
+
+<!ENTITY % heading "H1|H2|H3|H4|H5|H6">
+
+<!ENTITY % preformatted "PRE">
+
+<!ENTITY % i18n
+ "lang        %LanguageCode; #IMPLIED  -- language code --
+  dir         (ltr|rtl)      #IMPLIED  -- direction for weak/neutral text --"
+  >
+
+<!ENTITY % attrs "%i18n;">
+
+<!ENTITY % fontstyle
+ "B | FONT | I | TT">
+
+<!ENTITY % graphics
+ "BOX | RECT | LINE | POLY | ARC | PIE | TEXT">
+
+<!ENTITY % insert
+ "IMG | VAR">
+
+<!-- %inline; covers inline or "text-level" elements -->
+<!ENTITY % inline "#PCDATA | %fontstyle; | %graphics; | %insert;">
+
+<!ELEMENT (%fontstyle;) - - (%inline;)*>
+<!ATTLIST (%fontstyle;)
+  %attrs;                              -- %i18n --
+  >
+
+<!ELEMENT BR - O EMPTY                 -- forced line break -->
+<!ATTLIST BR
+  %attrs;                              -- %i18n --
+  >
+
+<!ENTITY % block
+     "P | %heading; | %preformatted;">
+
+<!ENTITY % flow "%block; | %inline;">
+
+<!ELEMENT PAGE O O (%flow;)+           -- document body -->
+<!ATTLIST PAGE
+  %attrs;                              -- %i18n --
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  valign      (top|middle|center|bottom) #IMPLIED -- vertical alignment --
+  >
+
+<!ELEMENT P - O (%inline;)*            -- paragraph -->
+<!ATTLIST P
+  %attrs;                              -- %i18n --
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  >
+
+<!ELEMENT (%heading;)  - - (%inline;)* -- heading -->
+<!ATTLIST (%heading;)
+  %attrs;                              -- %i18n --
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  >
+
+<!ELEMENT PRE - - (%inline;)*          -- preformatted text -->
+<!ATTLIST PRE
+  %attrs;                              -- %i18n --
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  >
+
+<!ELEMENT BOX - O EMPTY                -- unfilled box -->
+<!ATTLIST BOX
+  color       %Color;        #IMPLIED  -- override color --
+  height      %Length;       #REQUIRED -- height of box --
+  thickness   %Length;       #IMPLIED  -- override line thickness --
+  width       %Length;       #REQUIRED -- width of box --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+<!ELEMENT RECT - O EMPTY               -- filled box -->
+<!ATTLIST RECT
+  color       %Color;        #IMPLIED  -- override color --
+  height      %Length;       #REQUIRED -- height of box --
+  width       %Length;       #REQUIRED -- width of box --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+<!ELEMENT LINE - O EMPTY               -- polyline -->
+<!ATTLIST LINE
+  color       %Color;        #IMPLIED  -- override color --
+  thickness   %Length;       #IMPLIED  -- override line thickness --
+  x           %Lengths;      #REQUIRED -- horizontal positions --
+  y           %Lengths;      #REQUIRED -- vertical positions --
+  >
+
+<!ELEMENT POLY - O EMPTY               -- polygon (filled) -->
+<!ATTLIST POLY
+  color       %Color;        #IMPLIED  -- override color --
+  x           %Lengths;      #REQUIRED -- horizontal positions --
+  y           %Lengths;      #REQUIRED -- vertical positions --
+  >
+
+<!ELEMENT ARC - O EMPTY                -- unfilled arc -->
+<!ATTLIST ARC
+  color       %Color;        #IMPLIED  -- override color --
+  end         %Angle;        #IMPLIED  -- override end angle --
+  height      %Length;       #REQUIRED -- height of arc --
+  start       %Angle;        #IMPLIED  -- override start angle --
+  thickness   %Length;       #IMPLIED  -- override line thickness --
+  width       %Length;       #REQUIRED -- width of arc --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+<!ELEMENT PIE - O EMPTY                -- filled arc -->
+<!ATTLIST PIE
+  color       %Color;        #IMPLIED  -- override color --
+  end         %Angle;        #IMPLIED  -- override end angle --
+  height      %Length;       #REQUIRED -- height of arc --
+  start       %Angle;        #IMPLIED  -- override start angle --
+  width       %Length;       #REQUIRED -- width of arc --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+<!ELEMENT TEXT - - (%flow;)*           -- text box -->
+<!ATTLIST RECT
+  align       (left|center|right) #IMPLIED -- horizontal alignment --
+  height      %Length;       #REQUIRED -- height of box --
+  valign      (top|middle|center|bottom) #IMPLIED -- vertical alignment --
+  width       %Length;       #REQUIRED -- width of box --
+  x           %Length;       #REQUIRED -- horizontal position --
+  y           %Length;       #REQUIRED -- vertical position --
+  >
+
+
+<!ELEMENT IMG - O EMPTY                -- Embedded image -->
+<!ATTLIST IMG
+  %attrs;                              -- %coreattrs, %i18n, %events --
+  src         %URI;          #REQUIRED -- URI of image to embed --
+  height      %Length;       #IMPLIED  -- override height --
+  width       %Length;       #IMPLIED  -- override width --
+  >
+
+<!ELEMENT HEAD O O (DEFVAR)*           -- document head -->
+<!ATTLIST HEAD
+  %i18n;                               -- lang, dir --
+  >
+
+<!ELEMENT DEFVAR - O EMPTY             -- variable definition -->
+<!ATTLIST DEFVAR
+  name        CDATA          #REQUIRED -- name
+  value       CDATA          #REQUIRED -- value
+  >
+
+
+<!ENTITY % html.content "HEAD, PAGE">
+
+<!ELEMENT CUPSFORM - - (HEAD) (PAGE)+  -- document root element -->
+<!ATTLIST CUPSFORM
+  %i18n;                               -- lang, dir --
+  >
+
+ +

CUPS PostScript File

+ +

CUPS PostScript files are device-dependent Adobe PostScript program files. +The PostScript language is described in the + +Adobe PostScript Language Reference Manual, Third Edition. + +

The MIME type for CUPS PostScript files is +application/vnd.cups-postscript. + +

CUPS Raster File

+ +

CUPS raster files are device-dependent raster image files that contain a +PostScript page device dictionary and device-dependent raster imagery for +each page in the document. These files are used to transfer raster data +from the PostScript and image file RIPs to device-dependent filters that +convert the raster data to a printable format. + +

A raster file begins with a four byte synchronization word: 0x52615374 +("RaSt") for big-endian architectures and 0x74536152 ("tSaR") for little-endian +architectures. The writer of the raster file will use the native word order, +and the reader is responsible for detecting a reversed word order file and +swapping bytes as needed. The CUPS Image Library raster functions perform +this function automatically. + +

Following the synchronization word are a series of raster pages. Each page +starts with a page device dictionary header and is followed immediately by the +raster data for that page. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BytesDescriptionValues
0-63MediaClassNul-terminated ASCII string
64-127MediaColorNul-terminated ASCII string
128-191MediaTypeNul-terminated ASCII string
192-255OutputTypeNul-terminated ASCII string
256-259AdvanceDistance0 to 232 - 1 points
260-263AdvanceMedia0 = Never advance roll
+ 1 = Advance roll after file
+ 2 = Advance roll after job
+ 3 = Advance roll after set
+ 4 = Advance roll after page
264-267Collate0 = do not collate copies
+ 1 = collate copies
268-271CutMedia0 = Never cut media
+ 1 = Cut roll after file
+ 2 = Cut roll after job
+ 3 = Cut roll after set
+ 4 = Cut roll after page
272-275Duplex0 = Print single-sided
+ 1 = Print double-sided
276-283HWResolutionHorizontal and vertical resolution in dots-per-inch.
284-299ImagingBoundingBoxFour integers giving the left, bottom, right, and top positions + of the page bounding box in points
300-303InsertSheet0 = Do not insert separator sheets
+ 1 = Insert separator sheets
304-307Jog0 = Do no jog pages
+ 1 = Jog pages after file
+ 2 = Jog pages after job
+ 3 = Jog pages after set
308-311LeadingEdge0 = Top edge is first
+ 1 = Right edge is first
+ 2 = Bottom edge is first
+ 3 = Left edge is first
312-319MarginsLeft and bottom origin of image in points
320-323ManualFeed0 = Do not manually feed media
+ 1 = Manually feed media
324-327MediaPositionInput slot position from 0 to N
328-331MediaWeightMedia weight in grams per meter squared
332-335MirrorPrint0 = Do not mirror prints
+ 1 = Mirror prints
336-339NegativePrint0 = Do not invert prints
+ 1 = Invert prints
340-343NumCopies1 to 232 - 1
344-347Orientation0 = Do not rotate page
+ 1 = Rotate page counter-clockwise
+ 2 = Turn page upside down
+ 3 = Rotate page clockwise
348-351OutputFaceUp0 = Output face down
+ 1 = Output face up
352-359PageSizeWidth and length in points
360-363Separations0 = Print composite image
+ 1 = Print color separations
364-367TraySwitch0 = Do not change trays if selected tray is empty
+ 1 = Change trays if selected tray is empty
368-371Tumble0 = Do not rotate even pages when duplexing
+ 1 = Rotate even pages when duplexing
372-375cupsWidthWidth of page image in pixels
376-379cupsHeightHeight of page image in pixels
380-383cupsMediaTypeDriver-specific 0 to 232 - 1
384-387cupsBitsPerColor1, 2, 4, 8 bits
388-391cupsBitsPerPixel1 to 32 bits
392-395cupsBytesPerLine1 to 232 - 1 bytes
396-399cupsColorOrder0 = chunky pixels (CMYK CMYK CMYK)
+ 1 = banded pixels (CCC MMM YYY KKK)
+ 2 = planar pixels (CCC... MMM... YYY... KKK...)
400-403cupsColorSpace0 = white
+ 1 = RGB
+ 2 = RGBA
+ 3 = black
+ 4 = CMY
+ 5 = YMC
+ 6 = CMYK
+ 7 = YMCK
+ 8 = KCMY
+ 9 = KCMYcm
404-407cupsCompressionDriver-specific 0 to 232 - 1
408-411cupsRowCountDriver-specific 0 to 232 - 1
412-415cupsRowFeedDriver-specific 0 to 232 - 1
416-419cupsRowStepDriver-specific 0 to 232 - 1
+ +

The MIME type for CUPS Raster files is +application/vnd.cups-raster. + +

CUPS Raw Files

+ +

Raw files are printer-dependent print files that are in a format suitable +to the destination printer (e.g. HP-PCL, HP-RTL, etc.) The MIME type for CUPS +Raw files is application/vnd.cups-raw. + +

Internet Printing Protocol

+ +

The Internet Printing Protocol and the CUPS extensions to it are +described in the CUPS Implementation of IPP document. + +

Line Printer Daemon Protocol

+ +

The Line Printer Daemon (LPD) protocol is described by +RFC 1179: Line Printer Daemon +Protocol. + +

The URI method name for LPD is "lpd". + +

Server Message Block Protocol

+ +

The Server Message Block (SMB) and related Common Internet File +System (CIFS) protocols are described at +http://anu.samba.org/cifs. + +

The URI method name for SMB is "smb". Support for this protocol is +provided via the SAMBA smbspool(1) program provided with +SAMBA 2.0.6 and higher. + +

Directories

+ +
+ +
/etc/cups +
The scheduler configuration and MIME files reside here. + +
/etc/cups/certs +
The authentication certificates reside here. + +
/etc/cups/interfaces +
System V interface scripts reside here. + +
/etc/cups/ppd +
This directory contains PPD files for each printer. + +
/usr/bin +
The cancel, lp, lpq, + lpr, lprm, and lpstat commands + reside here. + +
/usr/lib, /usr/lib32 +
The shared libraries (DSOs) reside here. + +
/usr/lib/cups/backend +
The backend filters reside here. + +
/usr/lib/cups/cgi-bin +
The CGI programs reside here. + +
/usr/lib/cups/daemon +
The polling and LPD daemons reside here. + +
/usr/lib/cups/filter +
The file filters reside here. + +
/usr/sbin +
The accept, cupsd, + lpadmin, lpc, and reject + commands reside here. + +
/usr/share/cups +
This is the root directory of the CUPS static data. + +
/usr/share/cups/charsets +
The character set files reside here. + +
/usr/share/cups/data +
The filter data files reside here. + +
/usr/share/cups/fonts +
The pstoraster font files reside here. + +
/usr/share/cups/model +
The sample PPD files reside here. + +
/usr/share/cups/pstoraster +
The pstoraster data files reside here. + +
/usr/share/doc/cups +
The scheduler documentation files reside here. + +
/var/log/cups +
The access_log, error_log, and + page_log files reside here. + +
/var/spool/cups +
This directory contains print job files. + +
+ + + + + diff --git a/doc/images/accept-jobs.gif b/doc/images/accept-jobs.gif new file mode 100644 index 0000000000000000000000000000000000000000..9da7a0dce11b175dafc1f23c698367a584570a0a GIT binary patch literal 259 zc-jF20sQ_)Nk%v~VOana0KxzO%*>glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui09gPO z000Bf2)ZFdCCW*wy*O)0h6qc@3|ncQs5O8hV5D#?TZZ_~c#hUep#Q)OixH-;FljX}YJw1!H5r;IgHn-{ceE1IM+xKXBDiBI` zcVb9?iiL-PdK(0UYGZX*NR)z(YMGpLeI1O8h?b;&rJAUv6&|6FuBLpBR+Y4}f)yXF zjeDMCyk2Xwyk~X8!xbPzN1MwiPf*Rw(IqS{)2i1OJPSA3-Wl5=0m|Ry1uHG$4wB|a J9UmglrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui089WB z000BO2)ZFdCCW*wy*L*#L|7m*Xk=-c!xsX^>ArAegl%l!*sKJ2?@Ovt=71qmjFp2D ziS!KsykVg^p-wGLqZQZC5UI**By8P^r(sEYY>qgjV>LUDPF}QfG5%b6z|Tx{e1b=I zgKZK75JgLYbdFVbYD<$glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui08#)H z000BY2)ZFdCCW*wy*OJkL|7m*Xk=-g)bNFXfxd7&8KEoRI7ur(?*En5D09FRDaXlS zxwIrJPt*X=BNn0(tX7G_o*J5Bw3#GBx!3ejyl!6IYK+4gDc9Hcb2guT*Z+Nea25}A zfp&*bOo)PejeuSg1Q14xj*o$tXqb3!On?|1Mo6HYnV_4dom&|lqiAiAtfY{Rs;Cwo zua{#H!Cg9(kD9$Hq+P^)gS@K+1M&9+zyoAKO7z`2>?5A CbZnvk literal 0 Hc-jL100001 diff --git a/doc/images/cancel-job.gif b/doc/images/cancel-job.gif new file mode 100644 index 0000000000000000000000000000000000000000..3cc1e23bc650c00b22adb435e40862516f3b9d66 GIT binary patch literal 248 zc-jH@00;j^Nk%v~VN(DU0KxzO%*>g9fM7yGF&G#U0|Np800384LI3~%EC2ui08;=I z000BU2)ZFdCCW*wy*OVoL|7m*Xk=-g)$oOYfxd7|8KEoRcu6Zk?*Eq62y-YNfRrO~ zsTlxz%!m?Mm|CpKQX^V1N{+>e_ZyaGrsHZAOL1_;U#W5)SDWn@`n}ASJlz+o`iLgkro}5p{IMOgI%g~i4`6iMpj;6b!)U` yp15MVV3-jfLsY~vPEW?5W@?y9E literal 0 Hc-jL100001 diff --git a/doc/images/cancel-jobs.gif b/doc/images/cancel-jobs.gif new file mode 100644 index 0000000000000000000000000000000000000000..2384b903c673223b776c21f76c2ea6a9ad5f9d14 GIT binary patch literal 255 zc-jH~0093-Nk%v~VOana0KxzO%*>g9fM7yGF&G#U0|Np800384LI3~%EC2ui09gPO z000Bb2)ZFdCCW*wy*O)0h6qc@3|ncQs5O8hV5D#?TZZ_~c#hUep#Q)Oi-b8C55Wnt z$V?3YzGh^Zq*|;Ltf?Wb93@DjQVb>+w8}CyY&BaP-Sl+2tb^xx^!>ai+xZs{aaVYN zT5E-bfQEe=1P~W`XJ3ndW0aDNd3%!?9fO6ImYk%arj=P39vN+?h^VlKjd_2g6dxK# zZDL`Zlyt9IZoh0}LI6Zb%0N$0%g;J2F3{94JPS9~+8Ng&0m<9p1uHGy4v^x?9Umh0fMCo*G0Yee%mV_<007KaLI3~%EC2ui06G8^ z000A@2)ZFdCCW*wy^#zNmS+Pdj^s3SA7GShdl}#A&NQq9bUvdYcKiq3C}TH MbhQ>594QF^J97d~lmGw# literal 0 Hc-jL100001 diff --git a/doc/images/classes.gif b/doc/images/classes.gif new file mode 100644 index 0000000000000000000000000000000000000000..ace15df98035c8ff3e41036b0be59f2664f7d0d3 GIT binary patch literal 591 zc-jF^08~U*5-X9+fD*emQ%-t<0(_wQriGZ zZZazx6{;H!rfZ&NF^DjR%UP$gL12(v1z%TG%JvI>t<>1d$R6}E?QFaBuG=p#CYq`w ziZLKnI#?fMDjR}LReukMU5I;WPjg%#kve@k4n}f;gCRUfWn^cOf{Z>uD@%zdL!5^? zZErJON@0|Ace@NlyuZK^mQ+k1!FGr)XqH-AsBeLx4HT-7rY(4&t$Tq1JGN%5Vb2<> zecNi2Y_Y^HEYhh!)TfI?l!TXqlgPG)&Q*(hvyg$SQ4d$HfyWfAV+V3h%sVe{>bzsg*v?&fS|wvO z;ipJR`P$Vo+Q`t9b~&`r2nMgIIb~O{sU$>Hj3ZL$G-e2z&tV~XEGM?mG=|~0JOR9Q zx~ivQkCoAuorL9KVzjCZsL7LY2n_~8V(13pGyvmhOX_!0g^}SfQhCYc7E-lJ z<8mqB@6klgfj#Q`%u%b%(iC7vD_0O};S&#LvOb}>9YnB~>XIW%d3BaYhzM(>GRB~0 zFrl4c{!(`{Okt{tJ(sb!5}DI%@Dx;B@|5J*;qU$?8QeVQ>viyE2Cb&1&70FFgU_{d d<`(xg{4v$bVfLjbUglrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui0C4~m z000B^2)ZFdCCW*wy*TU5BN;-ljLguTXsWK!Ad-N=&UC#Rq-^heKjDgiZ%CxQOqhf6 zpjsA}N(=KcRSf{bB1XL0ms$%xn6?5ILsAra&K{R zg=>6igoRs;gNKWYhL0EzfOUzJlaZN%f|`6#nVX%Ak{1LJRI7)jq^+=nPMCqNuTZBJ zAD51=x2C|FW23#2oV1k!8Fs?K$B2}lVPl@I)fpjTvx?HOZlS)iQsdr=+{6|lNJXsd u?pIju#q#biG4$v7L_iBV`u{%ojR>#~purU`U<`Di>YzhZAnYwj002AUeve21 literal 0 Hc-jL100001 diff --git a/doc/images/continue.gif b/doc/images/continue.gif new file mode 100644 index 0000000000000000000000000000000000000000..ff774adb348deca51456cc9934e33be9f9aea9a9 GIT binary patch literal 224 zc-jHr03ZKHNk%v~VMG8F0KxzO%*>g9reH#cF&J_Z17`vNW&l@_LI3~%EC2ui07L*3 z000B62)ZFdCCW*wy;zbV!urgRjbxb(9tap_>$V2SzI1KHN?`ANk&2ju@bDrQjJ?SK zpbJirC1{e;a9)NIqA-FrYLVdV7UQs1!bdN6oo1uamWP@0&brx0yc%C2K(2syf_r&| zg+pT&8*@)~hI@pOd>9-VP?C>>j$W7+9V3WOiEmnZVvmUy9zavABTG!KvKT2Vv$qmB a3p2Q`x*q|oy*nr>zz%=IB^w?4ZZ&};` literal 0 Hc-jL100001 diff --git a/doc/images/cups-bar.gif b/doc/images/cups-bar.gif new file mode 100644 index 0000000000000000000000000000000000000000..b2bdf4b520db437c310a503ba6b27bd696fe580c GIT binary patch literal 1242 zc-jHl1SR`NNk%w1VMhQ`0P_F) z%*@RH0002Y%*@Qp%*@QpA^8LW000dDEC2ui07n2)07C@+u*pfQy*TU5@nB#mj$~-m;k{Y;ytnIwsiZN&m4v7XswuJ8gOvP;Gl130ww6EH@o#Dg|j9ca1AmkDFj8 zS{XKXAY>9XR*yh;F?nB{3I?LFK|*ykoVOOI8aS=Ez7hkevLz`Ky1x^{C@{=11JBPe z!#)kYEq7h8bV`VXN;m-rY8O>d zV4O-5gpmkfKwlewP0FNM(xAYTdTbgbP$5T20E_-I9Aa?dDMbQn$TDCdW`L3hRp?Su zSefM$3x&#Zmgo{wrj<0&!r?>#rCE;wE@l2gpdhHUX3w^j(xkKlO`R|&P)&)oD+y}t zHUJpLEGj^I5&{Ap`l2TWbE5UJJ5R+JO2wxz2F8>U3ulsNgIVvisq2rrP#;&yS( zbrdkBC76bwM#^&|K|2~%USCfQ3$59c$cZ-)bpQkAh5&@OU=j=j(3+4300C&f#o5S! z@{__U4n#D3nji=rWRA~B#>1_=DqA;MG35)U$TJ{9?g&X>Wysze;W7wKq{oiLFH4F% zg^{lW%l|6;3%EuStFR5&j#?Ks`YsM9$o`O9Df;12N>z%f!#DYgV7OBY^vsFGJ*#emy$DgA^Ui$uZT;BpW~qJjVg@QBm^ zJ{Eu!M@dkCSB@N*GUAddBDq0R1)A_oT}L9R7ma{aV@r-EVrgNHQF{56dz-Xa)Kgdq zsO2LFgt<&v+^GQdFoY=os0k$>s%z?nfpc*hu38 z12|;4#{!gEB*<*>7-K|pWWqAb2g%4&USOq-vW5nS!cahw@<~XCYH{o#4RD`^QyB&b z2*+3^>6Ao`iCQ#4SQ*EAQtp~OoLKq1siTrXA{MkkiG z;fSqcU|Itaq11MWr@$zv2M%Qnm(h4)lsZr%r}C>$0r2J*gbJr5;+vdL^wZm|g{^8D zH?sY<(FYqk zgh>kCxWq2|DxU44`wI^Fm&<5&ru~QwqLPKla&$zaOj)E`ph=@*rp#yWzUW;2h77%` zlobTInG;k~d`?-HIvMrMTmybS0Z^L-!%#B@0MLk8`eg3@ZUk*aN8cJ5-u?#YiwFP! EJKUogO#lD@ literal 0 Hc-jL100001 diff --git a/doc/images/cups-block-diagram.gif b/doc/images/cups-block-diagram.gif new file mode 100644 index 0000000000000000000000000000000000000000..2fe505e44b91deeb805b568a4db3a0fb508b0805 GIT binary patch literal 11637 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 B-D3a% literal 0 Hc-jL100001 diff --git a/doc/images/cups-small.gif b/doc/images/cups-small.gif new file mode 100644 index 0000000000000000000000000000000000000000..6adb4a29ffbd6b806d8eed34fdad33f6138e8890 GIT binary patch literal 1266 zc-jH-1P%K~Nk%w1VQ2t*0P+9;%*@Q0nVDv0W-~K000030|NsC0|NsC0A^8LW000F5 zEC2ui0B8Vv073))Si0Q)Fv>}*y;P9RyZ>M)f&+k^&M>Z|5CEnF2ZGAp#DF#d?g_gf zMB^g>Geuovvm_`sy(66bkjl^nG{>zj(HFtg+CH;@**F8gro_jj zgj?4byer~)Nf456i8gNvL_|X0AKjZb>HiP(?JJY134<#O)`DciDjrm5wU?-9CnKXPnbDTvVa3|4f5K7S6B=AM! zSYIVh=MMvpL6%}^eK=5Ac<_z(R8;T0D3mP`7Qt9sGhSe$EOS+sTM)thaLtgUiD6_2 zhR`Sjh1$62wZ88{PYI*?4fc95P!hd?1I4wU9X6lPAS{=i&_ zo?VF1doqTGo^>DAmj)l0_Jo62Oos5|L@{Wf#B=Lafe9Y8?x1TS<83QJnBi<_-$QF~ zvqbn}J9Ra2PGl=fQ*CO_rXl%ZbOXykTl6(kKS27Gix4ug5I1RZMXO zBbFK{-Eb^oSCF{BD!VbP${lImYwjA1)NIC4D-y>1WqfmY9^86Ew$5hPT}r(E%AOU% zhC(C`+PyIFy&mz^)!zKG&baOq|v6_F*_C|4I;#4HBJ&n(8w@p2}RL(2}!DTz7 zIG=4kc*1vOOfO{;dR^(rrfcEDoT>YJgRMGB_C>cOroJw|OtX+}?8J8AwwtsUuK4Sw z5B0$9=>jZSq?PU7mVgl?>3n3RM_&Z&00rl%Ljuo*JnjL4`dgCQKS1hOMq(ehtE`8? zrH@~CI=#Aew*Nrz)z~kCpmbjemmzCuiKEn_sG606e}~$YGVqr`cF?JT*DDeP!%`*$ cc1nF?aZ~|iF+YF}&@50&%OUg^gaiNpJ5-EOApigX literal 0 Hc-jL100001 diff --git a/doc/images/delete-class.gif b/doc/images/delete-class.gif new file mode 100644 index 0000000000000000000000000000000000000000..81b1465acdd35559182b55e5b98ade10bb0afcdf GIT binary patch literal 259 zc-jF20sQ_)Nk%v~VOana0KxzO%*>g9fM7yGF&G#U0|Np800384LI3~%EC2ui09gPO z000Bf2)ZFdCCW*wy*O)0h6qc@3|ncQs5O8hV5D#?TZZ_~c#hUep#Q)Oi)1+%jhX{S zX*x0sPu&3EyF{ZE>_ltbM!2)alJY!C%1CJ1ob7(o?=3ju7<-}TuYS)gw~Kptf_;G% z4|aKigMoyKT40ZbiWmeCZi!BfnS4%vo}F=La|IoUe1DOXo@9)ycPav=ey5JKs)d@E zv~wRzprW&CXm4}BXi9xoqaZ{<&dyU*&(lCGF4WjEJPSA3-W%H?0nOj#5-Tm@4wmNA J9Umg9fM7yGF&G#U0|Np800384LI3~%EC2ui0ABzU z000Bn2)ZFdCCW*wy*O)3h6qc@3|ncQXgPo)V5D#?mxlPxc#hXfp#MM=i)1+%jhX{S zxj7;$%%W@n@Li$>EOc4IYLl}DcM?5H%1?9lN%2OM@b~(iX2&m%@mbDimiv2cWORLg zfQ1Ybh&DCpHjZOgv*f^AVfjc))Z7#*W1@DF5KWcJPSAB<|yMK0o3R1 R7Ar044xH}h9Um|NkNW4ozWXWgvHHbZ8()Nlj1yEC2ui00031 z0RRI2jE||y?GK}zwAzca-n{z{hT=$;=82~2%C_zc$MQ_q_KoNI&iDQg3<`(DqVb4K zDwoWr^9hYgr_`$Tip^@b+^+Wv4vWX+viXcotJmzd`wfrF=k&V$j?e4&{J#GW7$`VM zSZH{Nn5ekO*y#8O87VnQS!sERnW?$S+3EQS8Y((UT55WVnyR|W+UoiW8!J0YTWfoZ z+W?T;1mMf7BmGNVZH=8Ry}e_7?TrH-E?z@kZZ3m9 ztq#Nf?EV5C&@Ioht6gt@kMirBfM357&*B9HIFQ7$eGCL9{NQjw#D^K^Jh?ofCY<;rVU zmR-@ecA?_j>oROZt$_CtMru}U+Q4`V&;09Guw%q}88@Cxd9hW=nA`R}xVE!r%bzhD z{zuj+=fd_LGi*M<<1Jrg z9bM+0O};_bTX;Ghh+ka76(^v7H$6z)gRxP#8gdSDHl2k`NoL(^&h52ah{Z{$TRY`F zMxZ+!%7$KaE&c}-ds)o~4S)SDrV@_%eRpDy^`W?pctL{L6p{29x#NiPsi@$JGS2uU zl|{Zc+f@xFCuEmS1{o!iNqXobGE0%ArIOSD*koTG{`97oR(|-Uh_z{WSDZtZ8K#<5 z(l#eWhso)upn5uoXP)y-^=4N%u9c{ZWI|f!gq7~dqG@1~HkhV%TG^;=7KSQng?x&Z zA*rQ087XU_sj4ZXr+T{Qtg)WNrl%27wWY2{_Udb!um=03i*LUA z?#pk#{{9Pazyc3UaKQ#2jBvsVFU)Ym4nGWW#1ch0fMCo*G0Yee%mV_<007KaLI3~%EC2ui07U>4 z000BA2)ZFdCCW*wy?Bx#!urgRjbu3v9tap_>$(QWzI1)XN?`ANl!}%EMR*}jj6n?Y zG63j`LuF+dg_0W5qvXKdZiQ5BglhzcC627OP#(M4=XV?awmg(%a-GOuTjz5Y1Q1qh zfO{Eza()#XYKxG8eu`{}OahOUnwpATRh)*D6&;yno||1^dS7j)79K!7vMx?47M_YOT literal 0 Hc-jL100001 diff --git a/doc/images/left.gif b/doc/images/left.gif new file mode 100644 index 0000000000000000000000000000000000000000..fd7b0410439bdc234c3e56e5c41308dd2834437f GIT binary patch literal 110 zc-jGO0FnPkNk%v~VGsZq0KxzO%*>g@#F4YJfTpH%o}O!&nP#i2c(=ENEC2ui01yBe z0009!2)Yn5q)5q{nV7DV`x2c8aADSz-i2bpnt|>##8X7yIA+uH4b!a~KovXD6eQQD QxKT0!L{Y^7$s_;(JJ*UWq5uE@ literal 0 Hc-jL100001 diff --git a/doc/images/logo.gif b/doc/images/logo.gif new file mode 100644 index 0000000000000000000000000000000000000000..9999795caa725187141a472f5dd1109491286b8c GIT binary patch literal 1958 zc-jG`2U++>Nk%v~VMhQc0QCR>@bK{O@9&O|j*E+not>SVo14DAzPr1-mX?;3l$2gx zURqjOYHDg`W@dJFc5`!c2?+@W1qIX7)6me+&CSiq%F3*)tf{G~!^6YCz`*P4>+0(2 zqobpsprGaD<>ch#`T6aBzr-i0J6(DJdx+ARyr2;N0BY;^N|_rl!cq$W>KU^z`&HGBUBT zu>b%7EC2ui07n2Q07VA=z+G-gEOL%WWM|22b_md@lu)Qz3#+VFi|Be0iEudO3V}lC z$#2d6q1ZbBY~4HjZnj@Wv*~YUe;$H@AB7$tHaLhjjEyHZCnqSA5)%}b4GsXC0c~s| zeHtX5EHfwq0~{V45DWu93MB(L0|_<)IvFi8J|_YtEfNGRE)~WVIvC2z2F(W~3J)59 zeKXdBGan9gJug2HjSb=rEEtfI5|tB{6vrt&${88W2G1lV1V0=;{1z4$7l!PJL1@vU zMvQJKjC3O1oC_4%=|Hv&1HA*!o|P!U&xgN{L^yO1`Gg9W1Y|&{T*(rRO8`80Y?8UD zW&i*I0%*{wQ-l6bKGv?y7*r4k4n{{CK{|(mfrAh+L*Q6L0N@ZCb7cIG;3L8h7kzsC z(BR=3whxC6B~64-;W>2bA|9iNArsF48+_*VV~v1UHUd7V_#q;K3akQbL>OV?0xSs; z7QA_|4Z(;M6f*o!u_HnT4D&KzBte>E#|00DnmvT}gHfbwZA9`)VG;wv5n52#WcbS@o=xDt^i`z)^>>3gOZQUL`zB(qF2SmN~IPDtX_hYP>;;Q==@OqD8^!NLzUm_P#!6+l3P06(;Fn|=`-zzPX9&``n; z{txW%f(0tnV8I9rxF^y;s->ysQL(uN3Ab&$@Yx08`EUei_;gS}4kd7aKn^DGvw{FC z{4>A+IjkUq3-Jy>tw(H1G-jZku&xLYuY~-{1Xxr@MYnJ2{;ST zu~OVcVygtWB16}mp=t!IN5cjrFG*0WfQ1+d*eCVG7t5f6g%@UxVN3u52vtoV+5{q! zd|6YbiT1JvGC~zfl8H-DneYSt4V!%J z04^}d(7_KFRN&Jc3-qucAWHTPVNxruK8daC$oV==JVeX+4*|q*2Lvf>0D}S>)Bpnu z#vZ#Q$Sc0(Gs)}-olKrJ*#QHA1@2@w-hjZ+f(L<+p5|*#Lg}U?l&F$ijPWT9UQ>hflHDp-bRo|?44?o_i0wdp%F7HE*n(ZG zfdnvMK#eeP8yB=7H-O4RaehF72)IB5Fn|mUdLRP`JOBnFNLf5aI2vd;ASXNF$zJ}@ zhZ=lC6%KmA0uJ#58|>gP5U7C-p!0$gydVNP^4AM?aGMEW;0FmP&8PlCMFOMwpoBe1 z5ZS0Ghz-2sFDmeW3PjKW8%#h17Vx47Y+!&9VBiEJNQVPPP=FD%Km;wQ69+~h0us=} zSLZpJM^Mv~891&%R%8KdTqOfG&B`scq7pkOFn}G@X^9uX$kATr1Ay${0ehLCYKBq> zE3%;lY{`cw79fG|rCgU;zpkK@b1{JDeydnE(I) literal 0 Hc-jL100001 diff --git a/doc/images/manage-classes.gif b/doc/images/manage-classes.gif new file mode 100644 index 0000000000000000000000000000000000000000..69d5b0147068125faa07a4a84266a6d81aa269fc GIT binary patch literal 289 zc-jFW0p9*cNk%v~VQ>Hx0KxzO%*>glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui0B`^l z000B-2)ZFdCCW*wy*TU53mHPNjLguTXsWKoAd-N=&UCFBq-^heFX4)SZ%CZIOqN5k zxH&kL5h$}V00=KmN_L8!K&9MC1GANspXNeYz0OL}6|mRb2G{L!ii509f75JHf`eaw zgL6xLgo}!Aj1~`kj(LWPh>n(&U0R2onVuE|5SvPsPo{KRn5UYFY-f0>uo)kGeTJ)m zxsR@#pNP7)kOIQHjlqnnfWFDdxQEXdA;rsRrPXdx*V=iq*xPkp;TR%FVZG-yRaWWM n?K>|q@2~SUKnptc`YZP%0p|MxW^e(+pMy~X1%3ztBLM(A>uiRu literal 0 Hc-jL100001 diff --git a/doc/images/manage-jobs.gif b/doc/images/manage-jobs.gif new file mode 100644 index 0000000000000000000000000000000000000000..adaff856f0929ebe37519e68994a60a767490353 GIT binary patch literal 266 zc-jF90rmbzNk%v~VP60g0KxzO%*>glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui0ABzU z000Bm2)ZFdCCW*wy*O)3h6qc@3|ncQXgPo)V5D#?mxlPxc#hXfp#MM=i)1+zgD~So zi5dWWOJ?LCMV6`)Y^i~vQoK`e!6+V=y-cb$D^a)2*>%Lx9lw?7@O00|s;R7(t)h(<9)X*+o~vM! zv9P(V6(6*^Zm6TfdTF4XQkr&WkRU`>SJF*A)WO##EH2qa$=ww^3pe29CgLFh(dO(F QD=p~`mhIggA1w(0J8!smBLDyZ literal 0 Hc-jL100001 diff --git a/doc/images/manage-printers.gif b/doc/images/manage-printers.gif new file mode 100644 index 0000000000000000000000000000000000000000..cd897291dd439440a3c86a2b66cb8ebd6774878e GIT binary patch literal 296 zc-jFd0oVRVNk%v~VQv5v0KxzO%*>glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui0B!&j z000B^2)ZFdCCW*wy*TT=$q>OJG6QFxXsS{}I0D8h&$Mieajow>bt{3Ma7c5NEC(b} zb7(e|m!xh02u7un=MsZ0bT{8wgZtHb%}MjQ`@}k-5oy{RKgYH2x;#8_aOrw=f_Q>} zdxc?acY|_+S&N1k4}Wfe6ODzBmY9}VPL+V0k^;fQk)g|kna{49%(KuEAjz6*yV-AtZfe=F(~z)id=eo?TN&r; uGE`OW#o_Wr3pw?#`8q%M`~N%oi3p$$pg|KYUJP__>Yzgj9zeWE0028T9*5-s literal 0 Hc-jL100001 diff --git a/doc/images/modify-class.gif b/doc/images/modify-class.gif new file mode 100644 index 0000000000000000000000000000000000000000..58a0ead8297209371b80fcbfd0ca3cfc7513fee7 GIT binary patch literal 267 zc-jFA0rdVyNk%v~VOszc0KxzO%*>glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui09ybQ z000Bn2)ZFdCCW*wy*O)1h6qc@3|ncQC^mp1V5D#?V}|(7cn;S}p#Q)Pi)1+zOU6P{ zxy&4%%Vur>@Lir1>_#fZG?QIi!^@3oBUmug7_Eer66oa2%s9MobiTb;@8fP)dV_v` z77uuBhKq!Qd2@nUj*}Mz5Rq(+ntz;OZ)Rt7bQK+VaD{-6sCu55sjrk19;T{}g{!BL zntZEo1s}A0Yjc^LvBaTqX=q=*1t3I0Thb|1Rn!{J*cB`;+ehCeJPSAB<|gAI0nz8} R6e}(24wvrV9UmglrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui0AThCh_ApzO&_8KcK^A4i-{v97$Bme+At6qKs literal 0 Hc-jL100001 diff --git a/doc/images/navbar.gif b/doc/images/navbar.gif new file mode 100644 index 0000000000000000000000000000000000000000..c19f634c0d3278ff58e20c19eafe9136c8bbd5e4 GIT binary patch literal 2869 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 Tn1e`|gi81agHQ-67z6-28w6=Z literal 0 Hc-jL100001 diff --git a/doc/images/navbar.xcf.gz b/doc/images/navbar.xcf.gz new file mode 100644 index 0000000000000000000000000000000000000000..28438a6bb82303522c41ea5b3ce198a9de9a23bb GIT binary patch literal 4253 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 literal 0 Hc-jL100001 diff --git a/doc/images/print-test-page.gif b/doc/images/print-test-page.gif new file mode 100644 index 0000000000000000000000000000000000000000..807dca10e6c69e9e2eb439a00057365f748df68b GIT binary patch literal 288 zc-jFV0pI>dNk%v~VP^mo0KxzO%*>glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui0A~Oc z000B+2)ZFdCCW*wy*TSl$q>OJG6QFxXo?Qu2pDQCuObgu7_tpvQFP}M3~4oKt? zbD$)jrlu1*8~}h9X++E6PP`j17p!YAzuQ7nx@IdY-sIOEM{nPEwM33_ocDQpYHVps zfQ5vDc8G^=g^CpqOjL@Af@F|dmXCXscAAfv1q2XThL??|oqU6bi&Jl)gRB)Ee@>~4 zr;xb3zLlYz7$3KbmYc7#iDIYA$9-74uFtJ-uydWga7vDvcorc>L*q1}kw4_=D6$+a mFY54N-x@v(IPv&2^&$b{`TrbPxZvlY6u^TKJb-YK0027`?SZ-g literal 0 Hc-jL100001 diff --git a/doc/images/printer-idle.gif b/doc/images/printer-idle.gif new file mode 100644 index 0000000000000000000000000000000000000000..68d990c628dedbf4326390527ef72f2e90aa9841 GIT binary patch literal 706 zc-jHN0zLglNk%w1VOjuC0P+9;0RI40RaM~N;Hs*s0001gk-vYDzkiXxA^8LW000F5 zEC2ui09pW0073))Si0Q)Fv>}*y^CnUxh7pGd<14vpEz!6>%QY4&ve>uB}(tM*u$=0 zh~*0aj!0x6HzDkv(CC0T1OcxjAXDO$YNXGu%!(~jZg(+7?vyLqy7<$y%2h8}_!c5O1#O@a zR!WRP_!jAB`?Z9$cdG_4C31H(A zdizN3T)OVI;oZx(uiw9b{pt&>?ju3M1^W$@co=a3AuVIfv^w~$y{pB-h-^IRve9Bg zZG=2w@aN}0nh$QUqw#^j(+Ej~1F`Ce!zK{J!PXLzHp!B$F;!J<`YG|1zggYpvXeMA z%FvQ4S$-^KZ{23iki0V_sP*gF|CtQpooYbnMxmBBKcy4M-C5$iA{&z@e5CS~(%)GY zwuySBIn~$SY5(E223JIZ}*wI++r^T@^^jv{DWCws3gD8=aCR3G_lbf6jnVq1aqNAh{ODr@msT`{UV~RXa zb|9cdbtSI`sH!zhz8kV)B833O#aR`3i#xZty1;+Jjb~JacFD}j%SVjU-XDP2+p*dK zeBV&f;AMi7hp^*EQtE!0h@tlH+VmOukfogbDLI z6u`|b))n)fk!G4+fU%3!vgav2879Rp@fd}_GxTc(nAWJ z9e*AbdbDXnrc(x{OOD=pkAS@z@ztpvHjzaIt{&cubs z;yQA&y$zTrab7GZzJxB>Y%X@P*KC&P^ZNDKs^mw4WnkgPw59do|` ztnAKQ#LZWp6HV1LR8dE*F%mz^4M-q^n;i&Mf~G9fl!MTf#EyhSwRaa<3^J7lTTdNh z%^4piRp5wfVPaQVUP*`CTtSe9RE%Jlg9c&fOqWb|IHpA-J2omv4vx(1HDrx+q^Kia zN-pVFlQ8DEjgV3<=3|v_eHCSoe{6XpUdmwk4OX+H0HlgZ#&RZ!b+tnql6tx62V<3$ zl0{-@Y51l+0YS26pFx3HS_PT$Ne-T&dFD=JS87$6WqL+-)>fQRijZYxrqk$Zi86!B jr?YWNDsBxl`U$Fts>&*41HCGWVY1e0>#evxlmGxb6oz`@ literal 0 Hc-jL100001 diff --git a/doc/images/printer-stopped.gif b/doc/images/printer-stopped.gif new file mode 100644 index 0000000000000000000000000000000000000000..76f45649b132bde80d5a90530f0cf990aa4f5278 GIT binary patch literal 794 zc-jFP1LgcjNk%w1VOjuC0P+9;;Nak@s;d70099300001gk-vYDzkiXxA^8LW000F5 zEC2ui09pW0073))Si0Q)Fv>}*y^LtUxh7o*d<14vpEz!6>%LuB}(tM*u$=0 zh~*myj!5JnHzDkv&}e`-1OcxjAXDO$YNXGu%!(}weV8v8{Hb9z$++MQBS{AMyne4< zPg!tsf`dqaWG`DLdy9O1et%1cW{D@23XFLUVl$E}mY<-ZqN56DR9c&K9d@8jryiYU zvOce{9C&d{6`PNLh*qjAvjj$XH@joJy)|yLZ(7L9e^IH1F zLyI0wx-^8frUUk5m6{($lP6iX&TwkxP?)kaCyX2}-JSFs9tCLZ!0u1?hk zx4T9zA5O7W3S386j!j09Ix3mZRpw$`N+@{m&Z!V1q&>o0?%loOjx9b{`_quYOaEm? zeBmB*TIHu7fAQF47gS^=HD6Vck>^l?Vfa!Pbqz-Mo=eSm=fP9kC6i!R8dex!Qr>`w z9*6ENg&|ewfq>OPD^Oa}{c(S6uiji|^0mQ_G<_92nSAtu+6 z!Xz0%BoKbnq+e+5r`BDI%qXK(Sk8qNLTowarFngYDGoeAaEaH2Q@|I9nu$$_A_SFr zxno678s`-Tl`Rn=T!+QMrhK8~IpiZ692QAY4l0u8RvAT_sG=?*I$EIbHE3x=j+G)2 YPqX2ntm^8kuqFTiJFzuv761SM literal 0 Hc-jL100001 diff --git a/doc/images/reject-jobs.gif b/doc/images/reject-jobs.gif new file mode 100644 index 0000000000000000000000000000000000000000..6d938e308475bdc9862421d2d21653ff105b4b3a GIT binary patch literal 252 zc-jH{00aL=Nk%v~VN?JV0KxzO%*>glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui08{`J z000BY2)ZFdCCW*wy*OhsL|7m*Xk=-g*6@XZfxd8D8KEoRxJfHP?*Et7$Z{waGY3=> zvn0X>fZnB9pyI3)tVBy{Fegppc6%f*#Z&XR9AR4=-*HubrrYD;c74uIL8eA|ZG(M# zU`T{~f?N{>e@=;kdy?5_ CZED;A literal 0 Hc-jL100001 diff --git a/doc/images/release-job.gif b/doc/images/release-job.gif new file mode 100644 index 0000000000000000000000000000000000000000..a05cd9cc7178499b395e08d26165b3e4a55adabe GIT binary patch literal 255 zc-jH~0093-Nk%v~VORhZ0KxzO%*>g9xnM%6F&Li`1DOH0N=$Kp;oL*3U;!!G@4w=Q7lH5t>$WadM2+c4lubub=v3ks-8Y)^Y><55f4pA zd4PL=VTy@@h>wgE1Q33ThIe#^XLX!oa)*Z&9deL(SAC_YkeHDZ9;APujkB?|i?x8P za8gCLo|bE4c4%*H#(c#SAVgWsIZ#o~(labB)7LvT*xML9A_2_Y+bb<04TR!Z9UmglrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui08s!G z000BV2)ZFdCCW*wy*O7gL|7m*Xk=-g)9{6Wfxd7o8KEoRxJD~M?*Ek4$Z{waQHN3z zvm}xRfZnB9plYns3|6wOG?$}%f0%g-h|3pUWz71AI9#MaO%EZGi_+&&y0EC~QRoy%)n literal 0 Hc-jL100001 diff --git a/doc/images/right.gif b/doc/images/right.gif new file mode 100644 index 0000000000000000000000000000000000000000..8ae8213ceaa55668ad026fb2b09254c96ab59dfa GIT binary patch literal 145 zc-nLKbhEHb6kw2Gc+9|X=FH3^M<#CG+^}p}@w|E2GiRo)UR|+$dkc_(6)FB?VdP@q zV9;Rz0+1ODEOr|_Jli-FvJG~d+<4a8Zc)`#HtD8S(z^75Lh&ne8~hLZ{XFpC{PoW- eYqsCz@mxK1*18bwZ*%53NM|f8I+>=#U=0BM(LkI4 literal 0 Hc-jL100001 diff --git a/doc/images/show-active.gif b/doc/images/show-active.gif new file mode 100644 index 0000000000000000000000000000000000000000..d232ef9f84342b411b132828eb6cdff279469b68 GIT binary patch literal 303 zc-jFk0nq+ONk%v~VR!%(0KxzO%*>glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui0C)ft z000C02)ZFdCCW*wy*TU5F&RRzjLguTXsWK*Ad-N=&U9@@1}Wcs?^`)V;72U-UZ%@o zd5|=H&&)GAqf)G#0br<{OrZtrwI`00H4Tiox%9Tf&Ul4=eKXNk%v~VUGY50KxzO%*>glrgMjfRC01ZXJ<5KW;2nIUjP69EC2ui0FM9^ z000C22)ZFdCCW*wy*TU5yO+cu1WU;bU#hNb%MPRo7;bIfxM!Gj?*Bm7P7w$ik4Q`m zbvZZ>5@_xzwN)!uOqQ~Zss?~!b0Y1suI5xaP0p-W4Xp+0B-aboJXd?i`~QA@d3R3{ zg;8{Fh8$+~jPmYWzM&9A(uiCbp0$Hv5fxY)PUlBojI)xx{knA*z2 z?#AHaqwf_Xk*w*B&sc|}?19hv5z?249~xE!Gmv1CBnX>^Ho$~|=#Zk37&9#Tc&Hyy j#gGL(I*J@=;bVya3`wfA2t&q62ftRz^bul&j06BXGu)o0 literal 0 Hc-jL100001 diff --git a/doc/images/start-class.gif b/doc/images/start-class.gif new file mode 100644 index 0000000000000000000000000000000000000000..2b6f43fad34cf9d50e46ca384a87ba7df433d834 GIT binary patch literal 238 zc-jH(01^L3Nk%v~VNL)P0KxzO%*>g9reH#cF&J_Z17`vNW&l@_LI3~%EC2ui08RiD z000BK2)ZFdCCW*wy*NuUL|7m*Xk=-g#qfoIfxd8Tgl=r#+N=b4?^CPMUZuY#1D0c8r05cbQa$7af*)oPV04j;4DR9&bfQRbfVwcddc2bgmg6 oLR`EtP*J_XFDos=#yK>{$`m>w0lUk=Dl8xkebG1^9xMp}JCE94=l}o! literal 0 Hc-jL100001 diff --git a/doc/images/start-printer.gif b/doc/images/start-printer.gif new file mode 100644 index 0000000000000000000000000000000000000000..017bb394aa59c23ee9b7b7058a49ad34c62840f9 GIT binary patch literal 255 zc-jH~0093-Nk%v~VN?JV0KxzO%*>g9xnM%6F&Li`1DOH6HT2X1t~bMr+JEvxO!Xn{FqM=W_b&#yGyxH`0t=@8^ASfq!%< z5E^u3eQjK7i+Y2Mj9?N3hf0rfONvp1o^zTS9Aj*dlYeY}r;(f(9i*R|kDauutFn?8 z9(ajwPH;$hPoI;%xELQpK+8W=Rm{*iD=pF0FFOl1*4r4^AOXtU;wmiP4wvFU93CtQ F06SU!YOeqQ literal 0 Hc-jL100001 diff --git a/doc/images/stop-class.gif b/doc/images/stop-class.gif new file mode 100644 index 0000000000000000000000000000000000000000..5cb7adfd808058a01d565fc69abd5c96e0114cc3 GIT binary patch literal 245 zc-jH=01E#{Nk%v~VNL)P0KxzO%*>h0fMCo*G0Yee%mV_<007KaLI3~%EC2ui08RiD z000BR2)ZFdCCW*wy*NuUL|7m*Xk=-g#qfoIfxd8Tgl=r#+N=b4?^CPM*Ndr@55+lW<*U|+azvpRL;>e)IOgOr`#+u`JyX8T8>;DyXfp>5j z1P~>5OMn!DU}2AHhC*ahcZ-B{Qh1z%o)jHimU(h|qnDYeq!%7;kYiq$Z-K9iUsP9X v5g(L2x>+PoP+7mg87nP6#l{vo3pLEq7|tL8z0%SuEY%K(*ghN{EC~QRBm`$i literal 0 Hc-jL100001 diff --git a/doc/images/stop-printer.gif b/doc/images/stop-printer.gif new file mode 100644 index 0000000000000000000000000000000000000000..b3accf3dfb2a3157d04b30385e2b0e11e6b0cb20 GIT binary patch literal 252 zc-jH{00aL=Nk%v~VN?JV0KxzO%*>h0fMCo*G0Yee%mV_<007KaLI3~%EC2ui08{`J z000BY2)ZFdCCW*wy*OhsL|7m*Xk=-g*6@XZfxd8D8KEoRxJfHP?*Et7=yE6?B*&Ps zXh}9@13-^BNjhKGD@luLV7SIeSX^LMvgD(+Y&DO|@QWj3Mw0LDb5*=%?4* CJ!;zk literal 0 Hc-jL100001 diff --git a/doc/index.html b/doc/index.html new file mode 100644 index 0000000000..1150e4cdf0 --- /dev/null +++ b/doc/index.html @@ -0,0 +1,36 @@ + + + Common UNIX Printing System + + + Easy Software Products Home Page + Do Administration Tasks + Manage Printer Classes Status + On-Line Help + Manage Jobs + Manage Printers + Download the Current CUPS Software + + + + +
+Common UNIX Printing System +
+ +

Do Administration Tasks

+

Manage Printer Classes

+

On-Line Help

+

Manage Jobs

+

Manage Printers

+

Download the Current CUPS Software

+ +
+ +

The Common UNIX Printing System, CUPS, and the CUPS logo are the +trademark property of Easy Software +Products. CUPS is copyright 1997-2000 by Easy Software Products, +All Rights Reserved. + + + diff --git a/doc/ipp.html b/doc/ipp.html new file mode 100644 index 0000000000..efc0f8495c --- /dev/null +++ b/doc/ipp.html @@ -0,0 +1,1409 @@ + + + + CUPS Implementation of IPP + + + + + + + +


+

CUPS Implementation of IPP


+CUPS-IPP-1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
1 Scope + +2 References + +3 Overview + +4 Operations + +5 Attributes + +A Glossary + +
+

1 Scope

+

1.1 Identification

+

This document provides an overview of the Internet Printing +Protocol ("IPP") version 1.1 as implemented in the Common UNIX Printing +System ("CUPS") version 1.1.

+

1.2 System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+

1.3 Document Overview

+

This document is organized into the following sections:

+ +

2 References

+

2.1 CUPS Documentation

+

The following CUPS documentation is referenced by this document:

+
    +
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • +
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • +
  • CUPS-IPP-1.1: CUPS Implmentation of IPP
  • +
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • +
  • CUPS-SDD-1.1: CUPS Software Design Description
  • +
  • CUPS-SPM-1.1: CUPS Software Programming Manual
  • +
  • CUPS-SSR-1.1: CUPS Software Security Report
  • +
  • CUPS-STP-1.1: CUPS Software Test Plan
  • +
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • +
  • CUPS-SVD-1.1.x: CUPS Software Version Description
  • +
+

2.2 Other Documents

+

The following non-CUPS documents are referenced by this document:

+
    +
  • Adobe PostScript Printer Description File Format Specification, + Version 4.3.
  • +
  • Adobe PostScript Language Reference, Third Edition.
  • +
  • IPP: Job and Printer Set Operations
  • +
  • IPP/1.1: Encoding and Transport
  • +
  • IPP/1.1: Implementers Guide
  • +
  • IPP/1.1: Model and Semantics
  • +
  • RFC 1179, Line Printer Daemon Protocol
  • +
  • RFC 2567, Design Goals for an Internet Printing Protocol
  • +
  • RFC 2568, Rationale for the Structure of the Model and Protocol + for the Internet Printing Protocol
  • +
  • RFC 2569, Mapping between LPD and IPP Protocols
  • +
  • RFC 2616, Hypertext Transfer Protocol -- HTTP/1.1
  • +
  • RFC 2617, HTTP Authentication: Basic and Digest Access + Authentication
  • +
+

3 Overview

+

CUPS 1.1 implements IPP/1.1 and the operations and attributes +defined in the "IPP: Job and Printer Set Operations", "IPP/1.1: +Output-bin Attribute Extension", and "IPP/1.1: finishings 'fold',' +trim', and 'bale' attribute values extension" specifications.

+

CUPS also provides 13 new operations and many new attributes to +support multiple IPP printers and printer classes on a single host.

+

3.1 IPP URIs

+

CUPS supports both the "http" and "ipp" methods. The following +resource names are used:

+
+
method://hostname:port/
+
Can be used for all "get" operations.
+
method://hostname:port/admin
+
Used for all administrative operations.
+
method://hostname:port/classes/name
+
Specifies a printer class.
+
method://hostname:port/jobs/id
+
Specifies a job.
+
method://hostname:port/printers/name
+
Specifies a printer.
+
+

So a typical printer URI would be +"ipp://foo.bar.com/printers/LaserJet".

+

In addition, the CUPS server also supports normal browser access to +"method://hostname:port/admin/", "method://hostname:port/classes/", +"method://hostname:port/jobs/", and "method://hostname:port/printers/" +to view and manage resources on the server dynamically.

+

3.2 CUPS IPP Operations

+

CUPS provides 13 extension operations in addition to most of the +standard IPP and registered extension operations: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Operation Name CUPS + Code Brief Description
Print-Job 1.0 + 0x0002 Print a file.
Validate-Job 1.0 + 0x0004 Validate job attributes.
Create-Job 1.1 + 0x0005 Create a print job.
Send-Document 1.1 + 0x0006 Send a file for a print job.
Cancel-Job 1.0 + 0x0008 Cancel a print job.
Get-Job-Attributes 1.0 0x0009 Get job attributes.
Get-Jobs 1.0 + 0x000A Get all jobs.
Get-Printer-Attributes 1.0 0x000B Get printer attributes.
Hold-Job 1.1 + 0x000C Hold a job for printing.
Release-Job 1.1 + 0x000D Release a job for printing.
Pause-Printer 1.0 + 0x0010 Pause printing on a printer.
Resume-Printer 1.0 + 0x0011 Resume printing on a printer.
Purge-Jobs 1.0 + 0x0012 Purge all jobs.
Set-Job-Attributes 1.1 0x0014 Set attributes for a pending +or held job.
CUPS-Get-Default 1.0 + 0x4001 Get the default destination.
CUPS-Get-Printers 1.0 0x4002 Get all of the available +printers.
CUPS-Add-Printer 1.0 + 0x4003 Add or modify a printer.
CUPS-Delete-Printer 1.0 0x4004 Delete a printer.
CUPS-Get-Classes 1.0 + 0x4005 Get all of the available printer classes.
CUPS-Add-Class 1.0 + 0x4006 Add or modify a printer class.
CUPS-Delete-Class 1.0 0x4007 Delete a printer class.
CUPS-Accept-Jobs 1.0 + 0x4008 Accept jobs on a printer or printer class.
CUPS-Reject-Jobs 1.0 + 0x4009 Reject jobs on a printer or printer class.
CUPS-Set-Default 1.0 + 0x400A Set the default destination.
CUPS-Get-Devices 1.1 + 0x400B Get all of the available devices.
CUPS-Get-PPDs 1.1 + 0x400C Get all of the available PPDs.
CUPS-Move-Job 1.1 + 0x400D Move a job to a different printer.
+
+

+

4 Operations

+

The following sections describe the operations supported by CUPS. +In the interest of brevity, operations which use only the standard IPP +attributes are not described.

+

4.1 Print-Job Operation

+

The Print-Job operation (0x0002) prints a file.

+

4.1.1 Print-Job Request

+

The following groups of attributes are supplied as part of the +Print-Job request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri):

    +

    The client MUST supply a URI for the specified printer.

    +
+

Group 2: Job Template Attributes

+
    +

    "job-billing" (text(MAX)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies a billing string that is logged + with the page accounting information.

    +

    "job-sheets" (1setof type3 keyword | name(MAX)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies one or two banner pages that are +printed before and after any files in the print job. The name of +"none" is reserved to indicate that no banner page should be printed. +If the client does not specify this attribute then the value of the +"job-sheets-default" printer object attribute is used.

    +

    Note: Standard IPP only allows specification of a single + job-sheets attribute value.

    +

    "media" (1setof type3 keyword | name(MAX)):

    +

    The client OPTIONALLY supplies one or more media attributes + specifying the size, type, source, and color of the output media. If +the client does not specify this attribute then the value of the +"media-default" printer object attribute is used.

    +

    Note: Standard IPP only allows specification of a single + media attribute value.

    +

    Other Job Template Attributes

    +
+

The Print-Job request is followed by a file to be printed.

+

4.1.2 Print-Job Response

+

The following groups of attributes are send as part of the +Print-Job Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

Group 2: Job Attributes

+
    +

    Standard Job Attributes

    +
+

4.2 Create-Job Operation

+

The Create-Job operation (0x0005) creates a new, empty print job.

+

4.2.1 Create-Job Request

+

The following groups of attributes are supplied as part of the +Create-Job request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri):

    +

    The client MUST supply a URI for the specified printer.

    +
+

Group 2: Job Template Attributes

+
    +

    "job-billing" (text(MAX)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies a billing string that is logged + with the page accounting information.

    +

    "job-sheets" (1setof type3 keyword | name(MAX)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies one or two banner pages that are +printed before and after any files in the print job. The name of +"none" is reserved to indicate that no banner page should be printed. +If the client does not specify this attribute then the value of the +"job-sheets-default" printer object attribute is used.

    +

    Note: Standard IPP only allows specification of a single + job-sheets attribute value.

    +

    "media" (1setof type3 keyword | name(MAX)):

    +

    The client OPTIONALLY supplies one or more media attributes + specifying the size, type, source, and color of the output media. If +the client does not specify this attribute then the value of the +"media-default" printer object attribute is used.

    +

    Note: Standard IPP only allows specification of a single + media attribute value.

    +

    Standard Job Template Attributes

    +
+

4.2.2 Create-Job Response

+

The following groups of attributes are send as part of the +Create-Job Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

Group 2: Job Attributes

+
    +

    Standard Job Attributes

    +
+

4.3 Set-Job-Attributes Operation

+

The Set-Job-Attributes operation (0x0014) changes the attributes of +an active (not completed) job.

+

4.3.1 Set-Job-Attributes Request

+

The following groups of attributes are supplied as part of the +Set-Job-Attributes request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri) and "job-id" (integer)

    +

    OR

    +

    "job-uri":

    +

    The client MUST supply a URI for the specified printer and a job +ID number, or the job URI.

    +
+

Group 2: Job Template Attributes

+
    +

    "job-sheets" (1setof type3 keyword | name(MAX)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies one or two banner pages that are +printed before and after any files in the print job. The name of +"none" is reserved to indicate that no banner page should be printed. +If the client does not specify this attribute then the value of the +"job-sheets-default" printer object attribute is used.

    +

    Note: Standard IPP only allows specification of a single + job-sheets attribute value.

    +

    "media" (1setof type3 keyword | name(MAX)):

    +

    The client OPTIONALLY supplies one or more media attributes + specifying the size, type, source, and color of the output media. If +the client does not specify this attribute then the value of the +"media-default" printer object attribute is used.

    +

    Note: Standard IPP only allows specification of a single + media attribute value.

    +

    Other Job Template Attributes

    +
+

4.3.2 Set-Job-Attributes Response

+

The following groups of attributes are send as part of the +Set-Job-Attributes Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

4.4 CUPS-Get-Default Operation

+

The CUPS-Get-Default operation (0x4001) returns the default printer +URI and attributes.

+

4.4.1 CUPS-Get-Default Request

+

The following groups of attributes are supplied as part of the +CUPS-Get-Default request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "requested-attributes" (1setOf keyword) :

    +

    The client OPTIONALLY supplies a set of attribute names and/or +attribute group names in whose values the requester is interested. If +the client omits this attribute, the server responds as if this +attribute had been supplied with a value of 'all'.

    +
+

4.4.2 CUPS-Get-Default Response

+

The following groups of attributes are send as part of the +CUPS-Get-Default Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

Group 2: Printer Object Attributes

+
    +

    The set of requested attributes and their current values.

    +
+

4.5 CUPS-Get-Printers Operation

+

The CUPS-Get-Printers operation (0x4002) returns the printer +attributes for every printer known to the system. This may include +printers that are not served directly by the server.

+

4.5.1 CUPS-Get-Printers Request

+

The following groups of attributes are supplied as part of the +CUPS-Get-Printers request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "limit" (integer (1:MAX)):

    +

    The client OPTIONALLY supplies this attribute limiting the number +of printers that are returned.

    +

    "printer-info" (text(127)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies this attribute to select which +printers are returned.

    +

    "printer-location" (text(127)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies this attribute to select which +printers are returned.

    +

    "printer-type" (type2 enum):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies a printer type enumeration to + select which printers are returned.

    +

    "printer-type-mask" (type2 enum):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies a printer type mask enumeration to +select which bits are used in the "printer-type" attribute.

    +

    "requested-attributes" (1setOf keyword) :

    +

    The client OPTIONALLY supplies a set of attribute names and/or +attribute group names in whose values the requester is interested. If +the client omits this attribute, the server responds as if this +attribute had been supplied with a value of 'all'.

    +
+

4.5.2 CUPS-Get-Printers Response

+

The following groups of attributes are send as part of the +CUPS-Get-Printers Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

Group 2: Printer Object Attributes

+
    +

    The set of requested attributes and their current values for each +printer.

    +
+

4.6 CUPS-Add-Printer Operation

+

The CUPS-Add-Printer operation (0x4003) adds a new printer or +modifies an existing printer on the system.

+

4.6.1 CUPS-Add-Printer Request

+

The following groups of attributes are supplied as part of the +CUPS-Add-Printer request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri):

    +

    The client MUST supply a URI for the specified printer.

    +
+

Group 2: Printer Object Attributes

+
    +

    "banner-end-default" (name(127)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies a banner page name that is printed +after files in a job. The reserved name "none" is used to specify that +no banner page should be printed.

    +

    "banner-start-default" (name(127)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies a banner page name that is printed +before files in a job. The reserved name "none" is used to specify +that no banner page should be printed.

    +

    "device-uri" (uri):

    +

    The client OPTIONALLY supplies a device URI for the specified +printer.

    +

    "ppd-name" (name(127)):

    +

    The client OPTIONALLY supplies a PPD name for the specified + printer.

    +

    "printer-is-accepting-jobs" (boolean):

    +

    The client OPTIONALLY supplies this boolean attribute indicating +whether or not the printer object should accept new jobs.

    +

    "printer-info" (text(127)):

    +

    The client OPTIONALLY supplies this attribute indicating the + printer information string.

    +

    "printer-location" (text(127)):

    +

    The client OPTIONALLY supplies this attribute indicating a textual +location of the printer.

    +

    "printer-more-info" (uri):

    +

    The client OPTIONALLY supplies this attribute indicating a URI for +additional printer information.

    +

    "printer-state" (type2 enum):

    +

    The client OPTIONALLY supplies this attribute indicating the + initial/current state of the printer. Only the "idle" and "stopped" + enumerations are recognized.

    +

    "printer-state-message" (text(MAX)):

    +

    The client OPTIONALLY supplies this attribute indicating a textual +reason for the current printer state.

    +

    "requesting-user-name-allowed" (1setof name(127))

    +

    OR

    +

    "requesting-user-name-denied" (1setof name(127)):

    +

    The client OPTIONALLY supplies one of these attributes to specify +an access control list for incoming print jobs. The special name +"ALLUSERS" is reserved to indicate that all users are allowed or +denied.

    +
+

The CUPS-Add-Printer request can optionally be followed by a PPD +file or System V interface script to be used for the printer. The +"ppd-name" attribute overrides any file that is attached to the end of +the request with a local CUPS PPD file.

+

4.6.2 CUPS-Add-Printer Response

+

The following groups of attributes are send as part of the +CUPS-Add-Printer Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

4.7 CUPS-Delete-Printer Operation

+

The CUPS-Delete-Printer operation (0x4004) removes an existing +printer from the system.

+

4.7.1 CUPS-Delete-Printer Request

+

The following groups of attributes are supplied as part of the +CUPS-Delete-Printer request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri):

    +

    The client MUST supply a URI for the specified printer.

    +
+

4.7.2 CUPS-Delete-Printer Response

+

The following groups of attributes are send as part of the +CUPS-Delete-Printer Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

4.8 CUPS-Get-Classes Operation

+

The CUPS-Get-Classes operation (0x4005) returns the printer +attributes for every printer class known to the system. This may +include printer classes that are not served directly by the server.

+

4.8.1 CUPS-Get-Classes Request

+

The following groups of attributes are supplied as part of the +CUPS-Get-Classes request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "limit" (integer (1:MAX)):

    +

    The client OPTIONALLY supplies this attribute limiting the number +of printer classes that are returned.

    +

    "printer-info" (text(127)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies this attribute to select which +printer classes are returned.

    +

    "printer-location" (text(127)):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies this attribute to select which +printer classes are returned.

    +

    "printer-type" (type2 enum):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies a printer type enumeration to + select which printer classes are returned.

    +

    "printer-type-mask" (type2 enum):

    +

    (CUPS 1.1 and higher)

    +

    The client OPTIONALLY supplies a printer type mask enumeration to +select which bits are used in the "printer-type" attribute.

    +

    "requested-attributes" (1setOf keyword) :

    +

    The client OPTIONALLY supplies a set of attribute names and/or +attribute group names in whose values the requester is interested. If +the client omits this attribute, the server responds as if this +attribute had been supplied with a value of 'all'.

    +
+

4.8.2 CUPS-Get-Classes Response

+

The following groups of attributes are send as part of the +CUPS-Get-Classes Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

Group 2: Printer Class Object Attributes

+
    +

    The set of requested attributes and their current values for each +printer class.

    +
+

4.9 CUPS-Add-Class Operation

+

The CUPS-Add-Class operation (0x4006) adds a new printer class or +modifies and existing printer class on the system.

+

4.9.1 CUPS-Add-Class Request

+

The following groups of attributes are supplied as part of the +CUPS-Add-Class request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri):

    +

    The client MUST supply a URI for the specified printer class.

    +
+

Group 2: Printer Object Attributes

+
    +

    "member-uris" (1setof uri):

    +

    The client OPTIONALLY supplies the "member-uris" set specifying +the printers and printer classes that are part of the class.

    +

    "printer-is-accepting-jobs" (boolean):

    +

    The client OPTIONALLY supplies this boolean attribute indicating +whether or not the printer object should accept new jobs.

    +

    "printer-info" (text(127)):

    +

    The client OPTIONALLY supplies this attribute indicating the + printer information string.

    +

    "printer-location" (text(127)):

    +

    The client OPTIONALLY supplies this attribute indicating a textual +location of the printer.

    +

    "printer-more-info" (uri):

    +

    The client OPTIONALLY supplies this attribute indicating a URI for +additional printer information.

    +

    "printer-state" (type2 enum):

    +

    The client OPTIONALLY supplies this attribute indicating the + initial/current state of the printer. Only the "idle" and "stopped" + enumerations are recognized.

    +

    "printer-state-message" (text(MAX)):

    +

    The client OPTIONALLY supplies this attribute indicating a textual +reason for the current printer state.

    +

    "requesting-user-name-allowed" (1setof name(127))

    +

    OR

    +

    "requesting-user-name-denied" (1setof name(127)):

    +

    The client OPTIONALLY supplies one of these attributes to specify +an access control list for incoming print jobs. The special name +"ALLUSERS" is reserved to indicate that all users are allowed or +denied.

    +
+

4.9.2 CUPS-Add-Class Response

+

The following groups of attributes are send as part of the +CUPS-Add-Class Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

4.10 CUPS-Delete-Class Operation

+

The CUPS-Delete-Class operation (0x4007) removes an existing +printer class from the system.

+

4.10.1 CUPS-Delete-Class Request

+

The following groups of attributes are supplied as part of the +CUPS-Delete-Class request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri):

    +

    The client MUST supply a URI for the specified printer class.

    +
+

4.10.2 CUPS-Delete-Class Response

+

The following groups of attributes are send as part of the +CUPS-Delete-Class Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

4.11 CUPS-Accept-Jobs Operation

+

The CUPS-Accept-Jobs operation (0x4008) sets the +"printer-is-accepting-jobs" attribute to true for the specified printer +or printer class.

+

4.11.1 CUPS-Accept-Jobs Request

+

The following groups of attributes are supplied as part of the +CUPS-Accept-Jobs request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri):

    +

    The client MUST supply a URI for the specified printer or printer +class.

    +
+

4.11.2 CUPS-Accept-Jobs Response

+

The following groups of attributes are send as part of the +CUPS-Accept-Jobs Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

4.12 CUPS-Reject-Jobs Operation

+

The CUPS-Reject-Jobs operation (0x4009) sets +the"printer-is-accepting-jobs" attribute to false for the specified +printer or printer class.

+

4.12.1 CUPS-Reject-Jobs Request

+

The following groups of attributes are supplied as part of the +CUPS-Reject-Jobs request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri):

    +

    The client MUST supply a URI for the specified printer or printer +class.

    +
+

Group 2: Printer Object Attributes

+
    +

    "printer-state-message" (text(MAX)):

    +

    The client OPTIONALLY supplies this attribute indicating a textual +reason for the current printer state.

    +
+

4.12.2 CUPS-Reject-Jobs Response

+

The following groups of attributes are send as part of the +CUPS-Reject-Jobs Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

4.13 CUPS-Set-Default Operation

+

The CUPS-Set-Default operation (0x400A) sets the default printer +destination for all clients when a resource name of "/printers" is +specified.

+

4.13.1 CUPS-Set-Default Request

+

The following groups of attributes are supplied as part of the +CUPS-Set-Default request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri):

    +

    The client MUST supply a URI for the specified printer or printer +class.

    +
+

4.13.2 CUPS-Set-Default Response

+

The following groups of attributes are send as part of the +CUPS-Set-Default Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

4.14 CUPS-Get-Devices Operation

+

The CUPS-Get-Devices operation (0x400B) returns all of the +supported device-uri's for the server (CUPS 1.1 and higher).

+

4.14.1 CUPS-Get-Devices Request

+

The following groups of attributes are supplied as part of the +CUPS-Get-Devices request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "device-class" (type1 keyword):

    +

    The client OPTIONALLY supplies a device class keyword to select + which devices are returned.

    +

    "limit" (integer (1:MAX)):

    +

    The client OPTIONALLY supplies this attribute limiting the number +of devices that are returned.

    +

    "requested-attributes" (1setOf keyword) :

    +

    The client OPTIONALLY supplies a set of attribute names and/or + attribute group names in whose values the requester is interested. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'.

    +
+

4.14.2 CUPS-Get-Devices Response

+

The following groups of attributes are send as part of the +CUPS-Get-Devices Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

Group 2: Device Object Attributes

+
    +

    The set of requested attributes and their current values for each +device.

    +
+

4.15 CUPS-Get-PPDs Operation

+

The CUPS-Get-PPDs operation (0x400C) returns all of the locally +available PPD files on the system (CUPS 1.1 and higher).

+

4.15.1 CUPS-Get-PPDs Request

+

The following groups of attributes are supplied as part of the +CUPS-Get-PPDs request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "limit" (integer (1:MAX)):

    +

    The client OPTIONALLY supplies this attribute limiting the number +of PPDs that are returned.

    +

    "ppd-make" (text(127)):

    +

    The client OPTIONALLY supplies a printer manufacturer to select + which PPDs are returned.

    +

    "requested-attributes" (1setOf keyword) :

    +

    The client OPTIONALLY supplies a set of attribute names and/or + attribute group names in whose values the requester is interested. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'.

    +
+

4.15.2 CUPS-Get-PPDs Response

+

The following groups of attributes are send as part of the +CUPS-Get-PPDs Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

Group 2: PPD Attributes

+
    +

    The set of requested attributes and their current values for each + PPD file.

    +
+

4.16 CUPS-Move-Job Operation

+

The CUPS-Move-Job operation (0x400D) moves an active print job to a +different printer (CUPS 1.1 and higher).

+

4.16.1 CUPS-Move-Job Request

+

The following groups of attributes are supplied as part of the +CUPS-Move-Job request:

+

Group 1: Operation Attributes

+
    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document.

    +

    "printer-uri" (uri) and "job-id" (integer)

    +

    OR

    +

    "job-uri":

    +

    The client MUST supply a URI for the specified printer and a job +ID number, or the job URI.

    +
+

Group 2: Job Template Attributes

+
    +

    "job-printer-uri" (uri)

    +

    The client MUST supply a URI for a printer on the same server.

    +
+

4.16.2 CUPS-Move-Job Response

+

The following groups of attributes are send as part of the +CUPS-Move-Job Response:

+

Group 1: Operation Attributes

+
    +

    Status Message:

    +

    The standard response status message.

    +

    Natural Language and Character Set:

    +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document.

    +
+

5 Attributes

+

CUPS provides many extension attributes to support multiple +devices, PPD files, standard job filters, printers, and printer +classes.

+

5.1 Device Attributes

+

Device attributes are returned by the CUPS-Get-Devices operation +and enumerate all of the available hardware devices and network +protocols that are supported by the server.

+

5.1.1 device-class (type2 keyword)

+

The device-class attribute specifies the class of device and can be +one of the following:

+
    +
  • "file" - a disk file.
  • +
  • "direct" - a parallel or fixed-rate serial data port, currently +used for Centronics, IEEE-1284, and USB printer ports.
  • +
  • "serial" - a variable-rate serial port.
  • +
  • "network" - a network connection, typically via AppSocket, HTTP, +IPP, LPD, or SMB/CIFS protocols.
  • +
+

5.1.2 device-info (text(127))

+

The device-info attribute specifies a human-readable string +describing the device, e.g. "Parallel Port #1".

+

5.1.3 device-make-and-model (text(127))

+

The device-makr-and-model attribute specifies a device +identification string provided by the printer connected to the device. +If the device or printer does not support identification then this +attribute contains the string "unknown".

+

5.1.4 device-uri (uri)

+

The device-uri attribute specifies a unique identifier for the +device. The actual format of the device-uri string depends on the value +of the device-class attribute:

+
    +
  • "file" - The device-uri will be of the form + "file:/path/to/filename".
  • +
  • "direct" - The device-uri will be of the form + "method:/dev/filename", where method may be "parallel" or "usb" in +the current implementation.
  • +
  • "serial" - The device-uri will be of the form + "serial:/dev/filename?baud=value+parity=value+flow=value". The parity +value can be one of "none", "even", or "odd". The flow value can be +one of "none", "soft" (XON/XOFF handshaking), or "hard" (CTS/RTS +handshaking).
  • +

    The URI returned by CUPS-Get-Devices will contain the maximum baud +rate supported by the device and the best type of flow control +available ("soft" or "hard").

    +
  • "network" - The device-uri will be of the form + "method://[username:password@]hostname[:port]/[resource]", where +method may be "http", "ipp", "lpd", "smb", or "socket" in the current +implementation.
  • +

    The URI returned by CUPS-Get-Devices will only contain the method +name followed by two slashes ("method://"). It is up to the client +application to add the appropriate host and other information when +adding a new printer.

    +

    The URI returned by Get-Printer-Attributes and CUPS-Get-Printers +has any username and password information stripped; the information is +still stored and used by the server internally to perform any needed +authentication.

    +
+

5.2 Job Template Attributes

+

5.2.1 blackplot (boolean)

+

The blackplot attribute specifies whether HP-GL/2 plot files should +be rendered entirely in black ink (blackplot=true) or using the colors +and shades specified in the file (blackplot=false). The default value +is false.

+

5.2.2 brightness (integer(0:200))

+

The brightness attribute specifies the overall brightness of the +printed output in percent. A brightness of 100 is normal, while 200 is +twice as bright and 50 is half as bright. The default value is 100.

+

Brightness is applied to the Cyan, Magenta, Yellow, and Black +values using the function "f(x) = brightness / 100 * x".

+

5.2.3 columns (integer(1:4))

+

The columns attribute specifies the number of columns to generate +when printing text files. The default value is 1.

+

5.2.4 cpi (type2 enum)

+

The cpi attribute specifies the number of characters per inch when +printing text files. Only the values 10, 12, and 17 are currently +supported. The default value is 10.

+

5.2.5 fitplot (boolean)

+

The fitplot attribute specifies whether to scale HP-GL/2 plot files +to fit on the selected media (fitplot=true) or use the physical scale +specified in the plot file (fitplot=false). The default value is false.

+

5.2.6 gamma (integer(1:10000))

+

The gamma attribute specifies the luminance correction for the +output. A value of 1000 specifies no correction, while values of 2000 +and 500 will generate lighter and darker output, respectively. The +default value is 1000.

+

Gamma is applied to the Red, Green, and Blue values (or luminance +for grayscale output) using the function "f(x) = x(1000/gamma) +".

+

5.2.7 hue (integer(-180:180))

+

The hue attribute specifies a color hue rotation when printing +image files. The default value is 0.

+

5.2.8 job-billing (text(MAX))

+

(CUPS 1.1 and higher)

+

The job-billing attribute provides a text value to associate with a +job for billing purposes.

+

5.2.9 job-hold-until (keyword | name(MAX))

+

(CUPS 1.1 and higher)

+

The job-hold-until attribute specifies a hold time. In addition to +the standard IPP/1.1 keyword names, CUPS supports name values of the +form "HH:MM" and "HH:MM:SS" that specify a hold time. The hold time is +in Greenwich Mean Time (GMT) and not in the local time zone. If +the specified time is less than the current time, the job is held until +the next day.

+

5.2.10 job-sheets (1setof type3 keyword | +name(MAX))

+

(CUPS 1.1 and higher)

+

The job-sheets attribute specifies one or two banner files that are +printed before and after a job. The reserved value of "none" disables +banner printing. The default value is stored in the job-sheets-default +attribute.

+

If only one value is supplied, the banner file is printed before +the job. If two values are supplied, the first value is used as the +starting banner file and the second as the ending banner file.

+

5.2.11 lpi (type2 enum)

+

The lpi attribute specifies the number of lines per inch when +printing text files. Only the values 6 and 8 are currently supported. +The default value is 6.

+

5.2.12 page-bottom (integer(0:MAX))

+

The page-bottom attribute specifies the bottom margin in points (72 +points equals 1 inch). The default value is the device physical margin.

+

5.2.13 page-left (integer(0:MAX))

+

The page-left attribute specifies the left margin in points (72 +points equals 1 inch). The default value is the device physical margin.

+

5.2.14 page-right (integer(0:MAX))

+

The page-right attribute specifies the right margin in points (72 +points equals 1 inch). The default value is the device physical margin.

+

5.2.15 page-set (type2 keyword)

+

The page-set attribute specifies which pages to print in a file. +The supported keywords are "all", "even", and "odd". The default value +is "all".

+

5.2.16 page-top (integer(0:MAX))

+

The page-top attribute specifies the top margin in points (72 +points equals 1 inch). The default value is the device physical margin.

+

5.2.17 penwidth (integer(0:MAX))

+

The penwidth attribute specifies the default pen width in +micrometers when printing HP-GL/2 plot files. The default value is 1000 +(1 millimeter).

+

5.2.18 position (type2 keyword)

+

The position attribute specifies the location of image files on the +media. The following keyword values are recognized:

+
    +
  • center - Center the image on the page (default)
  • +
  • top - Print the image centered at the top of the page
  • +
  • left - Print the image centered on the left of page
  • +
  • right - Print the image centered on the right of the +page
  • +
  • top-left - Print the image at the top left corner of + the page
  • +
  • top-right - Print the image at the top right corner +of the page
  • +
  • bottom - Print the image centered at the bottom of + the page
  • +
  • bottom-left - Print the image at the bottom left + corner of the page
  • +
  • bottom-right - Print the image at the bottom right + corner of the page
  • +
+

5.2.19 ppi (integer(1:MAX))

+

The ppi attribute specifies the resolution of an image file in +pixels per inch. The default value is the resolution included with the +file or 128 if no resolution information is available.

+

5.2.20 prettyprint (boolean)

+

The prettyprint attribute specifies whether text files should be +printed with a shaded header and keyword highlighting +(prettyprint=true) or without additional formatting +(prettyprint=false). The default value is false.

+

5.2.21 saturation (integer(0:200))

+

The saturation attribute specifies the color saturation when +printing image files. A saturation of 100 is normal, while values of 50 +and 200 will be half and twice as colorful, respectively. The default +value is 100.

+

5.2.22 scaling (integer(1:1000))

+

The scaling attribute specifies the scaling of image files with +respect to the selected media. A value of 100 specifies that the image +file should fit 100% of the page, or as much as possible given the +image dimensions. The default value is unspecified.

+

The scaling attribute overrides the ppi attribute if specified.

+

5.2.23 wrap (boolean)

+

The wrap attribute specifies whether long lines should be wrapped +(wrap=true) or not (wrap=false) when printing text files. The default +value is true.

+

5.3 PPD Attributes

+

5.3.1 ppd-natural-language (naturalLanguage)

+

The ppd-natural-language attribute specifies the language encoding +of the PPD file (the LanguageVersion attribute in the PPD file). If the +language is unknown or undefined then "en" (English) is assumed.

+

5.3.2 ppd-make (text(127))

+

The ppd-make attribute specifies the manufacturer of the printer +(the Manufacturer attribute in the PPD file). If the manufacturer is +not specified in the PPD file then an educated guess is made using the +NickName attribute in the PPD file.

+

5.3.3 ppd-make-and-model (text(127))

+

The ppd-make-and-model attribute specifies the manufacturer and +model name of the PPD file (the NickName attribute in the PPD file). If +the make and model is not specified in the PPD file then the ModelName +or ShortNickName attributes are used instead.

+

5.3.4 ppd-name (name(255))

+

The ppd-name attribute specifies the PPD filename on the server +relative to the model directory. The forward slash (/) is used to +delineate directories.

+

5.4 Printer Attributes

+

5.4.1 job-sheets-default (1setof type3 keyword | +name(MAX))

+

(CUPS 1.1 and higher)

+

The job-sheets-default attribute specifies the default banner +file(s) to print before and after each job. The value "none" specifies +that no banner should be printed.

+

5.4.2 job-sheets-supported (1setof type3 keyword | +name(MAX))

+

(CUPS 1.1 and higher)

+

The job-sheets-supported attribute specifies the available banner +files. There will always be at least one banner file available called +"none".

+

5.4.3 printer-type (type2 enum)

+

The printer-type attribute specifies printer type and capability +bits for the printer or class. The default value is computed from +internal state information and the PPD file for the printer. The +following bits are defined: +

+ + + + + + + + + + + + + + + + + + + + + + + +
Bit Description
0x00000001 Is a printer +class.
0x00000002 Is a remote +destination.
0x00000004 Can print in +black.
0x00000008 Can print in +color.
0x00000010 Can print on +both sides of the page in hardware.
0x00000020 Can staple +output.
0x00000040 Can do fast +copies in hardware.
0x00000080 Can do fast copy +collation in hardware.
0x00000100 Can punch output.
0x00000200 Can cover output.
0x00000400 Can bind output.
0x00000800 Can sort output.
0x00001000 Can handle media +up to US-Legal/A4.
0x00002000 Can handle media +from US-Legal/A4 to ISO-C/A2.
0x00004000 Can handle media +larger than ISO-C/A2.
0x00008000 Can handle +user-defined media sizes.
0x00010000 Is an implicit +(server-generated) class.
+
+

+

5.4.4 printer-type-mask (type2 enum)

+

(CUPS 1.1 and higher)

+

The printer-type-mask attribute is used to choose printers or +classes with the CUPS-Get-Printers and CUPS-Get-Classes operations. The +bits are defined identically to the printer-type attribute and default +to all 1's.

+

5.4.5 requesting-user-name-allowed (1setof +name(127))

+

(CUPS 1.1 and higher)

+

The requesting-user-name-allowed attribute lists all of the users +that are allowed to access a printer or class. Either this attribute or +the requesting-user-name-denied attribute will be defined, but not +both.

+

The special name "ALLUSERS" is reserved to indicate that all users +are allowed.

+

5.4.6 requesting-user-name-denied (1setof +name(127))

+

(CUPS 1.1 and higher)

+

The requesting-user-name-denied attribute lists all of the users +that are not allowed to access a printer or class. Either this +attribute or the requesting-user-name-allowed attribute will be +defined, but not both.

+

The special name "ALLUSERS" is reserved to indicate that all users +are denied.

+

5.5 Printer Class Attributes

+

5.5.1 member-names (1setof name(127))

+

The member-names attribute specifies each of the printer-name +attributes of the member printers and classes. Each name corresponds to +the same element of the member-uris attribute.

+

5.5.2 member-uris (1setof uri)

+

The member-uris attribute specifies each of the printer-uri +attributes of the member printers and classes. Each URI corresponds to +the same element of the member-names attribute.

+

A Glossary

+

A.1 Terms

+
+
C
+
A computer language.
+
parallel
+
Sending or receiving data more than 1 bit at a time.
+
pipe
+
A one-way communications channel between two programs.
+
serial
+
Sending or receiving data 1 bit at a time.
+
socket
+
A two-way network communications channel.
+
+

A.2 Acronyms

+
+
ASCII
+
American Standard Code for Information Interchange
+
CUPS
+
Common UNIX Printing System
+
ESC/P
+
EPSON Standard Code for Printers
+
FTP
+
File Transfer Protocol
+
HP-GL
+
Hewlett-Packard Graphics Language
+
HP-PCL
+
Hewlett-Packard Printer Control Language
+
HP-PJL
+
Hewlett-Packard Printer Job Language
+
IETF
+
Internet Engineering Task Force
+
IPP
+
Internet Printing Protocol
+
ISO
+
International Standards Organization
+
LPD
+
Line Printer Daemon
+
MIME
+
Multimedia Internet Mail Exchange
+
PCL
+
Page Control Language
+
PPD
+
PostScript Printer Description
+
SMB
+
Server Message Block
+
TFTP
+
Trivial File Transfer Protocol
+
+ + diff --git a/doc/ipp.pdf b/doc/ipp.pdf new file mode 100644 index 0000000000..270ababa2b --- /dev/null +++ b/doc/ipp.pdf @@ -0,0 +1,1432 @@ +%PDF-1.2 +%âãÏÓ +1 0 obj<>endobj +2 0 obj<>endobj +3 0 obj<>endobj +4 0 obj<>endobj +5 0 obj<>endobj +6 0 obj<>endobj +7 0 obj<>endobj +8 0 obj<>endobj +9 0 obj<>endobj +10 0 obj<>endobj +11 0 obj<>endobj +12 0 obj<>endobj +13 0 obj<>endobj +14 0 obj<>endobj +15 0 obj<>endobj +16 0 obj<>endobj +17 0 obj<>endobj +18 0 obj<>endobj +19 0 obj<>endobj +20 0 obj[11 0 R +13 0 R +14 0 R +15 0 R +16 0 R +17 0 R +18 0 R +19 0 R +]endobj +21 0 obj<>endobj +22 0 obj<>endobj +23 0 obj<>endobj +24 0 obj<>endobj +25 0 obj<>endobj +26 0 obj<>endobj +27 0 obj<>endobj +28 0 obj<>endobj +29 0 obj<>endobj +30 0 obj<>endobj +31 0 obj<>endobj +32 0 obj<>endobj +33 0 obj<>endobj +34 0 obj<>endobj +35 0 obj<>endobj +36 0 obj<>endobj +37 0 obj<>endobj +38 0 obj<>endobj +39 0 obj<>endobj +40 0 obj<>endobj +41 0 obj<>endobj +42 0 obj<>endobj +43 0 obj<>endobj +44 0 obj<>endobj +45 0 obj<>endobj +46 0 obj<>endobj +47 0 obj<>endobj +48 0 obj<>endobj +49 0 obj<>endobj +50 0 obj<>endobj +51 0 obj<>endobj +52 0 obj<>endobj +53 0 obj<>endobj +54 0 obj<>endobj +55 0 obj<>endobj +56 0 obj<>endobj +57 0 obj<>endobj +58 0 obj<>endobj +59 0 obj<>endobj +60 0 obj<>endobj +61 0 obj<>endobj +62 0 obj<>endobj +63 0 obj<>endobj +64 0 obj<>endobj +65 0 obj[21 0 R +22 0 R +23 0 R +24 0 R +25 0 R +26 0 R +27 0 R +28 0 R +29 0 R +30 0 R +31 0 R +32 0 R +33 0 R +34 0 R +35 0 R +36 0 R +37 0 R +38 0 R +39 0 R +40 0 R +41 0 R +42 0 R +43 0 R +44 0 R +45 0 R +46 0 R +47 0 R +48 0 R +49 0 R +50 0 R +51 0 R +52 0 R +53 0 R +54 0 R +55 0 R +56 0 R +57 0 R +58 0 R +59 0 R +60 0 R +61 0 R +62 0 R +63 0 R +64 0 R +]endobj +66 0 obj<>endobj +67 0 obj<>endobj +68 0 obj<>endobj +69 0 obj<>endobj +70 0 obj<>endobj +71 0 obj<>endobj +72 0 obj<>endobj +73 0 obj<>endobj +74 0 obj<>endobj +75 0 obj<>endobj +76 0 obj<>endobj +77 0 obj<>endobj +78 0 obj<>endobj +79 0 obj<>endobj +80 0 obj<>endobj +81 0 obj<>endobj +82 0 obj<>endobj +83 0 obj<>endobj +84 0 obj<>endobj +85 0 obj<>endobj +86 0 obj<>endobj +87 0 obj<>endobj +88 0 obj<>endobj +89 0 obj<>endobj +90 0 obj<>endobj +91 0 obj<>endobj +92 0 obj<>endobj +93 0 obj<>endobj +94 0 obj<>endobj +95 0 obj<>endobj +96 0 obj<>endobj +97 0 obj<>endobj +98 0 obj<>endobj +99 0 obj<>endobj +100 0 obj<>endobj +101 0 obj<>endobj +102 0 obj<>endobj +103 0 obj<>endobj +104 0 obj<>endobj +105 0 obj<>endobj +106 0 obj<>endobj +107 0 obj<>endobj +108 0 obj<>endobj +109 0 obj<>endobj +110 0 obj<>endobj +111 0 obj<>endobj +112 0 obj[66 0 R +67 0 R +68 0 R +69 0 R +70 0 R +71 0 R +72 0 R +73 0 R +74 0 R +75 0 R +76 0 R +77 0 R +78 0 R +79 0 R +80 0 R +81 0 R +82 0 R +83 0 R +84 0 R +85 0 R +86 0 R +87 0 R +88 0 R +89 0 R +90 0 R +91 0 R +92 0 R +93 0 R +94 0 R +95 0 R +96 0 R +97 0 R +98 0 R +99 0 R +100 0 R +101 0 R +102 0 R +103 0 R +104 0 R +105 0 R +106 0 R +107 0 R +108 0 R +109 0 R +110 0 R +111 0 R +]endobj +113 0 obj<>endobj +114 0 obj<>endobj +115 0 obj<>endobj +116 0 obj<>endobj +117 0 obj<>endobj +118 0 obj<>endobj +119 0 obj<>endobj +120 0 obj<>endobj +121 0 obj<>endobj +122 0 obj<>endobj +123 0 obj<>endobj +124 0 obj<>endobj +125 0 obj<>endobj +126 0 obj<>endobj +127 0 obj<>endobj +128 0 obj<>endobj +129 0 obj<>endobj +130 0 obj[113 0 R +114 0 R +115 0 R +116 0 R +117 0 R +118 0 R +119 0 R +120 0 R +121 0 R +122 0 R +123 0 R +124 0 R +125 0 R +126 0 R +127 0 R +128 0 R +129 0 R +]endobj +131 0 obj<>endobj +132 0 obj<>endobj +133 0 obj<>endobj +134 0 obj<>endobj +135 0 obj<>endobj +136 0 obj<>endobj +137 0 obj<>endobj +138 0 obj<>endobj +139 0 obj<>endobj +140 0 obj<>endobj +141 0 obj<>endobj +142 0 obj<>endobj +143 0 obj<>endobj +144 0 obj<>endobj +145 0 obj<>endobj +146 0 obj<>endobj +147 0 obj<>endobj +148 0 obj<>endobj +149 0 obj<>endobj +150 0 obj<>endobj +151 0 obj<>endobj +152 0 obj<>endobj +153 0 obj<>endobj +154 0 obj<>endobj +155 0 obj<>endobj +156 0 obj<>endobj +157 0 obj<>endobj +158 0 obj<>endobj +159 0 obj<>endobj +160 0 obj<>endobj +161 0 obj<>endobj +162 0 obj<>endobj +163 0 obj<>endobj +164 0 obj<>endobj +165 0 obj<>endobj +166 0 obj<>endobj +167 0 obj<>endobj +168 0 obj<>endobj +169 0 obj<>endobj +170 0 obj<>endobj +171 0 obj<>endobj +172 0 obj<>endobj +173 0 obj<>endobj +174 0 obj<>endobj +175 0 obj<>endobj +176 0 obj<>endobj +177 0 obj<>endobj +178 0 obj<>endobj +179 0 obj<>endobj +180 0 obj<>endobj +181 0 obj<>endobj +182 0 obj<>endobj +183 0 obj<>endobj +184 0 obj<>endobj +185 0 obj<>endobj +186 0 obj<>endobj +187 0 obj<>endobj +188 0 obj<>endobj +189 0 obj<>endobj +190 0 obj<>endobj +191 0 obj<>endobj +192 0 obj<>endobj +193 0 obj<>endobj +194 0 obj<>endobj +195 0 obj<>endobj +196 0 obj<>endobj +197 0 obj<>endobj +198 0 obj<>endobj +199 0 obj<>endobj +200 0 obj<>endobj +201 0 obj<>endobj +202 0 obj<>endobj +203 0 obj<>endobj +204 0 obj<>endobj +205 0 obj<>endobj +206 0 obj<>endobj +207 0 obj<>endobj +208 0 obj<>endobj +209 0 obj<>endobj +210 0 obj<>endobj +211 0 obj<>endobj +212 0 obj<>endobj +213 0 obj<>endobj +214 0 obj<>endobj +215 0 obj<>endobj +216 0 obj<>endobj +217 0 obj<>endobj +218 0 obj<>endobj +219 0 obj<>endobj +220 0 obj<>endobj +221 0 obj<>endobj +222 0 obj<>endobj +223 0 obj<>endobj +224 0 obj<>endobj +225 0 obj<>endobj +226 0 obj<>endobj +227 0 obj<>endobj +228 0 obj<>endobj +229 0 obj<>endobj +230 0 obj<>endobj +231 0 obj<>endobj +232 0 obj<>endobj +233 0 obj<>endobj +234 0 obj<>endobj +235 0 obj<>endobj +236 0 obj<>endobj +237 0 obj<>endobj +238 0 obj<>endobj +239 0 obj<>endobj +240 0 obj<>endobj +241 0 obj<>endobj +242 0 obj<>endobj +243 0 obj<>>>>>endobj +244 0 obj<>stream +xÚìÏsë8rÇIŠºÌ‰öŒî´üt§çyšÝ­ÚJñÙfvçÖ$ÁÊ!•S*Ç6•üÿ±~X"H€èn$è5¦jêÙE|ˆÆ·@ƒúÇOßòýÛßò?=å¿ýžÿçÿô,~*ÅOÿÈÛÿù×?þøÛï¿ÿºÏÿü—_Ÿò§§§·kýñõ¥ù÷¯|­ÿöœþº?•ßNå÷SùË©¼œÊ¿žÊ¿üÇ×?òÿýŸÿû¯¯ÿ–ÿíÛ׿ç‡oß¾>ÃKþ=ÿãõ§öcøä²+âõi»Ý>ÜËÛ?¶ß_—Î%^¶wY¤*w÷¯ËäOj¤Üöû¸ē‰é½Ü?–KáÂC]о/ëå!"—x[ÎõœE¼r˜ë‰KåÒ!˜¾rÛg޹^òȾü\ÆÕÊÏ3s=GžJRÎÉõ-òVâÃl\ŽuЄõV¾ÌÂ%²( + ‚B¹ü29×$X,0X –€Åƒ %ƒ/° ¬(ÚMÄåÝoÙ9h6×ÄXo`å\ûhò’LÀõ#𡬼sÕÑ,åÏ\M6A!|…gi,A +Ú Ñ ê£s5Ѭåà‹+›— 9Ä`™ãÅ`ž‹,öD.1?V{àÊàŠRç\uD98æY\‰c®}HÙ8媣`Jé++D91WT蚐°ŒÒË TÔ  LÔ‹Š4ðZåªBÃ2t,OãQ ÔxŒsÆq‰±FãzX¢Æ#F,Ï%£FL×]w÷Ûí—×cy>|ðÛa0IwÅ÷_†ƒüxÂ[‡ÿîŠG’þÅ˃ŸßÝuoœ*=[ í,¸ö~ºªÛk[ça=xì.Bú±àæØ\ìPƒ–.Î$[q¹¸¡==·aMJ&³»XéԜ.K™\¬@ž› É貘ÇUùÑv‡]¶cqeSÙà՛eN¤ܯjؤ½s’  ®|²¡ÅϼJé\Í Xd°˜ÎEùØÍÉÜZ9ƹfÂ"‚­¨\Õ FÈ1ŒȕυEÛи'’ –Y¹0p7ñú¥uZj+Cg‘¼c,Òé« …«rÎX•½ÅÍÁ‘jÄ¥{.B J<—°ÒlKÃ7D=Ì:¸ÎåÛÁÉ %i=•œkˆàBf½ .Ú`Ø`¹Š¹2O”,Á W­Ç’ó ìÍПR4q‡ãÚa…„–¤8®´&1Š«žÙ#3ì€á«aÚz/8 [c¸²0Dƒ¢õ ‚«æfóuXiæ*B J‡íÌ\Y OjOjäªÃê.d‡%F®"°îBú°ÒĕÖ]È'½1p5Á¸dZ“RW\wá¢ÄÄÀ•6ºÐRVŽr‰» 7æw£\u€Ý…[FJG¹*OŠ…²¢d”+ (2$*ÇVå'ÆB ÃRåÓ©¹Z’ Wå“s! q5ÂÀÚÛ=W¢È£­ÔrAˆ"v@;-W¨jàLi­ã¡ªnè¯t\5-4”=Ùí§ž±¿ÿ.Ï´’T¹Æúù=¾aÀ +¢6(®–KH·Kh%ºÖRÕÓbQ®•–ër›®Îa‡Àà ¯Çé¹ £^ >ÜÌіœáµCrí´\MçùÖ 1£$UsÑys¥Z®³í%·NH)}¢æÊ‰Îkœ+ÑsÝ´BPf=ègŒàp‡åz7.×MÛk¼b”¾Tq5ÔÊÀµÑrÝD° ¬•T؇ô¹WŠçZ鹊÷G”Q&ß V<זByW¤çª/ŸÕPÌ1PRWF4C#×NËu¾×úü+ü’QØV +.A5C#WªçڟòáªÕr[¬àª©fhäŠõ\盽§5Rì•K,×êZ[Éu6Ž;êÊ12BªWNZ,×:{—'%WG¤(³ÔgO@• ž«x j®Š5K5†ˆëWC6Ãq®ZÂp ÖbI…Ó5 ÊFÒâ¹Ä»Y¨¹®&EZ,ip-â\9%pžê¹*֚Nè(; +\n£á¬5;c+\ŒôÅq®æ" +®K‰kvª‰@“¤¥pµ¥×qgéB™ÐdcMãº(½Ž«àôWòD@“ë¢ô:®Œ3¾êÙwCÅuQz WÍÛÃÈ0’ ¤h#!r]”^ÃUðûMÏ%s Æð2r•^Õñ6g +ÌÃ’lì¨\g¥Ws5Ì]Œ +㘁´¶ÑR¹ÎJ¯æ½ØER2WÁ^f®“Ò«¹rfæŽÀ8f DQ)ëd݅~^¹e¢IàkSYŽ­\§Öç*®³Ý Fȑ#š ”(ªT?º²k ±ÌukDŸ+?krN7Ä="àVÌµë>š>h¸Þ;а›‚]†Yw¹k6+IlºŠšô¸ Wuáiè†X!dr¸Ñ˜ÄjøCýsȵèÝJ´§•¸rŽlH[âã‹:\…’K\[°'¢@Ø¢C­I¤€]Ÿ«VrU×Ê=öEèà£ÃDïû¯´ùÖṌŸêsí¯#èùVž«áxåÛ-â;^WÈ\OÌɱonn0¾d=äª\ÝT”‚lˆ{ó€¼0ÚT¹WWojò$ ð\{–l lbÕ¹.¶*qeÝKž„‰×ñÒáÊY²Ñ˜×Ó{Šyq—KΈÚ{ÈhzªX¯üPy8Å:F—« »òúh9ÔNþnï5ùÒ*¹Ä€+“,¯ñª è¨Wo'ÍéŧñýGH©\SßËy°†ÇeŽæãvQ°2Ÿ,’+çEQÁse¼(*t.a#‡s5–r*W͍çª>š^¸ +vt6מ͕4™¿peM/\œ¥ùp‰'óg®úÃÉ<–k2ߝÎ-‡͋ó·•Ü:\[æ»uîªßFwÒ²ßmµwpœOm›.Ò,²Î-ï\·u›þà,•\×FÍÕI¿\¹r¶ûRãkT§×ćk¥äjÔûËÛ}©4fÜkbÄኔ\¹z߁¿h£¶W]nj¯‰;×NÁU UPn9Ár­4áËNŕr¸RW6|ŒŽ¹Î«Ëë51áp%C®wшﲫÝÊ-§h®š+Vqõó¡¸g¯r~ô'/ÙÅlp\ëQ®Ó¿^òHjÁZv,¥Šk£tEr<Џ¨ëdÞ7ÛnlÌ\—᯻?"éx@·‰+×à¢Zr—Ûj{‡àꤥÈ]|Ëíé71âp .’7.y<€ +£®[‘"K~­lâŽÃÕ¿(—óM +-áðì8—Ðpz®”ÃÕ¿¨7RNf™*Œj1\·Ùÿj®˜ÃÕ»¨ðTà¹b\Šã|f.ÅEußÁnßÊ#`ÂÃĞk¨Šã|f.ÝÀT5_ŽÜp ×^­óŠã|®áE…ÒÁ&ŒJ[=Ì®9·r‡Çù\Ër¥#Bq­Q\µÚ՚8JqœÁ5¼HËU;â*”ñÆË- é5qxœÁ5¼(S:"×Ã%¢"ÎSÇù0\ƒ‹´\?Œê´áò;ô¼RqœÃ5¸¨[ývGסµœm”MçÃp .Òr?ŒjÕ£YU4ñ"Ú4®þE\-š+Uý6.5MìçCqõ/Òr¹ê^,ÕMìçCqõ/Òríùáa«68Íòþ ‰ýã|(®þEY/Mõʕ;ãŠK W'T•šØ;·ãê]ÄçJ\ñ®óۋ_¾,{lÔMìçÃqõ.Ê;Š-qen¸:ù‡Ýxã¼ì‘ª›Ø;·ãê]4ˆ£*,WÚâæ)­Š«ó~(EO¢Må’/Ú÷#¢âÂùåªÇ¸äã|H.ÅÀn÷X®µW£‹ç¯AeNä’/ªúC%;s Ï\BsŠCqœÉ%_T÷$[DX®W;Ê.é"Ñ Í« ¸—|Q&°üÂeÎ=Üy䒎óa¹ä‹ +E2þW=/WÁá’.ªn»Ê·EÞÙ¹j—t‘è¶²¾Æ6ÓJ\‚Ã%_”ßö¿ž#W铫{œÍ%_T ö+Càª8\òE½H0?qÙL—Q\Ù8WÃá’/’gÆé>®Îq>ès¥”ºór=ŸÞa?bšK©;3×Cÿøšü²¡ÎæuÕ»ꝪHqPJÛ:k®|¾!çéw·§†u\y1Ô׏áŒF~™WsÛìø9QeäÚÉÔ—Pì(É/4¬®KüuòÈȵ™‚ TSë¼;Àz齺 ®u+ M?\™j« ºã “Òdúu\©l)^¸š÷§»nÝî«ko»õʺ ®Dºµ®êºQ(¾unڑÀ[v…².Ÿ«öÉUtv¬÷7ïÒqY·äsM]Õ2¿ú®òöNå“+ª›v^Ȭ©K㊯ۧoƒ8ñƕu—áòžÒߌ§©KãJ®£0qÙÄóҟá¦×VËIÚªº$®Õõq¼=™t®êöÓ5ä$mU]WÚ}tk;.CúáõÏÍÝ[ÙtĪ윑Ò×%qÏ]ÓÆ+W¢ûѧ“T<¶ÔçÊ/ƒô8„wÞ¸2]:ÎeO¹éÀd#©;x®ýåóŽŸ|ðÆuŽš¸1‘†‘¶.‰«¸ÈÐÑÒKo\—½Îûƒ:À:eR¼Ë¹¶.‰ nÙ¯qëë¢Z{þ⇬ã‹õu•\ÃÄÎEu¯G÷叫“Òkmñîm®¾X_—ÂU_ `ü`;®±}½n=é½ÄÕ0‹V[—ÂÕ\~<ºeK®±}ØByŽCš—ƺ.]_ˆ¾ç²Ú_ÚÌÒ|Õ¢¯Kàj/Žùô[\½,Ú¸ôdЍKá:;æ“[öÉÕyіL¡ú’9]] +×Ù1×'ï“ëý ì —J•l:ZÇuvÌõ©¾—1ïë9Sš\ùPÔuñ~ùäËãÿc—‹|¶—‡á¤¦ÒLrTu \ÕÉOnÙ?×­µ«^(u@Õ%póÉ-OÁõ. +‰vЌÕ%póÉ-[raß-Z‹ÁX]—x÷b멸n‰×f®^]×Ù1ŸEr”Ë&ûø*™ìе\cu)\o&˜4·õS/\²{ãb§®.…ëM2âúì-¹JÜú¡k¬.…ëØÓUt}Q7®D²­x”KW—Âçð±‰ËæÜM.ý9Õù±º®ê|²&±çڍO¿6ÝyÈJË5V—ÂUߜº7®ªÛŸûÞmz«Kájn³Q.›sˆçkãï·M­–k¬®!ž—Þ¶%ä]A ®qö¶ ©Ÿ,ŽÕ¥puÞ ë«™«õ¹F꒸r—Õ¹ìf¤jŸk¤.ƒ«´çZãÒmú¡ÿ VÑ×%qƒßxàjô +3àj¸ëQ2\ŸÊ(—Õû7䵘_ÚQ.}]—îý¬n¹:}l \Úº$®úêÓǹ¬²Þè!Ón”ØÔµ*–ïí¹Ê×ëMóU|–ïY +¶X¾ë“kz.ó떗ÉUüÓr•‹ä2/pÉe3aþ䚞Ëjb¹h®õ"¹Ä?-WºH.ólõA¹’ere0ðµü>ŽO®¸ö0ðÅ}Ïn‘\ðA¹ª Z~¯Ù\Åô²×å÷ÐÍULMÞá¾70¸@ªrÃ\ e’ºÒò{9ç*Š+[\Àa +%°ß{ZÀ‘›ì ù=Å¡­´e&=@~¯thG„â‚¥Âèo‘ßoXÀQã¸÷}ô•±mç˜Á8lc®Á9æ½Qæ#/Á9°Üè–ã‚s`™±Åš3‡}€²×ÀXcV@éK`3Ëڬހò9°ÊÜX@=€ÀXa6.@l`3°½9êT˜ËÍ"8á Kèmœ£ Jè„m®gƒú¡€S˜ „A:àª%ô¢©€ìڐ„>G˜ ‡bH}fv_ï\bAB/0Ò -Vè׋‘Ã]‡+_Ž V˜Ȑ+ A,0 +-V裥ÈaÜ媗#ˆ(Â-ôDˆ *âƒ-ôéBäpÝåB} Â(»‚-ôÇ¥€VÏP„#C̾:\ÕB")£œ· Å }ºÙHd.„Ð'‹TæB,Ýċu+_†pd8üƒ"âȇxà B8j¤—Â!Gl#´A `1Û¨«>BðÌØå +h)‚¸xí\Åú,(ÖCéÑg­¡% ÇÜ ýŽhIÂ1ó3?ú•‚+~€áï€d¼s°=z @KŽy>r’s˜y€Õø©bå™a÷H*:sˆH؇–(30Ê&ÐúyÖ9eˆιÈQDs‘ƒ²Ôā9£Ò7”AОQéI+Ò@½t>¥Ï)Mª’ζÚ&HšÔ¡9›!"li¥åڇkˆ´åhél¨vc! »ô™ ±¢g83âžö¼nų¢ †®@žâÌcˆñqCË`3Ĉ9qx@Ë`iˆf(Í4€ó`¦Ÿ¬Tԇ -g€M>kΩj-k€MœdY“½´¬6± +ÈcX]>±rz‹€5D'VFÔ +œéöÔ1GNÀY™8樼A:©ÔgB©œÇ Üϙ.H,8ޏÃtºc wàÊêd†kÍÁ…Tú‰:,c=càÔ4Æ €?R§é°ŒÖÛNÓaә_‚& :C¢Åqí±`»0ºk…äªé0‘qƒph­ ±÷UKó„ªY.´v†èuâ,øV­!zÕzìÓÝ ¹ð†èQ:j ›ÖÖãrfWŠØ ¬OKüñÍPË%¢¹-±±’.h­ ѓ&æV>¬­'BõÊXZ?Þ¹±´°öõ^†˜È,e \<1÷3–½í#×½{&ܸ¥rU¤s©ÍJÉ\"š LdöܹK0‘;¸)82‡i\o\´;¼•Ÿ'–‘P¬.t¬Â^¿¹1p1_uFÃÒÇàd}¡ãNSbé¥ +\EiW°/)áøf08Ô&[õ cœFwžÿf<[l2êR6W›qÀúßtŽ*OôÛø\‹+Š¿S;‹añcq€‰‹ÙaQt_zî¬ñ¹‘‘«ˆ¸ÿ¥ó/9k·6\"â—{”56¼OßYqYtØqœ=šÌñ…Ie˜>˜¹l:ìŒöªÿ짌ý¹K.ê4Li¯ƒ~/ÛÌæqµ¶\Mä¦ÜÝo·Û/¯oåe»}È,?mcÍå¢ÃœSþ#†KȵqÀe'‰³tŽ+¼Û9á +®ÃÌK_8.±´îBrvm¦(ˆ=$W›…ÄupÇU/«»Ð\¬•O_ºäj‚áÚ´.¹‚ÑzÜöžKdKÑxw gÑ q!Øý^ +—XŒÒ¸°DôÖ!‰kvKÄgиš…X!•kæø—°MäšÕ)¹/T®9½3eû‰Ê5c`OJš#sÍ6Ähi/t®™†1±ŒÁ5Ï#îí2¸fbÔ,%=pÍ`sM®ôT9×ÄÚÁÈdr‰<\)´ášRY©Ã\®éÀx™dl.FÚÏ$ŽËšk¢Éóā×þ9椰áòoŠü,M+.ß`ɧv\~UÑ&Yؒ˧ƒ¶Ê¶åòf—ŒoÍEΡö41qÏåcÚb™®î†Ë½,ڟ›pÂÕ +·¶øhß"7\o¶è®Ë’CW+Âé,—\ŽºìþІÆÕŠ'küâª-.¹ø©ÕªGw-qËe‘^Hݞ“‹Kæ–ʇìþ‹ë6øà"æÅÇ[ï¹ðÃõV^qÙññýw/·÷Æuê5ƒAÞm_}ÝÛ'ש۞¶wê~z|õy_ß\çŽ;žpØ>ÜËývûøúêý–“pÍPàÿÿÿârõä +äÿÿMÌM‚0†á=§˜¥&¶v +ág©vêˆÅ%mÕp{©ÆÄí|ï3{lp²d Íӈ¦ ›Õá,*(†©Wƒ]í:=‚n¡b-ï ‹ñËØ†”ÿY"‚}H0ñ3iäç¼¶3Tºu¯Ú(F7‹³Ÿ0 +iü÷GO³é®7˜e ጱ ìúJ´P*«ÌS5žæ28o8îÞendstream +endobj +245 0 obj +6280 +endobj +246 0 obj<>>>endobj +247 0 obj<>stream +xÚ+ä2T0BCc3JÎår +ár á +äHÉHendstream +endobj +248 0 obj +31 +endobj +249 0 obj<>>>/Annots 20 0 R>>endobj +250 0 obj<>stream +xÚµWMSã8½ó+ºæU¯íØùØ ,›­&‹ÃÖrQl<ØVF’Ieý>I629°EU*²ž»ßë~j…'ùø hÒpDiur±8ùõ÷)…>-rìŒÆZd§%©Xó³Åw»ŒÝî`y¡Ý÷še¼ÖE^¤L¢vЈ‚ …†cod ‹‡BQ&Ò¦œÖR<WÄjO\>|C"'ýÀiVk.k®i. D®ïñEh‘Š’–§Ÿfóù§åá…td0EEµ.¹‰Ì3*, ¤†Ž¥ úYTàw7³º¸ÉVi^™¨ŸïæÉ^XïµêЋœêp÷귖»Á^-N|ÏG]ÍG`>n¯)ބâ(ô|ª(šJnURâªÞ+ކ&¾!Ó«­…ÔlUr0‡t¹›óýùxĵ€ïB޳ږd„=¹(K±±ç›['©ß\¼´‡©v-[†£1½;Á†#Ì¡aà‹fî1·xg„u€ŠâáOÐ=ž«©C_,Þ¶]Ip ƒ ­ º{÷õìtÆŸÏí;Bw8Ûêv‹ºwh+뺨(ðCïà?N'NšH·<ç84)W¯~¹[؊³‹Cê[´wÝT4Á×úñ“ØÐBzÿ°|¬ð±ïnl«Ë. oÑN×t`Úà¶ïàG(îöŒv÷ÃgûãÕÇfÖìÔÛÅ!õ-ډ;€îÐöñ ôâ㉀1ğk-‹U£ÿÏC”t#oÜ.Þß >6.>€î >©}„ø(v“îâ¯Kß$rûžôÉN:^<¿ÙûÏ$¤âN1OÛbüuòì ^`endstream +endobj +251 0 obj +1136 +endobj +252 0 obj<>>>>>endobj +253 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS047Ò3S072PIÑp VðÌ-ÈIÍMÍ+I,ÉÌÏSÈOSð Ð Éâ҅¨Õ…*6‰™˜˜…À|C…àäü‚T¨kW þúendstream +endobj +254 0 obj +108 +endobj +255 0 obj<>>>>>endobj +256 0 obj<>stream +xÚ­–Ks¢@Çï~Š>f«„tñq3“lÅ ++$§½ŒÐèlÁŒ;3T6ß~{Àgbª“ò€@óë÷þ´<¸¢Ÿ=:$Eë:n]Nà_AœÑ ×‡8½ðaŽ* êoñïÊÄëÕ&N§ëú•‘ëÁø)Œ`"“²@a˜áRÔæ]𼍹ßsk¯2™çò…‹eý`zø p jë5…Å+˜]ÚÚ kp²û} +Âñ·kÙ¿ü Ǟ/¬g< Ïõ†µ¿±_–ªö7c‚-Ѳ!̙8æSà^§ÎóCøýdr^µÁî…A•±a‚š/…=$Н÷µiä"<Œÿ¾XçûzÉ èvsf4šY¦ûw¸ÌÌ S£´à‚kCõ‘JÛú”,?ƒ\–-ý+Ê…³SèPÉ¥bEaë쨣ù)t„I©¸y¥…XKeÎàÆá)nŒúܱ‹ž>èߓÆÏ´íyrûLT;oï:·Õ§^Ǝ_/£O'f…j' ú?EAHá ƒÀWªÂ(• ©MT%C³ÃíÆfSž#L¥*˜h ÏxRí\{WŒ®ÛqÕøã&–% Ð^jÛ¯¸Já&åÖY3>IÁ~È0‘î’ŠÐÀãkÁÓMy—ÕÜވD¦¶;+&tãEر¬€UŠkõ¶ä)žÇ™Éó*  & Oš%7ŸŽéooІ.p? ê-ɉ‘‰Ì#ýïA¯½º[ÉrMí(Îú­ p3n¶šŸqÒoüj)˱ò@Û‘QebJÚz1Ø û"m}íl¿6*㌭׳@ó‚(à!œTž©c;tóù´áî•&Øà_SO-Ë>!ǁ»8®¦â:uË>£’ªbǨªê®™æI•À„/­RúÒoìjfÃܨ ßldðÍ7T·å(.ºÕ±ç7qëgëv²¯Gendstream +endobj +257 0 obj +712 +endobj +258 0 obj<>>>>>endobj +259 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS047Ò3S072PIÑp VðÌ-ÈIÍMÍ+I,ÉÌÏSÈOSð Ð Éâ҅¨Õ…*6‰™…À|#… Ô´Ô¢Ô¼äÔb”kW ¡õþendstream +endobj +260 0 obj +113 +endobj +261 0 obj<>>>>>endobj +262 0 obj<>stream +xÚ¥˜ÛnÛ8†ïó߸ IJ޶”»¦í)›lãì½,Ñ1 IԒtÒ¼ý‡’|HìÐ- + õÏéãpÈô¿‹|üÀ<„hE}q½¸˜þ™AèÃb…_fóå‡nŸ˜|âìùÅÄV0 S/4’Ow÷xðº­XÍ­àæînj–ò¦½f Z&sÍE£h)×ZòåF3%[ñ†•ÀŽÐò +¾‰%éî$o4“pÏ´ AƒÈ½Ž.ÉȄ»‚ۍn7z²Doûðå§fB-J×­CsµæÍ£‚ñJTåør hU­p¼Ì+6>ˆ<äOyµÁ +ØàTË +¾â…ÍÌë,Ù òJ h¥xâ%Ú4ìùO7/´¾ÃI P›¶RC½©4GԆ2º"DÖ°ûá ã¢Ê•B¢V‹¦k¡´g·4ƒ`ÞmiÚL#Ü:ãüáûz½ïso6”Óå¤`)ôÚîàZëvdAóÿU3½¥ò`_‘r%ž1L‰,4yÉå’ÁF±òÊÆ›íÄëðY?WÓ©ÉÝ]™ÈÓýü°—‡º?å ,­WŒ+}£G¦G;¼½ýp“]û#ó²æÍñ¨»áH˕6ўØïÅí¶qjVއ¿·-hˆöídù ˆ¥šòÒ-Š!Dß¾çWEÁ(Dß ÷¿ê—Ï_5Ԏ- ÏbS•¦LCb ++!¼e.½BÔÛþʓ߰;í ›²äfÛ.©ÃmããTdÒçá4BÖ{)ų2‹‚):º£S½4]œØÑ;-`fÞ©=ëÝ{ÐG˜ÛAh3êû!”?²á˜Òø0Õw…—/èϐ®^N͑ÐÒ2Ãd;²O”Ýá8ÌÖÝÉ·bØÖXˆ•MNcê¹,) ©B²G<~Lâ™|T¼õÜ͞¤Kl–x ]sñލw­ø¾aú]âf)޽ [%‰²£ÐʵälŸ™*$ou—Ç—Å…ïùx}ÿ +qêÍ!@Ks’Bôdèäýâ`æ{i§ŽRcrJœeX“Ç fJb5½ç ‹È°WÓk¡ßÁÄ7ùÎS»‰tiOð +'F”?Õx¾Y¡iÁÿéû~Hؒ$ã1^ñŠy.sDjW@$vdóx ÈbI2Û?ÿæ/s͜ÉÄûdz{3hwïAJL—;C"µ+$»B²yƒûݕ-Ù1DÁˆ’}DÖº¿"†é(ö|w:¤v¥CbW:6ct€®7֔“Ϣؘ'¶žÙ>ã ;ZöâÎ) ,]9‘Ú•‰]9Ù<Žqò/í~«œZzÐEd},9cP“Ø‘ iÑØ$ސIC;š¿2̓áw#å(Û„^ÎBóÙƒšÄŽ€HëÈ&qÐ,²Cºä†åãk,æÍo^`ïIæg e;!­#›Ä ¨{ ÝoáçvÍõk<ý£Ü¹sÐ¥û|&±#(Ò:‚²I¼õJ‡'¬ÿú?KâÔ÷2û!éªüçâ<>>>>>endobj +265 0 obj<>stream +xÚ­ØÍrÚ0ð;O¡c{À•,ËÇš4é”úDâŒÁ©mhûö]iŠ¡ŠW™N2$cþëßH‹àÇH0?‚ÉØü®¶£ëÅèÃMĄ`‹ S>>>>>endobj +268 0 obj<>stream +xÚ½Vݏâ6ç¯ñҒ#@awß¶§^µÕ~Ð#+µ/&ˆ·ÁÎÙÎrœúÇwÆÈ^¥S¥Š‡ٙù}ÍÀ—N CúÄ0Áx +é¶ósÒùðéFCHÖt2]C’õ&ð\¢NjeûÉ+]™@‡+ƒÑu4âKIްÖE¡wRmÀbê¯C†65r…àè\ˀ­ÊR‡¬öðñe¾ˆà^ùKR94hè5¬ ¾I·¿:y“PÛxÚîr™æPY*®Š½/`P™0ÜÏç œ£ö•C  (펐²(¹xV“¢‰gÅ07„dð›^5ìÛägÑô@¾¹ ËÞðëp8-ûPò1€µ,°é<9Tº9v>ëý¿T$Æ;Û¢oŒ®J˺]°f± IZ ¥0^Zwل6·µº£i@ó+W„ø¶‘ù.ÅæxùI¸Êˆ„ÚTbƒ@6ÀÇ\‘’£°ÀVy†ßm°RºlÑuý›§*”uéîÃ&e¥ç=“”$çE`j꜍Gaá{-p+”“)UÒiµEå¢ ¨]ïšAed—|¥Ç²ÿŸ”„V_IÐ}Ož¿|¾'ŸLˆg‰©\³uIßjpªd}t lM‚Û²ÿEùî«^ V²(( ÎáW·ì=Þý±ì× ?|šžd§~mÙãÁ‹ËMŽfÙog­MïyžÜ??Ý=<üyG»†@høárá@Z(ôfCtwÒå^Ò‡#MuEš«Í…AR‘R[¶– ÌÓæˆÎ2͘²ÂvîKÃ_¸ßiú¿A‰-þÿìµ¢Dï4¬„Rx¦iƒ<„ÁmÚwHüÂpˆ5†P{¿lKˆ ¿Ä<†Àìx~»Š:vY^Z–hÞ¨²ÓÿL¦ßVa›ëª`,´s×M]Ã2ÓŸfH,/Wêv<¾‰¢ÂÃN9ñháZTÍstЫW΋–ME*O›ü°—j{ð¤ޞ;ԃÅé¾÷¿‚7¢=LZ¯E°”·¡ÁxÂÇÓhEn‹™?”¶Î̖óàûœ®µZõ0Hdžü†W¾ûX]™¯.u¤D¥º ‚µºreåBe¶þ«¹ ƒ6ßs¾çëuíœ_yã8z÷?Æäzݐõt4ãï¿$ß;ÿ7Ñ¿°endstream +endobj +269 0 obj +882 +endobj +270 0 obj<>>>>>endobj +271 0 obj<>stream +xÚÍUMoÚ@½ó+Fœ@ª¯!pK£¦JU +ŽÔƒ/‹=ÀFf×Ù]7ɿϬ×PÒäKÂóõ潷뇃ˆ> #÷Ͷ¯IçäêƒdåÎƐä½eqÒOî)8l‚=XX.s®s¸žÍ@ÉâxQ¨G¦ÄL¬DÆ­PÔ +8!×ÂsÁ[«Å²²xQaèGÄ£pè†ÝÚ jø¡–à¶,8å]ì*ŒË Ø>;Ù Ì´6p*4„•rh0‡%ƒ• ñVÁ¡t٘‡~Ÿs`C·pî[CÆ­¦s4¥’ pã?Œ–„µVUiê­÷ kƒ2n äÚº°=¾›1yEÆwרnKԞÐC2Ú\"¶20Ecøú¨•Ãivšéfž{âj¶¾æµ7Ô¼€Ÿ\®+Š•Ãå†kžYiö­)Ý¿«%´Ýº²¾uP4­»„ÈÑdô—’ÈËêÝ$Í0Œ›™l@:Ñ̆Mçéʱ¨g-pË¥uRYµEiÃ#óxvãIí¶wyõ¬§Õ;?ԍñÎB1\j$ïÖêîÅ{ÃBáhG[«@íÕN{ÑSE§i²:Nä€ÄÇ/@‡Ã>{7ýZ¾çç8díîsJ>éçª, GžnÍiNã§<ý:}-¨]é Ò¢KRÓOÚkŸŒ˜&™§w‹Äïî´»ù5 ¥ëÉ͝KX›–˜ýWk;¿K¦ +–¢(ÈœÅ'›ö¦¿Ó~òäjÔ2OS–ö.ïf `d9GÂF¬é:Oû>ÿ¬ÉgƒQèÞ.ÌUÔùׄGû·‘YïÀÆ1åã8rÉgfºw×—õ·¤ó«óÕª!`endstream +endobj +272 0 obj +661 +endobj +273 0 obj<>>>>>endobj +274 0 obj<>stream +xÚÅUMoÛ8½ûW |²Hµd×NrËÛ"E¾vãv_hid+K‘*I%u±?~gHÙrlo‹¢‡…†$μ7ï=’Ÿ{ Œè—À,…ñ²ª÷˼÷îÒ濚žÏ`žæk„L–¨<<Îoî¯noÿÛÔ5½´ `YJYªXgøÏ­…ƒÒ‚Ô«æðZº5½C¨Å +Ad™n”£uÃùsoQ2ŽSF)U¡M%\©UÜ~J§ñ„?õŸõ2²kDgû°$.ÀmjÃ߸yÕ&‡@‰ +ƒ»«?ÃÅð’[¼û0m‡Ùk¶\ÿñøIœ€P9¬ËÕÍbÖOŽ×gz­´÷ªa)”BãÇ´AahjÒđ K¤ùÐcŠÂÑ:¡6P”í‘A-®š<¦ÀÓMÝW„Øgy Z4/ÔÙi(U^fÂa€Uo¸€]ëF2-—nŠP×M™k¢¯´[cVêIh‘¹ËÆC``ø"dã9ñÞGQŽ…h¤ë·xôò3wÙu¤ö%ZÁƒ÷ÇÜk‡—oÀ“#-YóøH6È )õ«my³”%æ'ÀRÞ$BÇqo?ÆQä*ÌKñCiûáÌTœÓ±Ù²ß„Dæ•_ñÌ£ŸÕÉðìPGJT¦%5l­Ð«:³Õð³æmþËeø|=ñ´¥»¾ŸôæXՒ7ÌÕNùÀã’ óˆèü‹Ò‹P:‰SýÚ UD\þ;ÚZ+‹Ç§ÆîÄ,4³fWF7µõ„;›ùh°È‡¥]jÜÖ¼ ‡éúÈý ¹„‡Mãížz7µk,Ü¡µtœ +ªÝêbZ<~Ã5U¨9Ôñž>!áV¨Uãtšâz-ŒÈ8OèN¡ô»Ù£ŒÓ®êûÊý*´ŽdÛºÿF1 9ڌéÌ£CÒRØxöqœÄdÐAH[99Cw:G鱞°t÷dÔIgMEÂí ÔM/}L¾©k—¦!šíB4N·!³8lmÔt&žÈR<ÝÊw¢PïÜ_ F_F£d²I«ÂõƒûÚqöݽ®|AZÎ@¦i ÝTÅ·L€?oá“YJàÓñ,>g +þʼám·I]¯_XÍÒÑwwËä|_€_wÁÏ¿Î{¿õþ¹µÖendstream +endobj +275 0 obj +859 +endobj +276 0 obj<>>>>>endobj +277 0 obj<>stream +xÚÅVÛN"A}ç+*•RòQZ8¿ƒ­+p}5 6оSbšÏØìЍç&€’Âà3H·œ¢nAÍßÒi_d´ía0¼Ýêã²,„Å<÷¤ÍÑ !÷XàU‰ø«{¥3ø R,qÒ8?ù9iNšýgř4N¯/GÐH0ùE>_lÄܣؖ0ÃËñ`xqrvökÝõ4}½÷ +¦BJ’¤¤Ö1$€°~>‚RL‘T í*fAºÌò"”»Õ;Ô\¬ž?ÇÆÀ¸:­º$Ä:äÛû¯OS*ið÷'Ê×ܝk°w]ž$­uÎÑZ •òGñ¤Ó‹{Ð;ìÄGë·ä€„B¾©4'Sü>OÛ¶889ðPí$>†ƒ×þçø2®ý¨ýÏ Äðendstream +endobj +278 0 obj +834 +endobj +279 0 obj<>>>>>endobj +280 0 obj<>stream +xÚíUÁNÛ@½ç+F¹Rm²Ž7J Š$%æP‰ËbOS{×ì® ýûÎîÚIQ[‰KUI<3ûÞ¼}3~î1ЇAÁpYÕûœöŽ/c` Ò¹}4:I ÍÓ%‚6\ä\å P×Rh÷Ä4*Ԛ/07FAd”¬Ñô]åv@ø£ƒ²=š2ÖAàrÔýÅ +3SHЅqµ˜lFSÎÁìx:…™cé°fXqaŠŒN’YS¡0®¹ãËS`‰U& i‚aäiÇôuq?Wh‚/8çMi`R£â×v’Ún“pÔuû®Lveðp8xöpD‚S»B;¢y›X«BXïïÆŽòF€ Õ¸C<] Ù{Ì;|nP›=D;šsY–rUˆ,”lj ¤Ú¶âмÐÔuYâ$͕VØwhÊ£íÞý•=ØÙF88_#Ø\«ø¿m-ökmQí· +al ûäF„'sø?WRåä‹}Mft ‚ì7MǓÛóëëïÝÍ{âkÞ\^ـȏ¥Úzìn¹ R›«¥Ô¸ÓÜ /‰¤k°ã« °éôñaìh)ɪ0¶€’ÖHŸ\‚FõBÕ~¯äNæbî2w@7 —<‡GD±ñݪ0KjÑñ²Mð²<ؙ7¶ÛÓ훿Ý>8(þ< +ԇfaæ—ð_Âû,ñqۂyu£3˜¶+tòøDH¿‘؉èGg=›oˆ2q)dRÖë~:Z÷´bÃmþQÌü©Ö0®ê-Ö́@ 9Ê,‰(;H¢Áß½câ$OÀ%3·‰¾¦½o½_mƒšendstream +endobj +281 0 obj +656 +endobj +282 0 obj<>>>>>endobj +283 0 obj<>stream +xÚÝVÛnÚ@}ç+F¼¤Úa …$oiÔDHI  •ZÉ/‹=àmì]gwÂßwÖ6†ªÒVªª +$.;—sÎÌÎø©Å G/ý¡{GYëìuz}l³ ÏÌâÎÀW_¦Þ Zoª…´¨ LrÔÜ +%»³ïä5Æ*//ùCç7KðˆŸÚøAØé½ z½ ì‚F[hiÀ’K^Y·V‹yaÑÀBiÀgÔëæðQª•«œ‡@iYß\Z³63f‰0ñ5¥EÜvY¸®¤²`P?c ±ÐÙt óu‰¢ü[û9’d°!wîjQ|v„Þg|*ÐØ#¢l$Y¨4U+!—°ÔªÈI‘Å.W‡Ëyž +BÅ ä\[gbª©«tµÁ°Bwã"»ØV .›ΖêÝßsŸ§pËå²àK.c¸J¸æ‘“úÂ;í-f/"cƒ¶]zîÈ*´—Ö¡Û¯˜ˆÑDô“˜ +I’G%Ò¾ÏüÏöÊZK0žNáNؖ¹0ãҊˆ"©¨ÈPZj;™ daÇ)¶$>a‡]Ü]~ »a÷¯ˆ„—&ÓÙxry{ûmS ×7ÔQ (#»::\²ÈæœP¶YÕÝ`«M=!ÊA´øb ^0jÀ^wz¨ö ;®€Q:±LP‡ÝÞû-Zt© ¦T X%"J¶|ÞD%UQÙoÿ »Î±¤BŸ Uù/2á͸séËì›Ûü笼Œ›Ç…šÃòS~sa+n…)‡ÅÞpp7p¯fM¨PÏLŒ½í0rB0a“<âz¥tL[éÇ'ÈöÕ4É3w ãSµ³ÐªÁ_Òà[%Êìo±gžX-Ä ^ ™ӗ½ãj$֐Tæ4zÝýïvvÅ1¹’q9xÅ¢´ÜKºE˜ðæˆr»ŠVÂ&D±ÄåHžð4=©÷ãY]ÖÒêž÷ª€²cÆYž¢›ÌUaɓF¸sóØ( ;oôœ1 ʽÄÎü>ôÞøØñqÖúÔú#nÆendstream +endobj +284 0 obj +766 +endobj +285 0 obj<>>>>>endobj +286 0 obj<>stream +xÚ͕Moâ0†ïüŠ'8$Å! moÝj[!µ…zX‰‹‰p•Ø©íôãßïØ ”vµ{Xq(çãw‡çƒ} è +Zßg­“«3`)̖t28¥/¢“Æßâ.'Óè]41R94ЖZYìΞ(-Æê´(ú´Ùa©ó\¿Jµ‚•ÑUiA/;gä¢rh‹J·Prãü±£´ß÷:÷Í|‹A´]û²ÀÎa\¢áNjÛú>–ÛOw•…[´–¯öJy½Öq%¸`š~þ‰Ï)êœøKΞà W«ŠÎÒárÍ ÏH6LÑêÒþ° Ê(Ø¢k‡ÌÝU—Žò¦tû“qڌþER‘‰Y˜½³8“¦'ëÓÞ¨gãêh2[-0½¦XpådF•tV¨\.Ú5¬v79‡f0^Ngµýï„ÍãÃ(àx(1óЈO\yÉÚ ®©£7g$pÉ«Üy•Š8ï°d8ï6jO®;,5ÙóŽqèÝXËÕͼ»ÏÞþœãÉl4¾»¸¹ù¹Í_“Z !Gx 48w m32ñ¸ôc-eNá´2OzÕý²-zé¢y¡„P¥­´¢ÝSÊÒ3§3ßëúJjl׺Ê,pÓuo§iôB7î_ÛvÚijþ€Þ5ƒ³´(dŒŠ2GOY}¥IÂ1PÀ† EGä÷·?³é0O!„³¾ðcÖºoýî‡m{endstream +endobj +287 0 obj +727 +endobj +288 0 obj<>>>>>endobj +289 0 obj<>stream +xÚµVMOÛ@½çWŒr‚ƒMR½Ñ*$ZÒ$T­ÄemOÈ"{×쮡é¯ïÌîBHZŠ)Òz=ï͛—ÛNzôéÃþóªóaÖÙ;B¿³9Ž`VìÌy)Q9¸ÏÎ.¾ŸŸÿÛÔ5Z ¥Ð@-®”¨ÜB8j#•Ã2œkƒ0—%ݗŠ^¹ÑY +xwvÓéAÒßO eТ¹£7|˜®Ò +»¨±tæ4Øs9_¥Ÿ ۅnJÆjaÓ|p9x·À;™cÒم«ú¹Ú}¿v矹†p99ʉˆ`$%‰a6πëºH8#†åß«þ`tµû +øñøSÐæàá<‘6y޵“ê:!ý-³É´.Q¨3q ªJ|„sFfCªm!sÁp¿@âg€x*í<×Ètvƒ¹[+},_  +ï¹GìölÔ\s¹×Ê铨H~•-#™ŠÎµKwÕõVR¥Îý½·#&€ã6¢„ ô|•îVnMàƒj¯éý¿‘jÇA…dRÄoƒ|[¹Y'œ·¬q¨šê?S*â%ʽ¼1†#xÄ-Òµy¡Ê¥ޕEIô„* k®k,ºž$ŸáÒv3˜ëk%oXëÈìžq7xÛ õKƒ¶°ñ{,e©ïYêp‹Žt|²Ö8ÆÞéAt’•h“ðhøüÑf •ÜŽóBÅÈMbÉ->*gW…·m k!×ÊMs&­c×Ē*×‹íµ »Š -D"郃ËéÉdê]ìÁÝ0–+z%éÉgB'Euש†A _¢„üùIÞ/ÇÓä¸(’q¼¨'䔓®ÃTRCgì²e´vfÞÔÓ¥uXÁwð!æ‚œÎæFÒB&ÊÙº[{Wn{«"/Šã=v¨¾CcdÁ>¦–²ý£@—D¾Êp0¤Q‹ÃÙ¦q/Ýb _ø%XúÔÒHC‡Æë)ý“9Úçüųª.±¢yXŸg㱗4ÜMFƒ_îùp¿7JÀ Ów„ëuþŒ®ÕÙÂmMKÀ«s2ë|ëüáendstream +endobj +290 0 obj +829 +endobj +291 0 obj<>>>>>endobj +292 0 obj<>stream +xÚíUMo›@½ûWŒ|Šl½˜‚“[š~ÈRÝ:6¾ù²…Á¡‚]²»´É¿ï,â:XŠdEê¡âÀÇ̛73ïi¹q˜ÒÅ!òaBRŽ>Ä£wŸ/g çô^,d>ÜlWï:M½•Î¥E k4•’'ñOBÀy‹òüÈ¡â;„L…úË=쵪+*a­ÎÔ `P¦ TB[¶;Iuå¸CȚξ¸ªÀ¯à{…ZØ\I¸îË»\«OÞXakK4Fì_”rí+d*t +ºãs_¦l1ìó‚ZðUÈ}Mq 8ÜÜ -×õíËøy^BÉí¸Ad[Ú+ºÒã¿öf E“Ð+¦KÚaÒÌ>cœÌï8ùŒT#În©‹Õ +–*Å¢áÚ`)¤Íª¤’ºDiY«#©9=·º™Ï:D­(±@‹½.ýÚ<À§‡ªlw1}¦Ó`7¡µ—ê—›O>äÆ:ãT Óªlæ0ÆbùÜmðÄxÙ÷Êø çïk4öL¿ÖUUä8ìÙ#BÝžåÚÓcü ´:îÔõjÉ tÛM†æIhåÒÂr»‰[AÀv½ ÅtëŠ +“>>>>>endobj +295 0 obj<>stream +xÚÝVÁnÚ@½ó#Np°Ãj’ÜÒ¨‰"%6®ÔJ¾,ö€·±wÝu(ßYÛ‚Ó6顪*ìÎÌ{ožgxè1ыÁ8tï¤è½zG'À¦-é$π®$·À5‚T êGL!›o`±©!Õ?k¿!JêL¶DOüI«ÏºT?áC…ƾ ÏV¥Êsµr+­ª’ÔYîóv°LU–¹ PÜ@ɵuWìKÂê¦Úi+D6Ø.]b`§Oý‚³]w—¿»|Ë©<‡k.W_!p™ÂyÆ5OœfwØIïXôŸ { ]6hûuäþlR{y›ºÿŒ¨MB_‰¨$xR#û̟øì ·­Wó9ܨóºÖ\Z‘P&•TJë@í碄,8¬ˆO<`§7g_âa<|‰WBºK ³yt5»=»¾þºm†s ÙjGêÌ®—¬Š%'”?óÚŸÆý˜v·ñžKåp[ün s0Ý!>º÷|ÕÆÅg`äI§L&VêxØõáq¥ÇÍ`N ‚u&’¬Cҙö·Œr•Ô^ü¿XÙM‰5#ú É‘ßavåëêÛþäÞjIWÃ+¸¹ÿWø:,¿$½¶iceê!sÀØ=¹Ü¹££B;k1õž†˜‚Ñè›-á7k¥SZlo+œ ÛgK$/܁LÔÞNlöE{Hs)ƒ’Ç­’lÒOFÍ2®µ¿*ÊÝll$¢B4D]˜Ç¦Ýó¦ÁÈ]fa½èoÀèuûÿCÔûØûïHšZendstream +endobj +296 0 obj +709 +endobj +297 0 obj<>>>>>endobj +298 0 obj<>stream +xÚÍUMOã0½÷WŒz¤MhÒ(¥ÜX´ J@»4VââÆnk”ÄÁv`ù÷;㸟ta%.«šÄóñÞÌ{És'‚þ"ÄÐO!/;ß³ÎéUQٜ¥gÈøñ +aÀ.hñŒ—Vhd…tÇCÍÝy^HQYP¥´”€AÌZ-gß\€ú³1­VÇc,3w‘'ÙS§AÔcjºÎƒ%ã0¢ÓÔ5Öçð*í8\ æpĊâ(¤§WCˆ‚ þ † KÂ3¬zù0™×—3Ý;F´™+â"v¼3Ä;WE¡^eµ€…VMm¨ÝÂ×D©âÄ£fÚÒ1Ñük«sO3N[d×T¢s×B3+Uëòëhøà©e¶1p+Œa‹w¥®±¬âLs?`ãžPNÙæ„{9wx¨Y7¬Z4x˜—K¦YNKž +{¨Kw3 Ç`#l×enTmé ð¥»;s3À…Éñ×)qµ"wÜûa&a¼§?ÔÑd·Š‹ÂõšŠ’UVæXIåM‰²sä‚큵ӍÏa¢XÁ­Ƴ'ì÷Á Ý(…ÛæJñ|>öGDRCÞhMŠ÷™+ ‚åK¨}Ün¤9XK³¯¤9lÕrÁyàá­¤p@—aºÂ·—¤Öúy<îýNz½ôñ'‹A%^wÂ,—séɈßÒXRù^Xµ· gá7G¹g·Þ¶Ù†a´ï¾ã¶zrÛ¦—_ٗ¬ö#ú‚1¶ vý–ƒFË.êÿOññ¯óۇiÖÿ Õôp?r:wZ¨EN*âÿ±?õ`·å¬Åhd„ÃD¾ŸaO²Ñøîâææ×J.í—k·™»ÅþFŠ£O õÃaÞ¹€Y'Èmnˆš´4ËsQ“É‚'5s”fJ‚UžÏéՙ÷EÔOÑçé0iۑ¼aTօ e¶ÊŦ¸u7æhct0ˆ{ÿø©K.:ЃYçgç—´$endstream +endobj +299 0 obj +753 +endobj +300 0 obj<>>>>>endobj +301 0 obj<>stream +xÚµUÁnÚ@½ó#Ÿ’ƒl$¹Ñ(©’@H­ÄeY°‘½ë쮛¦_ßÛJ J¥Dá’Ýñ¼7ïÍÌ>µbhÓ_ ÿdÞú2kÝt!Ža¶ä£ÞyféÉl 3…ÚÃh<Žî··?À•EA‡üZ9X“¡Ð ¼·jQz¥S%…WzÏkôk´`,hãé„Â*íùhñˆÒŸÎ[mãN”0 [›2KAH‰…Ïðh.j¢’^Ô娠É*½4ÌO<þòó“8éÏO秗{Ñï)â ù]¶Œds:7ÅêÕQR™‘UÜçÀyK‘Á Ìr—îQn¹±¸U­´êCI=L†@*HSŤˆßùŽrs^x¬D{)0ÔeþÁf*M¼Dv&Kk9C…xDºMGŽtöRÝ*͈žÐ)Λ¢À4¨H¢­ê"\‹`Qš•V¿1ýwaŽÎ‰¾6ÉÝàû'5‰Eá¨EØ.dS}Ãg™ÝîŸJtœ7,Õ EŽ¡È2óÌ*P‡;ô¤#o۝sœÝô𥲓m4©¯ºo¯¥¨ÕqœÿTÌèå_•#% ¸¥Z¾o3Ú@΁4Ú[Cs¦œg÷ÄRZšœÅ®´¬w0~•‰¤g¢‡éõd™e ×þĔ»Ø¤'pÑu'5êî!’‡µQ­áÄ]Ö0¤¥&µÝ肢¯ÆÓp¦áU&¨” º‚ºßj¿]õKØ\Ïʚ²p¬ÓŽBÌÊ!õ¿pPë7“shߗ¯œâKÍÈÀ`›œc«šà)µaéஞ’CS£êTؔ­ðªq¦ošÉÚïá{º´dɭЫ’î«I¾Z +$o¨)úC(Áký¡¤`ê¿fì\è:u˜5©ƒ¿Ts䘓ô/y®èõ WkïDqԍ’}kI‡ã1ܙ³ +kйÐ^IÊd$-í÷ÏãN/¢G»ß®“°!0̋ 9vû@PRþ,Œû E‡ý¤ÍÁñy¥}ÌE·ßÕ=׳ַÖ7¤Òendstream +endobj +302 0 obj +773 +endobj +303 0 obj<>>>>>endobj +304 0 obj<>stream +xÚíUMoÚ@½ó+FœÂÁ®×X6ä–ÒQ5- æÆe³ˆ#{íì®ÛäßwÖ|ZU*T©‡Šž7ï͛§áyÀÀ£ƒÈ‡q"¼ï>MEoèM8a'WË<˜­KçfhЙe\kø^¢â&-ä(~"XŒ50ǏÜÐãGìÁÖWÞKàyÑz +óâjàð%Õ&•[(U* *5l£Š uÔ¯Ú`î6¬$6èX§nÐÉuYñ=>W¨MÜNì¦È²â§åÞª¢*Ië¸1*}¨Œ§ˆ½*Ë,Ÿ†’+cKL¡»¶|–%lä}¶]ïýƒ›…­¥U슿qS)žÁW.·ß"ù“Àì‘+.¬3Køî¿D†2endstream +endobj +305 0 obj +594 +endobj +306 0 obj<>>>>>endobj +307 0 obj<>stream +xÚÍUMoÚ@½ó+Fœà°Û¸p£QSQ…@ÁH­Äe³^ÈFÆvv×júï;ã¯BÓVQ« +$Œç㽙y³ûÐñÁσ!}å¾ó>êœ]…àûméÕð|QÜëæF§NV݅M6ýq?ºïxÀ‚!É)ºS ­R³õ*[äyò¬—SØf:Ø\I½Õ*†:% ¡y”‰°–SÚ³« ðC"Á .*ˆû>àr½X±‰”*wìSvka©lž¥VU¡ â6j˜m³$ɾét;“¹…l Â9£o §,ƒÜTƒ° ãÈL| +u\ýGÊ +þæ¹2Âé,…I›ž|Ë:jç•®°0S֊:ÕHëD ƒ©ñè Åì«~sƒF#¸é®@;`8\Þ #$uv¥Ü)”îS˜Dg«\·Œ<4¤Uj–Ô©»Ïúf!VVâ_©N±‡²¬}À}ò Æô85Ĭ›:],`–Å*)±Vj/R§%fÊd±GýPˆ¹SnӛM¾lú¯V0_DÓùÍäúúk##ZmÖB§±–‚6k¤¼Žß(a±ûM¹²0†ÒÕ|Ž7‡Øýâ2xpj=þêep +j\a×Xþ(àtw†ÕÑCa0Ýç‰"ùT»‚Qgå4+o6 +>>>>>endobj +310 0 obj<>stream +xÚíUÁrÚ0½ó;\ +l<˜ä–¤M†™¦%Áܸ¨öÔ±eG’“öﻒ ¦ÀL›áÒC‡ƒÁ»«÷ÞîÓòÒ `LŸâ&SHËÞmÒÝGä™ÎbH²Áƒ¬š‚køZ£dšWn´–ü[£Q “ï=*ö©™ä¥fºQðˆJ± ^›ð¸‹&[¥™È˜Ì@¢ª+¡ìSSºÿ¨æ %+à3›†â@åp·e’¥%,QŸCé³=E/¥d…ºo+Âííє±S¡Jé'fÀ(L­ö‰ø‘¶˜ÁÄ f•ƒ&ØùbU†…ÅZbɄæ)T¥M‰B[q£û+bÓcÏ´n:ڑLànµXz¤Éûˆ9k +Ý5ÝUvÓñÂØŸî䞔UûY­ãÑx|³’­,ͬͪ%¦‰$TsáòóJ+ +H N„¼mQ3Óª™â‘nÁJßµg©>pªÆ”ç³Np´£}ÕÉõƒSæÏøÒ3rwbóª(ª7.6°1ÖTÿpp’,ÕÔ5ñÏÌk&5´ó9A“íØBïòü¿éÐà‡Pí·sõÉûd&z¬‡çô8¿Àãj™¸öÿ$׬žçÖPyí(°ûšL©#³ØÛñ›]Âsvq[äB¿ ø³WvP™åÿ‚¼dAFn*v*¯<%ïX‡e' ò–¤DÒ+”Ý-acåJj’˜ÙJs>¨ÎÔ(_©Éëp f-ƒ  :›¹˜˜—uF§ƒ& jˆ)ó\¶‡ã¿ü/ˆâȟÍí]ÿ”ôžz¿âFuhendstream +endobj +311 0 obj +611 +endobj +312 0 obj<>>>>>endobj +313 0 obj<>stream +xÚÍVÁnÚ@½ó#.©v°¡$pK“6BJm¨ÔJ\{À›®×tw åï;»kp IÛ(—*žyóæÍ›Ÿ:ôA·o_IÞø0mœ~êAÁtAOúçg0M[Q“)d|™¡šµÃöôâõ|\žì…½àòëä>¸F\áš'¨á þ,QŸWã±ÃŸf‹BˆbÃå–ª(WŠ0cŸ—†˜BÐåj%8¦À4¬˜26ÄPê“jÊWÚr¶Hߓ»¶À a¼BÅ /$\ì+ØXÒ`|ÇL©˜€&—%[¢à2cŠ%ÜãxÛE³¦$¬Ñ4]æãÒC¢‚n4ª!EÐ[j”KИ8¦Ý0 +IÚªfÔ c[³R`4™Àm‘¢pµî1gÒð„Š¤ÌQšðˆj3uJ‰`Z7aÖ2ÛFð·›B¥³ös­%$½40žLG㻋››ï»ygðxàðv0` +b/ˆ?l2ždUŸ¥BÒ@bú„™à97–——¤ô¬ o/¾ÍÚ¯¦e2®kiÁ![ƒYÅd™Ï œôÛ±23¦VÙ +Ó ž—eєNjZ=xµ|pàw,·dzZ¨G»Õ¨’76Y¡ñÈk&J× îրÚä6œþqìCy×T” +’åX¬w.@£ZS6¥­ +™:oò…‹<*Z3ÌX +sDY/놛ŒZt¼l“'Lˆ“£ ¸Í{|Câçnˆ¥á~ÃAù÷²+õ¦ rohÏ5Ü¢Ö´äÏyBš0£MQU=û‰ÍÉ}αÿϛ¿á&óêÆCðc€ñüÁ—vúÕÙïæo*LT¸‚¤TÊz½ÚŽm²ýIªÝx¶wc7Þ»ñ}mÉäJ×ÃƉaGì0§ØfÖêüêu:—t'ü¥!žBì¬(Š„Þm­l.(\kJv[¹¥>s±Ž´á›ú¼¢ÅD°?èùh £|%ÐÄÓ#497œÅ»9w;ƒÐþjø·ïúÓÆçÆoPˆ¨5endstream +endobj +314 0 obj +780 +endobj +315 0 obj<>>>>>endobj +316 0 obj<>stream +xÚÍUMoÚ@½ó+F\Rí`CqÂ-Mڈ*Z¨ÔJ¾,öob¯Ý5¤ÿ¾³kDéG.•/öî|¼™÷füÐò Gý!Dyëâuúé¼,ºžÑKܸÞ{׃Ëo³¹sÚ™Í®|Ň +•î.îÈežW»8~`\)BRdY±áb+YT¥‚"¦µäËJ£&TU–ǘ‚’ImL4¹¦’uª‘Ée2 ] ëÚDoÓ%Ó¼p± ol©¦ñ-ӕdÜ0±ªØ +‰.S&Y¤QŸ…7%´÷xˆŒê¶õ|z!êÐNքnT© FÑ'UÉ(Œ,Ò¾ë¹Ô×&§×w}“³)<›Á¤ˆ1³¹æ˜3¡yD‘ЍÊQh÷j;ã9'da‡ +ª'ìx£ÉÅ÷°v_ª+¢¦ ÓÙb<½½¸¹ù±eBQ~®ö€l84¸D•/)8¡´¼è”iK£Dê€Àø®²ŒœÝ£¦ñQ,?øP JiJ“@­¨⬒ô¡ êgF…MÊ£´Fõ* FJ;{Ž 8˜&p?7…ŒÃ.ü5@ +p p,7">-ä“c; Í%éa“ +T°fYe™À­ô©VnÌéÅ¢wa\+¥TIÇÔ½³ +嚼ɭ,DlõÈky”t0e1,Å~:7\§T¢ÅeŠ>>>>>endobj +319 0 obj<>stream +xÚÍTMsÚ0½ó+v8…™ZA†­M›ÒP07.Â^ˆ3¶äHr:ý÷YI†Àôcréà,ï¾÷vß®:úôá0HܕUiçòæ +øÒ-=IÆô'¿2ž0׫ù2š©GŒ¾ª ,ð¡Ac{é=¥ óÅ#—’Þ!lUYªŸ…ÜÁN«¦6 ¶ ¬ÕŦ±h@hÓÔuY`Â@-´u!–R_Ré@5q\Ž!a^Ö‡ +|·5ja %áÃÞÅRM‡àïÂ6Z”ðMÈ]#vBæp}'´È,jXâ ¼+¡û¬7Ê(Ø íúÌã2@Ge Ý}Q¥MF·Te!Á`æ•gÔז“Xì8Ûò§ó9ÌTŽ¥çZb%¤-2BRYS¡´ì•Ôn­ IeD.º°¾ Ÿu/è¼W›¨ÈÝ¡‹Ø¡^÷‚eɑe-ÌíâÔÍ=ƒÃqè纔‘…ÒÂlµLƒ£¿@Àj1¥ оScVlÏ­P¯MÂôȦڠ~m´;¥l_dtìa0<ž€Š«ºã¹}®5ÿZƒ8è&ç|A¢¢/ԏ¨YèÙ~i‚à+ö¼8ñÉâ˜ZIƒoÜ”ؚ=ϛÖfii¸ ÌКìsæK^ +Ó–>wârªózVÿÏEŒß°ˆ—7ãÖD>HXˆó¦4¦èbC« ˜@ýhóQLÑÑ(î»àxè{s6€þß¼u?§'ŒÆFendstream +endobj +320 0 obj +544 +endobj +321 0 obj<>>>>>endobj +322 0 obj<>stream +xÚ¥VÙnã6}ÏW\¨/jɱ≓E1ÙÚmÇ;À<ø…¯cŽ%RCQvü÷½\äE12™) Zîvøí¤gôëÃ0…ó Ȋ“›ÉIïá +Ò3˜ÌéÍÅð&¼ó>£Å¬6XN¾RÈú}§—IjƒnŸFc(µZ ŽLn_ ÊJ( l›FAU—¥ÒŠ:7¢Ì8®D†UF£;˜‹Ü^V†IÎ4‡¯jfŸÔô´ÔBº+;uïŸûîÛ¼ƒ,gU…UâG½‚þ0Œzž&‡'éÝkù&°ara£Cä¦4šZKä0ۀY Xøñhb^*Q3ãÀÓl(ëÂÞS<5w9lÅDÎf9¶À,öÚ6 ¼¸ +ÍZ饥بLåÄä‚7Kàs7L…z…zGÀ tµ%€(ðÕcGL;fSb +KÜP>==‡M,ð0qË T%fb.ìSKHyà0dL AIl(˜«>Œ_ßJ·¥Ì˜Ìç@›i#1!çÊJ“œdÚé§Ãéé{„鲎é’Á¢&gŠ52ni#“¡µx¦¼*£`{i¶eº€ÉsѨQÆÈzÖ/ýèí}uÞLQ°%Ƥ¸Pœ²åë½üãxÂæ"ϕ†žeÞq¬àÆ[[Âk¹MXf +#kÞÁOàq¾wk¶.WÔ[*³5òV{ʲbߨ‹aB:oh ¦j¹”j-¿Ãï á§Ö‚H¥ÿ÷iƒ3XKñ­Þ1Hðì–ÞçÁ–a™©ikÑ«‚LWí3ãj{ -`K”œLÐQB›5¯±•ÛòПwÁÖµ ÏÌlÏfu.öºW2³èÕ³w’ý´k¾§gf¡øuâv»°^ }¸üK:,l(ï•]D'GV|Q]Í"žÊ` +:>tå„÷¼ôûX^Ïç³±ý>c5ÿÍ-õ¯4¿0›p3§ïœ¿Œ¼¤üÛ ŠÃ/c$é"jŸq"\¡ŒœÅFŠóPÆÖ}«D•šÓrM;_>ýÓûòéáä*Ղ-I±ÓS_Ï9¢V¿içv2î}žŒ’ÖÈÒñôùñàDôê4äø à-؋(ê,]à¿^­S̫ʹ=FØüVÆ~•Tǁ­®U¾;Uä€}‹0LßÖț;lïÛø>‘ô.›ê~Ÿ<„ö9z0P÷3û*ý`ÜONþ=ù«È”øendstream +endobj +323 0 obj +1092 +endobj +324 0 obj<>>>>>endobj +325 0 obj<>stream +xڕVÛnã6}÷W ü”¾HvâlR,ÐÝm7MÑ¢éÖûPÄy ¥‘¥†"µ$ÇßR²9ñ¦H â\Ϝ9Ô·^ ýÅ0ñRö>Î{ãÏgÇ0ÏøÕìÝÌӓ~‰.×éÕx|W[4J”xU k×Ú¤?ÝçÚ:~uwUiãîÇw­®M‚÷ý¬s4ÁJ±%B?w®¢³~QÑÏéüß^Ãx:šø\²Jù̖Kúцžtò€®…—#$µ1¨e%±¤'á +­FM˜ÉltÆaædùõË tµQ˜ÂrŸ¾Þþ=¼F7ü‹-¬ )A+¹DSœ&AS,·™–R¯ƒ»[ëN­V +›SœÅBýÅén¨< uN‡šeÁ%‹ª’Eâë呦þ”^]™B8„JAӉéä+T¦Mü XÅ +µ +×@”Có$„Û`>üàœ)–µ£>8ï¤æÜB.ødíèÙ¬SXKدÐRܪÂôGßäþ acco6Tç¥èe²¥DhÀçWBÒ|\ú + Çó…)Ĕ£Ôä«\°‡aüùâ &óØ<œN$çã7½„9‡õ[¯3ö¢„Óh4k|F1,¥H*©Í|©µD¡§Á§]†þ¢~g/Ú`+LЬ`þåÈS†_o‡×¿'à ³BґÍu-SÞ"{ŠŒ÷fÀ žú¸ôðЁ…ªj3¾w¦ÆÅ)¯Pm™%žˆZjms‘r¢¦š´Ý/Îûq2!-2«¹¡3QKBÖ4TÛÉïmG N.·À“ÝÒ«Ü)´¼9<äšÅIt5‰¢Åéq8wž/áÉåkbQfßTgþ$ìmVíªÚq»D¢„PÁ‡ŽyEÝÕ³ ˜¿’%¢b™ÇnMJ´!!€GöܟäBf»ƒ—ÑãDÝ}ý¸«„ ¼dPэ|Ú5€?Ċuoÿ ËÓÀgýè)á#Û½‰gµJüÒõ³ÅÉñáý~¯ãN›TüOýã#œ2êR=›_|uöéµN¯NÕ咶ðo-©kê”J¶^ðü }køÔ¬Ê ÈÎ.>ÞÐ$UA͸M…Z´º<Þ¿¡‰\‘x ­¼š%ù‘&þäkˆ4Œ£ēîíȃ&Af{’—­+¾y1}•dÇ»?§ÜÿµÖú˜¤Ñäl"hO^Ð6:£ U#öÞËÓBP Mø~u0 ›"ìs¾±$ö²It dی{1j¼A½f°e)žŸ¶æ»ÒÜ^c ѽPB%¼$4Ö°±tÁIó‚Å** í…PÝëq¥Õ«†Vä;aß SQøÚî˜da éñi*ÌÙ'Ð5Äé\ñH7Ð3ø:™÷¥í@Û®=‡²öÓ\DÕjY½­xqB0ìðaPVFlÂÐCuĒCÁ ³x×Ì"¾àÙÍ.ÏC!ü•7Ͼ š›Û[vëáÅ$bãɌ_NÏyS¢7|?ü2ïýÕût£fendstream +endobj +326 0 obj +1135 +endobj +327 0 obj<>>>>>endobj +328 0 obj<>stream +xÚ½VßoâF~ç¯ñd¤³c$RÚª½ËjªPéü²à1Þ«½ëó®C8õïÌ®}€E’S«V!x~|ó}3;ë/£búK`9…ÙvÕè§Íèæ×9$ lr²,VKØdÁ8Oƒçt?ÀódóÙy¬Øa¶Š(=Ò ‰ãøf/ªJ¤“Þɧ™/£Bç6޼é’9›ÂÕûháô6š³ù}4–P´i •Å=6i&«øŽþÓÉ0qL‘®¾M.JXÛÈmkL;™K4 `§KÝ8{£­°R+8¨ nCª=ÈJìrY¢‰€se˜‹¶´ð$JŠ’âAÝñeÍ+ø¬·áV–%§K‹Ï6 Ö?~:Õ¼֜?ÿñð i#T…ÜÄö +ÅÇáºÎQN\ëF?ÉÌQeà®j«A£wRËAڂÌ9iÑç¨Û¦Ö†X¿ÊîÖáºÌ–+‰àŸx<è&ƒ¿@‰ +ÿ+ªg×;Ë`e…Ü+Y&]w‰º¥Æš *ïn¼¯šk6â9™Ñ ²iëZ7Ö8/¤»t$\ãïÖë±ãá¿ß=>ŽÉ.lWÙñ².7šýO%©˜Du»Ö(lØ/ >¬7tàæRÔ@i{)\@)]¥Þ‰Òã|Պ5ñ…÷Šj A7\³ÛµMƒÊÊbßwÎÎSCA ß ~ªxÔ2q|}v’ØuÒˆ¤*m ƒ–õ<Ö8ƒÿgŠ:ìkD*{аJa㗀o§hЯn‹Ô}t¸"·äçΒïnƒ›'ÌúùSH\NJ`ƐI#¶œ¼Cê·Ï ÇXÌú֞x„½ç7>QÜó¦®kU¹S:ì’FÀwôŒ,,;@??$Mw XË4¹lŒ½J›’¶†2 +ӟįmÚs`Óq§Õ7WTÙÀñK ¬%ï\©)…·Õ«×;_7Òmµ%PêmGzVÓ©è`^^nÉv·Åo¬4Çv"-­‹5¦;eäÞ-Ì^hýâ ÆS¨é¾ +·ÚZ]ß”ñÝÅ ºÊÿ<ô%:s%š=Í}jM||é=¡ûŽ_ZQzu`ÒÉ*þÒçÎðIâh$¯+òã™/»ÄÜþ#¾.ð%¶Îø/¹‚g7 ü*×UWm²œF XÌn9Âm¸ûª.±¢Yñï*4ŽtqPè}Ãå4þî·¥ùrN¯'κä¿lF¿þ\«=endstream +endobj +329 0 obj +932 +endobj +330 0 obj<>>>>>endobj +331 0 obj<>stream +xÚÍWMoÛ0 ½çW9%@íÚv؊}a°ƒ/ªMÇÚd˓ådݯ%Ù­›Öm½î04@‹ß{¤Iöç$„€þB8Y˜ORL^o&ÇoÏ |›ŒN+ú‘ÎNýȧGÛ¢§ø6×Ïx©q‹*žçŸ^}‹çñ|¾ùNÎ/ ³-ó&Ǿ'ÓZñËF#Ô&<ãXƒ&wZ0µå%Ч’¡¦@˨û?&j‚ËË$ç>˜«SÌX#4ì˜h¸½Ì ¡øá‰)îxB ò«š'L´A|‡÷†¬ù7tOè Y}Ua?ðj/Uú8SãtÏ}ΓܚL •"Z†+ƒŒ t|ꦪ¤Ò˜váj` +aʄ˜ÁwXÒ7+Ó’S™¦ÓI¬ó#|º–Õ_%×ø ¥Öœý?‰]B…åž§:M´ó"ÚA&Cp–Ä·à‰’jT¦èĦ—[x¿öÞ}<&„Ô¶jËüÉ zH7 ÁíͤÙäW$uÍ5—å¸j ™0k 3à‚ãôĘræÒ™I!äÞÐn;B¶º+Lä¶ä¿1=wؒ[´"/Z8bq´X‚3ZƒY‚”Pu›Ñ <¸°Ï-&³hj—i5î´Hn´è0ÝŒêún¤µ}©o9Dô:3}ý2X]ðQfzDĖ£ñ2!G‡³-y|<×Éÿ–#éã=gOPK1‘ª¤?'ð÷";²Ï })µ–ÅøZr~Ï ;Ní6俼 ?Nó6þòw]ÐkF¿žAUñ~çŸÒùÉepqÁZЦk‚¬ìõA;îø/¤ÙVN3݆g[~H~¢I)í{N#ŘÚË¥‚0ZÏ ”}¼Ì¤*\[¦«ÙŽqÁ.i¿xpDD &Ô4¬ð1¥G +dåúô<î_xàRßÅ_턃:—HáÝìX1:`†cŽô¥Ì‚Ó Š5rJ½0é7³$žõ ¼ÔªÁxn„1wʆ@¥©`´8QîñÊh÷ÀÁ­Ãž>"]5Ӎbí|í-QOþIÚõ9endstream +endobj +332 0 obj +937 +endobj +333 0 obj<>>>>>endobj +334 0 obj<>stream +xڝVMoã6½ûW JkIŽè!m·@€fábÝ¢]hsdq#‘*IÅ ?¾CQ²eÅñº…¦Èù|ó8ÿ'1ÌèÃ2tÛjòÓzòá×{ˆç°ÎédqG ÜFI”$`¶¬rY ¤Åê,ˆˆg³Y6ͦÓõRC{Õ0Y:Õu=f­›ÆÒN[‘ 4`ç*Q±B.J:Ú [€F'kÁ*/Š%}!‡ +¹`<À +tªˆ‹<Çi”8ßC/̶úGû` +ՔœÖÖ©~çL8‰š¾¥¨šmáþkeŒØÎN¼ â¢Bi„’&ùvysÌYSÚ.Da ‘}H¼—OÑü}œÔ j-x‡S]‹Á™ÈáÔÚ°parK—Â^³šê¶QªD&/V«=Wª}…†RQŒ(mun¼VMuÉ·úÑ곩ƒQ*Ûoæ¬4n— É\µ&J¹Ü-~µ¾þœÅÐY>¦»ìÂO“>ÝV«_ࡏ߼A&E‹N4Š SJfÍʰdr׸²fA·õ[·s°³&ÞãúAåVñŽõîÀEÝò2 ÜgïùOԎ_#¸,'ÚÙ4‚ÇüÔSK¼g©öÒÕ£‘);! 7(oÈåG¹+…)¨8$͌iªË¤rq¸¼+öÜFLU£f,¿Ñ *ïÁS1ÙälK`Ñúé¸AŸ˜§¡Ä%Fu¨œ8 \=×hlÅCÄ$ o¶Ìµ]ƒÆ8½Šq„Æ´”%Obûü‰Uxm.c›€ +™¤…âXþ”ÊWáMâàÅ%¥rž˜£û¼áFúÊœ\‡þ[ŸON»uJtþ\(mßFA$Ö®>­Uc‘}ƒÍóîWþòW˜Éíí8ËÓäOÑí3ñpÊn‚ijê4×JfišôƒÍC…¦ñ¦ô«o~¹Ò{¦ùx¬•Ìæ[Û$É +éÓµ&–¬P—:åVÝͺª[Ω[~Q›ÐˆÖ„}c&B´Ž+¯5¦ðŒ¯{¥9üŧ‡¿Ž(.Æ(fÁϬ>CL¦/ +±£sóÁ”<Ã{ø÷ç&%¥ÙÒ10ÁÕvš\„±'%ËÈh䓋¶#àý º‘J⠌Rõ^Ž3Ñ7®žyw]:ñ2!H·©O©౪K¤§„%NOÍÇÕÊ©…^:\&³ÿò›/çÑ´*É½Ûø¸žü>ùî:"ôendstream +endobj +335 0 obj +915 +endobj +336 0 obj<>>>>>endobj +337 0 obj<>stream +xÚ­—Moã6†ïùƒ½lr"R–{ËfÛE€u›,°_h‰¶¹¡DU¤ãzÑß¡h;r,ŰI`;Ö+ÎÃ_ræŸ+þû—WŸž®n›‰ài‰W’?ä×±ù¾«…§×œíéMU©Úðæ×Ds£–`vá™ï¶ªÎá?(YÁç×Ü}›ßÌonž¾ã¸ âÆõèĎ;¿¾ÿ:{â`ek±Zóú ŽZêÄo8žÖ¼›‚S‹ÅÆpÐÏÄRp Åì… É’•%¯a)$×>à@5‡­˜Ü²†Š HδUr‹€IˆóÆÀ­»[cfLJ þ¡Ä>øŽú5wúÇì…PÕ¢4¼ölž0kö/7E×|'‡ÙžÜÕ5˽œ“˜±Š-„f a4,Uݤâ Ä3É´Kä|É6ÒÀ “›·“2UT›àe­ +h(™mBˆÇ.˜ªl"Û(³Ùg—¥7a]´¥’RmE¹rh¬nDÉó_\â}¦!. ¦.Ÿ„±—É$òL~ó™ë¬• m¯üútø.åãËß_ Jý ÄÍdHú¸Ì§øC>vˆILŽjš&çUÝxâðtâÀê‚À¥(ø7p?¤ B‡÷€s;&Üeû}ÌhYÀ˜N݁ÙÀE)9A£çh5/”±¹×F”ͼć©O‡ó5ê^¾„àÕ6atBxÏJ—;\`°,{¾Ç6ÐP¸FÝ Qü¾ —öÃeJªú\h÷®ÁpºކÎ8ôÀ¡#ʬA |Æ`wgkE¶²¦…5«ó-zï9™Œ°ŽS÷’Ñ©aè99n*njcp˹ÀNÓ~qê>¶0ÛdÑ9Y®`iυLUvËžÂp’ްS÷b&ñ©mÒwAwvuJ·9Ž§#¬äÔ½ÀQrb%t¬ÖM™­>ò(a$§îE£“#Ñ´L½ØÓr%#œâÔ½hAz┨m!ð´FÐ1>iÔ}d4¶¸Ò.ÅØ0.šÒÆpê^®dÚ6.³s²5Ö'¸·< 6_½ßùŠÉÛ»èlŽ0…S÷ÂâkËô"lSxµX-úÃãŸÞýí½ÄE#ãÔ½Ü!i;&ºÈ-Y½²e)~9˜—Æ#läÔ½¼„¶m”¾Ã»ÑX_ïËÐ=¼?ø¥’Ék9u-™†GV»~ƒ³’ 7ñ¢’"{ƽÉ[qìI°Ïç7ƒŠL‚ч›Î©;káׇ4'À¾Ç‰Nº¯`ú¹³Ñù)mày¨×î|¨¹µJ¶VJÕúØýà1¾X ÙºÈ÷¾pãÍ*¤xÓ 5÷û»Ues§ë¾‘zÛÐV^¥¶EÜYÓßÌÙ9ú0Tâo‚“zß]¦ûd‰-S“(x¥ƒ\ ¼À îÐÇ¢ïa6³·yNíMh³œB·º»$‚ŸÖÝã²ûëê˜û™endstream +endobj +338 0 obj +1113 +endobj +339 0 obj<>>>>>endobj +340 0 obj<>stream +xÚÅUÁn£0½ç+F=%ÒÂÆ@ =v«¬©‡lCn¹80)^Imgûû;ÆÐ¤¢­z¨raæ½yïòQ!Ÿ¼£FåI^¡Ç˲~Á¶c¦ÑÔ{°Uº ’íd;™¤ /Æž$o;¾ß¬ÖÀ|\æPˆ§U×õºc¿áO fçÆ(±;„Rh£ê@»š³Í𮏮º SÏ2ÔÔ %¤Aµ‚¬äZûv¢g¡Xú… EB÷˜jÕ࿹WŽRœ­õ"h£BŽ{!1ÿTYØÕ¦èøúrõ3ÁËÆN¸¹{xجë Ï?§AÈ\dœœ@"qz{R}gë)T/¸õ_c|OªW5r8؋D]Ìðù`¯Üw$ë :›´Î†Aì V­ö{+îº}õÕi§tÜ%WaµkÅêÁø£Ëø­¶³é“Gä½ ò¬èBlÓiºOͺ{ì°º.mÏÔ[)¢ÍÑ¢60Y­ÈÄC-smM´8ÚÖ±Ä +¥9ÇöŽªüЋ2#ÆþЫ3t÷GΙÞ1„š?æt\~°,èæqùI;.bký˜·²XÐA‰‚Èq4ïú²:8$nD--Ürµ²cžëö’`úå?(‰ü948!³…E:ú3ú³À',endstream +endobj +341 0 obj +529 +endobj +342 0 obj<>>>>>endobj +343 0 obj<>stream +xÚ-± „wžâ˵­³F“nqëÒØ¿¦¦€-4¾¾ÍÝr_.w ‘ ’$”uöÒ£!»Ë¤3‚l¯¡QÌPœîú­}ÏhÑÅ>Nށ¡Õšša¿.û—K•¡5Ï T|Ï+XqÙ0ÄÉ=Ùpe®·Èúyö +dÀ˜&3MA5íhÞ9r%_ì·.æendstream +endobj +344 0 obj +149 +endobj +345 0 obj<>>>>>endobj +346 0 obj<>stream +xڝ•ÁrÚ0†ï<ÅÛnl ÇÄ1‰3¨cg¦WEÞ8*²D%JŸ¾kCi2S+$ƒ‡ÁÖòíþ«_럃ÎèÃ4ÑD3¸(_æ_!9ƒò‘V&Ó”Õ§s¸RÆ9nwŸË]@<Ý Gã(éB¢J´ÛGL ŽÉ4š´é~e|X¡|Ãxtø3Ó¬7-(®ë ¯1z; _s˕BÕ,PWR×`,X(ŸÛ›Š{±þ‰kRý =pºÀË&œP®1T½Ñ8Üò]«¢Ùh)¸—F;”F£‚ô[D ~k`mMmyãBéZÉ?¤îšœ+ô!UTn§JSùÆ®zÔE¯-Ñå%ÑxoŠ΅5zðÅy‘æy Ž†º!h¿ +ÏuÅm©©I|®é»éÊ¡ß䞶¤¢Ó{Vô§JI ¡îoóïÀ¬Ô¾ík±s›3+Ò/¬š±âîö?Åw кy^¸s©J˵{Ėf¼Fh×lxµèç]ãV¡÷CÆÅª-ôÊòõ“‡F³ôìƒvj†öÖ¨SSÜ| ōy8Ÿgå¼ޙ‹Ždº–ɐdŒ’»̍A.c'`f;aóâî-bw"¸:šÎÁ­¹–¿»…{Á.ûÙ R~lë%Ç&ˆZæË¬ŸµÜ¨v>U’ñ K.d¿Þ<ÃA§1Úæ÷؊…3ã|!¬\ûºÑuÂ},–¡émŸ‰´Dz¡R±Šq€U§@iiúÓV‡¦Áì%6™ýï/_éãé8šÑP¦…Ѩ}•ƒoƒ?g9endstream +endobj +347 0 obj +602 +endobj +348 0 obj<>>>>>endobj +349 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS047Ò3S072PIÑp VðÌ-ÈIÍMÍ+I,ÉÌÏSÈOSð Ð Éâ҅¨Õ…*66 šë)€Üsò‹‹‹*A®!\\‘endstream +endobj +350 0 obj +113 +endobj +351 0 obj<>>>/Annots 65 0 R>>endobj +352 0 obj<>stream +xÚ͛ÏrÛHÆï~ +wVˆþGò8›l¦¼—xcÏ8=ã-ËöØÊlíÛow`£%™R%YI•£š?›Á`³ýç4mü MgšÛåÙ?®Ï>|Ó6×w ø¡ k®¿ÿíúæÛÃØ<Ý5ŸWããêõï×ÿ9ûçõY»h#!}ôåë¯iÐë}³lú…¡ÏÍUb¯Mù½ùðÙ7黥ÃBœ¿4oâ rÙä*>F‰ruûô<&ñÿcqòàÍóŽ'2fâ‰{³ð4 ÿðّŒñ:cc$鸘QR@–ñXHZJ$Å uñ=^õû»ûۛÕýÓc‚ú.qBºjÚµÃÂMÚåhR څCŌ¦qú. +Sq0̤«ÿ½®ÆåL"—ã£ü¦‘S9Ǚöå¯ñå¯ûñ¿ ç`1œ„ðŠâ~QMREq?tqœ·Šấ6ås¢8¡>=ÝþXÆ4}›'è\T·ò"V²›øï,;ÌÚ®Ãd»øyr‡b²¾kÑͼÉ2Ì1+ZŽ2åëx7¾Œ·c®nXt'îµVIZŠÅâ`›Åzß¡/Õb™Ø›¨XE¤0‘>þvy5sIÊÑ1q}›.ŠdQœX|'LfÂû^Mug‹9ã@XE¾M³Öš93§o£«T +éËêñeFìrxòæäÁŒâc±ù0'qØy«€.~%«ÈŸ·Yä[Ü*FA(o“Â’…Ñ~ÃH݉H4÷Ç+ ÛZtǜVy°Õ&Z‡6iu› b— $R˜H——o“ÄÁËfÈÕM’(L¤ß¾^ä”ÍMßÉ]帡->ƒânôA«:s²V +ÃÎį̂ÔC¸šEqbÍ^BytjQRE­X<`_žÇ—lóh?]t¦w½–~Öw\p¹õJրŸ·øŽ Û/7ï< ©©h%J­P¾¬'í>’ùÐos~æÁ6ëq%T‡yC§V< +gÎåËýãêü_OßÞ¦ @J\³Ž£x}M¨³vï~IÞV½3IuÛ¡©¦Å°©ÆT³=ZjT{Noq0*äjÅ ¶ƒä’‰]·þÃñ„ž»õ?Œ¯«Ä³ö}ž"5ËƇRäÐÙx4½¤³Ñt&I Q'Øî:3±w鯐Dž@ȯãësô›‘²Ž.t¯x@é·q ª'll^=‰­O§/A'ÔǗñf5*" V¾5$O fí!ö½ _?ŸØvès±Ê¹‡ƒ’Øv¨â-Œj LÂÞ BQœ`;‰. )³}üö’'S:ˆ{‡@Måxí¤r•ûÀkæÁ:{ ¢xØSaiõ®ò„MçhžÓüoØÊcŠoØÎpԖô˜&ªô u5fg>ÿeµz¹ÿöc5¾Î âG„,q…Ž +yÝ=ŽßJ*û¾TBˆTÎËr¨µnDJ’˜Eq‚í¥¶€-cڔÃÍ.‰Å8Ž 5´ŠºÎç2ƒäP×®€V· +"ÑùJÅ öêژ.þ[¡y±×lãàÏȋFaMYûǁ0 +k¹Ú9Í(ˆ“–êÛDqB¥çóó_£ÂŸÆ»›sï*]µ~'îºMyå +@IcD½Ë‘Ʀ%•u‹ N’ÃÖ Œ#j•(%°Mö ±4¹uWqøWª¬­/O{8²¶ëœÓ݁HtºEq‚í--M·{æ ú*o8tƒòZÐ â%6Š5˜Ár]óŠ50¢-ÚDq[–î²²ùAo|™m! ++]³aÌìÚâ>èÙÌ|›n(%%‰Mßr‰óª;0) âkƶÔ‚• ÂO?ñ”Åy£ë¥‹Ãwªº!”ç9uCÇΫÁ$:a‰¢x·VãvV—ÈÆB4ՊÌ:~¬‡v`P^oË'„ExÊÛ QRÁ‡Cñ’³¿|ÿΪÎwP°¹s¨°<ÁBç`•üµC)q8ùëZ.qAw"aÙ©PgØJ w˜&¸vs]ó(ýƒ&® åÙ B\Óq º9‰NX¢(.¶ì%.±¨À<¡[„÷è”7Ä^sÇe­Óì8àÓÒ +Dq'ŠÚ§ña\;ˆ+hiµ§[gó·mŽº}fFiÌâ¶%.D·À%®Ó-‚HßU(Šƒ(q;k-h)‘S[P±yl®]܏5q¡ïʓЏñdi5ƒ`žk¢xÿ“Â2Ù䛾"ó„~KïpÈWyš7@'¶eà xtŽ‹Z¯xs° W Š»µ§¶7¯¯ó«“ÅÍCæ nûúä±Û‡ ¤ohK…ÁHß\ázÕ˜„U§BQ֞ãt­ŠÛ‡ +Ì`smò(íƒ&®ëʓ„¸®ç×ëî@$:a‰¢x¿öä¶«¸Æö¡ó„~ëÒäÁÛeûXWV&q ,ÂòΓŠYqÀvqn¢¸%-5fYÙ](]0XÇò¿}eòèïâ@y•D…3PW8Ã:ëAèÓ"m¢ø~: LÌ_H]nå =ƒ?Êë8UÖVìDÁµv¢ º9‰N¸]߉2Áö”–°Æ¤·Âò„~ëÊäá3”}nðð=.Ö0”­'íŒ5ô…’:}Sa|?ad?¦©Z8øDQC)ì·®Hõ2(o4{Þ,’’ ‡ªªõӞhçAŒbøŠDa³ù䦉\P©¨™è´ÃfÛZäÓVS5Ð֍|æ¡ÞW¦m%ÐÎف8˜U•$ +›Ïh;©JÜ´€j.†‡-k‡l`Ð~W{þ,~= ø”D=À‹›ÛÛñ9¿ž5€ ’®Ž_#R8l[N8ê¾J-SíÌÈÙä ÞB9íÐï&eד$ +Y·v’¸p¹j,†Íæj£9ø.JMUC›;ò™›z›ˆ™v‰è÷?“òÉJ…‡EøU kò¾Ô +‹áaË2#vϤÉÛÊÜN¿ÜÓêó¼< âÅVs±|~§_«J¿ }qy™³LsÞá«ì{Rãßgÿ¬Ë‚endstream +endobj +353 0 obj +2333 +endobj +354 0 obj<>>>/Annots 112 0 R>>endobj +355 0 obj<>stream +xÚ͜Ks·Çïü{¤»0xÌèf[‘Ë©r…‘˜ªxY’Cj¥}™;´âª|øàÑ 4fE€Œ³ÃH2å6z~;ó¦»ñXÿvÆgÌþæ³F»?7›³/ÏÞ~èf‚Í.ïf\u3mäìòöüry½îg»»ÙO»íÐo‡Ã›Ë/g¹þl9 6ӍZ´³ÍLµÑXÏ>9ú肇ûÙÛrƹû<{ Ú^Þº” .fO~ánf\¶‹&ÿÕ&ÒOÿ¸ø4ÿØéo†ù_wׇ§©d±cÑÈÛ÷ËaµÛ:¢ä cµ´ÿy1Í/Áž|#œa„·Û$2(Ӛ¬Eq%Æ$ä%ýÙKúûê¦/\r¥ÇX됸y\hj¸P½ö~Rn ½RÆÜ&ŸæƒdCIrÛó¤&,7z}ÎÈà GÑáÄB QѶa!s„g÷ÑÖ>ŠˆÚÖ#ÂÂãR:p’à^¢-EÓº¨›‘ÁÈYl`§ÇqCpàÆçŠð‚{ƒŽ1WÕB`¸­ƒFx›)zqñ¾8«à”ت1Ñ: ò5c³Æ.khVó»LƬ¦žf%ir:Èŋ”& W.02,8HLj“/nSWvŒL؂•Ä•¶ÐÔQÜj`ˆ0ÿÈ ø(¿=G\ĆZ,ǂÇÙÚtQ¡¢® ÒŸ+üûŒ¤icFӕ؀ ÷^ëœdcC$yYÝýÞ»YZ9:èÄ´Ž˜èØñl¢›:BÔ±–$»‹ b­bvÓõaV–.‡¡ƒ"ÙíjÄÜØ  +S[ŠòÄ3â ¯¬È«8™®‹È«’¸õ¨ðÈ…ÿ…´ «99Žj†¦;ý(.èÊ܍ +éÃZëÛÿ;ÜôÛ +'“ +¡­P=$€4ÚF½ŒZòÃ0<¬®‡Þ¯¥J3ñ‹üRU%¼r«pí(!Yߕ\„8V¬Äö‰v™†¡H¡ž-tIºÞö†iдQ¯¸e×ø>*4]ëZ禃‘‚BÓu!˜YÉK¢“‹ÝœXQа[¯úüf½<gĊB­Ô&‡¢P¯Î‡?ö})tDˆ2£»D~íÿø¶{¸½z‹š§^ªö”/ÿ±§¼AzªÕØO¢ÖOÀqK<A»&½´ÚÞíÊË<»n|kè ¡‹ú Wç\˜«7 «žò-©Jl¸¯ÿƒÞ [—Enj"Iؙ8ËQÐ0y³üÚϗÛÛùfwÛ¯Ÿ†Sž¥k·x‘Ñ­C‚Ops’zºª¬­uTÖDYÕ-âð•5eÄ¥[ËPÐ0PöñaU*¡Ä"µ«}2$:óêÜₐÜy½J|¯åÓFª”Oƒ‘¦+Ô˜EE%‹"ǰ1šT¬íÈÅV`î¦Ï +ÚuÙoöëåPHÉábX;¢ƒþnR§ßü{ºßtåiIÅÞ ïˆß· ýVOÅ@âҕ, +Úv½^Þ|ݯwÅ=«ÄpyØíûeDth0_ïvë~¹‰³™ZñªÐ¼#™ÔDhÁPæj&—n4…ö€º~Xݶ}±Ú!—5T¼Í¨²wÄ«óÕvèïû‡«söN0†Áݰ)¤®ÊËÉ¢LåY”iÌ¢¢žEÄ›#´ìf·~ÜlKú6Ïï¯dnBO‰W™W;̄AS“û-‹™y¡j$.\žËP¡aw«¡ß Á•@­ýìŒ<Žï¯SUµÖ:eÓ`­µIÙT×´oüø£(hØýr³Y–bPºÞÅx·@ÑÐÁ`&%1ˆ3–â¼í‹ifMU‘U“2i0ˆÈ*gS“8œ»J.A»G}~,V†éZ+/ã[B9wÎ[öÎþÕUia* +7]J¦Á +K–’i[ÓHî$¢ÊQ¡a_v×óëÕz½Úޗ<ªÈÌmàdLp@(NEýáŸ1›ªéJêÌB“T*tžJ…I©´«É $®•ö +Úædþ¼[ßηê0å§ 6ܾY†EƒYV®J« ªM•#ѐÿ.¡ÒÅet3¢‚ ¶ËMŸ‚î]SUûšÓ*Á"ÍeJÜնB"Ì/te0tžëïÃç¾µõ´Èl}Àʘà 1óC?ìîÊ{+2wé.'‚]E֔º;6>¼v9WŠá€n>ŸÁ€¥¡H.ÞøÙS3F@ EÍþì>]uè1z€'Xdè1NæøÕ-ÎãîuË`è¼u¹jO—‡³®jþ܅v‚pU»:º;p ©Ú_£”¬õo Ù7 Vê3ÞÆÌ«û¦¥]헡ÐÁÓöËû~~½†Ý¦”ľ9Ò½w9Ú£%2æm¥ÂR²ª­¡‡‚‚E´52•7¥ÓÚôr\Î`è<¯ïº¿j+Ètà ¯¨ï3UÖôtP°ˆÊš§ê¦tò•^^›ÃÐx^e¿öUNxmdŠæèсcqó„Ìí© ‰¶"²4¤ªY¶¤ªPU‘&å†Àó"Û ¼´HˆFś%K‹„XïáJ +st‹F%\¶ÚtÓ, U;«¡G‚E:«Q$ëjg!LêˆÎ; y¾³†Ý¾vÒí ájçœ(uâ=ù6œ^äªÂ‚ž6 +QX$}MU_DIw +(C¡CP·ß~[ÝŸKê&BPWŽxàPQw‚Õ—ª¾ÌÐÌé-¢/kIæl« +#̟¶Ì`è¼ýî°rGËûE*ÛÿɉàÐÆ…Z¸Iˆ°l6¾Ep`~nƒM´b_ë¯N’ÜÉ,wŠ$à®ÖYH⮲ $hؾ\óNjÝnˆKž)4«£œËG¥Í„›©5[NÒo˳ìۊ”|EuJ$åþ¦$hØþ¡ìÐ}°â”ê›qB»}ŠŒšÅSKë“nÖÖ-ə:?)¦»”1Eý+Á@ò5%A3ÀËá1œX.¯CJ +(#†æî;ù’ì›ên’õôšÀJÑïSæ¼TŒ¢þÍà4zÄÁ¯zqo–•Þt¹SÖmMd¬Ð¬¿»SCÄd‡ EW9ýÌIº”ùÉ.)R²Õi&’„Al~ô`ß–¥:/]í–ÜøËPÂDÐQTxí¶®|èH„#Tþdh³/VŠxº«©œ8ˆñ+’sqñ¾pÜ(^2dÎ ­ÝwQÿ×MR§gcñÿvÑÂihå¾:©;òµþÙ/›ýºßôÛ!ÄËÝÝ엋 ǙsãV†æ&Y­@»¿ŸýRMç`endstream +endobj +356 0 obj +2841 +endobj +357 0 obj<>>>/Annots 130 0 R>>endobj +358 0 obj<>stream +xÚ͙MoÛF†ïþ{t¢¹_ü8ºAh·Q€t‘#ÚU,JŠH!5ÐߝÝrV±¹Ic»M%‹}H¾3;3K~>“"w¥(•Ð…øØžý4?»xS •‹ù¶EiÄ|u>_^o±»¯wÛ¾ÙöÝ«ù§³Ÿçgy–;üHøùý­Ce¹(´Í*ъºpÿ„ÁF¼úɂí¸xc„”p=w…†î‚6ә^…[!ë*+ãËà<ÂöûÕl»ì‡åf¶YnoËÛæq6ǵB•uVÇp2@úâÙ¿ zñ +Ønvâ:ƒìiþ¨:!ºRY1ˆîxà ¬ÒnŒÂª”°H’¦¸‘°aÛåݔ˜ žÒ :ƒ‘·8úŹTåâUÑ­/ŸTÆU9¯33¨ìLe™g†TÖ)•‘¤ryŠ +ó#•gË­ûÏnÕl's˜C›:³1 ˆýâÖü3)žR׺'W¤nŒêÚºtcT×$Ô%RÀ…ó É¡MÆ0AÀ ÄðÀƒtÐ6‹se-)jí‹Eð„ÀÚ?E¥Ýo+¬rø®Ø +ƒwB\¶°•uÏQpÚs®kW,³Ørç(UŸÂpÞÃ.ûþ°¾>ö/=Fº„ñ‚Yá_ÇsQ…0 X<—9;“,vD’Ä~„ +óû´»žu6MßÍVÍÍò¸é'"›Á\dKȵ ˆíòD×ô® x<ÿ0äírIDD"ö÷ûf"Qr€Ã¹€'¸`@¸»æþË2„ÖùWÀ`@À¿'Plq+´Í]Hƨ`@¨~½ücH –¿?ˆ“1g‹±s¶¤>À$û"IŸì"Î#ŒÅ\wÜïw‡¾YM5X#Îù@AŠàdPRWŒ:ÆpDëCŒɉ©¨c’jP•ph€¸tÔ1„ •\AÌFÀš©9s|©~wr ꫘+òïíJuž7£Ç†( X¸C ‘I6DD’Ö Ü(ܶ…enœ3†¼iNïό̅ +5•+ »G%½Î ØlmÐ\AgðÅ*é*³îʘ«´¤îʤ»+$a}à(œGw•kb»»d1B²’0™ $5Z qÔ"uz«d€@æ±êùü•t’,}?tôæ$94 6å"ä(“C¤rÎ{Ô¡ù|lº~½½;ç(ȳåf³û2•Â9ÎÈPK¢KÁ·¶ Œàò𲐭#°Jʎ,®öþP‹­eÂ'¹fmœ0Ÿäfl㊔W¤4tÙ +çö _VÍv=éFu×(à=Et 20ßÜÏ18&Ô "˜ìy\3é¤1uî«¡?z„Áx¤1µ¤~Ç&5Äñ§ŽˆƒÓHú¶c Ѥ„óv„ÃyĽÞ,»n"+²õPí) wrNR™ýïÎI©meÊrlÂ`ÜV¦¬¨u°ÉÓ‘doë"Î#¬mÚkÜMS¢3 œøá•Y%ƒŠš‡ä>b èP!GD2@âCûH>'“^*ÌØ5„óRa©k°É󑤭\ݍP80ôÒñ°žr£ÀE‚¤œI–ú…”“8Üh€DwÁ9ò¥6ل¯ 3]†—¹ËÉa€w~ñÆâ[v°ªB²¾œb$øÌªcN#çíf×uËÃ=Ðtý\qú„*êDEQ&T›ÜécÔצ„œ;•ŸÄÕ=à©¶„i$͛CÛᙡú?ʘ”ÎU#3Hç¬K²ÛåTª`K!’áíIÂyB}<ì¶÷A4cžø“ËÉ5>c>|ôªè£|(Ð9ž×_¸z/ÞµûMÓ6Û~Ù¯w[øêöîêÊï-g&ŬTþ×ë5jøÛÙ?ÅÍ«endstream +endobj +359 0 obj +1416 +endobj +360 0 obj<>>>>>endobj +361 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS047Ò3S072PIÑp VðÌ-ÈIÍMÍ+I,ÉÌÏSÈOSð Ð Éâ҅¨Õ…*Î, º†prÁîendstream +endobj +362 0 obj +94 +endobj +363 0 obj<>endobj +364 0 obj<>endobj +365 0 obj<>endobj +366 0 obj<>endobj +367 0 obj<>endobj +368 0 obj<>endobj +369 0 obj<>endobj +370 0 obj<>endobj +371 0 obj<>endobj +372 0 obj<>endobj +373 0 obj<>endobj +374 0 obj<>endobj +375 0 obj<>endobj +376 0 obj<>endobj +377 0 obj<>endobj +378 0 obj<>endobj +379 0 obj<>endobj +380 0 obj<>endobj +381 0 obj<>endobj +382 0 obj<>endobj +383 0 obj<>endobj +384 0 obj<>endobj +385 0 obj<>endobj +386 0 obj<>endobj +387 0 obj<>endobj +388 0 obj<>endobj +389 0 obj<>endobj +390 0 obj<>endobj +391 0 obj<>endobj +392 0 obj<>endobj +393 0 obj<>endobj +394 0 obj<>endobj +395 0 obj<>endobj +396 0 obj<>endobj +397 0 obj<>endobj +398 0 obj<>endobj +399 0 obj<>endobj +400 0 obj<>endobj +401 0 obj<>endobj +402 0 obj<>endobj +403 0 obj<>endobj +404 0 obj<>endobj +405 0 obj<>endobj +406 0 obj<>endobj +407 0 obj<>endobj +408 0 obj<>endobj +409 0 obj<>endobj +410 0 obj<>endobj +411 0 obj<>endobj +412 0 obj<>endobj +413 0 obj<>endobj +414 0 obj<>endobj +415 0 obj<>endobj +416 0 obj<>endobj +417 0 obj<>endobj +418 0 obj<>endobj +419 0 obj<>endobj +420 0 obj<>endobj +421 0 obj<>endobj +422 0 obj<>endobj +423 0 obj<>endobj +424 0 obj<>endobj +425 0 obj<>endobj +426 0 obj<>endobj +427 0 obj<>endobj +428 0 obj<>endobj +429 0 obj<>endobj +430 0 obj<>endobj +431 0 obj<>endobj +432 0 obj<>endobj +433 0 obj<>endobj +434 0 obj<>endobj +435 0 obj<>endobj +436 0 obj<>endobj +437 0 obj<>endobj +438 0 obj<>endobj +439 0 obj<>endobj +440 0 obj<>endobj +441 0 obj<>endobj +442 0 obj<>endobj +443 0 obj<>endobj +444 0 obj<>endobj +445 0 obj<>endobj +446 0 obj<>endobj +447 0 obj<>endobj +448 0 obj<>endobj +449 0 obj<>endobj +450 0 obj<>endobj +451 0 obj<>endobj +452 0 obj<>endobj +453 0 obj<>endobj +454 0 obj<>endobj +455 0 obj<>endobj +456 0 obj<>endobj +457 0 obj<>endobj +458 0 obj<>endobj +459 0 obj<>endobj +460 0 obj<>endobj +461 0 obj<>endobj +462 0 obj<>endobj +463 0 obj<>endobj +464 0 obj<>endobj +465 0 obj<>endobj +466 0 obj<>endobj +467 0 obj<>endobj +468 0 obj<>endobj +469 0 obj<>endobj +470 0 obj<>endobj +471 0 obj<>endobj +472 0 obj<>1<>2<>6<>]>>>>endobj +xref +0 473 +0000000000 65535 f +0000000015 00000 n +0000000219 00000 n +0000001785 00000 n +0000001859 00000 n +0000001937 00000 n +0000002014 00000 n +0000002093 00000 n +0000002169 00000 n +0000002250 00000 n +0000002308 00000 n +0000002360 00000 n +0000002445 00000 n +0000002497 00000 n +0000002581 00000 n +0000002686 00000 n +0000002791 00000 n +0000002896 00000 n +0000003001 00000 n +0000003106 00000 n +0000003211 00000 n +0000003284 00000 n +0000003388 00000 n +0000003493 00000 n +0000003598 00000 n +0000003703 00000 n +0000003807 00000 n +0000003912 00000 n +0000004017 00000 n +0000004121 00000 n +0000004226 00000 n +0000004331 00000 n +0000004435 00000 n +0000004540 00000 n +0000004645 00000 n +0000004750 00000 n +0000004855 00000 n +0000004960 00000 n +0000005065 00000 n +0000005170 00000 n +0000005275 00000 n +0000005380 00000 n +0000005485 00000 n +0000005590 00000 n +0000005695 00000 n +0000005800 00000 n +0000005905 00000 n +0000006010 00000 n +0000006115 00000 n +0000006220 00000 n +0000006325 00000 n +0000006430 00000 n +0000006535 00000 n +0000006640 00000 n +0000006745 00000 n +0000006850 00000 n +0000006955 00000 n +0000007060 00000 n +0000007165 00000 n +0000007270 00000 n +0000007375 00000 n +0000007480 00000 n +0000007585 00000 n +0000007689 00000 n +0000007792 00000 n +0000007895 00000 n +0000008220 00000 n +0000008324 00000 n +0000008429 00000 n +0000008534 00000 n +0000008638 00000 n +0000008743 00000 n +0000008848 00000 n +0000008952 00000 n +0000009057 00000 n +0000009162 00000 n +0000009266 00000 n +0000009371 00000 n +0000009476 00000 n +0000009580 00000 n +0000009685 00000 n +0000009790 00000 n +0000009893 00000 n +0000009997 00000 n +0000010102 00000 n +0000010207 00000 n +0000010312 00000 n +0000010417 00000 n +0000010521 00000 n +0000010626 00000 n +0000010731 00000 n +0000010836 00000 n +0000010941 00000 n +0000011046 00000 n +0000011151 00000 n +0000011256 00000 n +0000011361 00000 n +0000011466 00000 n +0000011571 00000 n +0000011676 00000 n +0000011781 00000 n +0000011887 00000 n +0000011993 00000 n +0000012099 00000 n +0000012205 00000 n +0000012311 00000 n +0000012417 00000 n +0000012523 00000 n +0000012629 00000 n +0000012735 00000 n +0000012840 00000 n +0000012944 00000 n +0000013047 00000 n +0000013399 00000 n +0000013505 00000 n +0000013611 00000 n +0000013717 00000 n +0000013823 00000 n +0000013929 00000 n +0000014035 00000 n +0000014141 00000 n +0000014247 00000 n +0000014353 00000 n +0000014459 00000 n +0000014565 00000 n +0000014671 00000 n +0000014777 00000 n +0000014883 00000 n +0000014988 00000 n +0000015094 00000 n +0000015200 00000 n +0000015354 00000 n +0000015388 00000 n +0000015422 00000 n +0000016940 00000 n +0000016989 00000 n +0000017038 00000 n +0000017087 00000 n +0000017136 00000 n +0000017185 00000 n +0000017234 00000 n +0000017283 00000 n +0000017332 00000 n +0000017381 00000 n +0000017430 00000 n +0000017479 00000 n +0000017528 00000 n +0000017577 00000 n +0000017626 00000 n +0000017675 00000 n +0000017724 00000 n +0000017773 00000 n +0000017822 00000 n +0000017871 00000 n +0000017920 00000 n +0000017969 00000 n +0000018018 00000 n +0000018067 00000 n +0000018116 00000 n +0000018165 00000 n +0000018214 00000 n +0000018263 00000 n +0000018312 00000 n +0000018361 00000 n +0000018410 00000 n +0000018459 00000 n +0000018508 00000 n +0000018557 00000 n +0000018606 00000 n +0000018655 00000 n +0000018704 00000 n +0000018753 00000 n +0000018802 00000 n +0000018851 00000 n +0000018900 00000 n +0000018949 00000 n +0000018998 00000 n +0000019047 00000 n +0000019096 00000 n +0000019145 00000 n +0000019194 00000 n +0000019243 00000 n +0000019292 00000 n +0000019341 00000 n +0000019390 00000 n +0000019439 00000 n +0000019488 00000 n +0000019537 00000 n +0000019586 00000 n +0000019635 00000 n +0000019684 00000 n +0000019733 00000 n +0000019782 00000 n +0000019831 00000 n +0000019880 00000 n +0000019929 00000 n +0000019978 00000 n +0000020027 00000 n +0000020076 00000 n +0000020125 00000 n +0000020174 00000 n +0000020223 00000 n +0000020272 00000 n +0000020321 00000 n +0000020370 00000 n +0000020419 00000 n +0000020468 00000 n +0000020517 00000 n +0000020566 00000 n +0000020615 00000 n +0000020664 00000 n +0000020713 00000 n +0000020762 00000 n +0000020811 00000 n +0000020860 00000 n +0000020909 00000 n +0000020958 00000 n +0000021007 00000 n +0000021056 00000 n +0000021105 00000 n +0000021154 00000 n +0000021203 00000 n +0000021252 00000 n +0000021301 00000 n +0000021350 00000 n +0000021399 00000 n +0000021448 00000 n +0000021497 00000 n +0000021546 00000 n +0000021595 00000 n +0000021644 00000 n +0000021693 00000 n +0000021742 00000 n +0000021791 00000 n +0000021840 00000 n +0000021889 00000 n +0000021938 00000 n +0000021987 00000 n +0000022036 00000 n +0000022085 00000 n +0000022134 00000 n +0000022183 00000 n +0000022232 00000 n +0000022621 00000 n +0000022773 00000 n +0000029124 00000 n +0000029146 00000 n +0000029241 00000 n +0000029343 00000 n +0000029363 00000 n +0000029517 00000 n +0000030724 00000 n +0000030746 00000 n +0000030859 00000 n +0000031038 00000 n +0000031059 00000 n +0000031199 00000 n +0000031982 00000 n +0000032003 00000 n +0000032116 00000 n +0000032300 00000 n +0000032321 00000 n +0000032470 00000 n +0000033698 00000 n +0000033720 00000 n +0000033842 00000 n +0000034876 00000 n +0000034897 00000 n +0000035046 00000 n +0000035999 00000 n +0000036020 00000 n +0000036169 00000 n +0000036901 00000 n +0000036922 00000 n +0000037071 00000 n +0000038001 00000 n +0000038022 00000 n +0000038171 00000 n +0000039076 00000 n +0000039097 00000 n +0000039228 00000 n +0000039955 00000 n +0000039976 00000 n +0000040116 00000 n +0000040953 00000 n +0000040974 00000 n +0000041114 00000 n +0000041912 00000 n +0000041933 00000 n +0000042064 00000 n +0000042964 00000 n +0000042985 00000 n +0000043116 00000 n +0000043728 00000 n +0000043749 00000 n +0000043889 00000 n +0000044669 00000 n +0000044690 00000 n +0000044821 00000 n +0000045645 00000 n +0000045666 00000 n +0000045806 00000 n +0000046650 00000 n +0000046671 00000 n +0000046802 00000 n +0000047467 00000 n +0000047488 00000 n +0000047619 00000 n +0000048340 00000 n +0000048361 00000 n +0000048492 00000 n +0000049174 00000 n +0000049195 00000 n +0000049326 00000 n +0000050177 00000 n +0000050198 00000 n +0000050329 00000 n +0000051174 00000 n +0000051195 00000 n +0000051335 00000 n +0000051950 00000 n +0000051971 00000 n +0000052111 00000 n +0000053274 00000 n +0000053296 00000 n +0000053427 00000 n +0000054633 00000 n +0000054655 00000 n +0000054795 00000 n +0000055798 00000 n +0000055819 00000 n +0000055968 00000 n +0000056976 00000 n +0000056997 00000 n +0000057137 00000 n +0000058123 00000 n +0000058144 00000 n +0000058293 00000 n +0000059477 00000 n +0000059499 00000 n +0000059639 00000 n +0000060239 00000 n +0000060260 00000 n +0000060373 00000 n +0000060593 00000 n +0000060614 00000 n +0000060754 00000 n +0000061427 00000 n +0000061448 00000 n +0000061561 00000 n +0000061745 00000 n +0000061766 00000 n +0000061920 00000 n +0000064324 00000 n +0000064346 00000 n +0000064501 00000 n +0000067413 00000 n +0000067435 00000 n +0000067590 00000 n +0000069077 00000 n +0000069099 00000 n +0000069212 00000 n +0000069377 00000 n +0000069397 00000 n +0000069452 00000 n +0000069557 00000 n +0000069701 00000 n +0000069807 00000 n +0000069927 00000 n +0000070036 00000 n +0000070185 00000 n +0000070295 00000 n +0000070402 00000 n +0000070549 00000 n +0000070649 00000 n +0000070760 00000 n +0000070910 00000 n +0000071057 00000 n +0000071168 00000 n +0000071280 00000 n +0000071441 00000 n +0000071553 00000 n +0000071666 00000 n +0000071835 00000 n +0000071955 00000 n +0000072076 00000 n +0000072243 00000 n +0000072361 00000 n +0000072480 00000 n +0000072648 00000 n +0000072767 00000 n +0000072887 00000 n +0000073054 00000 n +0000073172 00000 n +0000073291 00000 n +0000073461 00000 n +0000073582 00000 n +0000073704 00000 n +0000073871 00000 n +0000073989 00000 n +0000074108 00000 n +0000074273 00000 n +0000074389 00000 n +0000074506 00000 n +0000074675 00000 n +0000074795 00000 n +0000074916 00000 n +0000075084 00000 n +0000075203 00000 n +0000075323 00000 n +0000075491 00000 n +0000075610 00000 n +0000075730 00000 n +0000075898 00000 n +0000076017 00000 n +0000076137 00000 n +0000076305 00000 n +0000076424 00000 n +0000076544 00000 n +0000076709 00000 n +0000076825 00000 n +0000076942 00000 n +0000077094 00000 n +0000077210 00000 n +0000077327 00000 n +0000077476 00000 n +0000077621 00000 n +0000077745 00000 n +0000077879 00000 n +0000078023 00000 n +0000078135 00000 n +0000078300 00000 n +0000078415 00000 n +0000078553 00000 n +0000078686 00000 n +0000078811 00000 n +0000078937 00000 n +0000079072 00000 n +0000079206 00000 n +0000079340 00000 n +0000079487 00000 n +0000079644 00000 n +0000079770 00000 n +0000079910 00000 n +0000080048 00000 n +0000080187 00000 n +0000080321 00000 n +0000080458 00000 n +0000080595 00000 n +0000080729 00000 n +0000080861 00000 n +0000080992 00000 n +0000081131 00000 n +0000081268 00000 n +0000081379 00000 n +0000081534 00000 n +0000081668 00000 n +0000081799 00000 n +0000081940 00000 n +0000082058 00000 n +0000082217 00000 n +0000082368 00000 n +0000082534 00000 n +0000082668 00000 n +0000082807 00000 n +0000082965 00000 n +0000083109 00000 n +0000083261 00000 n +0000083390 00000 n +0000083510 00000 n +0000083644 00000 n +0000083741 00000 n +0000083841 00000 n +trailer +<]>> +startxref +84069 +%%EOF diff --git a/doc/ipp.shtml b/doc/ipp.shtml new file mode 100644 index 0000000000..0015e65180 --- /dev/null +++ b/doc/ipp.shtml @@ -0,0 +1,1891 @@ + + + + + + CUPS Implementation of IPP + + + +

Scope

+ +

Identification

+ +

This document provides an overview of the Internet Printing Protocol +("IPP") version 1.1 as implemented in the Common UNIX Printing System +("CUPS") version 1.1. + + + +

Document Overview

+ +

This document is organized into the following sections: + +

+ + + +

Overview

+ +

CUPS 1.1 implements IPP/1.1 and the operations and attributes +defined in the "IPP: Job and Printer Set Operations", +"IPP/1.1: Output-bin Attribute Extension", and "IPP/1.1: finishings +'fold',' trim', and 'bale' attribute values extension" specifications. + +

CUPS also provides 13 new operations and many new attributes to +support multiple IPP printers and printer classes on a single host. + +

IPP URIs

+ +

CUPS supports both the "http" and "ipp" methods. The following +resource names are used: + +

+ +
method://hostname:port/ + +
Can be used for all "get" operations. + +
method://hostname:port/admin + +
Used for all administrative operations. + +
method://hostname:port/classes/name + +
Specifies a printer class. + +
method://hostname:port/jobs/id + +
Specifies a job. + +
method://hostname:port/printers/name + +
Specifies a printer. + +
+ +

So a typical printer URI would be "ipp://foo.bar.com/printers/LaserJet". + +

In addition, the CUPS server also supports normal browser access to +"method://hostname:port/admin/", "method://hostname:port/classes/", +"method://hostname:port/jobs/", and "method://hostname:port/printers/" +to view and manage resources on the server dynamically. + +

CUPS IPP Operations

+ +

CUPS provides 13 extension operations in addition to most of the +standard IPP and registered extension operations: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Operation NameCUPSCodeBrief Description
Print-Job1.00x0002Print a file.
Validate-Job1.00x0004Validate job attributes.
Create-Job1.10x0005Create a print job.
Send-Document1.10x0006Send a file for a print job.
Cancel-Job1.00x0008Cancel a print job.
Get-Job-Attributes1.00x0009Get job attributes.
Get-Jobs1.00x000AGet all jobs.
Get-Printer-Attributes1.00x000BGet printer attributes.
Hold-Job1.10x000CHold a job for printing.
Release-Job1.10x000DRelease a job for printing.
Pause-Printer1.00x0010Pause printing on a printer.
Resume-Printer1.00x0011Resume printing on a printer.
Purge-Jobs1.00x0012Purge all jobs.
Set-Job-Attributes1.10x0014Set attributes for a pending or held job.
CUPS-Get-Default1.00x4001Get the default destination.
CUPS-Get-Printers1.00x4002Get all of the available printers.
CUPS-Add-Printer1.00x4003Add or modify a printer.
CUPS-Delete-Printer1.00x4004Delete a printer.
CUPS-Get-Classes1.00x4005Get all of the available printer classes.
CUPS-Add-Class1.00x4006Add or modify a printer class.
CUPS-Delete-Class1.00x4007Delete a printer class.
CUPS-Accept-Jobs1.00x4008Accept jobs on a printer or printer class.
CUPS-Reject-Jobs1.00x4009Reject jobs on a printer or printer class.
CUPS-Set-Default1.00x400ASet the default destination.
CUPS-Get-Devices1.10x400BGet all of the available devices.
CUPS-Get-PPDs1.10x400CGet all of the available PPDs.
CUPS-Move-Job1.10x400DMove a job to a different printer.
+
+ +

Operations

+ +

The following sections describe the operations supported by CUPS. +In the interest of brevity, operations which use only the standard +IPP attributes are not described. + +

Print-Job Operation

+ +

The Print-Job operation (0x0002) prints a file. + +

Print-Job Request

+ +

The following groups of attributes are supplied as part of the +Print-Job request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri): + +

    The client MUST supply a URI for the specified printer. + +

+ +

Group 2: Job Template Attributes + +

    + +

    "job-billing" (text(MAX)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies a billing string that is logged + with the page accounting information. + +

    "job-sheets" (1setof type3 keyword | name(MAX)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies one or two banner pages that + are printed before and after any files in the print job. The + name of "none" is reserved to indicate that no banner page + should be printed. If the client does not specify this + attribute then the value of the "job-sheets-default" printer + object attribute is used. + +

    Note: Standard IPP only allows specification of a single + job-sheets attribute value. + +

    "media" (1setof type3 keyword | name(MAX)): + +

    The client OPTIONALLY supplies one or more media attributes + specifying the size, type, source, and color of the output + media. If the client does not specify this attribute then the + value of the "media-default" printer object attribute is used. + +

    Note: Standard IPP only allows specification of a single + media attribute value. + +

    Other Job Template Attributes + +

+ +

The Print-Job request is followed by a file to be printed. + +

Print-Job Response

+ +

The following groups of attributes are send as part of the Print-Job +Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

Group 2: Job Attributes + +

    + +

    Standard Job Attributes + +

+ +

Create-Job Operation

+ +

The Create-Job operation (0x0005) creates a new, empty print job. + +

Create-Job Request

+ +

The following groups of attributes are supplied as part of the +Create-Job request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri): + +

    The client MUST supply a URI for the specified printer. + +

+ +

Group 2: Job Template Attributes + +

    + +

    "job-billing" (text(MAX)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies a billing string that is logged + with the page accounting information. + +

    "job-sheets" (1setof type3 keyword | name(MAX)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies one or two banner pages that + are printed before and after any files in the print job. The + name of "none" is reserved to indicate that no banner page + should be printed. If the client does not specify this + attribute then the value of the "job-sheets-default" printer + object attribute is used. + +

    Note: Standard IPP only allows specification of a single + job-sheets attribute value. + +

    "media" (1setof type3 keyword | name(MAX)): + +

    The client OPTIONALLY supplies one or more media attributes + specifying the size, type, source, and color of the output + media. If the client does not specify this attribute then the + value of the "media-default" printer object attribute is used. + +

    Note: Standard IPP only allows specification of a single + media attribute value. + +

    Standard Job Template Attributes + +

+ +

Create-Job Response

+ +

The following groups of attributes are send as part of the +Create-Job Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

Group 2: Job Attributes + +

    + +

    Standard Job Attributes + +

+ +

Set-Job-Attributes Operation

+ +

The Set-Job-Attributes operation (0x0014) changes the attributes of +an active (not completed) job. + +

Set-Job-Attributes Request

+ +

The following groups of attributes are supplied as part of the +Set-Job-Attributes request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri) and "job-id" (integer) +

    OR +

    "job-uri": + +

    The client MUST supply a URI for the specified printer and + a job ID number, or the job URI. + +

+ +

Group 2: Job Template Attributes + +

    + +

    "job-sheets" (1setof type3 keyword | name(MAX)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies one or two banner pages that + are printed before and after any files in the print job. The + name of "none" is reserved to indicate that no banner page + should be printed. If the client does not specify this + attribute then the value of the "job-sheets-default" printer + object attribute is used. + +

    Note: Standard IPP only allows specification of a single + job-sheets attribute value. + +

    "media" (1setof type3 keyword | name(MAX)): + +

    The client OPTIONALLY supplies one or more media attributes + specifying the size, type, source, and color of the output + media. If the client does not specify this attribute then the + value of the "media-default" printer object attribute is used. + +

    Note: Standard IPP only allows specification of a single + media attribute value. + +

    Other Job Template Attributes + +

+ +

Set-Job-Attributes Response

+ +

The following groups of attributes are send as part of the Set-Job-Attributes +Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

CUPS-Get-Default Operation

+ +

The CUPS-Get-Default operation (0x4001) returns the default printer +URI and attributes. + +

CUPS-Get-Default Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-Default request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "requested-attributes" (1setOf keyword) : + +

    The client OPTIONALLY supplies a set of attribute names + and/or attribute group names in whose values the requester is + interested. If the client omits this attribute, the server + responds as if this attribute had been supplied with a value of + 'all'. + +

+ +

CUPS-Get-Default Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-Default Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

Group 2: Printer Object Attributes + +

    + +

    The set of requested attributes and their current values. + +

+ +

CUPS-Get-Printers Operation

+ +

The CUPS-Get-Printers operation (0x4002) returns the printer +attributes for every printer known to the system. This may include +printers that are not served directly by the server. + +

CUPS-Get-Printers Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-Printers request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "limit" (integer (1:MAX)): + +

    The client OPTIONALLY supplies this attribute limiting the + number of printers that are returned. + +

    "printer-info" (text(127)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies this attribute to + select which printers are returned. + +

    "printer-location" (text(127)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies this attribute to + select which printers are returned. + +

    "printer-type" (type2 enum): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies a printer type enumeration to + select which printers are returned. + +

    "printer-type-mask" (type2 enum): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies a printer type mask + enumeration to select which bits are used in the "printer-type" + attribute. + +

    "requested-attributes" (1setOf keyword) : + +

    The client OPTIONALLY supplies a set of attribute names + and/or attribute group names in whose values the requester is + interested. If the client omits this attribute, the server + responds as if this attribute had been supplied with a value of + 'all'. + +

+ +

CUPS-Get-Printers Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-Printers Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

Group 2: Printer Object Attributes + +

    + +

    The set of requested attributes and their current values for + each printer. + +

+ +

CUPS-Add-Printer Operation

+ +

The CUPS-Add-Printer operation (0x4003) adds a new printer or +modifies an existing printer on the system. + +

CUPS-Add-Printer Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Add-Printer request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri): + +

    The client MUST supply a URI for the specified printer. + +

+ +

Group 2: Printer Object Attributes + +

    + +

    "banner-end-default" (name(127)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies a banner page name that is + printed after files in a job. The reserved name "none" is used to + specify that no banner page should be printed. + +

    "banner-start-default" (name(127)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies a banner page name that is + printed before files in a job. The reserved name "none" is used to + specify that no banner page should be printed. + +

    "device-uri" (uri): + +

    The client OPTIONALLY supplies a device URI for the + specified printer. + +

    "ppd-name" (name(127)): + +

    The client OPTIONALLY supplies a PPD name for the specified + printer. + +

    "printer-is-accepting-jobs" (boolean): + +

    The client OPTIONALLY supplies this boolean attribute + indicating whether or not the printer object should accept new jobs. + +

    "printer-info" (text(127)): + +

    The client OPTIONALLY supplies this attribute indicating the + printer information string. + +

    "printer-location" (text(127)): + +

    The client OPTIONALLY supplies this attribute indicating a + textual location of the printer. + +

    "printer-more-info" (uri): + +

    The client OPTIONALLY supplies this attribute indicating a + URI for additional printer information. + +

    "printer-state" (type2 enum): + +

    The client OPTIONALLY supplies this attribute indicating the + initial/current state of the printer. Only the "idle" and "stopped" + enumerations are recognized. + +

    "printer-state-message" (text(MAX)): + +

    The client OPTIONALLY supplies this attribute indicating a + textual reason for the current printer state. + +

    "requesting-user-name-allowed" (1setof name(127)) +

    OR +

    "requesting-user-name-denied" (1setof name(127)): + +

    The client OPTIONALLY supplies one of these attributes to + specify an access control list for incoming print jobs. The + special name "ALLUSERS" is reserved to indicate that all users + are allowed or denied. + +

+ +

The CUPS-Add-Printer request can optionally be followed by a PPD +file or System V interface script to be used for the printer. The +"ppd-name" attribute overrides any file that is attached to the end of +the request with a local CUPS PPD file. + +

CUPS-Add-Printer Response

+ +

The following groups of attributes are send as part of the +CUPS-Add-Printer Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

CUPS-Delete-Printer Operation

+ +

The CUPS-Delete-Printer operation (0x4004) removes an existing +printer from the system. + +

CUPS-Delete-Printer Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Delete-Printer request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri): + +

    The client MUST supply a URI for the specified printer. + +

+ +

CUPS-Delete-Printer Response

+ +

The following groups of attributes are send as part of the +CUPS-Delete-Printer Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

CUPS-Get-Classes Operation

+ +

The CUPS-Get-Classes operation (0x4005) returns the printer +attributes for every printer class known to the system. This may +include printer classes that are not served directly by the server. + +

CUPS-Get-Classes Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-Classes request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "limit" (integer (1:MAX)): + +

    The client OPTIONALLY supplies this attribute limiting the + number of printer classes that are returned. + +

    "printer-info" (text(127)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies this attribute to + select which printer classes are returned. + +

    "printer-location" (text(127)): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies this attribute to + select which printer classes are returned. + +

    "printer-type" (type2 enum): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies a printer type enumeration to + select which printer classes are returned. + +

    "printer-type-mask" (type2 enum): + +

    (CUPS 1.1 and higher) + +

    The client OPTIONALLY supplies a printer type mask + enumeration to select which bits are used in the "printer-type" + attribute. + +

    "requested-attributes" (1setOf keyword) : + +

    The client OPTIONALLY supplies a set of attribute names + and/or attribute group names in whose values the requester is + interested. If the client omits this attribute, the server responds as + if this attribute had been supplied with a value of 'all'. + +

+ +

CUPS-Get-Classes Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-Classes Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

Group 2: Printer Class Object Attributes + +

    + +

    The set of requested attributes and their current values for + each printer class. + +

+ +

CUPS-Add-Class Operation

+ +

The CUPS-Add-Class operation (0x4006) adds a new printer class or +modifies and existing printer class on the system. + +

CUPS-Add-Class Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Add-Class request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri): + +

    The client MUST supply a URI for the specified printer class. + +

+ +

Group 2: Printer Object Attributes + +

    + +

    "member-uris" (1setof uri): + +

    The client OPTIONALLY supplies the "member-uris" set + specifying the printers and printer classes that are part of the class. + +

    "printer-is-accepting-jobs" (boolean): + +

    The client OPTIONALLY supplies this boolean attribute + indicating whether or not the printer object should accept new jobs. + +

    "printer-info" (text(127)): + +

    The client OPTIONALLY supplies this attribute indicating the + printer information string. + +

    "printer-location" (text(127)): + +

    The client OPTIONALLY supplies this attribute indicating a + textual location of the printer. + +

    "printer-more-info" (uri): + +

    The client OPTIONALLY supplies this attribute indicating a + URI for additional printer information. + +

    "printer-state" (type2 enum): + +

    The client OPTIONALLY supplies this attribute indicating the + initial/current state of the printer. Only the "idle" and "stopped" + enumerations are recognized. + +

    "printer-state-message" (text(MAX)): + +

    The client OPTIONALLY supplies this attribute indicating a + textual reason for the current printer state. + +

    "requesting-user-name-allowed" (1setof name(127)) +

    OR +

    "requesting-user-name-denied" (1setof name(127)): + +

    The client OPTIONALLY supplies one of these attributes to + specify an access control list for incoming print jobs. The + special name "ALLUSERS" is reserved to indicate that all users + are allowed or denied. + +

+ +

CUPS-Add-Class Response

+ +

The following groups of attributes are send as part of the CUPS-Add-Class Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

CUPS-Delete-Class Operation

+ +

The CUPS-Delete-Class operation (0x4007) removes an existing printer +class from the system. + +

CUPS-Delete-Class Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Delete-Class request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri): + +

    The client MUST supply a URI for the specified printer class. + +

+ +

CUPS-Delete-Class Response

+ +

The following groups of attributes are send as part of the +CUPS-Delete-Class Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

CUPS-Accept-Jobs Operation

+ +

The CUPS-Accept-Jobs operation (0x4008) sets the +"printer-is-accepting-jobs" attribute to true for the specified printer +or printer class. + +

CUPS-Accept-Jobs Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Accept-Jobs request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri): + +

    The client MUST supply a URI for the specified printer or printer class. + +

+ +

CUPS-Accept-Jobs Response

+ +

The following groups of attributes are send as part of the +CUPS-Accept-Jobs Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

CUPS-Reject-Jobs Operation

+ +

The CUPS-Reject-Jobs operation (0x4009) sets +the"printer-is-accepting-jobs" attribute to false for the specified +printer or printer class. + +

CUPS-Reject-Jobs Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Reject-Jobs request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri): + +

    The client MUST supply a URI for the specified printer or printer class. + +

+ +

Group 2: Printer Object Attributes + +

    + +

    "printer-state-message" (text(MAX)): + +

    The client OPTIONALLY supplies this attribute indicating a + textual reason for the current printer state. + +

+ +

CUPS-Reject-Jobs Response

+ +

The following groups of attributes are send as part of the +CUPS-Reject-Jobs Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

CUPS-Set-Default Operation

+ +

The CUPS-Set-Default operation (0x400A) sets the default printer +destination for all clients when a resource name of "/printers" is +specified. + +

CUPS-Set-Default Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Set-Default request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri): + +

    The client MUST supply a URI for the specified printer or + printer class. + +

+ +

CUPS-Set-Default Response

+ +

The following groups of attributes are send as part of the +CUPS-Set-Default Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

CUPS-Get-Devices Operation

+ +

The CUPS-Get-Devices operation (0x400B) returns all of the supported +device-uri's for the server (CUPS 1.1 and higher). + +

CUPS-Get-Devices Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-Devices request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "device-class" (type1 keyword): + +

    The client OPTIONALLY supplies a device class keyword to select + which devices are returned. + +

    "limit" (integer (1:MAX)): + +

    The client OPTIONALLY supplies this attribute limiting the number of + devices that are returned. + +

    "requested-attributes" (1setOf keyword) : + +

    The client OPTIONALLY supplies a set of attribute names and/or + attribute group names in whose values the requester is interested. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'. + +

+ +

CUPS-Get-Devices Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-Devices Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

Group 2: Device Object Attributes + +

    + +

    The set of requested attributes and their current values for + each device. + +

+ +

CUPS-Get-PPDs Operation

+ +

The CUPS-Get-PPDs operation (0x400C) returns all of the locally +available PPD files on the system (CUPS 1.1 and higher). + +

CUPS-Get-PPDs Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Get-PPDs request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "limit" (integer (1:MAX)): + +

    The client OPTIONALLY supplies this attribute limiting the number of + PPDs that are returned. + +

    "ppd-make" (text(127)): + +

    The client OPTIONALLY supplies a printer manufacturer to select + which PPDs are returned. + +

    "requested-attributes" (1setOf keyword) : + +

    The client OPTIONALLY supplies a set of attribute names and/or + attribute group names in whose values the requester is interested. If + the client omits this attribute, the server responds as if this + attribute had been supplied with a value of 'all'. + +

+ +

CUPS-Get-PPDs Response

+ +

The following groups of attributes are send as part of the +CUPS-Get-PPDs Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

Group 2: PPD Attributes + +

    + +

    The set of requested attributes and their current values for each + PPD file. + +

+ +

CUPS-Move-Job Operation

+ +

The CUPS-Move-Job operation (0x400D) moves an active print job to a +different printer (CUPS 1.1 and higher). + +

CUPS-Move-Job Request

+ +

The following groups of attributes are supplied as part of the +CUPS-Move-Job request: + +

Group 1: Operation Attributes + +

    + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.1 of the IPP Model and + Semantics document. + +

    "printer-uri" (uri) and "job-id" (integer) +

    OR +

    "job-uri": + +

    The client MUST supply a URI for the specified printer and + a job ID number, or the job URI. + +

+ +

Group 2: Job Template Attributes + +

    + +

    "job-printer-uri" (uri) + +

    The client MUST supply a URI for a printer on the same server. + +

+ +

CUPS-Move-Job Response

+ +

The following groups of attributes are send as part of the +CUPS-Move-Job Response: + +

Group 1: Operation Attributes + +

    + +

    Status Message: + +

    The standard response status message. + +

    Natural Language and Character Set: + +

    The "attributes-charset" and "attributes-natural-language" + attributes as described in section 3.1.4.2 of the IPP Model and + Semantics document. + +

+ +

Attributes

+ +

CUPS provides many extension attributes to support multiple devices, +PPD files, standard job filters, printers, and printer classes. + +

Device Attributes

+ +

Device attributes are returned by the CUPS-Get-Devices operation and +enumerate all of the available hardware devices and network protocols +that are supported by the server. + +

device-class (type2 keyword)

+ +

The device-class attribute specifies the class of device and can be +one of the following: + +

    + +
  • "file" - a disk file. + +
  • "direct" - a parallel or fixed-rate serial data port, + currently used for Centronics, IEEE-1284, and USB printer + ports. + +
  • "serial" - a variable-rate serial port. + +
  • "network" - a network connection, typically via AppSocket, + HTTP, IPP, LPD, or SMB/CIFS protocols. + +
+ +

device-info (text(127))

+ +

The device-info attribute specifies a human-readable string describing +the device, e.g. "Parallel Port #1". + +

device-make-and-model (text(127))

+ +

The device-makr-and-model attribute specifies a device +identification string provided by the printer connected to the device. +If the device or printer does not support identification then this +attribute contains the string "unknown". + +

device-uri (uri)

+ +

The device-uri attribute specifies a unique identifier for the +device. The actual format of the device-uri string depends on the value +of the device-class attribute: + +

    + +
  • "file" - The device-uri will be of the form + "file:/path/to/filename". + +
  • "direct" - The device-uri will be of the form + "method:/dev/filename", where method may be "parallel" or "usb" + in the current implementation. + +
  • "serial" - The device-uri will be of the form + "serial:/dev/filename?baud=value+parity=value+flow=value". + The parity value can be one of "none", "even", or "odd". + The flow value can be one of "none", "soft" (XON/XOFF + handshaking), or "hard" (CTS/RTS handshaking). + +

    The URI returned by CUPS-Get-Devices will contain the + maximum baud rate supported by the device and the best + type of flow control available ("soft" or "hard"). + +

  • "network" - The device-uri will be of the form + "method://[username:password@]hostname[:port]/[resource]", + where method may be "http", "ipp", "lpd", "smb", or + "socket" in the current implementation. + +

    The URI returned by CUPS-Get-Devices will only contain + the method name followed by two slashes ("method://"). + It is up to the client application to add the appropriate + host and other information when adding a new printer. + +

    The URI returned by Get-Printer-Attributes and + CUPS-Get-Printers has any username and password information + stripped; the information is still stored and used by the + server internally to perform any needed authentication. + +

+ +

Job Template Attributes

+ +

blackplot (boolean)

+ +

The blackplot attribute specifies whether HP-GL/2 plot files should be +rendered entirely in black ink (blackplot=true) or using the colors and shades +specified in the file (blackplot=false). The default value is false. + +

brightness (integer(0:200))

+ +

The brightness attribute specifies the overall brightness of the printed +output in percent. A brightness of 100 is normal, while 200 is twice as +bright and 50 is half as bright. The default value is 100. + +

Brightness is applied to the Cyan, Magenta, Yellow, and Black values using +the function "f(x) = brightness / 100 * x". + +

columns (integer(1:4))

+ +

The columns attribute specifies the number of columns to generate when +printing text files. The default value is 1. + +

cpi (type2 enum)

+ +

The cpi attribute specifies the number of characters per inch when +printing text files. Only the values 10, 12, and 17 are currently +supported. The default value is 10. + +

fitplot (boolean)

+ +

The fitplot attribute specifies whether to scale HP-GL/2 plot files to +fit on the selected media (fitplot=true) or use the physical scale specified +in the plot file (fitplot=false). The default value is false. + +

gamma (integer(1:10000))

+ +

The gamma attribute specifies the luminance correction for the output. +A value of 1000 specifies no correction, while values of 2000 and 500 will +generate lighter and darker output, respectively. The default value is +1000. + +

Gamma is applied to the Red, Green, and Blue values (or luminance for +grayscale output) using the function "f(x) = x(1000/gamma)". + +

hue (integer(-180:180))

+ +

The hue attribute specifies a color hue rotation when printing image +files. The default value is 0. + +

job-billing (text(MAX))

+ +

(CUPS 1.1 and higher) + +

The job-billing attribute provides a text value to associate with a job +for billing purposes. + +

job-hold-until (keyword | name(MAX))

+ +

(CUPS 1.1 and higher) + +

The job-hold-until attribute specifies a hold time. In addition to the +standard IPP/1.1 keyword names, CUPS supports name values of the form +"HH:MM" and "HH:MM:SS" that specify a hold time. The hold time is in +Greenwich Mean Time (GMT) and not in the local time zone. If the +specified time is less than the current time, the job is held until the +next day. + +

job-sheets (1setof type3 keyword | name(MAX))

+ +

(CUPS 1.1 and higher) + +

The job-sheets attribute specifies one or two banner files that are printed +before and after a job. The reserved value of "none" disables banner printing. +The default value is stored in the job-sheets-default attribute. + +

If only one value is supplied, the banner file is printed before the job. +If two values are supplied, the first value is used as the starting banner +file and the second as the ending banner file. + +

lpi (type2 enum)

+ +

The lpi attribute specifies the number of lines per inch when +printing text files. Only the values 6 and 8 are currently supported. +The default value is 6. + +

page-bottom (integer(0:MAX))

+ +

The page-bottom attribute specifies the bottom margin in points (72 points +equals 1 inch). The default value is the device physical margin. + +

page-left (integer(0:MAX))

+ +

The page-left attribute specifies the left margin in points (72 points +equals 1 inch). The default value is the device physical margin. + +

page-right (integer(0:MAX))

+ +

The page-right attribute specifies the right margin in points (72 points +equals 1 inch). The default value is the device physical margin. + +

page-set (type2 keyword)

+ +

The page-set attribute specifies which pages to print in a file. The +supported keywords are "all", "even", and "odd". The default value is +"all". + +

page-top (integer(0:MAX))

+ +

The page-top attribute specifies the top margin in points (72 points +equals 1 inch). The default value is the device physical margin. + +

penwidth (integer(0:MAX))

+ +

The penwidth attribute specifies the default pen width in micrometers +when printing HP-GL/2 plot files. The default value is 1000 (1 millimeter). + +

position (type2 keyword)

+ +

The position attribute specifies the location of image files on the +media. The following keyword values are recognized: + +

    + +
  • center - Center the image on the page (default) + +
  • top - Print the image centered at the top of the page + +
  • left - Print the image centered on the left of page + +
  • right - Print the image centered on the right of the page + +
  • top-left - Print the image at the top left corner of + the page + +
  • top-right - Print the image at the top right corner of + the page + +
  • bottom - Print the image centered at the bottom of + the page + +
  • bottom-left - Print the image at the bottom left + corner of the page + +
  • bottom-right - Print the image at the bottom right + corner of the page + +
+ +

ppi (integer(1:MAX))

+ +

The ppi attribute specifies the resolution of an image file in pixels +per inch. The default value is the resolution included with the file or +128 if no resolution information is available. + +

prettyprint (boolean)

+ +

The prettyprint attribute specifies whether text files should be printed +with a shaded header and keyword highlighting (prettyprint=true) or without +additional formatting (prettyprint=false). The default value is false. + +

saturation (integer(0:200))

+ +

The saturation attribute specifies the color saturation when +printing image files. A saturation of 100 is normal, while values of 50 +and 200 will be half and twice as colorful, respectively. The default +value is 100. + +

scaling (integer(1:1000))

+ +

The scaling attribute specifies the scaling of image files with +respect to the selected media. A value of 100 specifies that the image +file should fit 100% of the page, or as much as possible given the +image dimensions. The default value is unspecified. + +

The scaling attribute overrides the ppi attribute if specified. + +

wrap (boolean)

+ +

The wrap attribute specifies whether long lines should be wrapped +(wrap=true) or not (wrap=false) when printing text files. The default +value is true. + +

PPD Attributes

+ +

ppd-natural-language (naturalLanguage)

+ +

The ppd-natural-language attribute specifies the language encoding +of the PPD file (the LanguageVersion attribute in the PPD file). If the +language is unknown or undefined then "en" (English) is assumed. + +

ppd-make (text(127))

+ +

The ppd-make attribute specifies the manufacturer of the printer +(the Manufacturer attribute in the PPD file). If the manufacturer +is not specified in the PPD file then an educated guess is made using +the NickName attribute in the PPD file. + +

ppd-make-and-model (text(127))

+ +

The ppd-make-and-model attribute specifies the manufacturer and model +name of the PPD file (the NickName attribute in the PPD file). If the +make and model is not specified in the PPD file then the ModelName or +ShortNickName attributes are used instead. + +

ppd-name (name(255))

+ +

The ppd-name attribute specifies the PPD filename on the server +relative to the model directory. The forward slash (/) is used to +delineate directories. + +

Printer Attributes

+ +

job-sheets-default (1setof type3 keyword | name(MAX))

+ +

(CUPS 1.1 and higher) + +

The job-sheets-default attribute specifies the default banner file(s) to +print before and after each job. The value "none" specifies that no banner +should be printed. + +

job-sheets-supported (1setof type3 keyword | name(MAX))

+ +

(CUPS 1.1 and higher) + +

The job-sheets-supported attribute specifies the available banner files. +There will always be at least one banner file available called "none". + +

printer-type (type2 enum)

+ +

The printer-type attribute specifies printer type and capability bits for +the printer or class. The default value is computed from internal state +information and the PPD file for the printer. The following bits are defined: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
BitDescription
0x00000001Is a printer class.
0x00000002Is a remote destination.
0x00000004Can print in black.
0x00000008Can print in color.
0x00000010Can print on both sides of the page in hardware.
0x00000020Can staple output.
0x00000040Can do fast copies in hardware.
0x00000080Can do fast copy collation in hardware.
0x00000100Can punch output.
0x00000200Can cover output.
0x00000400Can bind output.
0x00000800Can sort output.
0x00001000Can handle media up to US-Legal/A4.
0x00002000Can handle media from US-Legal/A4 to ISO-C/A2.
0x00004000Can handle media larger than ISO-C/A2.
0x00008000Can handle user-defined media sizes.
0x00010000Is an implicit (server-generated) class.
+ +

printer-type-mask (type2 enum)

+ +

(CUPS 1.1 and higher) + +

The printer-type-mask attribute is used to choose printers or classes with +the CUPS-Get-Printers and CUPS-Get-Classes operations. The bits are defined +identically to the printer-type attribute and default to all 1's. + +

requesting-user-name-allowed (1setof name(127))

+ +

(CUPS 1.1 and higher) + +

The requesting-user-name-allowed attribute lists all of the users that are +allowed to access a printer or class. Either this attribute or the +requesting-user-name-denied attribute will be defined, but not both. + +

The special name "ALLUSERS" is reserved to indicate that all users +are allowed. + +

requesting-user-name-denied (1setof name(127))

+ +

(CUPS 1.1 and higher) + +

The requesting-user-name-denied attribute lists all of the users that are +not allowed to access a printer or class. Either this attribute or the +requesting-user-name-allowed attribute will be defined, but not both. + +

The special name "ALLUSERS" is reserved to indicate that all users +are denied. + +

Printer Class Attributes

+ +

member-names (1setof name(127))

+ +

The member-names attribute specifies each of the printer-name attributes of +the member printers and classes. Each name corresponds to the same element of +the member-uris attribute. + +

member-uris (1setof uri)

+ +

The member-uris attribute specifies each of the printer-uri attributes of +the member printers and classes. Each URI corresponds to the same element of +the member-names attribute. + + + + + diff --git a/doc/overview.html b/doc/overview.html new file mode 100644 index 0000000000..12bec26820 --- /dev/null +++ b/doc/overview.html @@ -0,0 +1,500 @@ + + + + An Overview of the Common UNIX Printing System + + + + + + + + +

An Overview of the
+ Common UNIX Printing System,
+ Version 1.1

+ +

July 10, 2000
+ Michael Sweet, Easy Software Products
+ Copyright 1998-2000, All Rights Reserved.

+
+ +

This whitepaper describes the Common UNIX Printing +SystemTM ("CUPSTM"), a portable and extensible +printing system for UNIX®. CUPS is being developed by +Easy Software Products, a software +firm located in Hollywood, Maryland that has been selling commercial +software for UNIX since 1993 through more than 40 distributors serving +over 80 countries worldwide. + +

Additional information on CUPS is available on the World Wide Web at +"http://www.cups.org". + +

Background

+ +

Printing within UNIX has historically been done using one of two +printing systems - the Berkeley Line Printer Daemon ("LPD") [RFC1179] +and the AT&T Line Printer system. These printing systems were +designed in the 70's for printing text to line printers; vendors have +since added varying levels of support for other types of printers. + +

Replacements for these printing systems have emerged [LPRng, +Palladin, PLP], however none of the replacements change the fundamental +capabilities of these systems. + +

Over the last few years several attempts at developing a standard +printing interface have been made, including the draft POSIX Printing +standard developed by the Institute of Electrical and Electronics +Engineers, Inc. ("IEEE") [IEEE-1387.4] and Internet Printing Protocol +("IPP") developed by the Internet Engineering Task Force ("IETF") +through the Printer Working Group ("PWG") [IETF-IPP]. The POSIX +printing standard defines a common set of command-line tools as well as +a C interface for printer administration and print jobs, but has been +shelved by the IEEE. + +

The Internet Printing Protocol defines extensions to the HyperText +Transport Protocol 1.1 [RFC2616] to provide support for remote printing +services. IPP/1.0 was accepted by the IETF as an experimental Request +For Comments [RFC] document in October of 1999. Since then the Printer +Working Group has developed an updated set of specifications for +IPP/1.1 which have been accepted by the IETF and are awaiting +publication as proposed standards. Unlike POSIX Printing, IPP enjoys +widespread industry support and is poised to become the standard +network printing solution for all operating systems. + +

CUPS uses IPP/1.1 to provide a complete, modern printing system for +UNIX that can be extended to support new printers, devices, and +protocols while providing compatibility with existing UNIX +applications. CUPS is free software provided under the terms of the +GNU General Public License and GNU Library General Public License. + +

History

+ +

The first production release of CUPS (based on IPP/1.0) was released +in October of 1999. Since then, we have released several patch updates +to the original CUPS 1.0 release that addressed security, portability, +and bugs found, but no new functionality was added to improve the +stability of the CUPS code. + +

CUPS 1.1 is based on IPP/1.1 and adds many of the functional +enhancements that have been requested by our users. As with 1.0, CUPS +1.1 will be followed by patch releases that address any problems found +with the software but add no new features. + +

Design Overview

+ +

Like most printing systems, CUPS is designed around a central print +scheduling process that dispatches print jobs, processes administrative +commands, provides printer status information to local and remote +programs, and informs users as needed. Figure 1 shows the basic +organization of CUPS. + +

+

Figure 1 - CUPS Block Diagram

+ +

Scheduler

+ +

The scheduler is a HTTP/1.1 server application that handles HTTP +requests. Besides handling printer requests via IPP POST requests, the +scheduler also acts as a full-featured web server for documentation, +status monitoring, and administration. + +

The scheduler also manages a list of available printers on the LAN +and dispatches print jobs as needed using the appropriate filters and +backends. + +

Configuration Files

+ +The configuration files consist of: + +
    + +
  • The HTTP server configuration file. + +
  • Printer and class definition files. + +
  • MIME type and conversion rule files. + +
  • PostScript Printer Description ("PPD") files. + +
+ +

The HTTP server configuration file is purposely similar to the +Apache server configuration file and defines all of the access control +properties for the server. + +

The printer and class definition files list the available printer +queues and classes. Printer classes are collections of printers. Jobs +sent to a class are forwarded to the first available printer in the +class, round-robin fashion. + +

The MIME type files list the supported MIME types (text/plain, +application/postscript, etc.) and "magic" rules for automatically +detecting the format of a file. These are used by the HTTP server to +determine the Content-Type field for GET and HEAD +requests and by the IPP request handler to determine the file type +when a Print-Job or Send-File request is received with a +document-format of application/octet-stream. + +

The MIME conversion rule files list the available filters. The +filters are used when a job is dispatched so that an application can +send a convenient file format to the printing system which then +converts the document into a printable format as needed. Each filter +has a relative cost associated with it, and the filtering algorithm +chooses the set of filters that will convert the file to the needed +format with the lowest total "cost". + +

The PPD files describe the capabilities of all printers, not just +PostScript printers. There is one PPD file for each printer. PPD files +for non-PostScript printers define additional filters through +cupsFilter attributes to support printer drivers. + +

CUPS API

+ +

The CUPS API contains CUPS-specific convenience functions for queuing +print jobs, getting printer information, accessing resources via HTTP +and IPP, and manipulating PPD files. Unlike the rest of CUPS, the CUPS +API is provided under the terms of the GNU LGPL so it may be used by +non-GPL applications. + +

Berkeley and System V Commands

+ +

CUPS provides the System V and Berkeley command-line interfaces for +submitting jobs and checking the printer status. The +lpstat and lpc status commands also show +network printers ("printer@server") when printer browsing is enabled. + +

The System V administation commands are supplied for managing +printers and classes. The Berkeley printer administration tool +(lpc) is only supported in a "read-only" mode to check the +current status of the printer queues and scheduler. + +

Filters

+ +

A filter program reads from the standard input or from a file if a +filename is supplied. All filters must support a common set of options +including printer name, job ID, username, job title, number of copies, +and job options. All output is sent to the standard output. + +

Filters are provided for many file formats and include image file +and PostScript raster filters that support non-PostScript printers. Multiple +filters are run in parallel to produce the required output format. + +

The PostScript raster filter is based on the GNU Ghostscript 5.50 +core. Instead of using the Ghostscript printer drivers and front-end, +the CUPS filter uses a generic raster printer driver and CUPS-compliant +front-end to support any kind of raster printer. This allows the same +printer driver filter to be used for printing raster data from any +filter. + +

CUPS Imaging

+ +

The CUPS Imaging library provides functions for managing large +images, doing colorspace conversion and color management, scaling +images for printing, and managing raster page streams. It is used by +the CUPS image file filters, the PostScript RIP, and all raster +printers drivers. + +

Backends

+ +

A backend program is a special filter that sends print data to a +device or network connection. Backends for parallel, serial, USB, LPD, IPP, +and AppSocket (JetDirect) connections are provided in CUPS 1.1. + +

SAMBA version 2.0.6 and higher includes a SMB backend +(smbspool(1)) that can be used with CUPS 1.0 or 1.1 for +printing to Windows. + +

Network Printing

+ +

Traditionally, network printing has been one of the hardest things to +get working under UNIX. One reason is because each vendor added their +own extensions to the LPD protocol (the previous standard for network +printing), making cross-platform printing difficult if not impossible. + +

Another reason is that you have to administer every network printer +on every client machine. In some cases you can "clone" the printer +configuration from a "master" client to each of the others, but even +that can be time-consuming and error-prone. Something better is needed. + +

CUPS provides "printer browsing", which allows clients to +automatically see and use printers from any server on a LAN. This means +that you only need to configure the server and the clients will +automatically see the printers and classes on it. + +

In addition, CUPS can automatically merge multiple identical network +printers into "implicit classes". This allows clients to send jobs to +the implicit class and have them print on the first available printer +or server. In addition, failsafe and load-balancing functions are +enabled simply by defining the same printer on multiple servers! + +

New Features in CUPS 1.1

+ +

CUPS 1.1 includes many new features and capabilities: + +

    + +
  1. Backends + +
  2. Banner Page Support + +
  3. Digest Authentication + +
  4. Directory Services + +
  5. Directory Structure Changes + +
  6. Documentation + +
  7. Drivers + +
  8. Filters + +
  9. IPP Support + +
  10. Job Persistence + +
  11. LPD Client Support + +
  12. User-Defined Printers and Options + +
  13. Web Administration Interface + +
+ +

1. Backends

+ +

CUPS 1.1 implements a new backend interface for retrieving a list of +available devices for CUPS clients. This allows administration +interfaces to query the CUPS scheduler for a list of available devices, +automatically configure printers if the device identification +information is available, and present the user with a list of available +devices rather than relying on the user to know what devices are +configured on the system. + +

The new release also includes a backend for USB printers under +*BSD and Linux. Support for USB under Solaris 8 will be provided in +a subsequent patch release. + +

2. Banner Page Support

+ +

CUPS 1.1 includes support for banner pages at the beginning and end +of a job. Banner pages may be of any file format and support variable +substitution for job titles, usernames, etc. Default banner pages are +associated with each printer and can be overridden with command-line +options by the user. + +

3. Digest Authentication

+ +

Digest authentication provides a more secure method of authenticating +access to the printing system. Unlike Basic authentication, Digest +authentication does not send passwords "in the clear" so it is more +difficult to gain unauthorized access to your system. + +

CUPS 1.1 implements Digest authentication using a special MD5 +password file instead of the UNIX password file. This file is managed +using the new lppasswd command. + +

4. Directory Services

+ +

CUPS 1.1 adds new directory service ("printer browsing") features to +make using CUPS on large LANs and WANs easier. You can now poll a +remote server for printer information and relay it to the LAN as well +as restrict what printer information is processed (e.g. to "hide" +servers, domains, or networks that you don't want to see.) + +

5. Directory Structure Changes

+ +

CUPS 1.1 now uses a directory structure that complies with the +Filesystem Hierarchy Standard ("FHS"), version 2.0. This should make +integration into existing Linux and *BSD distributions a lot easier. + +

6. Documentation

+ +

The CUPS 1.1 documentation has gone through many revisions, +including a completely rewritten administrators manual, a new +programmers manual, and an IPP implementation reference manual. + +

7. Drivers

+ +

CUPS 1.1 includes drivers for EPSON dot-matrix and inkjet printers. +As with the HP PCL drivers, the EPSON drivers don't necessarily provide +the best possible output for each printer but should provide adequate +printing quality for general day-to-day printing. + +

8. Filters

+ +

CUPS 1.1 includes new image, PostScript, PDF, and text filters. The image +filters have been upgraded to support Windows BMP and Alias PIX files. + +

The PostScript filter is now based off GNU Ghostscript 5.50. The new +filter provides much better performance with higher-resolution printers +and supports most Level 3 PostScript language features. + +

The new PDF filter is based off the excellent Xpdf software from +Derek Noonburg and supports automatic page scaling. The new filter is a +faster, smaller, more reliable replacement for the GNU Ghostscript PDF +filtering that was used in CUPS 1.0. + +

The new text filter now supports bidirectional text and can embed +fonts as needed. + +

9. IPP Support

+ +

Probably the least visible portion of CUPS is the IPP support. CUPS +1.1 implements all of the required IPP/1.1 operations and attributes +and most of the optional ones. The optional Create-Job and Send-File +operations are now implemented, allowing for better System V printing +system compatibility (one job ID per lp command) and +support for banner pages. + +

10. Job Persistence

+ +

CUPS 1.1 supports job persistence. This means that jobs are preserved +even after a reboot, a feature that was sorely missing from CUPS 1.0. + +

In addition, CUPS 1.1 allows you to keep job information after the +job has printed. The basic post-job persistence mode provides a job +history (number of pages printed, time job was printed, etc.) but does +not preserve the actual job files. This can be changed to discard all +information after a job is printed or keep the job files after printing +so you can reprint a job at some later time. + +

11. LPD Client Support

+ +

By popular request, CUPS 1.1 supports LPD-based clients using a new +mini-daemon that handles LPD requests and passes them on to the main +server. + +

12. User-Defined Printers and Options

+ +

CUPS 1.1 includes support for user-defined printers and options via +a new lpoptions command. User-defined printers are special +instances of the available printers (e.g. "printer/instance" or +"printer@server/instance") that can have their own default options such +as media size, resolution, and so forth. The lpoptions +command can also be used to set a different default printer queue. + +

13. Web Administration Interface

+ +

CUPS 1.0 provided a simple class, job, and printer monitoring +interface for web browsers. CUPS 1.1 replaces this interface with an +enhanced administration interface that allows you to add, modify, +delete, configure, and control classes, jobs, and printers. + +

Software Using CUPS

+ +

A lot has happened since CUPS 1.0 came out, and many software packages +are supporting CUPS. We have contributed code to the SAMBA team to support +CUPS, and parts of that are already available in SAMBA 2.0.6 and 2.0.7. +With any luck the final pieces that provide a complete integration with +SAMBA will be available in the next release of SAMBA. + +

Two graphical interfaces have appeared on the scene that use CUPS as +well. The KUPS project provides a KDE-based interface for CUPS and can be +found at: + +

+ +

The X Printing Panel ("XPP") project provides a graphical printing +panel for CUPS and can be found at: + +

+ +

Numerous other filters, drivers, tutorials, etc. have been made available +on the CUPS bazaar, available at: + +

+ +

Finally, our own ESP Print Pro software uses CUPS to provide drivers +for over 2300 printers and can be found at: + +

+ +

Operating Systems Using CUPS

+ +

One of our goals has always been to get as many UNIX/Linux +distributions using CUPS as possible. Debian is currently providing +CUPS as part of its stable distribution, and many other distributions +are considering it in their next releases. + +

Summary

+ +

The Common UNIX Printing System provides a modern printing interface +for UNIX applications that is both flexible and user-friendly. The +software provides System V and Berkeley compatible command-line +interfaces to ensure compatibility with existing applications. CUPS 1.1 +adds many new features that make it an even better choice for printing +under UNIX. + +

Who to Contact

+ +

For more information on CUPS please contact us at: + +

    +Attn: CUPS Information
    +Easy Software Products
    +44141 Airport View Drive Suite 204
    +Hollywood, Maryland 20636-3111 USA
    +
    ++1.301.373.9600
    +
    +cups-info@cups.org
    +
+ +

References

+ +
+ +
IEEE-1387.4
+ +
System Administration - Part 4: Printing Interfaces (draft)
+ +
IETF-IPP
+ +
Internet Printing Protocol/1.1
+ +
LPRng
+ +
An enhanced, extended, and portable implementation of the + Berkeley LPR print spooler functionality
+ +
Palladin
+ +
A printing system developed at the Massachussetts Institute + of Technology
+ +
PLP
+ +
The Portable Line Printer spooler system
+ +
RFC1179
+ +
Line Printer Daemon Protocol
+ +
RFC2046
+ +
Multipurpose Internet Mail Extensions (MIME) Part Two: Media Types
+ +
RFC2616
+ +
Hypertext Transfer Protocol -- HTTP/1.1
+ +
+ +

Trademarks

+ +

The Common UNIX Printing System, CUPS, and the CUPS logo are the +trademark property of Easy Software Products. All other trademarks are +the property of their respective owners. + + + diff --git a/doc/overview.pdf b/doc/overview.pdf new file mode 100644 index 0000000000000000000000000000000000000000..4f45850cf46cfd524f9abe20de06cf979caf0b48 GIT binary patch literal 33962 zc-pkO2Ut_t_CAaaq>Iv|2#Scbgp$yti1a2(4}=m(sDXrpP^E}c1OY*cbOjNCfK;hU z7o-c)oAf3iASfvCPr&Qw+_^LJ`<~}}jHm3g)_&i;SKIp>xNj&b3km~7D7Yu5I(sOD zIfXb;miE%pz#AA89A|~VT()&_M8Z*4oWcMJfCQ%k3hjZhv$1vI6qb|}7Zec^65>>X zVLdo?QPwVQFbsn8P|*b|z$uSJa_SIev79;xECS<-fCG4e3K#^;#SZ192y;PPR+J+4 zAS5mNW^7Mc_&V7SAvcm!i^JU&FNx`AYeN>qMSJOud5jmQ0$ys z?3`>kbv>{y2uEI^JkG@yg}JO{XJrdRAUSp25C|7uSy_Y=oG=~=k)Pwz^FSkjN={ZN zI6)hzXlHGWz#yEg5LgpVQ4t^(4YNW35$;wV*9 zBn$&YBQRD7Cl?^hk#L2DIl&Kwv4lR62q2m;4^Bvgwaekv!F&N>1fCc>tOF2@#9@I} zgt5SYj&@FjYeE-xC^!&{gkf!go(K#Ih;l*zUEEMW7h4Ph0klTpFhFZNR|F7i=MKao zToFz{#6h1H_tE`alDqAF)%9!gv-H@ zED4u~RDZPoXLwe2c2;&6E1V+`=L9FriWLfjATWRtc*B5}Kr0{|NEi#y251Yk1KI-} zfJmSt&BIfY!7bF)uBpkshEFu9^!eLOH z!lFXISilm7B_JVD1Rwcn#Dg{j5^0CV+F^lkn2il#UJg%06CX0SMk3sa<{-Ed?!c+1V4j<|f zawEa35Ew^-S6d>nK-iDKJbVoMMHhAm3;Wpx>|h#Tghcb7X+Rt*BMy}jzbGSqYS|si z*d5B){UT%cQwBkp2B$+f)S)=)P#pD(IO>PMPc68es~xf7a1wBbinv2X+%Jl_pBf&A z4_yu>!Q(&8ra!BL=m}Bqvy05+Gp;yhg}E2#g6)SI877&nfxa0EC7A zo`)3!P zIuxe=c?|j+OmPtcn24}2;V4W1mf#c-0sS|mA|acaNDyIkfJP8wPA5WL<0P!!2+#gt z0sbc#VM%cUfUp=C046{R{rCL-C5)I5_%|4_e}s_$5vER9OoCuWBBa>Af&q(&{strd zk1*oG01%-@g8(82kf47B0}>MY4MyT0VZahZ0KzyV4M|IP(OM1Ql5h|oX65Q2*UAano*0{u%DAh^tLFv9-`BP>C50U;qmJP{%PhYN`P z$)Uw0euEMDM;O952reK(bZ8AmW6H zi-P{;j0sDK{5F^$@oyp`{yYBPR5%A>RlyP#B~}P)LUBO=oPOQ*iVFQBbFhRc(F$PV z5iAM%t2!t0d!ZBkheC(8^#I_U>;x@g9vB2+R}LUl^mwok=tm7EY&gJwYh&U| zG$$(ruh=0W92S8=p zMx3~Y|C2cQZ^Vh~=`hOCa_#1KJdiqb|l7AykT(SNx zE-v)@i<=uTLRbN{5O6!#HI(~71_4Wg2^$K+PDKHQb8_L7I1Fs@!@MAVSnS0QbH<_J zC=OvM4%f>R5{HRI^2eKuKcI#G8=7#yAP6AhhaRASaw5bSAyc5aA zdGJenhmT}NUr&Xh#QjJ&BT`e=cZc^=*5$lgeZR@Xn$`r;>G58%0|8Um(2CytnWU2zLGI z#VtT55ngdh*%-I|uN9hrwPpFR_qT_A%$ei9T3dPozeLRFlzqCvRJ^M3!P6tSnR_hu zHde-l?!^el(b=6h85q0pQ*B1&?4nIjpa(CGPw@om6QAU8T7Z#RfF$%7sYZ>ZpL|zTEfcK~sR8}+rOEY`(vNJQLZT~wGuFJyZ_8V)O9j##K-sVC zLXY5Oliz^#YCctD6OJ`C`{+h4wf)JN+D^aQs}mLCfS44)E>}jVmz+W`dr9s_{yAwH zrt`Z-XzU$YB*68#yatm^RBjn`jMPwe@cpEXS%yoVHK~Azk>=cm&|4p8 zL*P!iY*SEC7+tM_UYuV$J8#25A*J#zHZfAeiL;$upv*N1i6V-S)q{PowQAI|D0Je>kVonyIH<#bkr?= z%WY5yCyVx?w*7Q=Jquvkk6StKLjJ_Ho&4^Gm=j{qW}a8VXmD*A+&E6>m?6UmdLpf% zp(ch*tg=hTARKd#B#2Uc&Mh5^^Q#XSR#sOjf569~9THHO29M^ayex8&uZfw-V20<- zHLZyHlT11@Jz3?(QPf8aXJ{W{&r>;r>lkXrScXrXkuhXXYfe9r`yL}7d?CX1>J>r5 zbIa_U61qv1fMav8>XQmWX@1Fy77DwrozuDQAd2LlgktTLIFDzC= zm9~^w!Nvo=|j)HqY8sw5$xYC>YFp4DE)Z9?xhZzJo_w5 zxsFW#9#u4L=Z)N#!>ZXP-qoMK3!db{)1alOHT59J|WnjX()8|CO(1(%&egW;lVbJ^TUN8&6T zWA!9VkEJ0m3Z`gOB?crc+3P%Qk0R|?;LMBBJ=&i&m6eiXxjZ;=_grvcK{~p2#tH=W zFR`)tIO7)@`C6i*7pf>*|H=7jQuBBQxc^B0`JE*o5Y7kFQsw!q{V$@SpAT0zE=*!q`L~Y>653^+OhVp^wFn zRjR7b@-g?cw&8R8?^Eq6+u$IjSjbu0vysT^mkX}R#A+;vo?XYMF<|F^4j z*LCxUg_ZzJmYvoa!uPZcZ$3O{m_CsWkft6z#ebKIM4m>R<)IO^@BFGSP5IU;?GbO| zdt1e)4Lc&K7i^7OZru#Zxq-RoK)VH3pg&o8^qR|a@V(+=`AgVd^}I#n^0cPcC)r7E zxjdTp-d~Fm(>85q`ID{k|I85g9(fIn3#A>u|_3` z^*#_nTh4dFP@ExylXY@T8b$&PBD*gZqmZXu+uNI%P<8T{bbksr>#;;H!e`vYb>LC5p{;1Sq@30!ybItCSTrGnRpJ8Kk{TECMe!@9EeY?z5 z?+Ct)Cv>{S>c=g-a_*j_TH5+skE z;n11|LI+hI)>AUsIQSfaPS(Hu9-p&^7KxZKzT4);blVTxI-#;L`Q4HGOAw7=ZS1yF z^0zySrSC@5iPV0Yo@LxURTR!=-W$l zv5kCrdpKG8{tq-C^gANJ(`nO%S~Tb?}E zcGp5w)3N75i+&Ro8Fajb)BP=g6$$9Bayi?hR9hWe@;IBO^1FdKUDyn^JfHM2P04t~ z(dR?xoM!Q+K(FaX^En0QO#+v#@1OGZ zS(B{2e7hQnb~3EK*{7lV3NzDDHmOtJORk>**vi|ODDw>a3MG%?AH(^0t+mEEMub&_ zzFN8^k!O}(l|FFVa5gaKq3=MLc*pR$te;Qh+4N!M-HfHz?ew9^Ule#N+)q35#f{jG zM+ApZ8cxUMoSTXw48NS-jil0a#Hzf{02&5JsV0q)jMQ+_+sssVojsjWes`8JXi|zJ ziqQ1sqKTqWUKoSnm6j81fUL;*fLZ-hQ0gEJr|7q51gg>TSX#Gp~K2d$+ zJC!{*!zTgNNndo$zBN3ZoSZX@Rtr-sjoSo|zfu*Fa~>3ky9phXFsz@5Vtva$<-&2?a88ONC8uANCBN{|gQdr- zmbJu3c8cgp5hqkbEY#!uXqsuxF&{p|7w;lgEDI6>mv%0ZXfd4#${C+8FJhSR<4;=0 zw8(wm-rDov>es{E7kQc=z42@E$n z$@Dx?MLDmX9{SkWcy5%uPh)((7lF<-v9sTqXwg$abS0C;M_=lB(fUChp|MuiTg4$g zid%9uH}$%bYuJZCb9bwJo5;>13z*E>c*0Izg)qFlv|etX3RRkG@bujPu*cyvWc%Oi zJ8tC2>C28~-NMYU-#%3e!S&R1P{xCCcF?uWub&-H^Nf`hu82X$baxWhqPYmoZ#SLk zF98zW&30_cvKn#zy_l$%*?@ZvIBzzT_NC;&oQho+t=mT=)lBr`8e&{IMu);%ANaWM z&dsjmBBd<#T~|~WmZHkSzf|W%*iFUozuT>k%zUUP{jxV=t_Aq;vqXT~Seb~aRL6{F z`9ckxE9;7T-tNpQ`~G?@Yro`aY1_#+iV4a?6&Ld+FDR&J0AD$qc1W$#E|M%otE~a% z2oC^di0U`F;&~3ivh&N^p&W(bz`lNc4E32S+Vs7M*XKs#~tSl|xvGg{j zF!UDo+g+m_b`DEk!Y!$-a_0p?iiaxb^Jdql-U*su!jkJ5TfEr1C(A&68R&cSJJ&vM zO2qYU7j{|4&fdW@dYc|K^m1;?9N(E*M7(=5V{uVe(UhWpP&jpj;6WXsFX0ruacv8W zI%OT<<+9uEsnAs>7+JYqHoWIug+yMFRi5_da@lSyZpm{Pwu9HLV0g5!mvUsJIr zmLXS0r@Q6m(xv1GUFj#I`YvukE7xZFpHjgJ#bPvD0dyCJuwnR9kevIb)W@uvp!4@4}uw7>cE{77? zepS=chT&6%6>+2Y^_H<=?-A&jEvN&uLQC#5M+4su!8a^FvC=}r%wVKYYBxFcXMRh% zXJ-mM_XDe#HZ-oZWW3Or?0%KnD`=Qm6p?#d!z8Xj-`snLU{d9+cdRn-p*yD&D-0Uf zU&+K>+xC2A_d29=T}GppvGt3kH%6-y;WN4}QXb-KoQH{o&QgchUnoa1wxvRQun<83 zruGuEi*a8wXVjVABFy}9WiJ~RYUX`BM*2E-ylL$%_*nlQ;ks;fZBQ_ZlJIcz$T7v% zRd8a?BeSiFg74=l%0seRuZ(;lC1q08cPjIze5$EqXzT-=gJxWHMubvIXg)c<<%Lq9 zl)yanK3|v@^!>(5t?HbX}KTR zM42mpC?eJ5YACJcGwnmJc737X}bzyj*z#7#xce3Z`v>p|2T4&qJ zQnH4C>ih}iiYJW}yPm?BvL*CPD_sMHs1?as%!!M^CzK~1H&S>P(@Wm3gl=Mv(;%F#sQ#)|F!pIhAaBiYIU17nB^GxfhaH`Cse!i#V71@q%e>#FHlRv2v z_POw?EuBA_zFGE~#;FDpv7#`({6*~f-*KEVW5kVXOjPnUkin~cV?!@~P=-lKGD^4O8+s>BE%syL; zCl_;$LTGKtb`@S4XaL|jJE<+Gw;Ni{&&wR`qfa)HWWLFdjvdx*Vw3c?Cb98?Pd-Yw zW=3)vL%3^VjOQS^R?i@as6vvf`JvmR<@hl*o{20W}nP*mSZz|(GR zkj2@hv&Z(ewL~r2gpPa_#U&hRb%(L%vrmAI83-rye&V)`dVEZh+nBBY9OX+&t1<)C zJgEmq&YTrL8PwNu%FDb2r2YJf@ys;`n_x4h4u2H5Yv^p6VQ!P`D0KoQD)?MR`pf*Y zwvN=o0GmGd4ENi~H9N%(9CYJUCD02A!>3vK7ySE%PRZC=I?X85dUkuRci8glt=_-A ziQk+`X4P;w;$Xgt2)Wm$^RlM#47S>Ga9CCcE#y4vRbW#`R;rg50aJhKz$EysZ{?RVksLm6U1u%vek38I1|m=f`MVnWPM0FG94PG>=2^ zhV1_D@;|SUNDP|Kmp!bHHuB6mYIt*q;bW_!x`Yoi6-~)o1DR$cuF`ik$#c~ZvQEat z`#bWyi8<{O7P}}Zl^E3L2+2?7e2j+lzL_+P^^;ALBxjhgHEHv&KT8`;IdE|q(m7M^ zY0Q~p`an*OWr_{JFP9yV=iGh0Z5k267EK;owjxbTmttVs7PEzC^F@bp_E5g91HNun zZw=dgKCok^#M~9s2bPnW&W%}8+}aS8Ul`G51@B-6L~2t6=>h~TAz1jA93z&WdVSg z95U-4zKH{rCs>q;Tkc*d)&DPVVl~E>)9VY5b1{z{%fH_q2mStjk+L_v zGNo*$Q1ylKQ>V_ijoes`nLD8huKSHRj$3HDjmfFppfAv`6Q2Ap%07Pmx>p$&@#PJU z1$;+-%+cK2`=xeXPrmo?SXR@*TJPN4&a4#e$XZ}M@rCzF>2OoO;VOqDc|X;OJq{9* z{rySI<}}6hQ4->HfZ;fHNcoh{7xRLLL1OW>B1bJBd#kezt2L=T4_oTE=p*s;1c1>k zd*%2{^=c^(c|I~zl{bi{jvdI%7S~v@MtQoP%r6Sd*GnkJhWVJ zbfA3vxj$WiR%=70y7OHZS5F(UaYoOA&-4*Z=~lwyPuw8N{p*?O4z8+kJ(uUV-so$d z|Gc1cWk{f84mtz9(E{N8d_TG7nw4%wRbH(ZCIVOyvjl||82?8ru1Q= zN{Bc4)STyw*VPLT(nc7~+C?rQbS8aeSTom{MHXo*g3!}iPXUVRSd+W-=RCrvhSt7} z4eLrurk=y4JH^!*3YhoDz4zj;@)(X-dqrUvzQm)qaQOz31I?r&!&Ymn7{zyF_^if7 z-WQTZl9{04?$$Ayk1w8&haTx5bhE8M-dxRIn(mNAA8L9Hmju*Bz8K2YH`h1|<+{?} z7$TB*IpS$?)+2`dtBarBSr58eISxJP%pS1Tk*wBBiB(6#6vB%%Kd9A+0#4@^9wWo` zHrqYS7pkOPu8R%j&J{Rr(bB~U(s5e_^>*B;$tVrrdh%+Z)Ygp!H<1aFI8iD7vbj6# zx};|T%WjIxs)a;&#Z|XcwCO!NS@LnD`Mk%twMv>uu6`ZjT#1R|smp}jHs()0u`{W? zfWNY)?RL^{#a)?Xrq}9yqW>#1&(wWaOyM9h?P;4SJhYK=(}O{uibGeLUim1)d&%N$ zuNY|ozhpHIx3h|#QA~=iyRY8)WGy|5Q-@t6(M-OqSHx#xPp!LfwD2ppsEburuWNX? z!n4(K_Ye0=T{5UkLl|zQfjH<}lWOmlCEU7N-&492S|o8Ud^PI=bx-92u*brmC8I@4 zv4{K3u15854vuPM1oO)xPo63*Ee)qhpFq$+~NZyv2~@D_ebvvLWQe zF)D|u^$Z+Lv~!H-uA}Ymxt4^fz|rjr<-C0kgh~c#pU=KzFa2h z(D*D2tqY8jlm6%zWI;M7Oj@n>sDiN# zey0Q9IwBr;-PTUw#IOxDnS{pP=)Py96s?-d9_`ZaHsVAdlUE!mY!-G?Ug%^u?UiF= zkCw^Ao1=<0k68P?)@oij65FZw_-)1*FWy;%q+vj%*j_m1o{(U)^OIaR`+?26=*8qW znP0lx{o_qr(Q?dWdKS&w_19yEd0|X+pX6$5GQ%E6UrhQ|AN`E!h|HZ+bPw_p*Aw=6 z2TKNzh}_K;EG}wri?B0^(gJYviRLahs>ZD;4OO0N({Zm?z?yY3;`YL9h%Ch^z~yVT&Nb-l*J zL1eckm#!=Fa&S9s$h- z)LDue0$M036n@m%uJu0h0_FKDxK4dN+Euc%{k89xjKkq|G5OTrj!Hj)%?LC+Ua!h} zG@M%}*ty~FQN7$7|Lm?q=4-iA-Pz?%^XsjGriJ9<%@;o%X}#(nm}_=&`m1^;1++=9 zAhzE)Yb;v1eI-0#p_s!}(sRf4tM3c>rZgYvkGNFd@~5c_Zo$T=hymV$H)JNxuM+n> zK66N$L79nv`f~U|`9I&HfBeY>$tRV2XBtPkpFPc;Fso1?KLO<|QB#YBTNGqC@@Bs~Aw8d2Q@UuHR!x-Z%U-V*)(EUdA*KK{$pw+-*4_%CJ`vo6i=M=gH8@ZHxz9OET}*A%p*eqGynu~0;5FY-2Z_w7h`iITgIH&2di8#{f7{hozy zWwCzS@@f{@VAG)H`J5Fwy;Y>`>htQV9lxIBKlw+3SbH!!6m3$sfl|>?J8puF8o^`a06cy76rI^xg70|IKHMbHk|J zCdA~5J#Td~uQjE;Gsjr&3di)hnXUOEq{(~`>#*U-Tl(I%tu6VNHT{M9Qq2rSTBa&*5b;!Eo-hN=;z0!HLac3t1QWZzE`mHZT8FJhdWdYTxwI2c>w?+Ebg z?zpByi{dTs4gt4ECWM>qN9VR_FSrew)KrRCd13Eq`U{ zv>Ivr)i1W*N&X|J;Jo8YK!thyv6lsBaiNUozq!_Wy|3%L?ppboc}&C2fzmZ{dDS(q zCgk>toENO8W7l*4$nL4NaDiK3SFBeth8-Rv*-}_it-)TptufZ=xa9DJ!QaO`B;#oA z1==sPuA+GVcc}MMyMh&JpSUHOS5}ycKD|~UJ6pk{#X$v}SQUIuWsqUs_6iy6Bl;o> zHFxe^R7U$%m`yd*!uQmf-T^^MC#ao?EsoYT$~t(%)hRAqK_0=thQsGFhdLxmMC zcYON3hc$r5qDEf%%q9C)_xRkiq9x%O`nziwHe0Yc*C;zJQwB3i(H8Th|;FT+l zX%tjTsdD_|JFk`RD{VKL$H{Gv?1nX;*#|IvZ`?`ywCn1%9-6_l;-uKpgg+x|xhr6Y z+?t;LTxAsX@Zp>Kp476pQsAln8I{+t-4!|aO4fuFR0-F{TV_<`s?P+=()ttgI38J; zH|~yMclq`4cMvnj@ojpDcWukfD~ZO4(c4M}+K|q@u##7!Tl{$NUM+87OZyJPvaW(m znAs$~!L}hhCY~XC(d7k~JhR9?2_yp{qtTT;)Ojk^U|>xb9`kVXN_LOUXXecDAm9Ui zWrJ*%geCEdsbP{XN(LySPRm_zjkN-s6uZchiVG`anAh~k#v3k<*ODUmYV0$LJf^_5 z1V16qvk*c2{*)dA)K@~UFQR#JLRTaZe`$&T+H6u`$LaM2AxNsB2XSlP!^Fs<@7#4AKrd2E z6y7b6?QKTvr0~nJVB4~zznS<{IxO%;qY|G3Y*(UqLttxmA_%^QcE>ZlLhL4#xgf7q>GFRB^XEkNeC}k};&2G2 zP3=zbWH#|RJvo|JoA9_(_N?4@^mlYHetaW#v-N=qnO_5dCUO%krraD;&%At7uEJB* z_39_``{AbzjjA0GVYQ$5F78bE6<&HXVyWMBrQo`IigZ$j7Erk9mEMDx@kHdu9Eg!e zd48`tB`!0i6~1NwJS&9>xE zfk6_P3Rc{P<a%5ZZJptH_PGdARJ zcAVxHiw0Pmhh|jWgYg{qt}gI)@;e(awuNuN&r~y6;Jo>M*9l=y&O$>0inyI6F`tjY!l^a#d_6ja16su2!~V+Q98Ii#(DKTp zyO!|HeZ1`JYYSy^M$|?9rY-ALx5n|??1+Q%@ zzmr3PI$7r0Q5f}VACi0Zy%vuv^_xE23b*Utu?Mbj?1kf33bLnS`NwK|Wd{Z?N%6B@ zFMqo@_Ye&DdasvxMW^k!_lev>K3JHLcgV~3f-%UIHoKTQESj{Hg{LYMVQ6|9-*v6Y z%Vt-ftZ$Q{8o+B_SlA~a_U4Vc6u;N~&k}IYHIJY$Rma%fis{|AQg8MP3c^be%UG@l zxU2XbRc6SY2EK}p0p>!|dpHAam3;f*_oao886n=yQVQ^URjCL+JdS;}ES^cH}{t+)r$6PAF3E<=u;8P#dt|ZXR;E z+M_9O@obKAj(v#1)rSmDPwVJ0T1|I(j80f5eL7w!MxFU)+ETD!N0nh2ucXs)$JUJQ zg+{==4&&=uoDQw6-mUd5pRRUxsE@js-OLh?m!kt-GYD!T_iAhDzX3(n8=JjT(R3I( zUbqw3%X}sobvM`Lvk#y2VweyIur9Jz(X$Vu(HDJ<`|VD`yA%9Xi8Bh%wBVZ@Ip;pq z(1Dk%ncD1ERmmhKkA2_vj-F|;y*b+gE>T{cwi$e zeJYBucR?(8hi4qDC+g*zvx~ab6E1!nC>eNk3-9qvWl5m(LbtDrL3qZqQy z%W^-4qoyHTQI8ugcqVqyyayFc-6yRmUL~^B;6Nx1;cHxUSF}oHH2bRN!H`E3=@*hq zo|B1M-;ur@mOpkf2k-J`@@c*F3x(aY-ul{7Prp)IU4)8s(^>1@$GaMc9h;86k9Y6V zFvnZXCK;TEQ&aKFP2pVg+K&L67c~s5&nDV?rI8lyfSlNa${6xapKel?kiZLzwt@oj z@-5^K%eR_@&-0)A?2m5_`KzB4(x7S<#tHGh70~SrcPyP=t1FU+Z@NZeavt0SGcyF*s2%g$;guU->^sx!j^YDw1 zY8Re{cy3hl*_Wr!9y45pn9~`0_A_s1-N%pX^o@sK;Lpv|b^46gp?PFGpbn>klGS)V zlSBpDWFQxfel!ey9r6%mZ=R0iQ8{a6JeoyFjRi+7s(LyN-6K-lK@WPLV(}gW8U$2luSI_@wko+N` z9oc(xfY0v3&{YE)SWfh92WAL+V6F~n9@B$f*Z?2mgD2gOhPeMU(Ee!XjQr6Mg5L$6 zOI2IsT({?Rs4>zV3(Rensv@!=4cpW})f>Rs&E|3BkUMX7!b)NMg)~64cQ{_&N@hb0 zsnj=dB99tQ&F0Y3lg|JNVk|Se+V`QrXTfeD1g}5|1)g{KWK_KdA_zV?L4X9i<88*S zj|Ac!<6cN7dnYD&J^d6OiuK}h_}10kL|ORKWWD9hRVHc(SzUtc*?AqVm6F=O4$!~+ z83W=h#CX-gwKbPoK87$;j6fKCBYS=E#I(+RW-?x=a3@MXT_3C@CWuFKF);2&g5jIz z9qyIil)vH-`TCKJLM>6;qpxK)=8}N~XUr>E@NK*-T&rNn2#RVlZcrYGz$=drrqQL; zkTjLzXJYZZCjvEEC<;jf^=Z)|cU6i7A-?8YtLsn-10Oc;iYVDEWwOSW?o&cMFS`>q z+d6F$ZfVQ*h1G)UET7~%25Q1ieXEx`>%2si}%w z@m{H?Tn~C34VLc~DMK3ByX6VV*OjZS=gj?>tz6coW)@K2L#}4I^A4OwVc%S`P^XlP z4KO~BowOYu_OYr*r&NO)_VG>1M|vZk&`(=)%M|tvklgxgR8lMn4{@zlskcCkDprUa zgcRxU-xa;e-rprG zl*Wv5sEV`iGdeW3k*j#9ym!0q?uWN#OdQKmpv)6ri49*- z3*%PVPQ37)_3^mW&99W?pyS9kBd*c8CKbP!=-|Rw%jzEdItRw!UY)N-rgrTMj8Yi> zOptR9IF$W%2qbh7zoSd%t%xc-C+Z^;&J}A?6*gOXk^>&OvN6TgRa)4U>c_z*t1h<9 z(b3|YZzb0$X?yocd&$!)Ik(s@E(*U(oh%eHsN1)DYdk){d5NEPtg<6QL*(>UG+1-A z4(*~StI0omJSj|<9uI42>c~}>gasVQ3uCy}jl~zQtliFM7U>n2D(t@96PT>OBr7LN zflu7I4cOM&3V!*P=JpYT=M^(iX&if#oHYgTf*cAekI(Zl%rOtyLMLeUb-9v_98SGW zvRW1+Dt^BK6ZT9?=7aRm%1vt*9P4E(N`QRiW8DlPWio2?EG{O=n_mc~@y?moI^hsD zz9c0lYm9e^zAEu73|Gg?pX;+F@bXfi%B|*x)U-B>ng?>(`O?QDOiT*+9zePwFa*P)Y{{pD@P%_ZU&Gp? z8X4az$Y?#4Qz`}6@4^5V#$39ep#s*t^lVDt@oCNWHVnzxeeX+S>u4YlkezkGgd8*F zFt$#b=5%Xh^KwWMIwukx;KMU-e4O8O&^tFM>62=~`uQ`{Uv(J`Bz((NNzq-cAHvhl z3ih?H^Bu>-wIWO!Gf3-pn{s6Ya5KjtujWk#JGuG<&iJ;d#b(77hI8gH;ooD=bky^n zm4v;^l4>S*tG2xuhF{5lxqsVw65ONVStC^@=6(@k*#9v|nZBP41ixkggy_PuZObt% zNg{DN4|?bD+p~005)m|z-O*C}1|M~YtVVtH$leHrOVVUykVuB#ek!53V?e}U0-*r)9QzLeHp2xw<#3iphJC=7D)_EBuoTKQcO3-LA2IRHru&?MGLS>{YQXAO|H_oU@ z{b%w&e){TtT-U@Zpj@eB-H*C%E@6)HB^rQ)@B(sPBQtxrSL1+!#fOc9=NyW9^c%m& zWksdf+#qM+kBnxpx5!w)Ex)|ouWM#Ah_BpC$-F^+n%`lu8&g=gke?`)H!Aji6Jj#R z%EhxIotNI4%@pW@-)WmSbv!o3G=AjuikZp8;{pSObuNd4r9J%7P|+J}$C-z>_`o}J zs;TWs)gifhZMj}9ZDt;p-WfA8x1_r4jjcw-z3*$CZ<%B8rq1c^?LC38V8EvIHGC{Z zis_|)eq8K1h$=NoS7y@4uvi&6X_fmal0I>ymzky3R*mYe!yBQc5&m|Q9nI=nZI_=- z=O%HamssLfnJKhcVOBib#~Y(xqz$xO>>l>11j8@1cpotcyQPbCEqPqWGkT`~h-Q1m(bY3Z)( zy^@YO<3K5+i8E%X{8+`*71?&ro41=27M>@^^qLU{=aG{zyMgCN&KM`WO7soXz{dr$ zeW)4fzQr>*cGKWFKDIkusjtVUGA8^v>Jxca#Gva46TIa4fY4sad%6>;VGJy>A)7H< zUv6j%7lNRJ8g=wQRL9SNTy%*)5)XW6e*s6VzX1?z)Qd zXqNEZw1s5}-IU5VNb_90K@}g~ooodAlrdGmGvzf zcRw&s>~2Sr?!F#e9D?M8q)5@fs%Bhn$mXpIEh$*o7UY`%zk}PiWg7m} zWi~!W%G|xj8Vf~_#S8j^_Y_UFRa_QLlwMpg0{g7e3Py?gSocDxWIy79U1s(o&W2M4 zSG1MchLP-X{QOI$w&vCjPs=@P-2gqg&~h$mC&$KwXZ*rOIW5k~ij6kM?=WB{cdlP^ z@oWp^*2?H7SR^)_vx=ub*eAk?xl@F94g$u;Bz%2UP*-0X>&@@2&Lx$@J$%hy2!5KI z$2E$Z9h;zb7cz<^1~>nUfP8r9t{w^!F8sljP% zxa2ciC-^@G52!VNU$3IhiS6rNLR61Zq1$R7fTR)ARNCy5+vQpmFGftH*nSkfdiEr$wQc3-Z&Xno~(t3~e3=72kcHuDk$I zNq)=Cn5#Tod!18F8rd8i>6;3qd*0-C;S@S~Zt&)5o~yQoPb=`X@_e16PK8v3-ynOJu+4%m*~zs? z@50MIjkOpoJy)D?=QvUIp-LRWLKzV07*IlKKr2_w4JbVxlNBS1L^_}Rct-JNmT_d! zZF-dI?&LIea9$bTaYUS63gV1o{w`38NsXlhW}X%+Hkt z+{0rBI?1Y2IulC+&(@ufRwuK2AaJDFLP0AGh1OiM zQteAv2K``ZD%3C|)_fy~@*vv1%Bkiq+sVz&4b5_1C&%OsR9vh7DDF-S09rK~&F>Q2 zKSgFDXxv%3)r!{K;iEJ+6>BiNx$e8EnXatn^l`U@SB|NJitK=p~8GbRxNJ zTM7vop83GlAuW+VY*DZ7g@Z^kWzcBadQP+L5nWI>ZgL6yU01QkDUiyYsu4Le|2_!u z&=mUnp(zju{{w{m2ZyFye}8ED&+}0L^?(08_>Y59C^h8&{IBDG9+Yw+9F)TU{-D%D zrA?j;j@xuh$ei*r$^t+WIv0&gZEjJ%&~Co_E}$^1OyHR`ZBWzgwFjGN*GgGa=YtUN zd`W|L%ig5}P!ML?C{gaqt)%5)t%dLX?pYO*52`TGboFUv1BiEj#Ox{jRGL8 z?z}J*!%*?nM5*uSD5%I?2g&L36U&!%*XxNA^@-Y%X4W6E(#L9^t+f$UMpg{#=HN@N zX6lyqH*61F4hGms^_@?hc+LkT?>j{w20q-c@O3cTLsuI{5>#V+`0Dy?V&-jRfl3u#H#pYOqP4PV@j&Qd z{-}gC`fg$QbLVA6LO&@~PR~o+V=&`o0lqgSrAh>gPp>nDIU2@$vnD}KWW&D3?A)Ty zcx!=T*7~TeT3rO=l&#+rocFKIp(2#?=p=&eJ^n0FVfHVBhxSU;*(-4^*?=bPCVsV} zS$=>VYkCK~<=tk_D{I*HVivVqP4nWs`?j_n{;Htgw;zGmHry7;6?Dnl_b>F9I4_$B ziepBpIrt{Sf}Y_P?0fM?GoY2veZIoWm2$aZ$yBEqGb4-antP|W>bF*fhAaW@ zyzkll_Vfp2ni{YA@hLNMef5)o`gW6D>~z5EAe?d^4Z3K1JzMJ3`}1a_{*Kty`#fsm zf^^$+pl5VnbqDsiFtZO@sbBbiGEIFg_?VT+?_8OYG9H~7%zy`|RHJcz-JvG|7qrVEs^Hu9!1eT&JCBAxq_<^t3YKjiZzdG>d*(dPB> zLcEsp{Vjz`$~0MZDf{maGD++Id(Hsd*5fZ zRTado!;6J?P{R0)R?uYjgTf6npL|ogeo0sL1E~;%j`upe=y91j_+UNbxb4pA@y%P~)F`@CXN`WAk-1)LI}&&>PBw8H8>#nXXd?WSp3f`zDYLyoNptV*lR+1; z$cO6C=ELl04Np>h+JTv^L1M2(gv72C!UBwh07e>F=>CREx zBXxS(sF+8j7*|=rn&mw7xhf{ZPwx4_E8}UYjX^S_txwn?AuWR{BUcRa(VFjoYE(fSDJhe4l z8DaiN6o#G9AKlkf6=GiP%QbM;6(L#tzKV2Ym!Tkrj#Wl3vlQDx1t4<#=B=Ds;D$k~ zgvN`!Ac*vgDvy{jZB{eQv93wd&qd_YXI6)9@kF03VhyW!B$TdZZY`h?8a}s1b}!x% z>MW~X?v_BnOI`^U3WYDW#?B<;bxiHC^BYBh(X`ue3b)7MpG>4d>E=XGS~Y{|vwKzCzt5j|Ii6 z{P-|w5#KY>)doj#Ndobw${CGjax5o}Mn0ue1L;4$WX;1Wyx%`ePGFN`uGGARI~^L> zekpz~y~Kb2x#C2u>Q+ikH`xSkSnmx-fUo}3xE6S#3Ya@y(QHCcP({`|K6+e*mE zwWZ_HWUrS<4K)TL5B~S9An2SBDEN1f3-IsrAQ$KV8xQ{9F5LkB`5q@O&cBi&7x3@N zFiLgSb{2~3ajs&1x;pR@Gq2%_e%7Hoj$ZDW+swlj0a{ub8bPAeovnR0qEyDXk9}4`x3Dg)5;f;}wLBVAUVY8!rdz=5u6sn{lptk0)-$45E-oR_rqq7Hq$DRgP+mWDS~YX0?bsiMLdqAS+bB^g4$Ip)?X8$s)Fy*fH@63{Mtq*s%wFfHneL4vU=E8k%j z8tjAl(MQsUxbM|%zWA+%goP#^p09q!)$4ws80@{Pry?;U>!K={DF1keJkqCD2^$P|TojjsEb9CcRlZBz&O4_Ry%}6R7 zqo;!5OhvEFBpA)FqfL1`x$mCJ5c**Zcc!Z7Ntl$o_)XImn%nl^sY(=aiFl~5ZXRHd zAW2ru5VwtIW%Ys{)kM`D4$p`n0lU4F)M8Lk2lNzxq#leDq8svt<=(`O5u6%x45P7g z_OB@X_#PTD;Iguj;HZwsr#DNVz2=$lZm9a)0(iwWQ8RN=uiW~`_nWxy9GZ}MAFr?{ zXTTE$A#P&UeAk=HMo0@JwI&Q@$mL4^iY~Pqa$qRG;XSj)Js%TE2k0tmN{W3^=1QoGTnl|u9n6&9AJ%$A0l!JUcjl;T zI4Q^u;hYb6?-oEc0NdH5}e&VW?I^&U8jPN?c7}=T5GJc0{>u{i~ z{IRs$YPP#raZ^Cu83UuG=x4moHn8pyD&l*5U@#oO|IriIb#pF{aKCyC3uWgje*6~u z=10JVTVX+97tMWJSoh)2qF!LXyQWL=o2D?8BL0ZAshRI4EQt>mpH;Sr9B5Y0y>o)C zx2jCY)o7RSS$divUF)87{pd9)%b$H&4Niz9OR$_2Dp`m+J3{n#aeG`?ob@VxMX^H`OIt?+qm21%9+17SYpNBZ$&~3JbrTOdybwM zoX-(4%iC|QwKCLql@a}2gON>ta$^C{L3DoD!u=+b>eQRkxBFHY&G6!Qiyv*{@dE^= zzZtjxdre6SM?gu9Ym>KuOv{wI#U&axR1g zE1nddV@i<9vPTrCd^u;+@$#JR)VofgI+!9{A8oyT`oumdN`hs*=%CN!Dz&LnGE73o z*vav0qKBK8$cloD*CW{HUL{-7BiRknOj&v3;Gx}@q;2#*^&YWd3(?gib}7(C zZG{7zLlw#5qPxPQ7MSalT_02+U-Ynw7y2@Hq=!Z>%Q0&Lu!_fo%7$oLvuV(Q%caM! zX=LPLv2OW>Dg)Mg$gY$n8|YH{HwLrn2DXG|aF+>D7@FRupJl&zOCVSiN!p}XFe8y~ z?!W$$O*qmyQ4#g)8?u&*-tBdXY$KPg&9r9sji6p2S&bxe=t{1a z2j$>YBv3F_4dUKSCQNI-Jjob6J@+wkP$JppIo28PcQQiP6&$DQVMJF4j2U66tG#-( zx#b(d$Zk^LBYRAwf$uPr?@~E-{53;x-XRc+PHAiFY_L`px5J#?+}- z=4=w4EFSU0Nv}WEAMn-YHdqg4N;t=zeyccmi9S3X2}pgJ#v3WjwV1*0-oE2DeN zAla-tQz9eTXGas`zoxZvEmJ{$X!b=eQ0Y$Sq5-oyyZWK)Y1X?N;L=Pd(+)ElC&5Yg zyxPNr_xMqwD0n@qn3T^wE*c&l#d!$nvUX>%+GBMZN|P@RgsQH{DXgrdqqCQVL-+1blDZh0&xbTaXckW>>)%wIR zZSa`)y)Y)zKzPVx3b~U+NFv7##4lWkW0*f1JE+6E7D#N0{Hy@1g^Kb;=ndY^KE|E^ zCQJ%zP2=<_b$l!|{70>pYHDY&v`6AON8JmXVLn#+$n`^2`T`$59NUwz)HZLLaNQL_ zWCj!ib=R+#y@%0W(Gqdu!^(`LzAGCP80VydFSNfQpL-HELRJ zJq^&)d85+c_JQV-LL>eGzOrVn=9DMNqU_i7U}5}za=Uc7F2U%*ws3JX%jL=JmByx7 z0BrgesV^-oYGmLez2;IX$%MjJF|U? z_}=_bASk5>;m3OuRq*16;zl|sc+5OpItt7 zJ{0y}%vXJ!mD1c-40|m!=_cXApS8K$J<*HiHMx>@IQ`;dP%7Q|<1_GunX-Z%N9$@) zpxvkQnmiAsZpn@c2!>&0`y1>#0X|Efsi}re-w@xU*(Ec&vL()TP#J|QsH0`DnC7hf zhXbfN^|-*swpV6TeQX_qBk;9^Pyw*zlhSk4}*5fv;O z+|Ooz#-vkC*5@n6tf6$W_nEIrLpMowTg$M-2#slSV)sp=CQEURWdPv;Y9o1?d1gUj zfiDxSg`(<+1e?mJbkd1(ji8!0V_!!;iH8cI&{J4bj9K2M!IM%VqiNCN%tuAnF7E>I z4E7aaibMyRw~Uz+qbOH%k%TT9zCqUho95CgqrFxqZR!yeA_1S8VIn|)4BWiN z9hD{%S&_3b9j0Ucqq^gDRA29Vjc4}iT?7Q}p@nuRC55{5s%!Xt1EY$V`XD~fB>ASn z4WqKuS%S-t%W7N+-tRuBmPPA)oakfu?&DM@U>=o^6w>Ig?`Q%dH7c>R&%_z7{La@n z(Yw!<&m`7J(}8DI9-6a6F7EymCFcm*b7CB+^P~q#K{L@~X;4$bPLau&<2A)=*$|bT z*v`4ixM>NjOcq~!AHC+IJBxK5ex2g?(UK}PKK@olxSh(wRbi@Lu=KSlA>~Ftjn0V5 zz1q5TdaUJs=!x}|6UC$O}CP4#3pRkF{d|k&pniy(QsJtNN z=Q5ZQA4=B2A=#M}k9qZJ{_sRcLzUAbqWt4Q)WKFa!kHZU#q+H)U$U{y) z)BUs`;!&Q1RL`=uRPz7+<1w8u?Vb{ zuM{qK@@Kgj z=S8dGkh!o$N8J%!E4c!qFssNPfxPP^P1>(VvXsq>hTKMGA6Dj=R#}g5W#aH4PvsLW zXK!*b>AgC8-Nlk#GSQc7%4C4Wo=z;N);q2{n|s7A222oj=E!Ip@6fO?7h}^|E92RV zBMkx7cc*Vg6-FWzckX?>;+*;F)zYw|F3>O6&%U()PZ}8dTp*%y(Y)Sjx-*1tg~dP? zW^;F}NNl>;BZQ_LhvOb{(8Lf>^@=+=dG=Hr+tBa+g~<80+{I&LWOBNl$(!g6ifBD` zy%kmG!>4|)(eKxAqPVAz>uNNuyM^fVGq-uG+%2`k=FCSmhe9|ksiB48bT_htPifOQ ziDNsRhlT02j$TLR=UZF7>u?LybU_KK8p7%k7fmscv64_O#@X~wCtJ|?s2z7%c+NzO zw6(s1ser^J>n#5mi4RxG=lzGn+}!7`iqoi@b`PC`YL<(hHn5CL_1(W7!KKz>zO>X+ zp5t4Z;xJGpNvOA4IdEzAf7kc{&3_D-`py>;rTz`@@jz_)kdv!GAq*I`dA_wX)E5w3 zetDBPIH-MS1;Hb$l+#)M60!K>BRV?;xn`wTu9StC0XV%&HaxR{unZ1e=| zc9YV(@AS}%;s%3Ci6sJ&Ke&G94-gFW2MGW7`2!C4-`mcB{+!tY4)`mZz&Zb(O|q2x ze{N?8=C4`y45FmiK1G`FHRdNxSARbXoS!A%k4Pz8LY8H%fL_;S2sI8 zH_%;h1QVS&*ECsRMi`HqsBd|t5o${QxA1k8v_Ll|iS$^YvaNg-A3ePtbDVjPJt}kb zd^sU(l~PJmNn&=;;Dt6<@V}p7c4o@KuUzPXiv6C0f>J2Shvb2~LtIi zd;LIFf6vLVNgMx4yqC7k$(h;Y`;;qnn#$LfK+~<4Xrd{Z3go`RW@ZIro_E#7QU;1e zAZ#aP-tals$r|-csdl#=%jqKYB!Z8IBU%PguJK4M6@ulqhL`PlZ6kwnpk?iFJxUaC4|{+1440{WJ-Y1t=mw&*(mXd)%y486_Kt7s4~NyMhlSr0-Dq71p%SMy z@3B=a0XgCU+KveV#?21v6){}vS43ejPoMVqF&~Z8_;Ylc%Vz`CE7*ZcqhBf4sF~4q z69A6O5r<*BAMhMlB!yUqH0Z^f)98$eKFx4RI`&f;V|4cJ*A~3Oc*3Z`GSXfpf)~|y z-&L03uwNZMw5Zpq8|MLxi5b>l-i6+eW&AAk&WlQbkjRI1Z8o>L$57NzNs+SBMzCe2IY zwxbs7YAC}Csq~{?2tsg&bN(LOfl$C7An-p3?x6o9xc_@UiugUaL;jo-1r9<8?%;o8 ztDq!pHv{;&RbV-b9q0(QASbhZ#$+0cR+PX6;#*Ds_F!%*oCQt(*29Udc@&C?8K~R& z=G5_YVMT?(=dBiv{bNtrtwHI9y2fqcSfS@x+TmJ{Tx`z#6}~bum<%4LM1~3w*Q0Pq z{P0l_{k%Mk(a`iYL{p}5Fs;6FPb~4I5=dl5OyIyIsb5u^6}}`$U+H^63e=R)=pzZt z6yYPZr*2FnRF~TAhsRKSPin<^1mYL+4;aD1WGI$1IMW%4 zNyv`WNNcZ$35lM(ZDH$s--4zlkWop<&+Jof$y_L>?!@*6-7(nO`-+g|HBu59Rtky{Z-GP*16r;o?Cnst#5NCudn4q>p0;2l1lr6XnAS(48Lw{IZ z7?ZQQ5+fiG)ZP0!U*e1Mhi*!Sj$l$D%36$I(rcxDX3N!OTEA5ko>{5$w8)KIp@>CJ;4Phi03ILI~TS+fjo1-`5qK=?3Sr@QTGRJDLuD&j|Z;#Tu2foNg+lsGTC{_ z#H$Qy8JTz7T8h=?MD=p0x-7kAj4Z^!FIa~W(gwVwINF0rW2;tMq+P0!$VW;mQoAeB z;g#e0W_eh_W=xy#B3lJ`cZ{*iO|f3 zQL3O_XXtGFYx5!dn{-vF!b9CxN~yX23rd``?bmCJ><|+$R`?{V_?{Jh)uEkY?A<_Exr63MUq_=`|>$5grERU0IZAmoL`m8jUpx`%Bocb+dIt&;fp^Y;o7JsAAQ z@0xXE7Iqqd-_qK=c>Y}Te{AZVZ4Hgk0n~6PH9Fvr4>c45 z0YRvZ{)zp{_4eBn%ReySuY6#C#yDYc7y`xxLo5gXm9OT{7!dI5efM85&R^LS|B7)T z^aTj~l@#Z%7#y)K2!_}O_+PXO;Y5@N0VB$Tf)Vru!hYrN`3uGcL6isom0#x17zhAC zunUOuSGJYEU_dB>4L~3$f*v3+qU}Kt7(!n_P#A)4AQ%j>4K5gBpW$2x`ho$7;|2yG z>H+3Nv>zDAiHLy!h;>0w1U3oP=;9&J738f(@V`#6CkoaD*{}f)VWu1tZ!33PGG3 zPza(gK%qcHJ^qEiL192dJ-85K4(#XmFBm773-~WE1Yh8U{1o{Y3=T4jL$zY#JXT0LfrVdhDGq{pBNB?fN>(&>Zdd=gucLFi1J`u2xAF^0}<=O5#!5G z_CSc)pr5V^M8LQJh~?l2{s#J~#=pRz{{yqP)ipIYv_=0#)26P5KRKC0-pb0J8vc*< zx45N|74<(}k%+(0;065j!JlyvVhA-dfWRS!hDJt4Ab_5c9-I?os0RT*|N9a@*8%9i WrAz#65dh-kf&6YRE literal 0 Hc-jL100001 diff --git a/doc/printing-overview.shtml b/doc/printing-overview.shtml new file mode 100644 index 0000000000..1682dae7f4 --- /dev/null +++ b/doc/printing-overview.shtml @@ -0,0 +1,125 @@ +

1 - Printing System Overview

+ +

This chapter provides an overview of how the Common UNIX Printing System +works. + +

The Printing Problem

+ +

For years the printing problem has plagued UNIX. Unlike +Microsoft® Windows® or Mac OS, UNIX has no standard interface or +system in place for supporting printers. Among the solutions currently +available, the Berkeley and System V printing systems are the most +prevalent. + +

These printing systems support line printers (text only) or +PostScript printers (text and graphics), and with some coaxing they can +be made to support a full range of printers and file formats. However, +because each varient of the UNIX operating system uses a different +printing system than the next developing printer drivers for a wide +range of printers and operating systems is extremely difficult. That +combined with the limited volume of customers for each UNIX varient has +forced most printer vendors to give up supporting UNIX entirely. + +

CUPS is designed to eliminate the printing problem. One +common printing system can be used by all UNIX varients to support the +printing needs of users. Printer vendors can use its modular filter +interface to develop a single driver program that supports a wide range +of file formats with little or no effort. Since CUPS provides both the +System V and Berkeley printing commands, users (and applications) can +reap the benefits of this new technology with no changes. + +

The Technology

+ +

CUPS is based upon an emerging Internet standard called the Internet +Printing Protocol. IPP has been embraced by dozens of printer and +printer server manufacturers and is supported by Microsoft Windows +2000. + +

IPP defines a standard protocol for printing as well as managing +print jobs and printer options like media size, resolution, and so +forth. Like all IP-based protocols, IPP can be used locally or over the +Internet to printers hundreds or thousands of miles away. Unlike other +protocols, however, IPP also supports access control, authentication, +and encryption, making it a much more capable and secure printing +solution than older ones. + +

IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") +which is the basis of web servers on the Internet. This allows users +to view documentation, check status information on a printer or server, +and manage their printers, classes, and jobs using their web browser. + +

CUPS provides a complete IPP/1.1 based printing system that provides +Basic, Digest, and local certificate authentication and user, domain, +or IP-based access control. TLS encryption will be available in future +versions of CUPS. + +

Jobs

+ +

Each file or set of files that is submitted for printing is called a +job. Jobs are identified by a unique number starting at 1 and +are assigned to a particular destination, usually a printer. Jobs can +also have options associated with them such as media size, number of +copies, and priority. + +

Classes

+ +

CUPS supports collections of printers known as classes. Jobs +sent to a class are forwarded to the first available printer in the +class. + +

Filters

+ +

Filters allow a user or application to print many types of files +without extra effort. Print jobs sent to a CUPS server are filtered +before sending them to a printer. Some filters convert job files to +different formats that the printer can understand. Others perform page +selection and ordering tasks. + +

CUPS provides filters for printing many types of image files, +HP-GL/2 files, PDF files, and text files. CUPS also supplies PostScript +and image file Raster Image Processor ("RIP") filters that convert +PostScript or image files into bitmaps that can be sent to a raster +printer. + +

Backends

+ +

Backends perform the most important task of all - they send the +filtered print data to the printer. + +

CUPS provides backends for printing over parallel, serial, and USB +ports, and over the network via the IPP, JetDirect (AppSocket), and +Line Printer Daemon ("LPD") protocols. Additional backends are +available in network service packages such as the SMB backend +included with the popular SAMBA software. + +

Backends are also used to determine the available devices. On +startup each backend is asked for a list of devices it supports, +and any information that is available. This allows the parallel +backend to tell CUPS that an EPSON Stylus Color 600 printer is +attached to parallel port 1, for example. + +

Printer Drivers

+ +

Printer drivers in CUPS consist of one of more filters specific to a +printer. CUPS includes sample printer drivers for Hewlett-Packard +LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, +and Stylus Photo printers. While these drivers do not generate optimal +output for the different printer models, they do provide basic printing +and demonstrate how you can write your own printer drivers and +incorporate them into CUPS. + +

Networking

+ +

Printers and classes on the local system are automatically shared +with other systems on the network. This allows you to setup one system +to print to a printer and use this system as a printer server or spool +host for all of the others. Users may then select a local printer by +name or a remote printer using "name@server". + +

CUPS also provides implicit classes, which are collections of +printers and/or classes with the same name. This allows you to setup +multiple servers pointing to the same physical network printer, for +example, so that you aren't relying on a single system for printing. +Because this also works with printer classes, you can setup multiple +servers and printers and never worry about a single point of failure +unless all of the printers and servers go down! diff --git a/doc/references.shtml b/doc/references.shtml new file mode 100644 index 0000000000..f47d54e8c4 --- /dev/null +++ b/doc/references.shtml @@ -0,0 +1,42 @@ +

References

+ +

CUPS Documentation

+ +

The following CUPS documentation is referenced by this document: + +

    +
  • CUPS-CMP-1.1: CUPS Configuration Management Plan +
  • CUPS-IDD-1.1: CUPS System Interface Design Description +
  • CUPS-IPP-1.1: CUPS Implmentation of IPP +
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual +
  • CUPS-SDD-1.1: CUPS Software Design Description +
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual +
  • CUPS-SSR-1.1: CUPS Software Security Report +
  • CUPS-STP-1.1: CUPS Software Test Plan +
  • CUPS-SUM-1.1.x: CUPS Software Users Manual +
  • CUPS-SVD-1.1: CUPS Software Version Description +
+ +

Other Documents

+ +

The following non-CUPS documents are referenced by this document: + +

diff --git a/doc/sam.html b/doc/sam.html new file mode 100644 index 0000000000..20e55feaa5 --- /dev/null +++ b/doc/sam.html @@ -0,0 +1,4238 @@ + + + + CUPS Software Administrators Manual + + + + + + + +

+

CUPS Software Administrators Manual


+CUPS-SAM-1.1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
Preface + +1 - Printing System Overview + +2 - Building and Installing CUPS + +3 - Printer Management + +4 - Printer Classes + +5 - Client Setup + +6 - Printing System Management + +7 - Printing with Other Systems + +A - Software License Agreement + +B - Common Network Settings + +C - Printer Drivers + +D - List of Files +
+
E - Troubleshooting Common Problems + +
+

Preface

+

This software administrators manual provides printer administration +information for the Common UNIX Printing SystemTM ("CUPS +TM"), version 1.1.1.

+

System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+ + +

Document Overview

+

This software administrators manual is organized into the following +sections:

+ +

Notation Conventions

+

Various font and syntax conventions are used in this guide. Examples +and their meanings and uses are explained below: +

+ + + + + + + + + + + + +
Example   Description
 
lpstat +
lpstat(1)
   The names of commands; +the first mention of a command or function in a chapter is followed by +a manual page section number.
 
/var +
/usr/share/cups/data/testprint.ps
    +File and directory names.
 
Request ID is Printer-123 +   Screen output.
 
lp -d printer filename ENTER +   Literal user input; special keys like ENTER are + in ALL CAPS.
 
12.3   Numbers in the text are +written using the period (.) to indicate the decimal point.
+
+ + +

+

Abbreviations

+ The following abbreviations are used throughout this manual: +
    +
    +
    kb
    +
    Kilobytes, or 1024 bytes +
     
    +
    Mb
    +
    Megabytes, or 1048576 bytes +
     
    +
    Gb
    +
    Gigabytes, or 1073741824 bytes +
     
    +
    +
+

Other References

+
    +
    +
    CUPS Software Programmers Manual
    +
    A programmer guide for interfacing with and/or extending the CUPS + software. +
     
    +
    CUPS Software Users Manual
    +
    An end-user guide for using the CUPS software. +
     
    +
    +
+

1 - Printing System Overview

+

This chapter provides an overview of how the Common UNIX Printing +System works.

+

The Printing Problem

+

For years the printing problem has plagued UNIX. Unlike +Microsoft® Windows® or Mac OS, UNIX has no standard interface or system +in place for supporting printers. Among the solutions currently +available, the Berkeley and System V printing systems are the most +prevalent.

+

These printing systems support line printers (text only) or +PostScript printers (text and graphics), and with some coaxing they can +be made to support a full range of printers and file formats. However, +because each varient of the UNIX operating system uses a different +printing system than the next developing printer drivers for a wide +range of printers and operating systems is extremely difficult. That +combined with the limited volume of customers for each UNIX varient has +forced most printer vendors to give up supporting UNIX entirely.

+

CUPS is designed to eliminate the printing problem. One +common printing system can be used by all UNIX varients to support the +printing needs of users. Printer vendors can use its modular filter +interface to develop a single driver program that supports a wide range +of file formats with little or no effort. Since CUPS provides both the +System V and Berkeley printing commands, users (and applications) can +reap the benefits of this new technology with no changes.

+

The Technology

+

CUPS is based upon an emerging Internet standard called the Internet +Printing Protocol. IPP has been embraced by dozens of printer and +printer server manufacturers and is supported by Microsoft Windows +2000.

+

IPP defines a standard protocol for printing as well as managing +print jobs and printer options like media size, resolution, and so +forth. Like all IP-based protocols, IPP can be used locally or over the +Internet to printers hundreds or thousands of miles away. Unlike other +protocols, however, IPP also supports access control, authentication, +and encryption, making it a much more capable and secure printing +solution than older ones.

+

IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") +which is the basis of web servers on the Internet. This allows users to +view documentation, check status information on a printer or server, +and manage their printers, classes, and jobs using their web browser.

+

CUPS provides a complete IPP/1.1 based printing system that provides +Basic, Digest, and local certificate authentication and user, domain, +or IP-based access control. TLS encryption will be available in future +versions of CUPS.

+

Jobs

+

Each file or set of files that is submitted for printing is called a +job. Jobs are identified by a unique number starting at 1 and are +assigned to a particular destination, usually a printer. Jobs can also +have options associated with them such as media size, number of copies, +and priority.

+

Classes

+

CUPS supports collections of printers known as classes. Jobs +sent to a class are forwarded to the first available printer in the +class.

+

Filters

+

Filters allow a user or application to print many types of files +without extra effort. Print jobs sent to a CUPS server are filtered +before sending them to a printer. Some filters convert job files to +different formats that the printer can understand. Others perform page +selection and ordering tasks.

+

CUPS provides filters for printing many types of image files, +HP-GL/2 files, PDF files, and text files. CUPS also supplies PostScript +and image file Raster Image Processor ("RIP") filters that convert +PostScript or image files into bitmaps that can be sent to a raster +printer.

+

Backends

+

Backends perform the most important task of all - they send the +filtered print data to the printer.

+

CUPS provides backends for printing over parallel, serial, and USB +ports, and over the network via the IPP, JetDirect (AppSocket), and +Line Printer Daemon ("LPD") protocols. Additional backends are +available in network service packages such as the SMB backend included +with the popular SAMBA software.

+

Backends are also used to determine the available devices. On +startup each backend is asked for a list of devices it supports, and +any information that is available. This allows the parallel backend to +tell CUPS that an EPSON Stylus Color 600 printer is attached to +parallel port 1, for example.

+

Printer Drivers

+

Printer drivers in CUPS consist of one of more filters specific to a +printer. CUPS includes sample printer drivers for Hewlett-Packard +LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, +and Stylus Photo printers. While these drivers do not generate optimal +output for the different printer models, they do provide basic printing +and demonstrate how you can write your own printer drivers and +incorporate them into CUPS.

+

Networking

+

Printers and classes on the local system are automatically shared +with other systems on the network. This allows you to setup one system +to print to a printer and use this system as a printer server or spool +host for all of the others. Users may then select a local printer by +name or a remote printer using "name@server".

+

CUPS also provides implicit classes, which are collections of +printers and/or classes with the same name. This allows you to setup +multiple servers pointing to the same physical network printer, for +example, so that you aren't relying on a single system for printing. +Because this also works with printer classes, you can setup multiple +servers and printers and never worry about a single point of failure +unless all of the printers and servers go down!

+

2 - Building and +Installing CUPS

+

This chapter shows how to build and install the Common UNIX Printing +System. If you are installing a binary distribution from the CUPS web +site, proceed to the section titled, Installing a +Binary Distribution.

+

Installing a Source Distribution

+

This section describes how to compile and install CUPS on your +system from the source code.

+

Requirements

+

You'll need ANSI-compliant C and C++ compilers to build CUPS on your +system. As its name implies, CUPS is designed to run on the UNIX +operating system, however the CUPS interface library and most of the +filters and backends supplied with CUPS should also compile and run +under Microsoft Windows.

+

For the image file filters and PostScript RIP, you'll need the JPEG, +PNG, TIFF, and ZLIB libraries. CUPS will build without these, but with +significantly reduced functionality. Easy Software Products maintains a +mirror of the current versions of these libraries at:

+ +

If you make changes to the man pages you'll need GNU groff or +another nroff-like package. GNU groff is available from:

+ +

The documentation is formatted using the HTMLDOC software. If you +need to make changes you can get the HTMLDOC software from:

+ +

Compiling CUPS

+

CUPS uses GNU autoconf to configure the makefiles and source code +for your system. Type the following command to configure CUPS for your +system:

+
    +
    +./configure ENTER
    +
    +
+

The default installation will put the CUPS software in the /etc +, /usr, and /var directories on your system, +which will overwrite any existing printing commands on your system. Use +the --prefix option to install the CUPS software in +another location:

+
    +
    +./configure --prefix=/some/directory ENTER
    +
    +
+

If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in a +system default location (typically /usr/include and +/usr/lib) you'll need to set the CFLAGS, +CXXFLAGS, and LDFLAGS environment variables prior +to running configure:

+
    +
    +setenv CFLAGS "-I/some/directory" ENTER
    +setenv CXXFLAGS "-I/some/directory" ENTER
    +setenv LDFLAGS "-L/some/directory" ENTER
    +./configure ... ENTER
    +
    +
+

or:

+
    +
    +CFLAGS="-I/some/directory"; export CFLAGS ENTER
    +CXXFLAGS="-I/some/directory"; export CXXFLAGS ENTER
    +LDFLAGS="-L/some/directory"; export LDFLAGS ENTER
    +./configure ... ENTER
    +
    +
+

Once you have configured things, just type:

+
    +
    +make ENTER
    +
    +
+

to build the software. + +

+

Installing the Software

+

Use the "install" target to install the software:

+
    +
    +make install ENTER
    +
    +
+
+ + +
WARNING: +

Installing CUPS will overwrite your existing printing system. If +you experience difficulties with the CUPS software and need to go back +to your old printing system, you will need to reinstall the old +printing system from your operating system CDs.

+
+
+

Running the Software

+

Once you have installed the software you can start the CUPS server +by typing:

+
    +
    +/usr/sbin/cupsd ENTER
    +
    +
+ + +

Installing a Binary Distribution

+

CUPS comes in a variety of binary distribution formats. Easy +Software Products provides binaries in TAR format with installation and +removal scripts ("portable" distributions), and in RPM and DPKG formats +for Red Hat and Debian-based distributions. Portable distributions are +available for all platforms, while the RPM and DPKG distributions are +only available for Linux. +

+ + +
WARNING: +

Installing CUPS will overwrite your existing printing system. If +you experience difficulties with the CUPS software and need to go back +to your old printing system, you will need to remove the CUPS software +with the provided script and/or reinstall the old printing system from +your operating system CDs.

+
+
+

+

Installing a Portable Distribution

+

To install the CUPS software from a portable distribution you will +need to be logged in as root; doing an su is good enough. +Once you are the root user, run the installation script with:

+
    +
    +./cups.install ENTER
    +
    +
+

After asking you a few yes/no questions the CUPS software will be +installed and the scheduler will be started automatically. + +

+

Installing an RPM Distribution

+

To install the CUPS software from an RPM distribution you will need +to be logged in as root; doing an su is good enough. Once +you are the root user, run RPM with:

+
    +
    +rpm -e lpr
    +rpm -i cups-1.1-linux-M.m.n-intel.rpm ENTER
    +
    +
+

After a short delay the CUPS software will be installed and the +scheduler will be started automatically.

+

Installing an Debian Distribution

+

To install the CUPS software from a Debian distribution you will +need to be logged in as root; doing an su is good enough. +Once you are the root user, run dpkg with:

+
    +
    +dpkg -i cups-1.1-linux-M.m.n-intel.deb ENTER
    +
    +
+

After a short delay the CUPS software will be installed and the +scheduler will be started automatically.

+

3 - Printer Management +

+

This chapter describes how to add your first printer and how to +manage your printers.

+

The Basics

+

Each printer queue has a name associated with it; the printer name +must start with a letter and can contain up to 127 letters, numbers, +and the underscore (_). Case is not significant, e.g. "PRINTER", +"Printer", and "printer" are considered to be the same name.

+

Printer queues also have a device associated with them. The device +can be a parallel port, a network interface, and so forth. Devices +within CUPS use Uniform Resource Identifiers ("URIs") which are a more +general form of Uniform Resource Locators ("URLs") that are used in +your web browser. For example, the first parallel port in Linux usually +uses a device URI of parallel:/dev/lp1. + +

+

You can see a complete list of supported devices by running the +lpinfo(8) command:

+
    +
    +lpinfo -v ENTER
    +file file
    +network socket
    +network http
    +network ipp
    +network lpd
    +direct parallel:/dev/lp1
    +serial serial:/dev/ttyS1?baud=115200
    +serial serial:/dev/ttyS2?baud=115200
    +direct usb:/dev/usb/lp0
    +network smb
    +
    +
+

The -v option specifies that you want a list of +available devices. The first word in each line is the type of device +(direct, file, network, or serial) and is followed by the device URI or +method name for that device. File devices have device URIs of the form +file:/directory/filename while network devices use the more +familiar method://server or method://server/path + format.

+

Finally, printer queues usually have a PostScript Printer +Description ("PPD") file associated with them. PPD files describe the +capabilities of each printer, the page sizes supported, etc., and are +used for PostScript and non-PostScript printers. CUPS includes PPD +files for HP LaserJet, HP DeskJet, EPSON 9-pin, EPSON 24-pin, and EPSON +Stylus printers.

+

Adding Your First Printer

+

CUPS provides two methods for adding printers: a command-line +program called lpadmin(8) and a Web interface. The +lpadmin command allows you to perform most printer +administration tasks from the command-line and is located in +/usr/sbin. The Web interface is located at:

+ +

and steps you through printer configuration. If you don't like +command-line interfaces, try the Web interface + instead.

+

Adding Your First Printer from the Command-Line

+

Run the lpadmin command with the -p option +to add a printer to CUPS:

+
    +
    +/usr/sbin/lpadmin -p printer -E -v device -m ppd ENTER
    +
    +
+

For an HP DeskJet printer connected to the parallel port this would +look like:

+
    +
    +/usr/sbin/lpadmin -p DeskJet -E -v parallel:/dev/lp1 -m deskjet.ppd ENTER
    +
    +
+

Similarly, an HP LaserJet printer using a JetDirect network +interface at IP address 11.22.33.44 would be added with the command:

+
    +
    +/usr/sbin/lpadmin -p LaserJet -E -v socket://11.22.33.44 -m laserjet.ppd ENTER
    +
    +
+

As you can see, deskjet.ppd and laserjet.ppd + are the PPD files for the HP DeskJet and HP LaserJet drivers included +with CUPS. You'll find a complete list of PPD files and the printers +they will work with in Appendix C, "Printer +Drivers".

+

Adding Your First Printer from the Web

+

The CUPS web server provides a user-friendly "wizard" interface for +adding your printers. Rather than figuring out which device URI and PPD +file to use, you can instead click on the appropriate listings and fill +in some simple information. Enter the following URL in your web browser +to begin:

+ +

Click on the Add Printer button to add a printer.

+

Managing Printers from the Command-Line

+

The lpadmin command enables you to perform most printer +administration tasks from the command-line. You'll find lpadmin + in the /usr/sbin directory.

+

Adding and Modifying Printers

+

Run the lpadmin command with the -p option +to add or modify a printer:

+
    +
    +/usr/sbin/lpadmin -p printer options ENTER
    +
    +
+

The options arguments can be any of the following:

+
    +
    +
    -c class
    +
    Adds the named printer to printer class class. If the +class does not exist then it is created.
    +
    -i interface
    +
    Copies the named interface script to the printer. + Interface scripts are used by System V printer drivers. Since all +filtering is disabled when using an interface script, scripts + generally should not be used unless there is no other driver for a +printer.
    +
    -m model
    +
    Specifies a standard printer driver which is usually a PPD file. A +list of all available models can be displayed using the lpinfo + command with the -m option. A list of printer drivers +included with CUPS can be found in Appendix +C, "Printer Drivers".
    +
    -r class
    +
    Removes the named printer from printer class class. If the +resulting class becomes empty then it is removed.
    +
    -v device-uri
    +
    Sets the device for communicating with the printer. If a job is +currently printing on the named printer then the job will be restarted +and sent to the new device.
    +
    -D info
    +
    Provides a textual description of the printer, e.g. "John's +Personal Printer".
    +
    -E
    +
    Enables the printer and accepts job. This option is equivalent to +running the enable(1) and accept(8) commands +on the printer.
    +
    -L location
    +
    Provides a textual location for the printer, e.g. "Computer Lab +5".
    +
    -P ppd-file
    +
    Specifies a local PPD file for the printer driver.
    +
    +
+

Deleting Printers

+

Run the lpadmin command with the -x option +to delete a printer:

+
    +
    +/usr/sbin/lpadmin -x printer ENTER
    +
    +
+

Setting the Default Printer

+

Run the lpadmin command with the -d option +to set a default printer:

+
    +
    +/usr/sbin/lpadmin -d printer ENTER
    +
    +
+

The default printer can be overridden by the user using the +lpoptions(1) command.

+

Starting and Stopping Printers

+

The enable and disable commands start and +stop printer queues, respectively:

+
    +
    +/usr/bin/enable printer ENTER
    +/usr/bin/disable printer ENTER
    +
    +
+

Printers that are disabled may still accept jobs for printing, but +won't actually print any files until they are restarted. This is useful +if the printer malfunctions and you need time to correct the problem. +Any queued jobs are printed after the printer is enabled (started).

+

Accepting and Rejecting Print Jobs

+

The accept and reject commands accept and +reject print jobs for the named printer, respectively:

+
    +
    +/usr/sbin/accept printer ENTER
    +/usr/sbin/reject printer ENTER
    +
    +
+

As noted above, a printer can be stopped but accepting new print +jobs. A printer can also be rejecting new print jobs while it finishes +those that have been queued. This is useful for when you must perform +maintenance on the printer and will not have it available to users for +a long period of time.

+

Managing Printers from the Web

+

The Web interface is located at:

+ +

From there you can perform all printer management tasks with a few +simple mouse clicks.

+

4 - Printer Classes

+

This chapter describes what printer classes are and how to manage +them.

+

The Basics

+

CUPS provides collections of printers called printer classes. +Jobs sent to a class are forwarded to the first available printer in +the class. Classes can themselves be members of other classes, so it is +possible for you to define very large, distributed printer classes for +high-availability printing.

+

CUPS also supports implicit classes. Implicit classes work +just like printer classes, but they are created automatically based +upon the available printers and classes on the network. This allows you +to setup multiple print servers with identical printer configurations +and have the client machines send their print jobs to the first +available server. If one or more servers go down, the jobs are +automatically redirected to the servers that are running, providing +fail-safe printing.

+

Managing Printer Classes from the Command-Line

+

Run the lpadmin command with the -p and +-c options to add a printer to a class:

+
    +
    +/usr/sbin/lpadmin -p printer -c class ENTER
    +
    +
+

The class is created automatically if it doesn't exist. To +remove a printer from a class use the -r option:

+
    +
    +/usr/sbin/lpadmin -p printer -r class ENTER
    +
    +
+

To remove the entire class just use the -x option:

+
    +
    +/usr/sbin/lpadmin -x class ENTER
    +
    +
+

Managing Printer Classes from the Web Interface

+

The Web interface is located at:

+ +

The Add Class and Modify Class interfaces +provide a list of available printers; click on the printers of interest +to add them to the class.

+

Implicit Classes

+

A noted earlier, implicit classes are created automatically from the +available network printers and classes. To disable this functionality, +set the ImplicitClasses + directive to Off in the cupsd.conf file. You +will find more information on doing this in +Chapter 6, "Printing System Management".

+

5 - Client Setup

+

This chapter discusses several ways to configure CUPS clients for +printing.

+

The Basics

+

A client is any machine that sends print jobs to another machine for +final printing. Clients can also be servers if they communicate +directly with any printers of their own.

+

CUPS supports several methods of configuring client machines:

+ +

Manual Configuration of Print Queues

+

The most tedious method of configuring client machines is to +configure each remote queue by hand using the lpadmin + command:

+
    +
    +lpadmin -p printer -E -v ipp://server/printers/printer ENTER
    +
    +
+

The printer name is the name of the printer on the +server machine. The server name is the hostname or IP +address of the server machine. Repeat the lpadmin command +for each remote printer you wish to use.

+

Specifying a Single Server for Printing

+

CUPS can be configured to run without a local spooler and send all +jobs to a single server. However, if that server goes down then all +printing will be disabled. Use this configuration only as absolutely +needed.

+

The default server is normally "localhost". To override the default +server create a file named /etc/cups/client.conf and add a +line reading:

+
    +
    +ServerName server
    +
    +
+

to the file. The server name can be the hostname or IP +address of the default server.

+

The default server can also be customized on a per-user basis. To +set a user-specific server create a file named ~/.cupsrc and +add a line reading:

+
    +
    +ServerName server
    +
    +
+

to the file. The server name can be the hostname or IP +address of the default server.

+

Automatic Configuration of Print Queues

+

CUPS supports automatic client configuration of printers on the same +subnet. To configure printers on the same subnet, do nothing. +Each client should see the available printers within 30 seconds +automatically. The printer and class lists are updated automatically as +printers and servers are added or removed.

+

If you want to see printers on other subnets as well, use the +BrowsePoll directive as described next.

+

Specifying Multiple Servers for Printing

+

If you have CUPS servers on different subnets, then you should +configure CUPS to poll those servers. Polling provides the benefits of +automatic configuration without significant configuration on the +clients, and multiple clients on the same subnet can share the same +configuration information.

+

Polling is enabled by specifying one or more +BrowsePoll directives in the /etc/cups/cupsd.conf + file. For information on making these changes, see +Chapter 6, "Printing System Management".

+

6 - Printing System +Management

+

This chapter shows how you can configure the CUPS server.

+

The Basics

+

Several text files are used to configure CUPS. All of the server +configuration files are located in the /etc/cups directory:

+
    +
    + + +
    classes.conf
    +
    This file contains information on each printer class. Normally you +manipulate this file using the lpadmin command or the Web +interface. +
      + +
    +
    client.conf
    +
    This file provides the default server name for client machines. +See Chapter 5, "Client Setup" for more +information. +
      + +
    +
    cupsd.conf
    +
    This file controls how the CUPS server (/usr/sbin/cupsd +) operates and is normally edited by hand. +
      + +
    +
    mime.convs
    +
    This file contains a list of standard file conversion filters and +their costs. You normally do not edit this file. +
      + +
    +
    mime.types
    +
    This file contains a list of standard file formats and how to + recognize them. You normally do not edit this file. +
      + +
    +
    printers.conf
    +
    This file contains information on each printer. Normally you +manipulate this file using the lpadmin command or the Web +Interface. +
     
    +
    +
+

Restarting the CUPS Server

+

Once you have made a change to a configuration file you need to +restart the CUPS server by sending it a HUP signal or +using the supplied initialization script. The CUPS distributions +install the script in the init.d directory with the name +cups. The location varies based upon the operating system:

+
    +
    +/etc/rc.d/init.d/cups restart ENTER
    +/etc/init.d/cups restart ENTER
    +/sbin/init.d/cups restart ENTER
    +
    +
+

Changing the Server Configuration

+

The /etc/cups/cupsd.conf file contains configuration +directives that control how the server functions. Each directive is +listed on a line by itself followed by its value. Comments are +introduced using the number sign ("#") character at the beginning of a +line. Since the server configuration file consists of plain text, you +can use your favorite text editor to make changes to it. + +

+

Server Directives

+

The cupsd.conf file contains many directives that +determine how the server operates:

+ + + +

AccessLog

+
+

Examples

+
    +
    +AccessLog /var/log/cups/access_log
    +AccessLog /var/log/cups/access_log-%s
    +AccessLog syslog
    +
    +
+

Description

+

The AccessLog directive sets the name of the access log +file. If the filename is not absolute then it is assumed to be relative +to the ServerRoot directory. The +access log file is stored in "common log format" and can be used by any +web access reporting tool to generate a report on CUPS server activity.

+

The server name can be included in the filename by using %s + in the name.

+

The special name "syslog" can be used to send the access information +to the system log instead of a plain file.

+

The default access log file is /var/log/cups/access_log. + +

+

Allow

+
+

Examples

+
    +
    +Allow from All
    +Allow from None
    +Allow from *.domain.com
    +Allow from .domain.com
    +Allow from host.domain.com
    +Allow from nnn.*
    +Allow from nnn.nnn.*
    +Allow from nnn.nnn.nnn.*
    +Allow from nnn.nnn.nnn.nnn
    +Allow from nnn.nnn.nnn.nnn/mm
    +Allow from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
    +
    +
+

Description

+

The Allow directive specifies a hostname, IP address, +or network that is allowed access to the server. Allow + directives are cummulative, so multiple Allow directives +can be used to allow access for multiple hosts or networks. The +/mm notation specifies a CIDR netmask: +

+ + + + + + +
mmnetmask +mmnetmask
00.0.0.0 +8255.0.0.0
1128.0.0.0 +16255.255.0.0
2192.0.0.0 +24255.255.255.0
...... +32255.255.255.255
+
+

+

The Allow directive must appear inside a +Location directive. + +

+

AuthClass

+
+

Examples

+
    +
    +AuthClass Anonymous
    +AuthClass User
    +AuthClass System
    +AuthClass Group
    +
    +
+

Description

+

The AuthClass directive defines what level of +authentication is required:

+
    +
  • Anonymous - No authentication should be performed + (default.)
  • +
  • User - A valid username and password is required.
  • +
  • System - A valid username and password is required, +and the username must belong to the "sys" group; this can be changed +using the SystemGroup + directive.
  • +
  • Group - A valid username and password is required, +and the username must belong to the group named by the +AuthGroupName directive.
  • +
+

The AuthClass directive must appear inside a +Location directive. + +

+

AuthGroupName

+
+

Examples

+
    +
    +AuthGroupName mygroup
    +AuthGroupName lp
    +
    +
+

Description

+

The AuthGroupName directive sets the group to use for +Group authentication.

+

The AuthGroupName directive must appear inside a +Location directive. + +

+

AuthType

+
+

Examples

+
    +
    +AuthType None
    +AuthType Basic
    +AuthType Digest
    +
    +
+

Description

+

The AuthType directive defines the type of +authentication to perform:

+
    +
  • None - No authentication should be performed + (default.)
  • +
  • Basic - Basic authentication should be performed +using the UNIX password and group files.
  • +
  • Digest - Digest authentication should be performed +using the /etc/cups/passwd.md5 file.
  • +
+

When using Basic or Digest authentication, +clients connecting through the localhost interface can +also authenticate using certificates.

+

The AuthType directive must appear inside a +Location directive. + +

+

BrowseAddress

+
+

Examples

+
    +
    +BrowseAddress 255.255.255.255:631
    +BrowseAddress 192.0.2.255:631
    +BrowseAddress host.domain.com:631
    +
    +
+

Description

+

The BrowseAddress directive specifies an address to +send browsing information to. Multiple BrowseAddress + directives can be specified to send browsing information to different +networks or systems.

+

The default address is 255.255.255.255:631 which will +broadcast the information to all networks the server is connected to. +

+ + +
NOTE: +

If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8 +bits, printer browsing (and in fact all broadcast reception) will not +work. This problem appears to be fixed in HP-UX 11.0.

+
+
+ + +

+

BrowseAllow

+
+

Examples

+
    +
    +BrowseAllow from all
    +BrowseAllow from none
    +BrowseAllow from 192.0.2
    +BrowseAllow from 192.0.2.0/24
    +BrowseAllow from 192.0.2.0/255.255.255.0
    +BrowseAllow from *.domain.com
    +
    +
+

Description

+

The BrowseAllow directive specifies a system or network +to accept browse packets from. The default is to accept browse packets +from all hosts.

+

Host and domain name matching require that you enable the +HostNameLookups directive.

+

IP address matching supports exact matches, partial addresses that +match networks using netmasks of 255.0.0.0, 255.255.0.0, and +255.255.255.0, or network addresses using the specified netmask or bit +count. + +

+

BrowseDeny

+
+

Examples

+
    +
    +BrowseDeny from all
    +BrowseDeny from none
    +BrowseDeny from 192.0.2
    +BrowseDeny from 192.0.2.0/24
    +BrowseDeny from 192.0.2.0/255.255.255.0
    +BrowseDeny from *.domain.com
    +
    +
+

Description

+

The BrowseDeny directive specifies a system or network +to reject browse packets from. The default is to deny browse packets +from no hosts.

+

Host and domain name matching require that you enable the +HostNameLookups directive.

+

IP address matching supports exact matches, partial addresses that +match networks using netmasks of 255.0.0.0, 255.255.0.0, and +255.255.255.0, or network addresses using the specified netmask or bit +count. + +

+

BrowseOrder

+
+

Examples

+
    +
    +BrowseOrder allow,deny
    +BrowseOrder deny,allow
    +
    +
+

Description

+

The BrowseOrder directive specifies the order of +allow/deny processing. The default order is deny,allow:

+
    +
  • allow,deny - Browse packets are accepted unless + specifically denied.
  • +
  • deny,allow - Browse packets are rejected unless + specifically allowed.
  • +
+ + +

BrowseInterval

+
+

Examples

+
    +
    +BrowseInterval 0
    +BrowseInterval 30
    +
    +
+

Description

+

The BrowseInterval directive specifies the maximum +amount of time between browsing updates. Specifying a value of 0 +seconds disables outgoing browse updates but allows a server to receive +printer information from other hosts.

+

The BrowseInterval value should always be less than the BrowseTimeout value. Otherwise +printers and classes will disappear from client systems between +updates. + +

+

BrowsePoll

+
+

Examples

+
    +
    +BrowsePoll 192.0.2.2:631
    +BrowsePoll host.domain.com:631
    +
    +
+

Description

+

The BrowsePoll directive polls a server for available +printers once every BrowseInterval + seconds. Multiple BrowsePoll directives can be +specified to poll multiple servers.

+

If BrowseInterval is set to 0 then the server is polled +once every 30 seconds. + +

+

BrowsePort

+
+

Examples

+
    +
    +BrowsePort 631
    +BrowsePort 9999
    +
    +
+

Description

+

The BrowsePort directive specifies the UDP port number +used for browse packets. The default port number is 631. +

+ + +
NOTE: +

You must set the BrowsePort to the same value on all +of the systems that you want to see.

+
+
+ + +

+

BrowseRelay

+
+

Examples

+
    +
    +BrowseRelay 193.0.2.1 192.0.2.255
    +BrowseRelay 193.0.2.0/255.255.255.0 192.0.2.255
    +BrowseRelay 193.0.2.0/24 192.0.2.255
    +BrowseRelay *.domain.com 192.0.2.255
    +BrowseRelay host.domain.com 192.0.2.255
    +
    +
+

Description

+

The BrowseRelay directive specifies source and +destination addresses for relaying browsing information from one host +or network to another. Multiple BrowseRelay directives can +be specified as needed.

+

BrowseRelay is typically used on systems that bridge +multiple subnets using one or more network interfaces. It can also be +used to relay printer information from polled servers with the line:

+
    +
    +BrowseRelay 127.0.0.1 255.255.255.255
    +
    +
+

This effectively provides access to printers on a WAN for all +clients on the LAN(s). + +

+

BrowseShortNames

+
+

Examples

+
    +
    +BrowseShortNames Yes
    +BrowseShortNames No
    +
    +
+

Description

+

The BrowseShortNames directive specifies whether or not +short names are used for remote printers when possible. Short names are +just the remote printer name, without the server ("printer"). If more +than one remote printer is detected with the same name, the printers +will have long names ("printer@server1", "printer@server2".)

+

The default value for this option is Yes. + +

+

BrowseTimeout

+
+

Examples

+
    +
    +BrowseTimeout 300
    +BrowseTimeout 60
    +
    +
+

Description

+

The BrowseTimeout directive sets the timeout for +printer or class information that is received in browse packets. Once a +printer or class times out it is removed from the list of available +destinations.

+

The BrowseTimeout value should always be greater than +the BrowseInterval value. +Otherwise printers and classes will disappear from client systems +between updates. + +

+

Browsing

+
+

Examples

+
    +
    +Browsing On
    +Browsing Off
    +
    +
+

Description

+

The Browsing directive controls whether or not network +printer browsing is enabled. The default setting is On. +

+ + +
NOTE: +

If you are using HP-UX 10.20 and a subnet that is not 24, 16, or 8 +bits, printer browsing (and in fact all broadcast reception) will not +work. This problem appears to be fixed in HP-UX 11.0.

+
+
+ + +

+

DataDir

+
+

Examples

+
    +
    +DataDir /usr/share/cups
    +
    +
+

Description

+

The DataDir directive sets the directory to use for +data files. + +

+

DefaultCharset

+
+

Examples

+
    +
    +DefaultCharset utf-8
    +DefaultCharset iso-8859-1
    +DefaultCharset windows-1251
    +
    +
+

Description

+

The DefaultCharset directive sets the default character +set to use for client connections. The default character set is +utf-8 but is overridden by the character set for the language +specified by the client or the DefaultLanguage directive. + +

+

DefaultLanguage

+
+

Examples

+
    +
    +DefaultLanguage de
    +DefaultLanguage en
    +DefaultLanguage es
    +DefaultLanguage fr
    +DefaultLanguage it
    +
    +
+

Description

+

The DefaultLanguage directive specifies the default +language to use for client connections. Setting the default language +also sets the default character set if a language localization file +exists for it. The default language is "en" for English. + +

+

Deny

+
+

Examples

+
    +
    +Deny from All
    +Deny from None
    +Deny from *.domain.com
    +Deny from .domain.com
    +Deny from host.domain.com
    +Deny from nnn.*
    +Deny from nnn.nnn.*
    +Deny from nnn.nnn.nnn.*
    +Deny from nnn.nnn.nnn.nnn
    +Deny from nnn.nnn.nnn.nnn/mm
    +Deny from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
    +
    +
+

Description

+

The Deny directive specifies a hostname, IP address, or +network that is allowed access to the server. Deny + directives are cummulative, so multiple Deny directives +can be used to allow access for multiple hosts or networks. The +/mm notation specifies a CIDR netmask: +

+ + + + + + +
mmnetmask +mmnetmask
00.0.0.0 +8255.0.0.0
1128.0.0.0 +16255.255.0.0
2192.0.0.0 +24255.255.255.0
...... +32255.255.255.255
+
+

+

The Deny directive must appear inside a +Location directive. + +

+

DocumentRoot

+
+

Examples

+
    +
    +DocumentRoot /usr/share/doc/cups
    +DocumentRoot /foo/bar/doc/cups
    +
    +
+

Description

+

The DocumentRoot directive specifies the location of +web content for the HTTP server in CUPS. If an absolute path is not +specified then it is assumed to be relative to the +ServerRoot directory. The default directory is +/usr/share/doc/cups.

+

Documents are first looked up in a sub-directory for the primary +language requested by the client (e.g. /usr/share/doc/cups/fr/... +) and then directly under the DocumentRoot directory (e.g. +/usr/share/doc/cups/...), so it is possible to localize the web +content by providing subdirectories for each language needed. + +

+

ErrorLog

+
+

Examples

+
    +
    +ErrorLog /var/log/cups/error_log
    +ErrorLog /var/log/cups/error_log-%s
    +ErrorLog syslog
    +
    +
+

Description

+

The ErrorLog directive sets the name of the error log +file. If the filename is not absolute then it is assumed to be relative +to the ServerRoot directory. The +default error log file is /var/log/cups/error_log.

+

The server name can be included in the filename by using %s + in the name.

+

The special name "syslog" can be used to send the error information +to the system log instead of a plain file. + +

+

Group

+
+

Examples

+
    +
    +Group sys
    +Group system
    +Group root
    +
    +
+

Description

+

The Group directive specifies the UNIX group that +filter and CGI programs run as. The default group is sys, +system, or root depending on the operating system. + +

+

HostNameLookups

+
+

Examples

+
    +
    +HostNameLookups On
    +HostNameLookups Off
    +
    +
+

Description

+

The HostNameLookups directive controls whether or not +CUPS looks up the hostname for connecting clients. The default is +Off to avoid the potential server performance problems with +hostname lookups. Turn this option On only if absolutely +required. + +

+

ImplicitClasses

+
+

Examples

+
    +
    +ImplicitClasses On
    +ImplicitClasses Off
    +
    +
+

Description

+

The ImplicitClasses directive controls whether implicit +classes are created based upon the available network printers and +classes. The default setting is On but is automatically +turned Off if Browsing + is turned Off. + +

+

KeepAlive

+
+

Examples

+
    +
    +KeepAlive On
    +KeepAlive Off
    +
    +
+

Description

+

The KeepAlive directive controls whether or not to +support persistent HTTP connections. The default is On.

+

HTTP/1.1 clients automatically support persistent connections, while +HTTP/1.0 clients must specifically request them using the +Keep-Alive attribute in the Connection: field of +each request. + +

+

KeepAliveTimeout

+
+

Examples

+
    +
    +KeepAliveTimeout 60
    +KeepAliveTimeout 30
    +
    +
+

Description

+

The KeepAliveTimeout directive controls how long a +persistent HTTP connection will remain open after the last request. The +default is 60 seconds. + +

+

Listen

+
+

Examples

+
    +
    +Listen 127.0.0.1:631
    +Listen 192.0.2.1:631
    +
    +
+

Description

+

The Listen directive specifies a network address and +port to listen for connections. Multiple Listen directives +can be provided to listen on multiple addresses.

+

Description

+

The Listen directive is similar to the +Port directive but allows you to restrict access to specific +interfaces or networks. + +

+

Location

+
+

Examples

+
    +
    +<Location />
    +...
    +</Location>
    +
    +<Location /admin>
    +...
    +</Location>
    +
    +<Location /printers/name>
    +...
    +</Location>
    +
    +
+

Description

+

The Location directive specifies access control and +authentication options for the specified HTTP resource or path. More +information can be found later in this chapter in +"Printing System Security". + +

+

LogLevel

+
+

Examples

+
    +
    +LogLevel debug
    +LogLevel error
    +LogLevel info
    +LogLevel none
    +LogLevel warn
    +
    +
+

Description

+

The LogLevel directive specifies the level of logging +for the ErrorLog file. The +following values are recognized:

+
    +
  • debug - Log everything.
  • +
  • info - Log all requests and state changes (default).
  • +
  • warn - Log errors and warnings.
  • +
  • error - Log only errors.
  • +
  • none - Log nothing.
  • +
+ + +

MaxClients

+
+

Examples

+
    +
    +MaxClients 100
    +MaxClients 1024
    +
    +
+

Description

+

The MaxClients directive controls the maximum number of +simultaneous clients that will be allowed by the server. The default is +100 clients. +

+ + +
NOTE: +

Since each print job requires a file descriptor for the status +pipe, the CUPS server internally limits the MaxClients + value to 1/3 of the available file descriptors to avoid possible +problems when printing large numbers of jobs.

+
+
+ + +

+

MaxLogSize

+
+

Examples

+
    +
    +MaxLogSize 1048576
    +MaxLogSize 1m
    +MaxLogSize 0
    +
    +
+

Description

+

The MaxLogSize directive controls the maximum size of +each log file. Once a log file reaches or exceeds the maximum size it +is closed and renamed to filename.O. This allows you to +rotate the logs automatically. The default size is 1048576 bytes (1MB).

+

Setting the maximum size to 0 disables log rotation. + +

+

MaxRequestSize

+
+

Examples

+
    +
    +MaxRequestSize 10485760
    +MaxRequestSize 10m
    +MaxRequestSize 0
    +
    +
+

Description

+

The MaxRequestSize directive controls the maximum size +of print files, IPP requests, and HTML form data in HTTP POST requests. +The default limit is 0 which disables the limit check. + +

+

Order

+
+

Examples

+
    +
    +Order Allow,Deny
    +Order Deny,Allow
    +
    +
+

Description

+

The Order directive defines the default access control. +The following values are supported:

+
    +
  • Allow,Deny - Allow requests from all systems except + for those listed in a Deny directive.
  • +
  • Deny,Allow - Allow requests only from those listed in +an Allow directive.
  • +
+

The Order directive must appear inside a +Location directive. + +

+

PageLog

+
+

Examples

+
    +
    +PageLog /var/log/cups/page_log
    +PageLog /var/log/cups/page_log-%s
    +PageLog syslog
    +
    +
+

Description

+

The PageLog directive sets the name of the page log +file. If the filename is not absolute then it is assumed to be relative +to the ServerRoot directory. The +default page log file is /var/log/cups/page_log.

+

The server name can be included in the filename by using %s + in the name.

+

The special name "syslog" can be used to send the page information +to the system log instead of a plain file. + +

+

Port

+
+

Examples

+
    +
    +Port 631
    +Port 80
    +
    +
+

Description

+

The Port directive specifies a port to listen on. +Multiple Port lines can be specified to listen on multiple +ports. The default port is 631.

+

Description

+

The Port directive will listen for connections on all +network interfaces. To limit connections to a single interface use the Listen directive with the interface +address. + +

+

PreserveJobHistory

+
+

Examples

+
    +
    +PreserveJobHistory On
    +PreserveJobHistory Off
    +
    +
+

Description

+

The PreserveJobHistory directive controls whether the +history of completed, cancelled, or aborted print jobs is stored on +disk.

+

A value of On (the default) preserves job information +until the administrator purges it with the cancel command.

+

A value of Off removes the job information as soon as +each job is completed, cancelled, or aborted. + +

+

PreserveJobFiles

+
+

Examples

+
    +
    +PreserveJobFiles On
    +PreserveJobFiles Off
    +
    +
+

Description

+

The PreserveJobFiles directive controls whether the +document files of completed, cancelled, or aborted print jobs are +stored on disk.

+

A value of On preserves job files until the +administrator purges them with the cancel command. Jobs +can be restarted (and reprinted) as desired until they are purged.

+

A value of Off (the default) removes the job files as +soon as each job is completed, cancelled, or aborted. + +

+

Printcap

+
+

Examples

+
    +
    +Printcap
    +Printcap /etc/printcap
    +
    +
+

Description

+

The Printcap directive controls whether or not a +printcap file is automatically generated and updated with a list of +available printers. If specified with no value (the default), then no +printcap file will be generated.

+

When a filename is specified (e.g. /etc/printcap), the +printcap file is written whenever a printer is added or removed. The +printcap file can then be used by applications that are hardcoded to +look at the printcap file for the available printers. + +

+

RequestRoot

+
+

Examples

+
    +
    +RequestRoot /var/spool/cups
    +RequestRoot /foo/bar/spool/cups
    +
    +
+

Description

+

The RequestRoot directive sets the directory for +incoming IPP requests and HTML forms. If an absolute path is not +provided then it is assumed to be relative to the +ServerRoot directory. The default request directory is +/var/spool/cups. + +

+

RIPCache

+
+

Examples

+
    +
    +RIPCache 8m
    +RIPCache 1g
    +RIPCache 2048k
    +
    +
+

Description

+

The RIPCache directive sets the size of the memory +cache used by Raster Image Processor ("RIP") filters such as +imagetoraster and pstoraster. The size can be +suffixed with a "k" for kilobytes, "m" for megabytes, or "g" for +gigabytes. The default cache size is "8m", or 8 megabytes. + +

+

ServerAdmin

+
+

Examples

+
    +
    +ServerAdmin user@host
    +ServerAdmin root@foo.bar.com
    +
    +
+

Description

+

The ServerAdmin directive identifies the email address +for the administrator on the system. By default the administrator email +address is root@server, where server is the +server name. + +

+

ServerBin

+
+

Examples

+
    +
    +ServerBin /usr/lib/cups
    +ServerBin /foo/bar/lib/cups
    +
    +
+

Description

+

The ServerBin directive sets the directory for +server-run executables. If an absolute path is not provided then it is +assumed to be relative to the ServerRoot + directory. The default executable directory is /usr/lib/cups + or /usr/lib32/cups (IRIX 6.5). + +

+

ServerName

+
+

Examples

+
    +
    +ServerName foo.domain.com
    +ServerName myserver.domain.com
    +
    +
+

Description

+

The ServerName directive specifies the hostname that is +reported to clients. By default the server name is the hostname. + +

+

ServerRoot

+
+

Examples

+
    +
    +ServerRoot /etc/cups
    +ServerRoot /foo/bar/cups
    +
    +
+

Description

+

The ServerRoot directive specifies the absolute path to +the server configuration and state files. It is also used to resolve +relative paths in the cupsd.conf file. The default server +directory is /etc/cups. + +

+

SystemGroup

+
+

Examples

+
    +
    +SystemGroup sys
    +SystemGroup system
    +SystemGroup root
    +
    +
+

Description

+

The SystemGroup directive specifies the system +administration group for System authentication. More +information can be found later in this chapter in +"Printing System Security". + +

+

TempDir

+
+

Examples

+
    +
    +TempDir /var/tmp
    +TempDir /foo/bar/tmp
    +
    +
+

Description

+

The TempDir directive specifies an absolute path for +the directory to use for temporary files. The default directory is +/var/tmp.

+

Temporary directories must be world-writable and should have the +"sticky" permission bit enabled so that other users cannot delete +filter temporary files. The following commands will create an +appropriate temporary directory called /foo/bar/tmp:

+
    +
    +mkdir /foo/bar/tmp ENTER
    +chmod a+rwxt /foo/bar/tmp ENTER
    +
    +
+ + +

Timeout

+
+

Examples

+
    +
    +Timeout 300
    +Timeout 90
    +
    +
+

Description

+

The Timeout directive controls the amount of time to +wait before an active HTTP or IPP request times out. The default +timeout is 300 seconds. + +

+

User

+
+

Examples

+
    +
    +User lp
    +User guest
    +
    +
+

Description

+

The User directive specifies the UNIX user that filter +and CGI programs run as. The default user is lp. + +

+

Printing System Security

+

CUPS provides support for address, certificate, and password (Basic +and Digest) based authentication and access control. Certificate and +password authentication provide ways to limit access to individual +people or groups.

+

Address based access control allows you to limit access to specific +systems, networks, or domains. While this does not provide +authentication, it does allow you to limit the potential users of your +system efficiently.

+

CUPS maintains a list of locations that have access control and/or +authentication enabled. Locations are specified using the +Location directive:

+ +

Locations generally follow the directory structure of the +DocumentRoot directory, however CUPS does have several +virtual locations for administration, classes, jobs, and printers: +

+ + + + + + + + + + + + +
LocationDescription
/adminThe path for all administration operations.
/classesThe path for all classes.
/classes/nameThe resource for class name.
/jobsThe path for all jobs.
/jobs/idThe resource for job id.
/printersThe path for all printers.
/printers/nameThe path for printer name.
/printers/name.ppdThe PPD file path for printer +name.
+
+

+

Authentication Using Certificates

+

CUPS supports a local certificate-based authentication scheme that +can be used in place of Basic or Digest + authentication by clients connecting through the localhost + interface. Certificate authentication is not supported or allowed from +clients on any other interface.

+

Certificates are 128-bit random numbers that refer to an internal +authentication record in the server. A client connecting via the +localhost interface sends a request with an authorization header +of:

+
    +
    +Authorization: Local 0123456789ABCDEF0123456789ABCDEF
    +
    +
+

The server then looks up the local certificate and authenticates +using the username associated with it.

+

Certificates are generated by the server automatically and stored in +the /etc/cups/certs directory using the process ID of the +CGI program started by the server. Certificate files are only readable +by the User and +Group defined in the cupsd.conf file. When the +CGI program ends the certificate is removed and invalidated +automatically.

+

The special file /etc/cups/certs/0 defines the root +certificate which can be used by any client running as the +super-user or another user that is part of the group defined by the +SystemGroup directive. The root certificate is +automatically regenerated every 5 minutes.

+

Using Basic Authentication

+

Basic authentication uses UNIX users and passwords to authenticate +access to resources such as printers and classes, and to limit access +to administrative functions. +

+ + +
NOTE: +

Basic authentication sends the username and password Base64 encoded +from the client to the server, so it offers no protection against +eavesdropping. This means that a malicious user can monitor network +packets and discover valid users and passwords that could result in a +serious compromise in network security. Use Basic authentication with +extreme care.

+
+
+

+

The CUPS implementation of Basic authentication does not allow +access through user accounts without a password. If you try to +authenticate using an account without a password, your access will be +immediately blocked.

+

Once a valid username and password is authenticated by CUPS, any +additional group membership requirements are checked. +

+ + +
NOTE: +

The root user is considered by CUPS to be a member of every group.

+
+
+ + +

+

Use the AuthType directive to enable Basic +authentication:

+
    +
    +AuthType Basic
    +
    +
+ + +

Using Digest Authentication

+

Digest authentication uses users and passwords defined in the +/etc/cups/passwd.md5 file to authenticate access to resources +such as printers and classes, and to limit access to administrative +functions. +

+ + +
NOTE: +

Unlike Basic authentication, Digest passes the MD5 sum (basically a +complicated checksum) of the username and password instead of the +strings themselves. Also, Digest authentication does not use the UNIX +password file, so if an attacker does discover the original password +it is less likely to result in a serious security problem so long as +you use a different UNIX password than the corresponding Digest +password.

+

The current CUPS implementation of Digest authentication uses the +client's hostname or IP address for the "nonce" value. The nonce value +is an additional string added to the username and password to make +guessing the password more difficult. The server checks that the nonce +value matches the client's hostname or address and rejects the MD5 sum +if it doesn't. Future versions of CUPS will support Digest "session" +authentication which adds the request data to the MD5 sum, providing +even better authentication and security.

+

Digest authentication does not guarantee that an attacker cannot +gain unauthorized access, but it is safer than Basic authentication +and should be used in place of Basic authentication whenever possible. +Support for Digest authentication in web browsers is not yet +universally available.

+
+
+ + +

+

The lppasswd(1) command is used to add, change, or +remove accounts from the passwd.md5 file. To add a user to +the default system group, type:

+
    +
    +lppasswd -a user ENTER
    +Password: (password) ENTER [password is not echoed]
    +Password again: (password) ENTER [password is not echoed]
    +
    +
+ + +

Once added, a user can change his/her password by typing:

+
    +
    +lppasswd ENTER
    +Old password: (password) ENTER [password is not echoed]
    +Password: (password) ENTER [password is not echoed]
    +Password again: (password) ENTER [password is not echoed]
    +
    +
+ + +

To remove a user from the password file, type:

+
    +
    +lppasswd -x user ENTER
    +
    +
+

Once a valid username and password is authenticated by CUPS, any +additional group membership requirements are checked. +

+ + +
NOTE: +

The root user is considered by CUPS to be a member of every group.

+
+
+

+

Use the AuthType directive to enable Digest +authentication:

+
    +
    +AuthType Digest
    +
    +
+

System and Group Authentication

+

The AuthClass directive +controls the level of authentication to perform. System + and Group authentication extend the normal user-based +authentication to require membership in a UNIX group. For System + authentication each user must belong to the sys, +system, or root group; the actual group depends on +the operating system.

+

For Group authentication each user must belong to the +group named by the AuthGroupName + directive:

+
    +
    +<Location /path>
    +AuthType Digest
    +AuthClass Group
    +AuthGroupName mygroup
    +</Location>
    +
    +
+

The named group must be a valid UNIX user group, usually defined in +the /etc/group or /etc/netgroup files. +Additionally, when using Digest authentication you need to create user +accounts with the named group:

+
    +
    +lppasswd -g mygroup -a user ENTER
    +Password: (password) ENTER [password is not echoed]
    +Password again: (password) ENTER [password is not echoed]
    +
    +
+ + +

Printer Accounting

+

CUPS maintains a log of all accesses, errors, and pages that are

+

The log files are normally stored in the /var/log/cups + directory. You can change this by editing the /etc/cups/cupsd.conf + configuration file.

+

The access_log File

+

The access_log file lists each HTTP resource that is +accessed by a web browser or CUPS/IPP client. Each line is in the +so-called "Common Log Format" used by many web servers and web +reporting tools:

+
    +
    +host group user date-time \"method resource version\" status bytes
    +
    +127.0.0.1 - - [20/May/1999:19:20:29 +0000] "POST /admin/ HTTP/1.1" 401 0
    +127.0.0.1 - mike [20/May/1999:19:20:31 +0000] "POST /admin/ HTTP/1.1" 200 0
    +
    +
+

The host field will normally only be an IP address unless you +have enabled the HostNameLookups + directive in the cupsd.conf file.

+

The group field always contains "-" in CUPS.

+

The user field is the authenticated username of the +requesting user. If no username and password is supplied for the +request then this field contains "-".

+

The date-time field is the date and time of the request in +local time and is in the format:

+
    +
    +[DD/MON/YYYY:HH:MM:SS +ZZZZ]
    +
    +
+

where ZZZZ is the timezone offset in hours and minutes from +Greenwich Mean Time (a.k.a. GMT a.k.a. ZULU.)

+

The method field is the HTTP method used ("GET", "PUT", +"POST", etc.)

+

The resource field is the filename of the requested resource.

+

The version field is the HTTP specification version used by +the client. For CUPS clients this will always be "HTTP/1.1".

+

The status field contains the HTTP result status of the +request. Usually it is "200", but other HTTP status codes are possible. +For example, 401 is the "unauthorized access" status in the example +above.

+

The bytes field contains the number of bytes in the request. +For POST requests the bytes field contains the number of bytes +that was received from the client.

+

The error_log File

+

The error_log file lists messages from the scheduler +(errors, warnings, etc.):

+
    +
    +level date-time message
    +
    +I [20/May/1999:19:18:28 +0000] Job 1 queued on 'DeskJet' by 'mike'.
    +I [20/May/1999:19:21:02 +0000] Job 2 queued on 'DeskJet' by 'mike'.
    +I [20/May/1999:19:22:24 +0000] Job 2 was cancelled by 'mike'.
    +
    +
+

The level field contains the type of message:

+
    +
  • E - An error occurred.
  • +
  • W - The server was unable to perform some action.
  • +
  • I - Informational message.
  • +
  • D - Debugging message.
  • +
+

The date-time field contains the date and time of when the +page started printing. The format of this field is identical to the +data-time field in the access_log file.

+

The message fields contains a free-form textual message.

+

The page_log File

+

The page_log file lists each page that is sent to a +printer. Each line contains the following information:

+
    +
    +printer user job-id date-time page-number num-copies job-billing
    +
    +DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 0 acme-123
    +
    +
+

The printer field contains the name of the printer that +printed the page. If you send a job to a printer class, this field will +contain the name of the printer that was assigned the job.

+

The user field contains the name of the user (the IPP +requesting-user-name attribute) that submitted this file for +printing.

+

The job-id field contains the job number of the page being +printed. Job numbers are reset to 1 whenever the CUPS server is +started, so don't depend on this number being unique!

+

The date-time field contains the date and time of when the +page started printing. The format of this field is identical to the +data-time field in the access_log file.

+

The page-number and num-pages fields contain the page +number and number of copies being printed of that page. For printer +that can not produce copies on their own, the num-pages field +will always be 1.

+

The job-billing field contains a copy of the job-billing + attribute provided with the IPP create-job or +print-job requests or "-" if none was provided. + +

+

File Typing and Filtering

+

CUPS provides a MIME-based file typing and filtering mechanism to +convert files to a printable format for each printer. On startup the +CUPS server reads MIME database files from the /etc/cups + directory (or a directory specified by the +ServerRoot directive) to build a file type and conversion +database in memory. These database files are plain ASCII text and can +be edited with your favorite text editor.

+

The mime.types and mime.convs files define the +standard file types and filters that are available on the system.

+

mime.types

+

The mime.types file defines the known file types. Each +line of the file starts with the MIME type and may be followed by one +or more file type recognition rules. For example, the text/html + file type is defined as:

+
    +
    +text/html       html htm \
    +                printable(0,1024) + \
    +                (string(0,"<HTML>") string(0,"<!DOCTYPE"))
    +
    +
+

The first two rules say that any file with an extension of .html + or .htm is a HTML file. The third rule says that any file +whose first 1024 characters are printable text and starts with the +strings <HTML> or <!DOCTYPE is a HTML file as +well.

+

The first two rules deal solely with the name of the file being +typed. This is useful when the original filename is known, however for +print files the server doesn't have a filename to work with. The third +rule takes care of this possibility and automatically figures out the +file type based upon the contents of the file instead.

+

The available tests are:

+
    +
  • ( expr ) - Parenthesis for expression grouping
  • +
  • + - Logical AND
  • +
  • , or whitespace - Logical OR
  • +
  • ! - Logical NOT
  • +
  • match("pattern") - Pattern match on filename
  • +
  • extension - Pattern match on "*.extension"
  • +
  • ascii(offset,length) - True if bytes are valid + printable ASCII (CR, NL, TAB, BS, 32-126)
  • +
  • printable(offset,length) - True if bytes are + printable 8-bit chars (CR, NL, TAB, BS, 32-126, 160-254)
  • +
  • string(offset,"string") - True if bytes are identical +to string
  • +
  • contains(offset,range,"string") - True if the range +of bytes contains the string
  • +
  • char(offset,value) - True if byte is identical
  • +
  • short(offset,value) - True if 16-bit integer is +identical (network or "big-endian" byte order)
  • +
  • int(offset,value) - True if 32-bit integer is + identical (network or "big-endian" byte order)
  • +
  • locale("string") - True if current locale matches +string
  • +
+

All numeric values can be in decimal (123), octal (0123), or +hexadecimal (0x123) as desired. + +

+

Strings can be in quotes, all by themselves, as a string of +hexadecimal values, or some combination:

+
    +
    +"string"
    +'string'
    +string
    +<737472696e67>
    +<7374>ring
    +
    +
+

As shown in the text/html example, rules can continue +on multiple lines using the backslash (\) character. A more complex +example is the image/jpeg rules:

+
    +
    +image/jpeg      jpeg jpg jpe string(0,<FFD8FF>) &&\
    +                (char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\
    +                 char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\
    +                 char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
    +                 char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
    +
    +
+

This rule states that any file with an extension of .jpeg +, .jpg, or .jpe is a JPEG file. In addition, any +file starting with the hexadecimal string <FFD8FF> (JPEG +Start-Of-Image) followed by a character between and including 0xe0 + and 0xef (JPEG APPn markers) is also a JPEG file.

+

mime.convs

+

The mime.convs file defines all of the filter programs +that are known to the system. Each line consists of:

+
    +
    +source destination cost program
    +
    +text/plain application/postscript 50 texttops
    +application/vnd.cups-postscript application/vnd.cups-raster 50 pstoraster
    +image/* application/vnd.cups-postscript 50 imagetops
    +image/* application/vnd.cups-raster 50 imagetoraster
    +
    +
+

The source field is a MIME type, optionally using a wildcard +for the super-type or sub-type (e.g. "text/plain", "image/*", +"*/postscript").

+

The destination field is a MIME type defined in the +mime.types file.

+

The cost field defines a relative cost for the filtering +operation from 1 to 100. The cost is used to choose between two +different sets of filters when converting a file. For example, to +convert from image/jpeg to +application/vnd.cups-raster, you could use the imagetops + and pstoraster filters for a total cost of 100, or the +imagetoraster filter for a total cost of 50.

+

The program field defines the filter program to run; the +special program "-" can be used to make two file types equivalent. The +program must accept the standard filter arguments and environment +variables described in the CUPS Interface Design Description and CUPS +Software Programmers Manual:

+
    +
    +program job user title options [filename]
    +
    +
+

If specified, the filename argument defines a file to read +when filtering, otherwise the filter must read from the standard input. +All filtered output must go to the standard output. + +

+

Adding Filetypes and Filters

+

Adding a new file type or filter is fairly straight-forward. Rather +than adding the new type and filter to the mime.types and +mime.convs files which are overwritten when you upgrade to a new +version of CUPS, you simple need to create new files with .types + and .convs extensions in the /etc/cups + directory. We recommend that you use the product or format name, e.g.:

+
    +
    +myproduct.types
    +myproduct.convs
    +
    +
+

If you are providing a filter for a common file format or printer, +add the company or author name:

+
    +
    +acme-msword.types
    +acme.msword.convs
    +
    +
+

This will help to prevent name collisions if you install many +different file types and filters.

+

Once you choose the names for these files, create them using your +favorite text editor as described earlier in this chapter. Once you +have created the files, restart the cupsd process as +described earlier in "Restarting the CUPS Server" +.

+

Printer Drivers and PPD Files

+

Most CUPS printer drivers utilize one or more printer-specific +filters and a PPD file for each printer model. Printer driver filters +are registered via the PPD file using cupsFilter + attributes:

+
    +
    +*cupsFilter: "application/vnd.cups-raster 0 rastertohp"
    +
    +
+

The filter is specified using the source file type only; the +destination file type is assumed to be printer/name - +suitable for sending to the printer.

+

Writing Your Own Filter or Printer Driver

+

CUPS supports an unlimited number of file formats and filters, and +can handle any printer. If you'd like to write a filter or printer +driver for your favorite file format or printer, consult the CUPS +Software Programmers Manual for step-by-step instructions.

+

7 - Printing with Other +Systems

+

This chapter describes how to print from client systems that use the +LPD, Mac OS, or Windows printing protocols.

+

The Basics

+

CUPS is based on the IPP protocol, so any system that supports IPP +can send jobs to and receive jobs from CUPS automatically. However, not +all systems support IPP yet. This chapter will show you how to connect +these systems to your CUPS server, either to accept jobs from your +server for printing, or to send jobs to your server.

+

Printing from LPD Clients

+

CUPS supports limited functionality for LPD-based clients. With LPD +you can print files to specific printers, list the queue status, and so +forth. However, the automatic client configuration and printer options +are not supported by the LPD protocol, so you must manually configure +each client for the printers it needs to access.

+

The cups-lpd(8) program provides support for LPD +clients. To enable LPD support on your server, edit the +/etc/inetd.conf file and add a line reading:

+
    +
    +printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
    +
    +
+

The path to the cups-lpd may vary depending on your +installation.

+

Once you have added this line, send the inetd(8) + process a HUP signal or reboot the system:

+
    +
    +killall -HUP inetd ENTER [IRIX and some versions of Linux]
    +kill -HUP pid ENTER [Others]
    +reboot ENTER [For all systems if the HUP signal fails]
    +
    +
+

Printing to LPD Servers

+

CUPS provides the lpd backend for printing to LPD-based +servers and printers. Use a device URI of lpd://server/name + to print to a printer on an LPD server, where server is +the hostname or IP address of the server and name is the +queue name.

+

Microsoft Windows NT provides an LPD service under the name "TCP/IP +Printing Services". To enable LPD printing on NT, open the "Services" +control panel, select the "TCP/IP Printing Services" service, and click +on the "Start" button. Any shared printer will then be available via +the LPD protocol.

+

Printing from Mac OS Clients

+

CUPS does not provide Mac OS support directly. However, there are +several free and commercial software packages that do.

+

Columbia Appletalk Package (CAP)

+

Because the CAP LaserWriter server (lwsrv(8)) does not +support specification of PPD files, we do not recommend that you use +CAP with CUPS. However, you can run the lpsrv program for +limited printing with the command:

+
    +
    +lwsrv -n "Name" -p printer -a /usr/lib/adicts -f /usr/lib/LW+Fonts
    +
    +
+

where Name is the name you want to use when sharing the +printer, and printer is the name of the CUPS print queue. + +

+

XINET KA/Spool

+

To use your system as a print server for Mac OS clients, configure +each printer using a papserver(8) in the +/usr/adm/appletalk/services file, specifying the corresponding +PPD file in the /etc/cups/ppd directory for each printer. + For a printer named MyPrinter the entry would look like:

+
    +
    +/usr/etc/appletalk/papserver -I -L -P /etc/cups/ppd/MyPrinter.ppd \
    +"Printer Description" MyPrinter
    +
    +
+
+ + +
NOTE: +

Enter the text above on a single line without the backslash (\) + character.

+
+
+

NetATalk

+

To use your system as a print server for Mac OS clients, configure +each printer in the papd.conf file, specifying the +corresponding PPD file in the /etc/cups/ppd directory for +each printer. For a printer named MyPrinter the entry +would look like:

+
    +
    +Printer Description:MyPrinter@MyServer:\
    +        :pr=|/usr/bin/lp -d MyPrinter:\
    +        :op=daemon:\
    +        :pd=/etc/cups/ppd/MyPrinter.ppd
    +
    +
+ + +

Printing to Mac OS Servers

+

CUPS currently does not provide a backend to communicate with a Mac +OS server. However, you can write and install a short shell script in +the /usr/lib/cups/backend directory that sends a print file +using the appropriate command. The following is a short script that +will run the papif command provided with CAP.

+

After copying this script to /usr/lib/cups/backend/cap, +specify a device URI of cap://server/printer to use this +backend with a print queue. + +

+
    +
    +"/usr/lib/cups/backend/cap"
    +#!/bin/sh
    +#
    +# Usage: cap job user title copies options [filename]
    +#
    +
    +# No arguments means show available devices...
    +
    +if test ${#argv} = 0; then
    +	echo "network cap \"Unknown\" \"Mac OS Printer via CAP\""
    +	exit 0
    +fi
    +
    +# Collect arguments...
    +
    +user=$2
    +copies=$4
    +
    +if test ${#argv} = 5; then
    +	# Get print file from stdin; copies have already been handled...
    +	file=/var/tmp/$$.prn
    +	copies=1
    +	cat > $file
    +else
    +	# Print file is on command-line...
    +	file=$6
    +fi
    +
    +# Create a dummy cap.printers file for this printer based
    +# upon a device URI of "cap://server/printer"...
    +
    +echo $PRINTER/$DEVICE_URI | \
    +	awk -F/ '{print $1 "=" $5 ":LaserWriter@" $4}' > /var/tmp/$$.cap
    +
    +CAPPRINTERS=/var/tmp/$$.cap; export CAPPRINTERS
    +
    +# Send the file to the printer, once for each copy. This assumes that you
    +# have properly initialized the cap.printers file...
    +
    +while [ $copies -gt 0 ]; do
    +	papif -n $user < $file
    +
    +        copies=`expr $copies - 1`
    +done
    +
    +# Remove any temporary files...
    +if test ${#argv} = 5; then
    +	/bin/rm -f $file
    +fi
    +
    +/bin/rm -f /var/tmp/$$.cap
    +
    +exit 0
    +
    +
+ + +

Printing from Windows Clients

+

While CUPS does not provide Windows support directly, the free SAMBA +software package does. SAMBA version 2.0.6 is the first release of +SAMBA that supports CUPS. You can download SAMBA from:

+ +

To configure SAMBA for CUPS, edit the smb.conf file and +replace the existing printing commands and options with the line:

+
    +
    +printing = cups
    +
    +
+

That's all there is to it! Remote users will now be able to browse +and print to printers on your system.

+

Printing to Windows Servers

+

CUPS can print to Windows servers in one of two ways. The first way +uses the LPD protocol on the CUPS system and the "TCP/IP Printing +Services" on the Windows system. You can find out more about this +configuration in the LPD section earlier in this +chapter.

+

The second way is through the Microsoft Server Message Block ("SMB") +protocol. Support for this protocol is provided with the free SAMBA +software package. You can download SAMBA from:

+ +

To configure CUPS for SAMBA, run the following command:

+
    +
    +ln -s `which smbspool` /usr/lib/cups/backend/smb ENTER
    +
    +
+

The smbspool(1) program is provided with SAMBA starting +with SAMBA 2.0.6. Once you have made the link you can configure your +printers with one of the following device URIs:

+
    +
    +smb://workgroup/server/sharename
    +smb://server/sharename
    +smb://user:pass@workgroup/server/sharename
    +smb://user:pass@server/sharename
    +
    +
+

The workgroup name need only be specified if your +system is using a different workgroup. The user:pass + strings are required when printing to Windows NT servers or to shares +with passwords enabled under Windows 95 and 98.

+

A - Software License Agreement

+

Common UNIX Printing System License +Agreement

+

Copyright 1997-2000 by Easy Software Products +
44141 AIRPORT VIEW DR STE 204 +
HOLLYWOOD, MARYLAND 20636-3111 USA +
+
Voice: +1.301.373.9603 +
Email: cups-info@cups.org +
WWW: http://www.cups.org

+

Introduction

+

The Common UNIX Printing SystemTM, ("CUPSTM"), +is provided under the GNU General Public License ("GPL") and GNU +Library General Public License ("LGPL"), Version 2. A copy of these +licenses follow this introduction.

+

The GNU LGPL applies to the CUPS API library, located in the "cups" +subdirectory of the CUPS source distribution and in the +"/usr/include/cups" directory and "libcups.a", "libcups.sl", or +"libcups.so" files in the binary distributions.

+

The GNU GPL applies to the remainder of the CUPS distribution, +including the "pstoraster" filter which is based upon GNU Ghostscript +5.50 and the "pdftops" filter which is based upon Xpdf 0.90.

+

For those not familiar with the GNU GPL, the license basically +allows you to:

+
    +
  • Use the CUPS software at no charge.
  • +
  • Distribute verbatim copies of the software in source or binary +form.
  • +
  • Sell verbatim copies of the software for a media fee, or sell +support for the software.
  • +
  • Distribute or sell printer drivers and filters that use CUPS so +long as source code is made available under the GPL.
  • +
+

What this license does not allow you to do is make changes or +add features to CUPS and then sell a binary distribution without source +code. You must provide source for any new drivers, changes, or +additions to the software, and all code must be provided under the GPL +or LGPL as appropriate.

+

The GNU LGPL relaxes the "link-to" restriction, allowing you to +develop applications that use the CUPS API library under other licenses +and/or conditions as appropriate for your application.

+

Trademarks

+

Easy Software Products has trademarked the Common UNIX Printing +System, CUPS, and CUPS logo. These names and logos may be used freely +in any direct port or binary distribution of CUPS. To use them in +derivative products, please contract Easy Software Products for written +permission. Our intention is to protect the value of these trademarks +and ensure that any derivative product meets the same high-quality +standards as the original.

+

Binary Distribution Rights

+

Easy Software Products also sells rights to the CUPS source code +under a binary distribution license for vendors that are unable to +release source code for their drivers, additions, and modifications to +CUPS under the GNU GPL and LGPL. For information please contact us at +the address shown above.

+

The Common UNIX Printing System provides a "pstoraster" filter that +utilizes the GNU GhostScript 5.50 core to convert PostScript files into +a stream of raster images. For binary distribution licensing of this +software, please contact:

Miles Jones +
Director of Marketing +
Artifex Software Inc. +
454 Las Gallinas Ave., Suite 108 +
San Rafael, CA 94903 USA +
Voice: +1.415.492.9861 +
Fax: +1.415.492.9862 +
EMail: info@arsoft.com
+

+

The "pdftops" filter is based on the Xpdf 0.90 software. For binary +distribution licensing of this software, please contact:

+ Derek B. Noonburg +
Email: derekn@foolabs.com +
WWW: +http://www.foolabs.com/xpdf/

+

Support

+

Easy Software Products sells software support for CUPS as well as a +commercial printing product based on CUPS called ESP Print Pro. You can +find out more at our web site:

+ + + +

GNU GENERAL PUBLIC LICENSE

+

Version 2, June 1991

+
+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+
+
+
+
+

Preamble

+

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too.

+

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things.

+

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it.

+

For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights.

+

We protect your rights with two steps: (1) copyright the software, +and (2) offer you this license which gives you legal permission to +copy, distribute and/or modify the software.

+

Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, +we want its recipients to know that what they have is not the original, +so that any problems introduced by others will not reflect on the +original authors' reputations.

+

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all.

+

The precise terms and conditions for copying, distribution and +modification follow.

+

GNU GENERAL PUBLIC LICENSE +
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+
    +
  1. This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you".
  2. +

    Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does.

    +
  3. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy an appropriate copyright notice +and disclaimer of warranty; keep intact all the notices that refer to +this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the +Program.
  4. +

    You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee.

    +
  5. You may modify your copy or copies of the Program or any portion of +it, thus forming a work based on the Program, and copy and distribute +such modifications or work under the terms of Section 1 above, provided +that you also meet all of these conditions: +
      +
    1. You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change.
    2. +
    3. You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any part +thereof, to be licensed as a whole at no charge to all third parties +under the terms of this License.
    4. +
    5. if the modified program normally reads commands interactively when +run, you must cause it, when started running for such interactive use +in the most ordinary way, to print or display an announcement including +an appropriate copyright notice and a notice that there is no warranty +(or else, saying that you provide a warranty) and that users may +redistribute the program under these conditions, and telling the user +how to view a copy of this License. (Exception: if the Program itself +is interactive but does not normally print such an announcement, your +work based on the Program is not required to print an announcement.)
    6. +
    +
  6. +

    These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it.

    +

    Thus, it is not the intent of this section to claim rights or +contest your rights to work written entirely by you; rather, the intent +is to exercise the right to control the distribution of derivative or +collective works based on the Program.

    +

    In addition, mere aggregation of another work not based on the +Program with the Program (or with a work based on the Program) on a +volume of a storage or distribution medium does not bring the other +work under the scope of this License.

    +
  7. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: +
      +
    1. Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections 1 +and 2 above on a medium customarily used for software interchange; or,
    2. +
    3. Accompany it with a written offer, valid for at least three years, +to give any third party, for a charge no more than your cost of +physically performing source distribution, a complete machine-readable +copy of the corresponding source code, to be distributed under the +terms of Sections 1 and 2 above on a medium customarily used for +software interchange; or,
    4. +
    5. Accompany it with the information you received as to the offer to +distribute corresponding source code. (This alternative is allowed +only for noncommercial distribution and only if you received the +program in object code or executable form with such an offer, in accord +with Subsection b above.)
    6. +
    +
  8. +

    The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that +is normally distributed (in either source or binary form) with the +major components (compiler, kernel, and so on) of the operating system +on which the executable runs, unless that component itself accompanies +the executable.

    +

    If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent access +to copy the source code from the same place counts as distribution of +the source code, even though third parties are not compelled to copy +the source along with the object code.

    +
  9. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such parties +remain in full compliance.
  10. +
  11. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying the +Program or works based on it.
  12. +
  13. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License.
  14. +
  15. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program.
  16. +

    If any portion of this section is held invalid or unenforceable +under any particular circumstance, the balance of the section is +intended to apply and the section as a whole is intended to apply in +other circumstances.

    +

    It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice.

    +

    This section is intended to make thoroughly clear what is believed +to be a consequence of the rest of this License.

    +
  17. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License may +add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among countries +not thus excluded. In such case, this License incorporates the +limitation as if written in the body of this License.
  18. +
  19. The Free Software Foundation may publish revised and/or new +versions of the General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns.
  20. +

    Each version is given a distinguishing version number. If the +Program specifies a version number of this License which applies to it +and "any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a +version number of this License, you may choose any version ever +published by the Free Software Foundation.

    +
  21. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally.
  22. +
+

NO WARRANTY

+
    +
  1. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. + EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS +WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  2. +
  3. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES.
  4. +
+

END OF TERMS AND CONDITIONS

+ + +

GNU LIBRARY GENERAL PUBLIC LICENSE

+

Version 2, June 1991

+
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+

Preamble

+

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users.

+

This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too.

+

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things.

+

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the library, or if you modify it.

+

For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights.

+

Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library.

+

Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations.

+

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all.

+

Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License, which was designed for utility +programs. This license, the GNU Library General Public License, +applies to certain designated libraries. This license is quite +different from the ordinary one; be sure to read it in full, and don't +assume that anything in it is the same as in the ordinary license.

+

The reason we have a separate public license for some libraries is +that they blur the distinction we usually make between modifying or +adding to a program and simply using it. Linking a program with a +library, without changing the library, is in some sense simply using +the library, and is analogous to running a utility program or +application program. However, in a textual and legal sense, the linked +executable is a combined work, a derivative of the original library, +and the ordinary General Public License treats it as such.

+

Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better.

+

However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended +to permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to +achieve this as regards changes in header files, but we have achieved +it as regards changes in the actual functions of the Library.) The +hope is that this will lead to faster development of free libraries.

+

The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library.

+

Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one.

+

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+

0. This License Agreement applies to any software +library which contains a notice placed by the copyright holder or other +authorized party saying it may be distributed under the terms of this +Library General Public License (also called "this License"). Each +licensee is addressed as "you".

+

A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables.

+

The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".)

+

"Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library.

+

Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does and +what the program that uses the Library does.

+

1. You may copy and distribute verbatim copies of +the Library's complete source code as you receive it, in any medium, +provided that you conspicuously and appropriately publish on each copy +an appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the Library.

+

You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee.

+

2. You may modify your copy or copies of the +Library or any portion of it, thus forming a work based on the Library, +and copy and distribute such modifications or work under the terms of +Section 1 above, provided that you also meet all of these conditions:

+
    +
  1. The modified work must itself be a software library.
  2. +

    +

  3. You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change.
  4. +

    +

  5. You must cause the whole of the work to be licensed at no charge +to all third parties under the terms of this License.
  6. +

    +

  7. If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses the +facility, other than as an argument passed when the facility is +invoked, then you must make a good faith effort to ensure that, in the +event an application does not supply such function or table, the +facility still operates, and performs whatever part of its purpose +remains meaningful.
  8. +

    (For example, a function in a library to compute square roots has a +purpose that is entirely well-defined independent of the application. + Therefore, Subsection 2d requires that any application-supplied +function or table used by this function must be optional: if the +application does not supply it, the square root function must still +compute square roots.)

    +
+

These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it.

+

Thus, it is not the intent of this section to claim rights or +contest your rights to work written entirely by you; rather, the intent +is to exercise the right to control the distribution of derivative or +collective works based on the Library.

+

In addition, mere aggregation of another work not based on the +Library with the Library (or with a work based on the Library) on a +volume of a storage or distribution medium does not bring the other +work under the scope of this License.

+

3. You may opt to apply the terms of the ordinary +GNU General Public License instead of this License to a given copy of +the Library. To do this, you must alter all the notices that refer to +this License, so that they refer to the ordinary GNU General Public +License, version 2, instead of to this License. (If a newer version +than version 2 of the ordinary GNU General Public License has appeared, +then you can specify that version instead if you wish.) Do not make +any other change in these notices.

+

Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy.

+

This option is useful when you wish to copy part of the code of the +Library into a program that is not a library.

+

4. You may copy and distribute the Library (or a +portion or derivative of it, under Section 2) in object code or +executable form under the terms of Sections 1 and 2 above provided that +you accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections 1 +and 2 above on a medium customarily used for software interchange.

+

If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to distribute +the source code, even though third parties are not compelled to copy +the source along with the object code.

+

5. A program that contains no derivative of any +portion of the Library, but is designed to work with the Library by +being compiled or linked with it, is called a "work that uses the +Library". Such a work, in isolation, is not a derivative work of the +Library, and therefore falls outside the scope of this License.

+

However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. Section +6 states terms for distribution of such executables.

+

When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law.

+

If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.)

+

Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, whether +or not they are linked directly with the Library itself.

+

6. As an exception to the Sections above, you may +also compile or link a "work that uses the Library" with the Library to +produce a work containing portions of the Library, and distribute that +work under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications.

+

You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things:

+
    +
  1. Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that uses +the Library", as object code and/or source code, so that the user can +modify the Library and then relink to produce a modified executable +containing the modified Library. (It is understood that the user who +changes the contents of definitions files in the Library will not +necessarily be able to recompile the application to use the modified +definitions.)
  2. +

    +

  3. Accompany the work with a written offer, valid for at least three +years, to give the same user the materials specified in Subsection 6a, +above, for a charge no more than the cost of performing this +distribution.
  4. +

    +

  5. If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place.
  6. +

    +

  7. Verify that the user has already received a copy of these + materials or that you have already sent this user a copy.
  8. +
+

For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major components +(compiler, kernel, and so on) of the operating system on which the +executable runs, unless that component itself accompanies the +executable.

+

It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute.

+

7. You may place library facilities that are a work +based on the Library side-by-side in a single library together with +other library facilities not covered by this License, and distribute +such a combined library, provided that the separate distribution of the +work based on the Library and of the other library facilities is +otherwise permitted, and provided that you do these two things:

+
    +
  1. Accompany the combined library with a copy of the same work based +on the Library, uncombined with any other library facilities. This +must be distributed under the terms of the Sections above.
  2. +

    +

  3. Give prominent notice with the combined library of the fact that +part of it is a work based on the Library, and explaining where to +find the accompanying uncombined form of the same work.
  4. +
+

8. You may not copy, modify, sublicense, link with, +or distribute the Library except as expressly provided under this +License. Any attempt otherwise to copy, modify, sublicense, link with, +or distribute the Library is void, and will automatically terminate +your rights under this License. However, parties who have received +copies, or rights, from you under this License will not have their +licenses terminated so long as such parties remain in full compliance.

+

9. You are not required to accept this License, +since you have not signed it. However, nothing else grants you +permission to modify or distribute the Library or its derivative works. + These actions are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Library (or any work based +on the Library), you indicate your acceptance of this License to do so, +and all its terms and conditions for copying, distributing or modifying +the Library or works based on it.

+

10. Each time you redistribute the Library (or any +work based on the Library), the recipient automatically receives a +license from the original licensor to copy, distribute, link with or +modify the Library subject to these terms and conditions. You may not +impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance +by third parties to this License.

+

11. If, as a consequence of a court judgment or +allegation of patent infringement or for any other reason (not limited +to patent issues), conditions are imposed on you (whether by court +order, agreement or otherwise) that contradict the conditions of this +License, they do not excuse you from the conditions of this License. + If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, +then as a consequence you may not distribute the Library at all. For +example, if a patent license would not permit royalty-free +redistribution of the Library by all those who receive copies directly +or indirectly through you, then the only way you could satisfy both it +and this License would be to refrain entirely from distribution of the +Library.

+

If any portion of this section is held invalid or unenforceable +under any particular circumstance, the balance of the section is +intended to apply, and the section as a whole is intended to apply in +other circumstances.

+

It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is implemented +by public license practices. Many people have made generous +contributions to the wide range of software distributed through that +system in reliance on consistent application of that system; it is up +to the author/donor to decide if he or she is willing to distribute +software through any other system and a licensee cannot impose that +choice.

+

This section is intended to make thoroughly clear what is believed +to be a consequence of the rest of this License.

+

12. If the distribution and/or use of the Library +is restricted in certain countries either by patents or by copyrighted +interfaces, the original copyright holder who places the Library under +this License may add an explicit geographical distribution limitation +excluding those countries, so that distribution is permitted only in or +among countries not thus excluded. In such case, this License +incorporates the limitation as if written in the body of this License.

+

13. The Free Software Foundation may publish +revised and/or new versions of the Library General Public License from +time to time. Such new versions will be similar in spirit to the +present version, but may differ in detail to address new problems or +concerns.

+

Each version is given a distinguishing version number. If the +Library specifies a version number of this License which applies to it +and "any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation.

+

14. If you wish to incorporate parts of the Library +into other free programs whose distribution conditions are incompatible +with these, write to the author to ask for permission. For software +which is copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally.

+

NO WARRANTY

+

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, +THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT +WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU +ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

+

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW +OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY +WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE +LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL +OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES.

+

END OF TERMS AND CONDITIONS

+

B - Common Network Settings +

+

This appendix covers many of the popular TCP/IP network interfaces +and printer servers available on the market today.

+

Configuring a Network Interface

+

When you first install a network printer or print server on your +LAN, you need to set the Internet Protocol ("IP") address. On most +higher-end "workgroup" printers, you can set the address through the +printer control panel. However, in most cases you will want to assign +the addresses remotely from your workstation. This makes administration +a bit easier and avoids assigning duplicate addresses accidentally.

+

To setup your printer or print server for remote address assignment, +you'll need the Ethernet Media Access Control ("MAC") address, also +sometimes called a node address, and the IP address you want to use for +the device. The Ethernet MAC address can often be found on the printer +test page or bottom of the print server. + +

+

Configuring the IP Address Using ARP

+

The easiest way to set the IP address of a network device is to use +the arp(8) command. The arp sends an Address +Resolution Protocol ("ARP") packet to the specified Ethernet MAC +address, setting the network device's IP address:

+
    +
    +arp -s ip-address ethernet-address ENTER
    +arp -s host.domain.com 08:00:69:00:12:34 ENTER
    +arp -s 192.0.2.2 08:00:69:00:12:34 ENTER
    +
    +
+

Configuring the IP Address Using RARP

+

The most flexible way to remotely assign IP addresses under UNIX is +through the Reverse Address Resolution Protocol ("RARP"). RARP allows a +network device to request an IP address using its Ethernet MAC address, +and one or more RARP servers on the network will respond with an ARP +packet with the IP address the device can use.

+

RARP should be used when you have to manage many printers or print +servers, or when you have a network device that does not remember its +IP address after a power cycle. If you just have a single printer or +print server, the arp command is the way to go.

+

Some UNIX operating systems use a program called rarpd(8) + to manage RARP. Others, like Linux, support this protocol in the +kernel. For systems that provide the rarpd program you +will need to start it before RARP lookups will work:

+
    +
    +rarpd ENTER
    +
    +
+

Under IRIX you can enable this functionality by default using:

+
    +
    +chkconfig rarpd on ENTER
    +
    +
+

Both the rarpd program and kernel RARP support read a +list of Ethernet and IP addresses from the file /etc/ethers. +Each line contains the Ethernet address (colon delimited) followed by +an IP address or hostname like:

+
    +
    +08:00:69:00:12:34 myprinter.mydomain.com
    +08:00:69:00:12:34 192.0.2.2
    +
    +
+

Add a line to this file and cycle the power on the printer or print +server to set its address. + +

+

Configuring the IP Address Using BOOTP

+

The BOOTP protocol is used when you need to provide additional +information such as the location of a configuration file to the network +interface. Using the standard bootpd(8) program supplied +with UNIX you simply need to add a line to the /etc/bootptab + file; for IRIX:

+
    +
    +myprinter 08:00:69:00:12:34 192.0.2.2 myprinter.boot
    +
    +
+ + +

Newer versions of bootpd use a different format:

+
    +
    +myprinter:ha=080069001234:ip=192.0.2.2:t144=myprinter.boot
    +
    +
+

The myprinter.boot file resides in the +/usr/local/boot directory by default. If you do not need to +provide a boot file you may leave the last part of the line blank. + + +

+ + +
NOTE: +

Some versions of UNIX do not enable the BOOTP service by default. +The /etc/inetd.conf usually contains a line for the BOOTP +service that can be uncommented if needed.

+
+
+

+

Verifying the Printer Connection

+

To test that the IP address has been successfully assigned and that +the printer is properly connected to your LAN, type:

+
    +
    +ping ip-address ENTER
    +
    +
+

If the connection is working properly you will see something like:

+
    +
    +ping myprinter ENTER
    +PING myprinter (192.0.2.2): 56 data bytes
    +64 bytes from 192.0.2.2: icmp_seq=0 ttl=15 time=5 ms
    +64 bytes from 192.0.2.2: icmp_seq=1 ttl=15 time=3 ms
    +64 bytes from 192.0.2.2: icmp_seq=2 ttl=15 time=3 ms
    +64 bytes from 192.0.2.2: icmp_seq=3 ttl=15 time=3 ms
    +
    +
+

If not, verify that the printer or print server is connected to the +LAN, it is powered on, the LAN cabling is good, and the IP address is +set correctly. You can usually see the current IP address and network +status by printing a configuration or test page on the device. + +

+

Common Network Interface Settings

+

Once you have set the IP address you can access the printer or print +server using the ipp, lpd, or socket + backends. The following is a list of common network interfaces and +printer servers and the settings you should use with CUPS: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Model/ManufacturerDevice +URI(s)
Apple LaserWriterlpd:// +address/PASSTHRU
Axis w/o IPP +
(see directions)
socket://address +:9100 +
socket://address:9101 +
socket://address:9102
Axis w/IPPipp://address +/LPT1 +
ipp://address/LPT2 +
ipp://address/COM1
Castelle LANpressTM +lpd://address/pr1 +
lpd://address/pr2 +
lpd://address/pr3
DPI NETPrintlpd://address +/pr1 +
lpd://address/pr2 +
lpd://address/pr3
EFI® Fiery® RIPlpd:// +address/print
EPSON® Multiprotocol Ethernet +Interface Boardsocket://address
Extended System ExtendNET +lpd://address/pr1 +
lpd://address/pr2 +
lpd://address/pr3
Hewlett Packard JetDirect w/o IPP +socket://address:9100 +
socket://address:9101 +
socket://address:9102
Hewlett Packard JetDirect w/IPP +ipp://address/ipp +
ipp://address/ipp/port1 +
ipp://address/ipp/port2 +
ipp://address/ipp/port3
Intel® NetportExpress XL, PRO/100 +lpd://address/LPT1_PASSTHRU +
lpd://address/LPT2_PASSTHRU +
lpd://address/COM1_PASSTHRU
LexmarkTM MarkNet +lpd://address/ps
Linksys EtherFast® +
(see directions)
socket://address +:4010 +
socket://address:4020 +
socket://address:4030
Kodak®lpd://address/ps
QMS® CrownNetTM +lpd://address/ps
Tektronix® PhaserShareTM +socket://address:9100
XEROX® 4512 NIClpd:// +address/PORT1
XEROX® XNIClpd://address +/PASSTHRU
XEROX® (most others)socket:// +address:5503
+
+

+

Configuring Axis Print Servers

+

The Axis print servers can be configured using ARP, RARP, or BOOTP. +However, on models that do not provide IPP support an additional step +must be performed to configure the TCP/IP portion of the print server +for use with CUPS. + +

+

Each print server contains a configuration file named config + that contains a list of network parameters used by the server. To +modify this file you must first download it from the print server using +the ftp(1) program:

+
    +
    +ftp ip-address ENTER
    +Connected to ip-address.
    +220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
    +ftp> user root ENTER
    +331 User name ok, need password
    +Password: pass ENTER (this is not echoed)
    +230 User logged in
    +ftp> get config ENTER
    +local: config remote: config
    +200 PORT command successful.
    +150 Opening data connection for config (192,0,2,2),
    +(mode ascii).
    +226 Transfer complete.
    +##### bytes received in #.## seconds (##### Kbytes/s)
    +ftp> quit ENTER
    +221 Goodbye.
    +
    +
+ + +

Next, edit the file with your favorite text editor and locate the +lines beginning with:

+
    +
    +RTN_OPT.     : YES
    +RTEL_PR1.    : 0
    +RTEL_PR2.    : 0
    +RTEL_PR3.    : 0
    +RTEL_PR4.    : 0
    +RTEL_PR5.    : 0
    +RTEL_PR6.    : 0
    +RTEL_PR7.    : 0
    +RTEL_PR8.    : 0
    +
    +
+ + + Change the RTN_OPT line to read: +
    +
    +RTN_OPT.     : NO
    +
    +
+ + +

This disables the Reverse TELNET protocol and enables the standard +TELNET protocol on the print server. Next, assign a port number for +each parallel and serial port on the server as follows:

+
    +
    +RTEL_PR1.    : 9100
    +RTEL_PR2.    : 9101
    +RTEL_PR3.    : 9102
    +RTEL_PR4.    : 9103
    +RTEL_PR5.    : 9104
    +RTEL_PR6.    : 9105
    +RTEL_PR7.    : 9106
    +RTEL_PR8.    : 9107
    +
    +
+ + +

This essentially makes the Axis print server look like a Hewlett +Packard JetDirect EX print server. Save the file and then upload the +new config file using the ftp command:

+
    +
    +ftp ip-address ENTER
    +Connected to ip-address.
    +220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
    +ftp> user root ENTER
    +331 User name ok, need password
    +Password: pass ENTER (this is not echoed)
    +230 User logged in
    +ftp> put config CONFIG ENTER
    +local: config remote: CONFIG
    +200 PORT command successful.
    +150 Opening data connection for config (192,0,2,2), (mode ascii).
    +226 Transfer complete.
    +##### bytes received in #.## seconds (##### Kbytes/s)
    +ftp> get hardreset ENTER
    +local: hardreset remote: hardreset
    +200 PORT command successful.
    +421 Axis NPS ### hard reset, closing connection.
    +ftp> quit ENTER
    +221 Goodbye.
    +
    +
+

Your Axis print server is now ready for use!

+

Configuring Linksys Print Servers

+

The Linksys print servers can be configured using ARP, RARP, or +BOOTP. Like older Axis print servers, an additional step must be +performed to configure the TCP/IP portion of the print server for use +with CUPS. + +

+

Each print server contains a configuration file named CONFIG + that contains a list of network parameters used by the server. To +modify this file you must first download it from the print server using +the ftp(1) program:

+
    +
    +ftp -n ip-address ENTER
    +Connected to ip-address.
    +220 Print Server Ready.
    +Remote system type is Print.
    +ftp> get CONFIG ENTER
    +local: CONFIG remote: CONFIG
    +200 Command OK.
    +150 Open ASCII Mode Connection.
    +WARNING! 68 bare linefeeds received in ASCII mode
    +File may not have transferred correctly.
    +226 Transfer complete.
    +##### bytes received in #.## seconds (##### Kbytes/s)
    +ftp> quit ENTER
    +221 Goodbye.
    +
    +
+ + +

Next, edit the file with your favorite text editor and locate the +lines beginning with:

+
    +
    +0100 L1_PROUT:P1
    +0120 L2_PROUT:P1
    +0140 L3_PROUT:P1
    +
    +
+

Change the port number for each parallel and serial port on the +server as follows:

+
    +
    +0100 L1_PROUT:P1
    +0120 L2_PROUT:P2
    +0140 L3_PROUT:P3
    +
    +
+ + +

This maps each virtual printer with a physical port. Save the file +and then upload the new CONFIG file using the ftp + command:

+
    +
    +ftp -n ip-address ENTER
    +Connected to ip-address.
    +220 Print Server Ready.
    +Remote system type is Print.
    +ftp> put CONFIG ENTER
    +local: CONFIG remote: CONFIG
    +200 Command OK.
    +150 Open ASCII Mode Connection.
    +226 Transfer complete.
    +##### bytes received in #.## seconds (##### Kbytes/s)
    +ftp> quit ENTER
    +221 Goodbye.
    +
    +
+

Your Linksys print server is now ready for use!

+

C - Printer Drivers

+

This appendix lists the printer drivers that are provided with CUPS.

+

Printer Drivers

+

CUPS includes the following printer drivers:

+ +

EPSON 9-pin Dot Matrix

+

The EPSON 9-pin Dot Matrix driver (epson9.ppd) supports +9-pin dot matrix printers that implement the ESC/P command set. It +provides 60x72, 120x72, and 240x72 DPI output in black only.

+

EPSON 24-pin Dot Matrix

+

The EPSON 24-pin Dot Matrix driver (epson9.ppd) supports +24-pin dot matrix printers that implement the ESC/P command set. It +provides 120x180, 180x180, 360x180, and 360x360 DPI output in black +only.

+

EPSON Stylus Color

+

The EPSON Stylus Color driver (stcolor.ppd) supports +EPSON Stylus Color printers that implement the ESC/P2 command set. It +provides 180, 360, and 720 DPI output in black and color (CMYK).

+

EPSON Stylus Photo

+

The EPSON Stylus Photo driver (stphoto.ppd) supports +EPSON Stylus Photo printers that implement the ESC/P2 command set. It +provides 180, 360, and 720 DPI output in black and color (CMYKcm).

+

HP DeskJet

+

The HP DeskJet driver (deskjet.ppd) supports HP DeskJet +printers that implement the PCL command set. It provides 150, 300, and +600 DPI output in black and color (CMYK).

+

The DeskJet printers that implement the HP-PPA command set (720C, +722C, 820C, and 1100C) are not supported due to a complete lack +of documentation and support from Hewlett Packard.

+

The duplexer provided with the HP DeskJet 900 series printers is +also not supported for similar reasons.

+

HP LaserJet

+

The HP LaserJet driver (laserjet.ppd) supports HP +LaserJet printers that implement the PCL command set. It provides 150, +300, and 600 DPI output in black only and supports the duplexer if +installed.

+

LaserJet printers that do not implement PCL (3100, 3150) are not +supported due to a complete lack of documentation and support from +Hewlett Packard.

+

D - List of Files

+

This appendix lists the files and directories that are installed for +the Common UNIX Printing System. +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PathnameDescription
/etc/cups/certs/The location of +authentication certificate files for local HTTP clients.
/etc/cups/classes.confThe printer classes +configuration file for the scheduler.
/etc/cups/cupsd.confThe scheduler +configuration file.
/etc/cups/interfaces/The location of +System V interface scripts for printers.
/etc/cups/mime.convsThe list of standard +file filters included with ESP Print Pro.
/etc/cups/mime.typesThe list of +recognized file types for ESP Print Pro.
/etc/cups/ppd/The location of PostScript +Printer Description ("PPD") files for printers.
/etc/cups/printers.confThe printer +configuration file for the scheduler.
/usr/bin/cancelThe System V cancel job(s) +command.
/usr/bin/disableThe System V disable +printer command.
/usr/bin/enableThe System V enable +printer command.
/usr/bin/lpThe System V print command.
/usr/bin/lpoptionsSets user-defined +printing options and defaults.
/usr/bin/lppasswdAdds, changes, or +removes Digest password accounts.
/usr/bin/lpqThe Berkeley status command.
/usr/bin/lprThe Berkeley print command.
/usr/bin/lprmThe Berkeley cancel job(s) +command.
/usr/bin/lpstatThe System V status +command.
/usr/include/cups/CUPS API header files.
/usr/lib32/libcups.a +
/usr/lib32/libcupsimage.a
Static libraries (IRIX 6.5)
/usr/lib/libcups.a +
/usr/lib/libcupsimage.a
Static libraries (all others)
/usr/lib/libcups.sl.2 +
/usr/lib/libcupsimage.sl.2
Shared libraries (HP-UX)
/usr/lib32/libcups.so.2 +
/usr/lib32/libcupsimage.so.2
Shared libraries (IRIX 6.5)
/usr/lib/libcups.so.2 +
/usr/lib/libcupsimage.so.2
Shared libraries (all others)
/usr/lib/cups/backend/Backends for +various types of printer connections.
/usr/lib/cups/cgi-bin/CGI programs for +the scheduler.
/usr/lib/cups/daemon/Daemons for polling +and LPD support.
/usr/lib/cups/filter/Filters for various +types of files.
/usr/lib/locale/The location of +language-specific message files. (System V)
/usr/lib/nls/msg/The location of +language-specific message files. (Compaq Tru64 UNIX)
/usr/share/locale/The location of +language-specific message files. (Linux, *BSD)
/usr/sbin/acceptThe accept-jobs command.
/usr/sbin/cupsdThe CUPS print scheduler.
/usr/sbin/lpadminThe System V printer +administration tool.
/usr/sbin/lpcThe Berkeley printer +administration tool.
/usr/sbin/lpinfoThe get-devices and +get-ppds command.
/usr/sbin/lpmoveThe move-jobs command.
/usr/sbin/rejectThe reject-jobs command.
/usr/share/catman/a_man/ +
/usr/share/catman/u_man/
Man pages (IRIX)
/usr/share/man/Man pages (Compaq Tru64 +UNIX, HP-UX, Solaris)
/usr/man/Man pages (all others)
/usr/share/cups/data/The location of +filter data files.
/usr/share/cups/data/testprint.psThe +PostScript test page file.
/usr/share/cups/fonts/The location of +PostScript fonts for the PostScript RIP.
/usr/share/cups/model/The location of +PostScript Printer Description ("PPD") files and interface scripts +that may be used to setup a printer queue.
/usr/share/cups/pstoraster/Other +PostScript RIP initialization files.
/usr/share/cups/pstoraster/FontmapThe +font mapping file (converts filenames to fontnames)
/usr/share/cups/templates/The location of +HTML template files for the web interfaces.
/usr/share/doc/cups/Documentation and web +page data for the scheduler.
/var/log/cups/The location of scheduler +log files.
/var/spool/cups/The location of print +files waiting to be printed.
+
+

+

E - Troubleshooting Common Problems

+

This appendix covers some of the common problems first-time users +encounter when installing and configuring CUPS.

+

Commercial support for CUPS is available from Easy Software +Products. For more information please contact us at:

+ +

My Applications Don't See the Available Printers

+

Many applications read the /etc/printcap file to get a +list of available printers.

+

The default CUPS configuration does not create the /etc/printcap + file automatically. To enable automatic creation and updating of this +file, use the Printcap directive +described in Chapter 6, "Printing System +Management".

+

CUPS Doesn't Recognize My Username or Password!

+

CUPS will ask you for a UNIX username and password when you perform +printer administration tasks remotely or via a web browser. The default +configuration requires that you use the root username and +the corresponding password to authenticate the request.

+

CUPS does not allow you to authenticate an administration request +with an account that has no password for security reasons. If you do +not have a password on your root account then you won't be +able to add printers remotely or via the web interface! + +

+

To disable password authentication you need to edit the +/etc/cups/cupsd.conf file and comment out the lines reading:

+
    +
    +AuthType Basic
    +AuthClass System
    +
    +
+ for the /admin location. Then restart the CUPS server as +described in Chapter 8, "Printing System +Management". +
+ + +
NOTE: +

Disabling password checks will allow any local user to change your +printer and class configuration, but remote administration from +another machine will still not be allowed.

+
+
+

I Can't Do Administration Tasks from Another Machine! +

+

The default CUPS configuration limits administration to the local +machine. To open up access, edit the /etc/cups/cupsd.conf + and comment out the lines reading:

+
    +
    +Order deny,allow
    +Deny from all
    +Allow from 127.0.0.1
    +
    +
+ for the /admin location. Then restart the CUPS server as +described in Chapter 8, "Printing System +Management". +
+ + +
NOTE: +

Allowing administration access from all hosts is a potential + security risk. Please read Chapter 6, +"Printing System Management" for a description of these risks and +ways to minimize them.

+
+
+ + +

I Can't Do Administration Tasks from My Web Browser! +

+

This problem is usually caused by:

+
    +
  1. not specifying the correct password for the root account.
  2. +
  3. accessing the CUPS server using the hostname or IP address of the +server without enabling remote access for administration functions. +This can be corrected by following the instructions in the +"I Can't Do Administration Tasks from Another Machine!" section +earlier in this appendix.
  4. +
  5. not setting a password on the root account. CUPS will not + authenticate a user account that does not have a password for + security reasons.
  6. +
  7. authenticating using an account other than root, but the account +you are using is not a member of the system group.
  8. +
  9. configuring CUPS to use Digest authentication, but your web +browser does not support Digest authentication.
  10. +
+

Connection Refused Messages

+

Under normal circumstances, "connection refused" messages for a +networked printer should be expected from time to time. Most network +interfaces only allow a single connection to be made at any given time +(one job at a time) and will refuse access to all other systems while +the first connection is active. CUPS automatically retries the +connection once every 30 seconds.

+

If the problem persists and you are unable to print any jobs to the +printer, verify that another machine is not maintaining a connection +with the printer, and that you have selected the proper port or printer +name for the printer.

+

Also, most external print servers will refuse connections if the +connected printer is turned off or is off-line. Verify that the +affected printer is turned on and is online.

+

Write Error Messages

+

If you get "write error" messages on a printer queue the printer +interface (usually a Hewlett Packard JetDirect interface) has timed out +and reset the network connection from your workstation.

+

The error is caused by that startup delay between the initial setup +of the printer or plotter and the first page of print data that is +sent. + +

+

To correct the problem, change the idle timeout on the interface to +at least 180 seconds or 3 minutes. To change the timeout on a Hewlett +Packard JetDirect interface, type:

+
    +
    +telnet ip-address ENTER
    +
    +Trying ip-address...
    +Connected to ip-address.
    +Escape character is `^]'.
    +
    +Please type [Return] two times, to initialize telnet configuration
    +For HELP type "?"
    +> idle-timeout: 180 ENTER
    +> quit ENTER
    +
    +
+ + diff --git a/doc/sam.pdf b/doc/sam.pdf new file mode 100644 index 0000000000..e747633349 --- /dev/null +++ b/doc/sam.pdf @@ -0,0 +1,3294 @@ +%PDF-1.2 +%âãÏÓ +1 0 obj<>endobj +2 0 obj<>endobj +3 0 obj<>endobj +4 0 obj<>endobj +5 0 obj<>endobj +6 0 obj<>endobj +7 0 obj<>endobj +8 0 obj<>endobj +9 0 obj<>endobj +10 0 obj<>endobj +11 0 obj<>endobj +12 0 obj<>endobj +13 0 obj<>endobj +14 0 obj<>endobj +15 0 obj<
>endobj +16 0 obj<>endobj +17 0 obj<>endobj +18 0 obj<>endobj +19 0 obj[16 0 R +18 0 R +]endobj +20 0 obj<>endobj +21 0 obj<>endobj +22 0 obj<>endobj +23 0 obj<>endobj +24 0 obj<>endobj +25 0 obj<>endobj +26 0 obj<>endobj +27 0 obj<>endobj +28 0 obj<>endobj +29 0 obj<>endobj +30 0 obj<>endobj +31 0 obj<>endobj +32 0 obj<>endobj +33 0 obj[20 0 R +21 0 R +23 0 R +24 0 R +25 0 R +26 0 R +27 0 R +28 0 R +29 0 R +30 0 R +31 0 R +32 0 R +]endobj +34 0 obj<>endobj +35 0 obj<>endobj +36 0 obj<>endobj +37 0 obj<>endobj +38 0 obj<>endobj +39 0 obj[34 0 R +36 0 R +38 0 R +]endobj +40 0 obj<>endobj +41 0 obj<>endobj +42 0 obj[41 0 R +]endobj +43 0 obj<>endobj +44 0 obj<>endobj +45 0 obj<>endobj +46 0 obj<>endobj +47 0 obj<>endobj +48 0 obj[44 0 R +45 0 R +46 0 R +47 0 R +]endobj +49 0 obj<>endobj +50 0 obj<>endobj +51 0 obj<>endobj +52 0 obj<>endobj +53 0 obj[50 0 R +51 0 R +52 0 R +]endobj +54 0 obj<>endobj +55 0 obj<>endobj +56 0 obj[55 0 R +]endobj +57 0 obj<>endobj +58 0 obj<>endobj +59 0 obj<>endobj +60 0 obj<>endobj +61 0 obj[58 0 R +59 0 R +60 0 R +]endobj +62 0 obj<>endobj +63 0 obj<>endobj +64 0 obj<>endobj +65 0 obj<>endobj +66 0 obj[62 0 R +63 0 R +64 0 R +65 0 R +]endobj +67 0 obj<>endobj +68 0 obj<>endobj +69 0 obj<>endobj +70 0 obj[67 0 R +68 0 R +69 0 R +]endobj +71 0 obj<>endobj +72 0 obj<>endobj +73 0 obj[71 0 R +72 0 R +]endobj +74 0 obj<>endobj +75 0 obj<>endobj +76 0 obj<>endobj +77 0 obj<>endobj +78 0 obj<>endobj +79 0 obj<>endobj +80 0 obj<>endobj +81 0 obj<>endobj +82 0 obj<>endobj +83 0 obj<>endobj +84 0 obj<>endobj +85 0 obj<>endobj +86 0 obj<>endobj +87 0 obj<>endobj +88 0 obj<>endobj +89 0 obj<>endobj +90 0 obj<>endobj +91 0 obj<>endobj +92 0 obj<>endobj +93 0 obj<>endobj +94 0 obj<>endobj +95 0 obj<>endobj +96 0 obj<>endobj +97 0 obj<>endobj +98 0 obj<>endobj +99 0 obj<>endobj +100 0 obj<>endobj +101 0 obj<>endobj +102 0 obj<>endobj +103 0 obj<>endobj +104 0 obj<>endobj +105 0 obj<>endobj +106 0 obj<>endobj +107 0 obj<>endobj +108 0 obj<>endobj +109 0 obj<>endobj +110 0 obj<>endobj +111 0 obj<>endobj +112 0 obj<>endobj +113 0 obj<>endobj +114 0 obj<>endobj +115 0 obj<>endobj +116 0 obj<>endobj +117 0 obj<>endobj +118 0 obj<>endobj +119 0 obj<>endobj +120 0 obj<>endobj +121 0 obj<>endobj +122 0 obj<>endobj +123 0 obj<>endobj +124 0 obj[74 0 R +75 0 R +76 0 R +77 0 R +78 0 R +79 0 R +80 0 R +81 0 R +82 0 R +83 0 R +84 0 R +85 0 R +86 0 R +87 0 R +88 0 R +89 0 R +90 0 R +91 0 R +92 0 R +93 0 R +94 0 R +95 0 R +96 0 R +97 0 R +98 0 R +99 0 R +100 0 R +101 0 R +102 0 R +103 0 R +104 0 R +105 0 R +106 0 R +107 0 R +108 0 R +109 0 R +110 0 R +111 0 R +112 0 R +113 0 R +114 0 R +115 0 R +116 0 R +117 0 R +118 0 R +119 0 R +120 0 R +121 0 R +122 0 R +123 0 R +]endobj +125 0 obj<>endobj +126 0 obj<>endobj +127 0 obj[125 0 R +126 0 R +]endobj +128 0 obj<>endobj +129 0 obj<>endobj +130 0 obj<>endobj +131 0 obj<>endobj +132 0 obj[128 0 R +129 0 R +130 0 R +131 0 R +]endobj +133 0 obj<>endobj +134 0 obj[133 0 R +]endobj +135 0 obj<>endobj +136 0 obj[135 0 R +]endobj +137 0 obj<>endobj +138 0 obj<>endobj +139 0 obj[137 0 R +138 0 R +]endobj +140 0 obj<>endobj +141 0 obj[140 0 R +]endobj +142 0 obj<>endobj +143 0 obj<>endobj +144 0 obj[142 0 R +143 0 R +]endobj +145 0 obj<>endobj +146 0 obj[145 0 R +]endobj +147 0 obj<>endobj +148 0 obj[147 0 R +]endobj +149 0 obj<>endobj +150 0 obj<>endobj +151 0 obj[149 0 R +150 0 R +]endobj +152 0 obj<>endobj +153 0 obj[152 0 R +]endobj +154 0 obj<>endobj +155 0 obj[154 0 R +]endobj +156 0 obj<>endobj +157 0 obj<>endobj +158 0 obj[156 0 R +157 0 R +]endobj +159 0 obj<>endobj +160 0 obj[159 0 R +]endobj +161 0 obj<>endobj +162 0 obj[161 0 R +]endobj +163 0 obj<>endobj +164 0 obj[163 0 R +]endobj +165 0 obj<>endobj +166 0 obj<>endobj +167 0 obj<>endobj +168 0 obj<>endobj +169 0 obj<>endobj +170 0 obj<>endobj +171 0 obj<>endobj +172 0 obj<>endobj +173 0 obj[165 0 R +166 0 R +167 0 R +168 0 R +169 0 R +170 0 R +171 0 R +172 0 R +]endobj +174 0 obj<>endobj +175 0 obj<>endobj +176 0 obj<>endobj +177 0 obj[174 0 R +175 0 R +176 0 R +]endobj +178 0 obj<>endobj +179 0 obj<>endobj +180 0 obj[178 0 R +179 0 R +]endobj +181 0 obj<>endobj +182 0 obj[181 0 R +]endobj +183 0 obj<>endobj +184 0 obj[183 0 R +]endobj +185 0 obj<>endobj +186 0 obj<>endobj +187 0 obj[185 0 R +186 0 R +]endobj +188 0 obj<>endobj +189 0 obj<>endobj +190 0 obj<>endobj +191 0 obj<>endobj +192 0 obj<>endobj +193 0 obj<>endobj +194 0 obj[189 0 R +191 0 R +193 0 R +]endobj +195 0 obj<>endobj +196 0 obj<>endobj +197 0 obj<>endobj +198 0 obj<>endobj +199 0 obj[196 0 R +198 0 R +]endobj +200 0 obj<>endobj +201 0 obj<>endobj +202 0 obj<>endobj +203 0 obj<>endobj +204 0 obj<>endobj +205 0 obj<>endobj +206 0 obj[201 0 R +203 0 R +205 0 R +]endobj +207 0 obj<>endobj +208 0 obj<>endobj +209 0 obj[208 0 R +]endobj +210 0 obj<>endobj +211 0 obj<>endobj +212 0 obj<>endobj +213 0 obj<>endobj +214 0 obj[210 0 R +211 0 R +212 0 R +213 0 R +]endobj +215 0 obj<>endobj +216 0 obj<>endobj +217 0 obj<>endobj +218 0 obj<>endobj +219 0 obj<>endobj +220 0 obj<>endobj +221 0 obj[215 0 R +216 0 R +217 0 R +218 0 R +219 0 R +220 0 R +]endobj +222 0 obj<>endobj +223 0 obj<>endobj +224 0 obj<>endobj +225 0 obj<>endobj +226 0 obj<>endobj +227 0 obj<>endobj +228 0 obj<>endobj +229 0 obj[223 0 R +225 0 R +226 0 R +227 0 R +228 0 R +]endobj +230 0 obj<>endobj +231 0 obj<>endobj +232 0 obj<>endobj +233 0 obj<>endobj +234 0 obj<>endobj +235 0 obj<>endobj +236 0 obj[230 0 R +231 0 R +232 0 R +233 0 R +234 0 R +235 0 R +]endobj +237 0 obj<>endobj +238 0 obj<>endobj +239 0 obj<>endobj +240 0 obj<>endobj +241 0 obj<>endobj +242 0 obj<>endobj +243 0 obj[238 0 R +240 0 R +242 0 R +]endobj +244 0 obj<>endobj +245 0 obj<>endobj +246 0 obj<>endobj +247 0 obj<>endobj +248 0 obj<>endobj +249 0 obj<>endobj +250 0 obj<>endobj +251 0 obj<>endobj +252 0 obj<>endobj +253 0 obj<>endobj +254 0 obj<>endobj +255 0 obj<>endobj +256 0 obj<>endobj +257 0 obj<>endobj +258 0 obj<>endobj +259 0 obj<>endobj +260 0 obj<>endobj +261 0 obj<>endobj +262 0 obj<>endobj +263 0 obj<>endobj +264 0 obj<>endobj +265 0 obj<>endobj +266 0 obj<>endobj +267 0 obj<>endobj +268 0 obj<>endobj +269 0 obj<>endobj +270 0 obj<>endobj +271 0 obj<>endobj +272 0 obj<>endobj +273 0 obj<>endobj +274 0 obj<>endobj +275 0 obj<>endobj +276 0 obj<>endobj +277 0 obj<>endobj +278 0 obj<>endobj +279 0 obj<>endobj +280 0 obj<>endobj +281 0 obj<>endobj +282 0 obj<>endobj +283 0 obj<>endobj +284 0 obj<>endobj +285 0 obj<>endobj +286 0 obj[244 0 R +245 0 R +246 0 R +247 0 R +248 0 R +249 0 R +250 0 R +251 0 R +252 0 R +253 0 R +254 0 R +255 0 R +256 0 R +257 0 R +258 0 R +259 0 R +260 0 R +261 0 R +262 0 R +263 0 R +264 0 R +265 0 R +266 0 R +267 0 R +268 0 R +269 0 R +270 0 R +271 0 R +272 0 R +273 0 R +274 0 R +275 0 R +276 0 R +277 0 R +278 0 R +279 0 R +280 0 R +281 0 R +282 0 R +283 0 R +284 0 R +285 0 R +]endobj +287 0 obj<>endobj +288 0 obj<>endobj +289 0 obj<>endobj +290 0 obj<>endobj +291 0 obj<>endobj +292 0 obj<>endobj +293 0 obj<>endobj +294 0 obj<>endobj +295 0 obj<>endobj +296 0 obj<>endobj +297 0 obj<>endobj +298 0 obj<>endobj +299 0 obj<>endobj +300 0 obj<>endobj +301 0 obj<>endobj +302 0 obj<>endobj +303 0 obj<>endobj +304 0 obj<>endobj +305 0 obj<>endobj +306 0 obj<>endobj +307 0 obj<>endobj +308 0 obj<>endobj +309 0 obj<>endobj +310 0 obj<>endobj +311 0 obj<>endobj +312 0 obj<>endobj +313 0 obj<>endobj +314 0 obj<>endobj +315 0 obj<>endobj +316 0 obj<>endobj +317 0 obj<>endobj +318 0 obj<>endobj +319 0 obj<>endobj +320 0 obj<>endobj +321 0 obj<>endobj +322 0 obj<>endobj +323 0 obj<>endobj +324 0 obj<>endobj +325 0 obj<>endobj +326 0 obj<>endobj +327 0 obj<>endobj +328 0 obj<>endobj +329 0 obj<>endobj +330 0 obj<>endobj +331 0 obj<>endobj +332 0 obj<>endobj +333 0 obj[287 0 R +288 0 R +289 0 R +290 0 R +291 0 R +292 0 R +293 0 R +294 0 R +295 0 R +296 0 R +297 0 R +298 0 R +299 0 R +300 0 R +301 0 R +302 0 R +303 0 R +304 0 R +305 0 R +306 0 R +307 0 R +308 0 R +309 0 R +310 0 R +311 0 R +312 0 R +313 0 R +314 0 R +315 0 R +316 0 R +317 0 R +318 0 R +319 0 R +320 0 R +321 0 R +322 0 R +323 0 R +324 0 R +325 0 R +326 0 R +327 0 R +328 0 R +329 0 R +330 0 R +331 0 R +332 0 R +]endobj +334 0 obj<>endobj +335 0 obj<>endobj +336 0 obj<>endobj +337 0 obj<>endobj +338 0 obj<>endobj +339 0 obj<>endobj +340 0 obj<>endobj +341 0 obj<>endobj +342 0 obj<>endobj +343 0 obj<>endobj +344 0 obj<>endobj +345 0 obj<>endobj +346 0 obj<>endobj +347 0 obj<>endobj +348 0 obj<>endobj +349 0 obj<>endobj +350 0 obj<>endobj +351 0 obj<>endobj +352 0 obj<>endobj +353 0 obj<>endobj +354 0 obj<>endobj +355 0 obj<>endobj +356 0 obj<>endobj +357 0 obj<>endobj +358 0 obj<>endobj +359 0 obj<>endobj +360 0 obj<>endobj +361 0 obj<>endobj +362 0 obj<>endobj +363 0 obj<>endobj +364 0 obj<>endobj +365 0 obj<>endobj +366 0 obj<>endobj +367 0 obj<>endobj +368 0 obj<>endobj +369 0 obj<>endobj +370 0 obj<>endobj +371 0 obj<>endobj +372 0 obj<>endobj +373 0 obj<>endobj +374 0 obj<>endobj +375 0 obj<>endobj +376 0 obj<>endobj +377 0 obj<>endobj +378 0 obj<>endobj +379 0 obj[334 0 R +335 0 R +336 0 R +337 0 R +338 0 R +339 0 R +340 0 R +341 0 R +342 0 R +343 0 R +344 0 R +345 0 R +346 0 R +347 0 R +348 0 R +349 0 R +350 0 R +351 0 R +352 0 R +353 0 R +354 0 R +355 0 R +356 0 R +357 0 R +358 0 R +359 0 R +360 0 R +361 0 R +362 0 R +363 0 R +364 0 R +365 0 R +366 0 R +367 0 R +368 0 R +369 0 R +370 0 R +371 0 R +372 0 R +373 0 R +374 0 R +375 0 R +376 0 R +377 0 R +378 0 R +]endobj +380 0 obj<>endobj +381 0 obj<>endobj +382 0 obj<>endobj +383 0 obj<>endobj +384 0 obj<>endobj +385 0 obj<>endobj +386 0 obj<>endobj +387 0 obj<>endobj +388 0 obj<>endobj +389 0 obj<>endobj +390 0 obj<>endobj +391 0 obj<>endobj +392 0 obj<>endobj +393 0 obj<>endobj +394 0 obj<>endobj +395 0 obj<>endobj +396 0 obj<>endobj +397 0 obj<>endobj +398 0 obj<>endobj +399 0 obj<>endobj +400 0 obj<>endobj +401 0 obj<>endobj +402 0 obj<>endobj +403 0 obj<>endobj +404 0 obj<>endobj +405 0 obj<>endobj +406 0 obj<>endobj +407 0 obj<>endobj +408 0 obj[380 0 R +381 0 R +382 0 R +383 0 R +384 0 R +385 0 R +386 0 R +387 0 R +388 0 R +389 0 R +390 0 R +391 0 R +392 0 R +393 0 R +394 0 R +395 0 R +396 0 R +397 0 R +398 0 R +399 0 R +400 0 R +401 0 R +402 0 R +403 0 R +404 0 R +405 0 R +406 0 R +407 0 R +]endobj +409 0 obj<>endobj +410 0 obj<>endobj +411 0 obj<>endobj +412 0 obj<>endobj +413 0 obj<>endobj +414 0 obj<>endobj +415 0 obj<>endobj +416 0 obj<>endobj +417 0 obj<>endobj +418 0 obj<>endobj +419 0 obj<>endobj +420 0 obj<>endobj +421 0 obj<>endobj +422 0 obj<>endobj +423 0 obj<>endobj +424 0 obj<>endobj +425 0 obj<>endobj +426 0 obj<>endobj +427 0 obj<>endobj +428 0 obj<>endobj +429 0 obj<>endobj +430 0 obj<>endobj +431 0 obj<>endobj +432 0 obj<>endobj +433 0 obj<>endobj +434 0 obj<>endobj +435 0 obj<>endobj +436 0 obj<>endobj +437 0 obj<>endobj +438 0 obj<>endobj +439 0 obj<>endobj +440 0 obj<>endobj +441 0 obj<>endobj +442 0 obj<>endobj +443 0 obj<>endobj +444 0 obj<>endobj +445 0 obj<>endobj +446 0 obj<>endobj +447 0 obj<>endobj +448 0 obj<>endobj +449 0 obj<>endobj +450 0 obj<>endobj +451 0 obj<>endobj +452 0 obj<>endobj +453 0 obj<>endobj +454 0 obj<>endobj +455 0 obj<>endobj +456 0 obj<>endobj +457 0 obj<>endobj +458 0 obj<>endobj +459 0 obj<>endobj +460 0 obj<>endobj +461 0 obj<>endobj +462 0 obj<>endobj +463 0 obj<>endobj +464 0 obj<>endobj +465 0 obj<>endobj +466 0 obj<>endobj +467 0 obj<>endobj +468 0 obj<>endobj +469 0 obj<>endobj +470 0 obj<>endobj +471 0 obj<>endobj +472 0 obj<>endobj +473 0 obj<>endobj +474 0 obj<>endobj +475 0 obj<>endobj +476 0 obj<>endobj +477 0 obj<>endobj +478 0 obj<>endobj +479 0 obj<>endobj +480 0 obj<>endobj +481 0 obj<>endobj +482 0 obj<>endobj +483 0 obj<>endobj +484 0 obj<>endobj +485 0 obj<>endobj +486 0 obj<>endobj +487 0 obj<>endobj +488 0 obj<>endobj +489 0 obj<>endobj +490 0 obj<>endobj +491 0 obj<>endobj +492 0 obj<>endobj +493 0 obj<>endobj +494 0 obj<>endobj +495 0 obj<>endobj +496 0 obj<>endobj +497 0 obj<>endobj +498 0 obj<>endobj +499 0 obj<>endobj +500 0 obj<>endobj +501 0 obj<>endobj +502 0 obj<>endobj +503 0 obj<>endobj +504 0 obj<>endobj +505 0 obj<>endobj +506 0 obj<>endobj +507 0 obj<>endobj +508 0 obj<>endobj +509 0 obj<>endobj +510 0 obj<>endobj +511 0 obj<>endobj +512 0 obj<>endobj +513 0 obj<>endobj +514 0 obj<>endobj +515 0 obj<>endobj +516 0 obj<>endobj +517 0 obj<>endobj +518 0 obj<>endobj +519 0 obj<>endobj +520 0 obj<>endobj +521 0 obj<>endobj +522 0 obj<>endobj +523 0 obj<>endobj +524 0 obj<>endobj +525 0 obj<>endobj +526 0 obj<>endobj +527 0 obj<>endobj +528 0 obj<>endobj +529 0 obj<>endobj +530 0 obj<>endobj +531 0 obj<>endobj +532 0 obj<>endobj +533 0 obj<>endobj +534 0 obj<>endobj +535 0 obj<>endobj +536 0 obj<>endobj +537 0 obj<>endobj +538 0 obj<>endobj +539 0 obj<>endobj +540 0 obj<>endobj +541 0 obj<>endobj +542 0 obj<>endobj +543 0 obj<>endobj +544 0 obj<>endobj +545 0 obj<>endobj +546 0 obj<>endobj +547 0 obj<>endobj +548 0 obj<>endobj +549 0 obj<>endobj +550 0 obj<>endobj +551 0 obj<>endobj +552 0 obj<>endobj +553 0 obj<>endobj +554 0 obj<>endobj +555 0 obj<>endobj +556 0 obj<>endobj +557 0 obj<>endobj +558 0 obj<>endobj +559 0 obj<>endobj +560 0 obj<>endobj +561 0 obj<>endobj +562 0 obj<>endobj +563 0 obj<>endobj +564 0 obj<>endobj +565 0 obj<>endobj +566 0 obj<>endobj +567 0 obj<>endobj +568 0 obj<>endobj +569 0 obj<>endobj +570 0 obj<>endobj +571 0 obj<>endobj +572 0 obj<>endobj +573 0 obj<>endobj +574 0 obj<>endobj +575 0 obj<>>>>>endobj +576 0 obj<>stream +xÚìÏsë8rÇIŠºÌ‰öŒî´üt§çyšÝ­ÚJñÙfvçÖ$ÁÊ!•S*Ç6•üÿ±~X"H€èn$è5¦jêÙE|ˆÆ·@ƒúÇOßòýÛßò?=å¿ýžÿçÿô,~*ÅOÿÈÛÿù×?þøÛï¿ÿºÏÿü—_Ÿò§§§·kýñõ¥ù÷¯|­ÿöœþº?•ßNå÷SùË©¼œÊ¿žÊ¿üÇ×?òÿýŸÿû¯¯ÿ–ÿíÛ׿ç‡oß¾>ÃKþ=ÿãõ§öcøä²+âõi»Ý>ÜËÛ?¶ß_—Î%^¶wY¤*w÷¯ËäOj¤Üöû¸ē‰é½Ü?–KáÂC]о/ëå!"—x[ÎõœE¼r˜ë‰KåÒ!˜¾rÛg޹^òȾü\ÆÕÊÏ3s=GžJRÎÉõ-òVâÃl\ŽuЄõV¾ÌÂ%²( + ‚B¹ü29×$X,0X –€Åƒ %ƒ/° ¬(ÚMÄåÝoÙ9h6×ÄXo`å\ûhò’LÀõ#𡬼sÕÑ,åÏ\M6A!|…gi,A +Ú Ñ ê£s5Ѭåà‹+›— 9Ä`™ãÅ`ž‹,öD.1?V{àÊàŠRç\uD98æY\‰c®}HÙ8媣`Jé++D91WT蚐°ŒÒË TÔ  LÔ‹Š4ðZåªBÃ2t,OãQ ÔxŒsÆq‰±FãzX¢Æ#F,Ï%£FL×]w÷Ûí—×cy>|ðÛa0IwÅ÷_†ƒüxÂ[‡ÿîŠG’þÅ˃ŸßÝuoœ*=[ í,¸ö~ºªÛk[ça=xì.Bú±àæØ\ìPƒ–.Î$[q¹¸¡==·aMJ&³»XéԜ.K™\¬@ž› É貘ÇUùÑv‡]¶cqeSÙà՛eN¤ܯjؤ½s’  ®|²¡ÅϼJé\Í Xd°˜ÎEùØÍÉÜZ9ƹfÂ"‚­¨\Õ FÈ1ŒȕυEÛи'’ –Y¹0p7ñú¥uZj+Cg‘¼c,Òé« …«rÎX•½ÅÍÁ‘jÄ¥{.B J<—°ÒlKÃ7D=Ì:¸ÎåÛÁÉ %i=•œkˆàBf½ .Ú`Ø`¹Š¹2O”,Á W­Ç’ó ìÍПR4q‡ãÚa…„–¤8®´&1Š«žÙ#3ì€á«aÚz/8 [c¸²0Dƒ¢õ ‚«æfóuXiæ*B J‡íÌ\Y OjOjäªÃê.d‡%F®"°îBú°ÒĕÖ]È'½1p5Á¸dZ“RW\wá¢ÄÄÀ•6ºÐRVŽr‰» 7æw£\u€Ý…[FJG¹*OŠ…²¢d”+ (2$*ÇVå'ÆB ÃRåÓ©¹Z’ Wå“s! q5ÂÀÚÛ=W¢È£­ÔrAˆ"v@;-W¨jàLi­ã¡ªnè¯t\5-4”=Ùí§ž±¿ÿ.Ï´’T¹Æúù=¾aÀ +¢6(®–KH·Kh%ºÖRÕÓbQ®•–ër›®Îa‡Àà ¯Çé¹ £^ >ÜÌіœáµCrí´\MçùÖ 1£$UsÑys¥Z®³í%·NH)}¢æÊ‰Îkœ+ÑsÝ´BPf=ègŒàp‡åz7.×MÛk¼b”¾Tq5ÔÊÀµÑrÝD° ¬•T؇ô¹WŠçZ鹊÷G”Q&ß V<זByW¤çª/ŸÕPÌ1PRWF4C#×NËu¾×úü+ü’QØV +.A5C#WªçڟòáªÕr[¬àª©fhäŠõ\盽§5Rì•K,×êZ[Éu6Ž;êÊ12BªWNZ,×:{—'%WG¤(³ÔgO@• ž«x j®Š5K5†ˆëWC6Ãq®ZÂp ÖbI…Ó5 ÊFÒâ¹Ä»Y¨¹®&EZ,ip-â\9%pžê¹*֚Nè(; +\n£á¬5;c+\ŒôÅq®æ" +®K‰kvª‰@“¤¥pµ¥×qgéB™ÐdcMãº(½Ž«àôWòD@“ë¢ô:®Œ3¾êÙwCÅuQz WÍÛÃÈ0’ ¤h#!r]”^ÃUðûMÏ%s Æð2r•^Õñ6g +ÌÃ’lì¨\g¥Ws5Ì]Œ +㘁´¶ÑR¹ÎJ¯æ½ØER2WÁ^f®“Ò«¹rfæŽÀ8f DQ)ëd݅~^¹e¢IàkSYŽ­\§Öç*®³Ý Fȑ#š ”(ªT?º²k ±ÌukDŸ+?krN7Ä="àVÌµë>š>h¸Þ;а›‚]†Yw¹k6+IlºŠšô¸ Wuáiè†X!dr¸Ñ˜ÄjøCýsȵèÝJ´§•¸rŽlH[âã‹:\…’K\[°'¢@Ø¢C­I¤€]Ÿ«VrU×Ê=öEèà£ÃDïû¯´ùÖṌŸêsí¯#èùVž«áxåÛ-â;^WÈ\OÌɱonn0¾d=äª\ÝT”‚lˆ{ó€¼0ÚT¹WWojò$ ð\{–l lbÕ¹.¶*qeÝKž„‰×ñÒáÊY²Ñ˜×Ó{Šyq—KΈÚ{ÈhzªX¯üPy8Å:F—« »òúh9ÔNþnï5ùÒ*¹Ä€+“,¯ñª è¨Wo'ÍéŧñýGH©\SßËy°†ÇeŽæãvQ°2Ÿ,’+çEQÁse¼(*t.a#‡s5–r*W͍çª>š^¸ +vt6מ͕4™¿peM/\œ¥ùp‰'óg®úÃÉ<–k2ߝÎ-‡͋ó·•Ü:\[æ»uîªßFwÒ²ßmµwpœOm›.Ò,²Î-ï\·u›þà,•\×FÍÕI¿\¹r¶ûRãkT§×ćk¥äjÔûËÛ}©4fÜkbÄኔ\¹z߁¿h£¶W]nj¯‰;×NÁU UPn9Ár­4áËNŕr¸RW6|ŒŽ¹Î«Ëë51áp%C®wшﲫÝÊ-§h®š+Vqõó¡¸g¯r~ô'/ÙÅlp\ëQ®Ó¿^òHjÁZv,¥Šk£tEr<Џ¨ëdÞ7ÛnlÌ\—᯻?"éx@·‰+×à¢Zr—Ûj{‡àꤥÈ]|Ëíé71âp .’7.y<€ +£®[‘"K~­lâŽÃÕ¿(—óM +-áðì8—Ðpz®”ÃÕ¿¨7RNf™*Œj1\·Ùÿj®˜ÃÕ»¨ðTà¹b\Šã|f.ÅEußÁnßÊ#`ÂÃĞk¨Šã|f.ÝÀT5_ŽÜp ×^­óŠã|®áE…ÒÁ&ŒJ[=Ì®9·r‡Çù\Ër¥#Bq­Q\µÚ՚8JqœÁ5¼HËU;â*”ñÆË- é5qxœÁ5¼(S:"×Ã%¢"ÎSÇù0\ƒ‹´\?Œê´áò;ô¼RqœÃ5¸¨[ývGסµœm”MçÃp .Òr?ŒjÕ£YU4ñ"Ú4®þE\-š+Uý6.5MìçCqõ/Òr¹ê^,ÕMìçCqõ/Òríùáa«68Íòþ ‰ýã|(®þEY/Mõʕ;ãŠK W'T•šØ;·ãê]ÄçJ\ñ®óۋ_¾,{lÔMìçÃqõ.Ê;Š-qen¸:ù‡Ýxã¼ì‘ª›Ø;·ãê]4ˆ£*,WÚâæ)­Š«ó~(EO¢Må’/Ú÷#¢âÂùåªÇ¸äã|H.ÅÀn÷X®µW£‹ç¯AeNä’/ªúC%;s Ï\BsŠCqœÉ%_T÷$[DX®W;Ê.é"Ñ Í« ¸—|Q&°üÂeÎ=Üy䒎óa¹ä‹ +E2þW=/WÁá’.ªn»Ê·EÞÙ¹j—t‘è¶²¾Æ6ÓJ\‚Ã%_”ßö¿ž#W铫{œÍ%_T ö+Càª8\òE½H0?qÙL—Q\Ù8WÃá’/’gÆé>®Îq>ès¥”ºór=ŸÞa?bšK©;3×Cÿøšü²¡ÎæuÕ»ꝪHqPJÛ:k®|¾!çéw·§†u\y1Ô׏áŒF~™WsÛìø9QeäÚÉÔ—Pì(É/4¬®KüuòÈȵ™‚ TSë¼;Àz齺 ®u+ M?\™j« ºã “Òdúu\©l)^¸š÷§»nÝî«ko»õʺ ®Dºµ®êºQ(¾unڑÀ[v…².Ÿ«öÉUtv¬÷7ïÒqY·äsM]Õ2¿ú®òöNå“+ª›v^Ȭ©K㊯ۧoƒ8ñƕu—áòžÒߌ§©KãJ®£0qÙÄóҟá¦×VËIÚªº$®Õõq¼=™t®êöÓ5ä$mU]WÚ}tk;.CúáõÏÍÝ[ÙtĪ윑Ò×%qÏ]ÓÆ+W¢ûѧ“T<¶ÔçÊ/ƒô8„wÞ¸2]:ÎeO¹éÀd#©;x®ýåóŽŸ|ðÆuŽš¸1‘†‘¶.‰«¸ÈÐÑÒKo\—½Îûƒ:À:eR¼Ë¹¶.‰ nÙ¯qëë¢Z{þ⇬ã‹õu•\ÃÄÎEu¯G÷叫“Òkmñîm®¾X_—ÂU_ `ü`;®±}½n=é½ÄÕ0‹V[—ÂÕ\~<ºeK®±}ØByŽCš—ƺ.]_ˆ¾ç²Ú_ÚÌÒ|Õ¢¯Kàj/Žùô[\½,Ú¸ôdЍKá:;æ“[öÉÕyіL¡ú’9]] +×Ù1×'ï“ëý ì —J•l:ZÇuvÌõ©¾—1ïë9Sš\ùPÔuñ~ùäËãÿc—‹|¶—‡á¤¦ÒLrTu \ÕÉOnÙ?×­µ«^(u@Õ%póÉ-OÁõ. +‰vЌÕ%póÉ-[raß-Z‹ÁX]—x÷b멸n‰×f®^]×Ù1ŸEr”Ë&ûø*™ìе\cu)\o&˜4·õS/\²{ãb§®.…ëM2âúì-¹JÜú¡k¬.…ëØÓUt}Q7®D²­x”KW—Âçð±‰ËæÜM.ý9Õù±º®ê|²&±çڍO¿6ÝyÈJË5V—ÂUߜº7®ªÛŸûÞmz«Kájn³Q.›sˆçkãï·M­–k¬®!ž—Þ¶%ä]A ®qö¶ ©Ÿ,ŽÕ¥puÞ ë«™«õ¹F꒸r—Õ¹ìf¤jŸk¤.ƒ«´çZãÒmú¡ÿ VÑ×%qƒßxàjô +3àj¸ëQ2\ŸÊ(—Õû7䵘_ÚQ.}]—îý¬n¹:}l \Úº$®úêÓǹ¬²Þè!Ón”ØÔµ*–ïí¹Ê×ëMóU|–ïY +¶X¾ë“kz.ó떗ÉUüÓr•‹ä2/pÉe3aþ䚞Ëjb¹h®õ"¹Ä?-WºH.ólõA¹’ere0ðµü>ŽO®¸ö0ðÅ}Ïn‘\ðA¹ª Z~¯Ù\Åô²×å÷ÐÍULMÞá¾70¸@ªrÃ\ e’ºÒò{9ç*Š+[\Àa +%°ß{ZÀ‘›ì ù=Å¡­´e&=@~¯thG„â‚¥Âèo‘ßoXÀQã¸÷}ô•±mç˜Á8lc®Á9æ½Qæ#/Á9°Üè–ã‚s`™±Åš3‡}€²×ÀXcV@éK`3Ëڬހò9°ÊÜX@=€ÀXa6.@l`3°½9êT˜ËÍ"8á Kèmœ£ Jè„m®gƒú¡€S˜ „A:àª%ô¢©€ìڐ„>G˜ ‡bH}fv_ï\bAB/0Ò -Vè׋‘Ã]‡+_Ž V˜Ȑ+ A,0 +-V裥ÈaÜ媗#ˆ(Â-ôDˆ *âƒ-ôéBäpÝåB} Â(»‚-ôÇ¥€VÏP„#C̾:\ÕB")£œ· Å }ºÙHd.„Ð'‹TæB,Ýċu+_†pd8üƒ"âȇxà B8j¤—Â!Gl#´A `1Û¨«>BðÌØå +h)‚¸xí\Åú,(ÖCéÑg­¡% ÇÜ ýŽhIÂ1ó3?ú•‚+~€áï€d¼s°=z @KŽy>r’s˜y€Õø©bå™a÷H*:sˆH؇–(30Ê&ÐúyÖ9eˆιÈQDs‘ƒ²Ôā9£Ò7”AОQéI+Ò@½t>¥Ï)Mª’ζÚ&HšÔ¡9›!"li¥åڇkˆ´åhél¨vc! »ô™ ±¢g83âžö¼nų¢ †®@žâÌcˆñqCË`3Ĉ9qx@Ë`iˆf(Í4€ó`¦Ÿ¬Tԇ -g€M>kΩj-k€MœdY“½´¬6± +ÈcX]>±rz‹€5D'VFÔ +œéöÔ1GNÀY™8樼A:©ÔgB©œÇ Üϙ.H,8ޏÃtºc wàÊêd†kÍÁ…Tú‰:,c=càÔ4Æ €?R§é°ŒÖÛNÓaә_‚& :C¢Åqí±`»0ºk…äªé0‘qƒph­ ±÷UKó„ªY.´v†èuâ,øV­!zÕzìÓÝ ¹ð†èQ:j ›ÖÖãrfWŠØ ¬OKüñÍPË%¢¹-±±’.h­ ѓ&æV>¬­'BõÊXZ?Þ¹±´°öõ^†˜È,e \<1÷3–½í#×½{&ܸ¥rU¤s©ÍJÉ\"š LdöܹK0‘;¸)82‡i\o\´;¼•Ÿ'–‘P¬.t¬Â^¿¹1p1_uFÃÒÇàd}¡ãNSbé¥ +\EiW°/)áøf08Ô&[õ cœFwžÿf<[l2êR6W›qÀúßtŽ*OôÛø\‹+Š¿S;‹añcq€‰‹ÙaQt_zî¬ñ¹‘‘«ˆ¸ÿ¥ó/9k·6\"â—{”56¼OßYqYtØqœ=šÌñ…Ie˜>˜¹l:ìŒöªÿ짌ý¹K.ê4Li¯ƒ~/ÛÌæqµ¶\Mä¦ÜÝo·Û/¯oåe»}È,?mcÍå¢ÃœSþ#†KȵqÀe'‰³tŽ+¼Û9á +®ÃÌK_8.±´îBrvm¦(ˆ=$W›…ÄupÇU/«»Ð\¬•O_ºäj‚áÚ´.¹‚ÑzÜöžKdKÑxw gÑ q!Øý^ +—XŒÒ¸°DôÖ!‰kvKÄgиš…X!•kæø—°MäšÕ)¹/T®9½3eû‰Ê5c`OJš#sÍ6Ähi/t®™†1±ŒÁ5Ï#îí2¸fbÔ,%=pÍ`sM®ôT9×ÄÚÁÈdr‰<\)´ášRY©Ã\®éÀx™dl.FÚÏ$ŽËšk¢Éóā×þ9椰áòoŠü,M+.ß`ɧv\~UÑ&Yؒ˧ƒ¶Ê¶åòf—ŒoÍEΡö41qÏåcÚb™®î†Ë½,ڟ›pÂÕ +·¶øhß"7\o¶è®Ë’CW+Âé,—\ŽºìþІÆÕŠ'küâª-.¹ø©ÕªGw-qËe‘^Hݞ“‹Kæ–ʇìþ‹ë6øà"æÅÇ[ï¹ðÃõV^qÙññýw/·÷Æuê5ƒAÞm_}ÝÛ'ש۞¶wê~z|õy_ß\çŽ;žpØ>ÜËývûøúêý–“pÍPàÿÿÿârõä +äÿÿMŒA‚0E÷œb–šØÚ]¢Á B=@c‹bš¶h¸½­ÍOfñç¿·çÑöÈ &À{Øe¸Z¤þr¹‚ùé Ó½{ £ ”a¬3Âic¡Ó,Æ5¿{>JOÓÄ£ˆ&8‚À£®¬Å>aŠÎÅNÿvùù£å|qö»ó¢ìO¤Ÿ‹®7”±ń ”ãm(-´Ê*óR2 NÑNåò÷endstream +endobj +577 0 obj +6286 +endobj +578 0 obj<>>>endobj +579 0 obj<>stream +xÚ+ä2T0BCc3JÎår +ár á +äHÉHendstream +endobj +580 0 obj +31 +endobj +581 0 obj<>>>/Annots 19 0 R>>endobj +582 0 obj<>stream +xڅUÛrÚ0}ç+vòDfŠksÉcsiJ'7&>ð"ldˑdúõݕ šN‡eíž={V¼u"ñÁ(†þò²s9í|þzqÓ$QŒ`8ô覚/XÎϧ¯ˆH ŠÑó^?‰ƒ˜PÓ¥0`ÔÂn˜æÀŠRTÂXͬÒJV5LB­ÕZÜà‹¨,ׇ0¡*ÕBéÒ¿ãØ%‡+U–¸|~˜ü"!ô¢¾Ï˜RQ½@¶5–—;~c¢7 +ƒ!ô¯ûcâQŒ¤ifݳ«ç4;:×ÉΝÍÎ?ÁškC,£€~yÑÈIõûˆ1Â=9xÄkÁ7½™v DýéÑãé’aŒ!ÆçJHÆT¤_IÈ|wvTB܈q£Sï²2¨•¶l.¹W˜Ä‘l‹B“š$á, {sfxªæ$;BŒ£h˜XX2sÎ+(øšKÄ0߂Sþ˜²~î 3Û„ ˆÒˉƒA» j>¨þPÂ8Úmk§åE«çÎb©VE“[sÌ-Üq«H˜RYt#˪‚éâ]£d³7“ÒɃ}­ +2,¢¡1ØäŽ$>± ´mðOwæ’ë—| 9Ú?ô¤¨88³Ó ™  }5.8&2ÎëÂUÜÂÞÚX¤U¹’dÖIš¢÷€y,6ŽÈcöB`W¼ª¹çÿÖð3ÂÑwHã£ñAk\3N† îÒkJ¡Sñû=7†½p¸”*_Ñvvé¼O±¿Ôu†Ÿ‘ê¬Ë‚UÀøÎíµÐ<·¢ni#º ¤Q'ÉMS“UÑ]a— 9¶‹¦Ê©)L +»m¥gEaEÙ(½Ú_s­6†j&2©26˵¨[á¸>Év͍Û¾ÎÔ×éÇ`oåö ù¦e‡´˜ìa^ykª‚ûYú°—T+ö;—ȼ1V•â7fÚÝj·Ïp»Dڞ’Ê­yeå¶¥¥£Á œŸÔF0¼:KêÕBàè?MRt³Nû†‚”T©ªw W«'º$ce‡ -ˆ§3Ö·ÔÉ{“f'Ywç\޶ÜÂgŌdPãØ¸Øþzïo¯^¼d-É8 .p¿Fíò£óÓQœendstream +endobj +583 0 obj +839 +endobj +584 0 obj<>>>/Annots 33 0 R>>endobj +585 0 obj<>stream +xÚµ˜MS9†ïüŠ>’ƒÇ£ñ|ysB¶RE{÷ÄE±e¬Í|e¤Á°¿~»¥[v°ð +ʔÌ#M÷Û­n~1ñ‡Á$¥ßEyv9?žË`¾Âÿ¤9ƒùòüS½èJQiøö(ÚG)6æÿ"c–EY9_Kª^é oðe)+©tËuÝ*(yÕñ¨Û^ÉÿÄd¥kÐk«º(ꍬ@‰…–u¥þ°OYôO‰ò Â¥ALºÒ ¸žŸ…AˆnУï¢3Ñg qŒí €Ù ´”L^¡ „)Cs|´”ÀðoêÅ]ùtLþò7_ÛØÅaB33R‡ÁîZԖôœ=+-ʽØíV ·« :² ‡#/OԙE8cÐÙ |:÷´•ÑC;ꉗvÔ ­g^Ü%O2Š’wäó˜â²åOˆ >/'=1…ᲓŒ"ë%|©”æEAë¿ïfod:Ōê£cžè ´ßG;ê†ø×‡»ò“½Øñ'ègæ£ÇÔï+¯ø fR\´êíEË©Ì ¢™O´ž¶šxh(!O0‡|´PJç{øë’%yfKe<ÑÂUÁ•ï XFì ˜øëi«‡‡vŒ¶›vÊɌÛâ'–ÅÖß»*$5¼™Ð]óöj¥á®3فO­ž¶bxhè;“v€¡3ùp—°0tøÔMÍQ"}¡3™ý,è€ñöJÇé®7فO鞶Bzh”öÐ`{SæÅ]ù˜agóò|–ïBdâÌö¦ÌÍFê5|ÓYۇéŠÆdb[SJþšÁ‘àì NBy衃“cŸ÷Ñ@)yw Ú*2[þ±±õ™Fvbφƒò\ˆJ ¸xhÅ;m„(´-%óÍà¨ÖlK£”¡—v£u楀;|eq— ÄNhmù´Ž˜í€—TÐ벬+¸zS·?©°Sš¿CRc߉¶B›O螶:zhÀN˜‘ŽÚ¨¶‡{ø …¹õ÷Ê9:|jåã{œµâil›!mr;ðT6›ÜG;@ ˜:‰—v#o쥀9z¼Ã_—7ž&æ­ŽÁ·c¨WðYïp*‹óÐv?㝑v ´1yç¡€²‹ÞQ}¸KÐ6¦bé墄ˆ%èïŽ?AޜÙ~vÏÛºûÚ®ëÚ´µ¾ ܵ5~{¼§ W #\o4‰l¹­5§› \¤zÄ"M—GoBþá­¬;«‘ô¢§ž+͟`±› Tú;enA@ÓÍÉC'—"€ë'^6h´™‡-X¶P +^Q½2_á3ÙX¿ËñÔ\V¸ÞQԛþþ$émc½‚’}ƙþÄ0|ËÑvÊI¡­lÈ<;;r/ʨÕmµ(|mÕØ/ïÏÙý‡}]"F]oÀæk/ÑÌü}Rí-lÕ᪥•‹`>àP·°ê*sQ„êÌ@lÍ*ZRõK$Ê3ηwP|ƒÇÏáÚ ª®ü!ÚÀ:À·î¶îy{°È¸SíX­1,ãEרñ’k>ÖBé† +hÐ(Ÿ$´ÿMh—²E;êöÙ*FÁš'6ɾ‹_>¾|"OûJ=ÂH¿ô,àÙO¨e§›N÷«³#N Œ–Ðôõ…&’Mp};¿þ~ô7a^PŽ¢ü>å#¨F,$~÷S<+(äO±ÿ\GÄÖ>7ÛwÈÅÍ \]Ü͌Շ¶²(0N;–Üš@*»¹hñ¤ÍR›Vjt +7ÔA lîÜ%ܟ÷@×8)\ ³Ê=)O šBlíÎ5˨ÃO{Æ\ïìŽ|ûw£_·y9b1uêQ/"ún’ûó¥›Xlý²›endstream +endobj +586 0 obj +1428 +endobj +587 0 obj<>>>>>endobj +588 0 obj<>stream +xڍ’ÍRƒ0…÷<Å]êŒP”PwÕÑ.œŽ?¥J€($š«oo耣èd“äÞ|ç̹yqøf!À„1ç"u×+@ÒÂTâAšŸ¬³LÒWF4\¦¦'„ú7À^l»ÒŠB!êZ/Œß‘ZEsЕmY‰V›-SÐޒú¼‡ÆÔxqƒØ‹,õ)› +Ú +½ÀÖnX-²wMÕ È"èŽSš;Æmgp[Z’1.J–8þ“¸™!nؔˆC¡djó3m× Á–}–·º¢hA%å‡ïúüúåþn;Qè£ÍøNŠR’¦¡RÁ¶‹öwskxþꆲe¹ŸÆ5•9Ø!™®€ð|aî雦<··Æt²jõfâ™úÛ«9ã`¤\óaÆÆZ5'ž ¼4Œ¡^¦òë¼aœ)-‰.аygfàÿøá£Ä÷VÐÕB{¾J{ç ¦íendstream +endobj +589 0 obj +358 +endobj +590 0 obj<>>>>>endobj +591 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS041×3R072PIÑPp VÎO+)O,JUpLÉÍÌË,.)J,É/*VðMÌ+MÌÑ Éâ҅è҅j3‰™è™(€ùŽIIE©e™‰%™ùyÅ 9×®@.~%endstream +endobj +592 0 obj +125 +endobj +593 0 obj<>>>>>endobj +594 0 obj<>stream +xڝUÁrÓ0½ç+öØÎ¤¦IKҁ4LRàЋb¯cQY2’œ¿ç­ì¤Áía:“iâÝ÷Þ¾}’&t‰¿ ͧt5£¼½]^}¸¥é%­J|β+šÍohUœMè‚^ۨ톖û¹¦»-û­æÝùê'Ú®i2‘¶‹®ïâêzšM¥uUé@y¥šÈžﶺà@ʒëûɕT¹Ŋ靫kgéþ˧ÏøvÎ?†¬c»¥É\Ø.A4Í®;~jYx·6\ÿ- ÅÓy6“âÎӞ•ԕÌú’3ÑPš—PΨR£6-IiF÷ÖèG¦Ï:÷.¸2>L_Ïè»¶…Û…ô?è>«œî–ãn6°N€!jrÕ9¢²…òž}©r–¾ÐM¯­pâ§R~k›Æù^cª½s›äbp¦ÚYøÞzÏ6š=©­ÒFaœ±” ˜ß²dè²ÅÁîoO>t°4Ï ¿v!â)o•xփMgÇE~ÞÜk&£-UÓÃYäߑœ5û‡swìeîuŸ‰¸WM¥óðp>Nßw:VC]͔;õ[wvì)GÚ֐­ +èwG%ŠÊÖòÊnXBxäàR›äu­"¼ýèvŒ¸Ž“«ã±Ê‡¼[å5ì$1)íÙ5ìՉ „^àS¡Ë’e3CŸÐ +±Òoe䬯5'‹¦Âk( rI…‚˜ðåy†JáX‚Âs͈‡ÒykbF«JEøW¯±¨Îà¤ÇèZG.†C#jubËÛá<èD‹øÓYp°E"'90ûütólÇ]XÌ“QۜÆ[ ”Óš‡¹{w¿XÊP¸^ôF¤‘EµU‘ÿãœgtg%HéF®©ÖYÐç9zAj?{8MÝ_̖¹â€ä /¦ÄM£vEk”—dJÉÓ%ð>'¤†g$Èq—™ç'e,ô„g±9M~·~£c4é2²°´Ä3Äd©-¸“é‡[}@¾v}tŽ7Šñx×M‹ñ$Œ;pÜ¥N5Ñ¹J÷®q³jàš-—âI:kzHlñR‰œWÖ·Ùw3@9^Bñð +¹yz+ÌçÙ?½å®o.³[4 ôµ|¿}ý üjºendstream +endobj +595 0 obj +836 +endobj +596 0 obj<>>>>>endobj +597 0 obj<>stream +xÚ}WMoÛ8¼çW<ô”¶»““¦Ù¤H°ÞÚÅ^z¡)*f-‘*IÅëþúGJ²-ÄE$²È÷13oHÿ:›Ð~&ôqÆ¿²:»]ž}¸ÿD“+Zx3»žÐ2?_®-•\[ڗÝûåO,º¤É$-O¯²/ûü}¾ íi%¼Ê©©­!aHUʽhóB&(gT „É…ËIвÄʀðý˹Ó&ðò¹³ÁJ[fô8ŸÓZ ®R†“#åäc6唪Z9!cµ£ÜþVƓ-¨æÊ!{Þÿï•{şJ˜¦24N9 `ßÔµu!…yÖÒYo‹@ÿj“Û­¤œ^\\dígÓYvɟq…¹*´Qˆ¹ï¯n[ ÂºT7†N¶ª,ù/ª›ø’~ڕ?*ÚÖA[ôTꍢJåZ Šñú·‘Sޖ /ÅíÞrưÎè‰7e`8N´t5ùQÄU‚¡•¢†_•– ÙеŒÕ/ÁR·5zZ7&w*÷¼/¬mãQB¤¡Ò%ã±»Œ¾›ØƒELwXÃÚnr¥bD‰Ê[2°QJå‡èKk‚³%úl +€J±ï[évuz®Ä†Õ„T\SeB»µX•*¡¤$T°ç¥ÃMˆ¡Îl™3à÷-ê!¡Rì@ ÞnkîžÑ{ØÕʍ—ê¿@K'ŒçÆzaӏówËåüݏ÷´]k”ˆ8¼ DéàV­ZÝâqXÒ!;-רö W&‚¥W­¶ ÙT@ªÅI®•ܰDCãI褊o¸r±^70ØAæ¨ZÅ¥j×핲Þ+Ÿ¨ˆRn<ãšÖq/+‡ò”B}šxÕyœi«ºTA±&>L² uÊíˆÚù *¦)ì·Ý49¢;ý¢|H5D=“T.è‚u¢}K(naèF€¬X…~n’©ÕZ荶C†A¯B—QbÚPÑ°Ï ²2›q¨A0wž%?ݛîøã4áòž4Û/‚)0a‰«ÀáŠ8p—èj«Jvµ#ûÁ›Öw¥è³6ú9H;ÎwžÑ×èI˜ lÈ䒂£5ŠLS­”ÚR.y]ÀéÂÀrÈC¿6|ËRã%²)…ƒuz¬nÚø&ºP/ƶvªhkñª:g2꽕ZpÏ[Ö,½ +8)6[öOJŽ™ªf̤­u'Z$´N‡ÝiJ>'ÿùì C^*:¶{ÇÜ»5\ÒùVôŽørqYDÄnqÐ$HÙ +í|‚ÒK²›nmââçt¯÷ºäjOöÚ¾O®Ã‚ðÉ8D]—ÝL¡¬t´Á3v`‡~/T¦È6`N*øÌÊÒ ùǾeÆu¨±t Gb%,LU°Ëc_Þ:OՊ­“ÒÂVÝú8Ì“u³c)×E`Ȝ¼±(ÄzûŒÂĈ€|îgô7Ÿqžàü:áŠZ!DYPæbÂoüŸí°«õh†ÑÔ§ˆ Œèa>þëéô{œßÝwÿræÀGQ|ÎÞ´?€KÌÍ­ étÒE©OC߄çÎã'8ÏØQ´oñ<몎Ðu0ijCÇ8èò +*QwÒ-e¯— +èh=©á[!7Ãiw zºx0*ŠvyˆgKŒ3ߣƼ`Ö\+½$ó\ÑÍâaq'é]uùø×/$û4î:ºebðû▢»¤Çþ¢†[ÀÖº Î|‘.nóùh€ñWAÔM]/,R‡ïS '\^Óì!àP´ +>ŸæwÌgcËè&Ï5+Gk_|t÷ƒ“o¸«GVK ƒ} Û÷ÖÌ/žo»€ˆ Ë&?pq´\Ç£bqó|{C|=‡ñ©–øë–×Éåή?%¤£Â1ñi- +¯´Ñ^,¤ùŒo¢äã´o|5½àm3þìòâ:ãoGo~ûù²<ûçìH]]áendstream +endobj +598 0 obj +1453 +endobj +599 0 obj<>>>>>endobj +600 0 obj<>stream +xڅUˎã6¼û+:{ɰ5~Áž¹%³A²ë`¼È™#Ñ#f(RaSãè﷚”¼¶7‹ÀY|tUWu·þ™,hŽß‚¶KZm¨l&ûÉí‡5-´?`gs·¥}uó Êí*&4)˞:ÖEO•Ž:4ÆiŠ5¶^•±êÉj¬¿šRsAŸqT!v-iUÖô”C‘A0~Aƒ¤ÈŽä?íÿžÌi¶XKÁ¢‰Ä]ÛúyJ +·•ëÉ8\mT4Þ\År$Pо–wký‘·V¼i{böQ[Ko?ïS€+påèýîñÓGzŒ½í˜Þz ª›ùœÚ`ÒN€1"«¬Å AˆÒbšRÓÿª¦ ~ûážÛ¬ìlµ,Ö³‚½ æUÎç¾:0[n‹Íù¹*ŸCú™yégñÈÃ<—ÆF9Æ­.ÍÁ”BPÌ‹|Õ¸ÒvôåÄqܽ6a”l~ÕG«cœí ¡ +ý®X‡ßtL¦¼Óü"ÿ‡0œ³„÷³Ö¸)-×ùy®h2ô +rØßÕ^dÂôWml*4Ö'*OÎGzÖN‘M£,ù.¶]L¤ÅýÊ:hwb•*myz…Œ³½Älƒ5•F±0´KwŒ{NUºä1¡ÕþH½ï¨D±ƒÁ +Þù£;áŒDå*÷Ձ«ßâ6ØFºâÌ÷«å£ŽG^Àåÿ +%#–V1ÃáÔ#š¬/¡ ÷—š¹‹^z˶'®±VÑÑĚ<·áèé¾Ëð¹»®û%÷šÈ4XKËKEh£“…˜8b– 8šiäÅgP_`#·Þ[(ÎÙUÀ]@é ÇDÕò™E„Fõ²Š)¤­.£Œš¤Áÿ©'§Mi +XO}bâùÙÿ9óxS ˜ËMö#õQšˆCÅ0ec6ƒ17­eJL°ÁŠKßn¦t¬ 梘Qz+1ÐXúø¼nÁoô2Ù#™²vŕç³ï¦³ÑH«çt£j¨l™†cȶîY*b´{dr1ѦÄþ¿Æ¦à!÷c„œ¶—Ø(E¢¥=Uƒ»ª ]ªS$5vÈttcHzj¸”Òú7 J] $§¥ž?ô¤ž0&¾rKbˆò|E:Ò9«9)ICq‡º‚ŸñUÄø!}7½XoqlµÚwr8àGˆGqþ— +ßP“†ŠGˆ?”ëT*ïY¾7Û.çßùX¬ïæÅ=¥Ý­¼¿ßOþœ|Ù䞗endstream +endobj +601 0 obj +924 +endobj +602 0 obj<>>>>>endobj +603 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS041×3R072PIÑPp VÎO+)O,JUpLÉÍÌË,.)J,É/*VðMÌ+MÌÑ Éâ҅è҅j³‰™šé™+€ùE™y%©E +.E™e©EÅ Y×®@.˃%«endstream +endobj +604 0 obj +127 +endobj +605 0 obj<>>>/Annots 39 0 R>>endobj +606 0 obj<>stream +xڍUÛrÓ0}ÏWì0$Ší„\x£¥é„NhÒáò¦Ør"°$#ÉÍäïٕrqK L§Ê(Ý=:{öìöW'…Rg0A®:«N6…,U éxÌÞÀh<Uñ2ƒ\4²*¤Þ×̵ó¼ªèzy·X¾ZýÀÔ!¤)¥öbno0ÌXFé«­toyí…·5;x€7°&Ѐ(#"ø­€K£”Ñpw3ÿ + +µ§w–{ç…b0/aoàVs)¢pµê$,ÁªèH鸽†A6`SK§øoώ}–À”<= ÐÃð—¾~ÛïãÉÖãv ›Ù¯›uÿÄâéño­„Þ†™»ZñŸ‚ö¿ÞwܗŠk¨9}ÑîãõÍl¬)K@a¸6iAÓ½J"HÄ$Ö +”üžËНÉ=8óÿl0ÁCA:IiÉÒå¿äLjµÑ 3v„ +´žiÒ)¢üÏ?×á$Á]šPøôPÐçÎoH]Gendstream +endobj +607 0 obj +886 +endobj +608 0 obj<>>>/Annots 42 0 R>>endobj +609 0 obj<>stream +xÚ¥VYOÛ@~ϯõ¥ á+„#T(pù$´’´íά`¸t²ÇaÃ÷Éê\Êjèê,ßuak¨tÀë¬ö—eÚ´’kï®VÕºþµ®ÖˆeÓO•­N¥mÛ  ÒoË­tî÷ðý†/mª´i¬èãÑè}¿¾1¥¯C­|¿GyÛ qçÿ¸”x8ÐÑ:gO|9 8Ðsló Çω·+é÷—Á‰{ÈE–/H{ÞWðÝîvpH·Üúl­ö¨›f:!qËÔ ­ÈàœÉœ•;›UÕY;C—Ê<—nŽÜ‘½nÿيÿüü\P›endstream +endobj +610 0 obj +845 +endobj +611 0 obj<>>>>>endobj +612 0 obj<>stream +xÚåVMsÚ0½ó+v8%3`08|¤'’4Ó&¥„L/¹È¶ jŒD%âߕd\cȤ—ž:̀FÚ}o?žVüjøÐŏÃô­W‹ÆtÑèz#Ü/¿ä‚‘7„^Ð÷Ðp4ö0âRRHöè¢ßÇMw4 +¼®;º2P]ƒ²ÿB¨Îíü 2F¸ˆÏî¹Ò$M_‚^Qx‰ÞIÏ?Û|ßY·{Ccý¬¨5k2çÖMä’jЊ-{® +˜K‡ãÃØÀ`ží^àYÞ5y¥¥Ëôq1;Ӌ‚Ò7©µû=cûc2¼¼»<jàՓ¸~ž=ÁŽ!¨ØR¹“LSÈE&¾1¥ÅF2n*Wš®=¸OŒl¨d”G6yD÷MÉ=fI¢,Ռ*„Ö+›¢%Úç „ÇÀ)M!–B½š¥ei\'mÕ( ¿ z!iµœ' ‘b]àcܤzt}£{°Ë›Ù—»}”æ·F<Ç>}FfkJCFx;$ +7p=˜„‡û`¯Á–°Ôž!<ùn0xC©Z°[±Ô ¨Æ]†wŒ)xš×€¿2ž½y‡ã"pÃ)ä¿( z‚¨ä/ê1t°šå¬©1ü“Ésê!;š<=ptqKÕ}puãâð5:,‡ ŸÀ攊ᨪ!…T,—Ô^$¢@ +¡?A,lP÷ÿ¾v*; í ˜Â.‹(ÙråA9)ML&Jƒ ÁȌۭƒë_4ÍtóýÉèىèxX÷‘ØÁسõ$ç-Q¯& +$t9U.àWF•»…§$…àauÀ5Û!­hœ¥ˆ»·±SžÆõ ŸisˆEèžWy´û#ŒAw荌©ã.çé$^3nzF´ +ψ•nÛùµ‡½îÿl‚a€ÐÖÊ÷ ½~oüËdþyendstream +endobj +613 0 obj +888 +endobj +614 0 obj<>>>>>endobj +615 0 obj<>stream +xÚÍT͎Ó0¼ç)æX$lâ44-œ¶H +ËnöÜØM ‰]ü£Ò·ÇN`¥ˁÃ*‘’ØßüdFò÷Œ!Ãr•îfÈÞÕÙ«°õ!î¬ÖñE,>jçyß+݂kÜÞìp­œ·j¼2úEý5‚J06HQ%Pm &|'ñþþæÎü‰[‰ƒ5ÃÌ%þàÂÙœTÄh)¼Á^¢7m?”w°Æø·æbfÏ/â ºY@¹´]±%-’¯Ö©Mh;ŠÏº‘£f2•l&z'íKØ0ù;)ß½™h6‰5fEŠ’ŽÙØã=í¬“Óõ¯ …&a”‘_øAvt š(íeOÓÄöS½½}虌ô«Äquð҂ÃuÆzÙóó#aŽyŜ.qǨ¸ãœk:)B9æ™8a}šÞ Ü«&Ît2ð»wRlè#Í_˽JÿRþÌöœëÇoíý#ïYÈý³êy}1ÀÊ*fR¼®¦?™Ôîfµ+1(ºáÞX‡ׁ÷‰€L8Ry‚±"-.˂VÈÿí´ØÖٗì'-ªbêendstream +endobj +616 0 obj +418 +endobj +617 0 obj<>>>>>endobj +618 0 obj<>stream +xÚu“AoÚ@…ïüŠ'Ÿ@¤½%M¤H´¢Ä¹Eª{ÁÛÚ»Îî:$ÿ¾³k“4Dcϼ÷æÛÙ§A‚)ÿ,SÌÈëÁU6¸¸½D:E¶Gº˜Æ+,–+dÅp† 6F*' ¾“¢ƒ¨…r£ì77̑$¾aÒuLfó4N}SVJ‹¼¤ÆwÂæFî„E©pTxÕ­Á^ëÐôꤊSEŒº¢þ³;ÏK$Kï9e»4žwnWden?Æâ’t/|É åå›ÑS+Z’,Šj²V璜(p”®„t_áXôÔŠê–³ZGÆuE„J¸Sîœr­I…¶ñ1Ø<™u4x $]öåv ÕÖ»ðà;½O« +þŸk#ð8üõ8ŠqMV€*͞ò ä^²…CćÑf{÷#»ÙFc~ì2FAíÌ8êˆ@,Íù¬d#ž’íD°¶~4?_Ü÷¦‹êæ_XLª²š‘=3,>Ðg™¦Æru }‡²ó ª*Q¡Ñ†g`êµùƒ`±§\ŒÏ’{2l¸çú2Æ· gƒ ¾~ØÜ£e@ÌE›[aySØñ®àÝdVL“IFÛ;=Žp,%¿g@¨=åƒP‚#™-½ÿ,»Ö99}Ò\MW’ ’¤àAºe=ŠvF­01nµx¡º©Ä8Àû~fú×YKÕ¾°j˯_½º}GÎù€ÝšOû5“ørÁeU“|¼Ãþæ¬Þ¯E²šu§üÿÛ=_ÎùJO}Q2ó/n²ÁÏÁ_OUendstream +endobj +619 0 obj +578 +endobj +620 0 obj<>>>/Annots 48 0 R>>endobj +621 0 obj<>stream +xڕWmoâFþž_1ʗã$0Ø‘ª*½KÚ«®W8U•òeÁKØÃöº»k(ýõÙ]cLr՝öÎÎë3Ï _…0À! Çô•^ý´¸ê?Ž a±Æ“ñäqç/YÀŠe 9+™æ 7¡ È5è"Ï¥2<†˜ïĊkX@Y&²0ïßPíÀ«í$¹ÈÖò¹3y~ïNJƒҝ²,¾sïC˜Òkt­‚¹âîBo_O¥æ©ó·‚ ‰­E>H ö>ãf/Õ´\m¹¹p¸1&¿p$òK'I7Nb¡øÊ@ÎKžÜõ1;ý$bš+Ápœ1‡yøã’ñax ßw%zåŠw¦ÐK'_ЗÁ¥ô¤ËÓÊôl Æ$³8/ho׬£Ì˜œ¯ÄZ "̆8 Žö,3¢;lÇD–X-ÈÀZ(Ø®@|P]Ê§ìù= ÈHÙZ&‰Ü#r±¤Ø«øúô‰¤Sn62†Œ¥è>Û œH5t8 aÃvuUš%í¨#mæŽ|ĒX¥:ôé™ 63ºß¤Ë•– +ÍIsÏT*4ÆR‘¦š]Pwý>æbÇÕYåÞºÐϙÙ4oQdÌޏhìšõQdýCr%2Ãü]ðÂz]Ð{—'3©Í|¥Dn`æ?rm_ˆž;׳ÙÇk,šíj¦±y#ºÙ ³¡ðÓP¢‘֘(R´´YBËÙ“b‘X‹+ï[×Jä셃ÿâyÅj]àft-d&s[8ÔüƳ†ùLf½š€·‚ðþðu6GP¯’}#¿ÁyJ™Ág†iþ•#zñÓ°µßfóß¿À´‡ìç梑;#'ðÜ’B »’M!¼õ\9Œ\•î㘈I^!¨©ï|N‹Lu½ ,Ør%w‚B@DúNqA0§¯4|çFÑzÏö0^|Q,Åj -ÆçÁũÈZ§ƒ­üɗà­¡5£®\´«ñ¨F  -7 9*¢.M±tlí}$,Å, Ó[ UÉ´¥÷NBõ,“È•Å+R™ó‚•^ «¾^žyçÁH¡Š­®ˆ;!Wƒ`€#œ>Búxú§e0€a¢;)›ZÑ=%0§ùÞ¸¡^  ´„‘‹ƒ† öO€xj¢Œ¶ƒî``,>6ã¨l­éÍXá >øø>c|--JZžŠ¬}ñzµJ:=ïù…ñŽý‚ÍŽ-YÖ_7\^ß*¼÷½/Ð˽¹¡“îäuòñ*:Ð{ ïTÒ Á¦`ÚÔ糚HmslÙo‰Â²û֑—á”ÆþÃ8Ý´p«РÀ7Ø¡{Y$1ö©ÜZ0þÏL”]´g›#‡Œ»ýÆM€a½È\àÀÍ_O9Zª€ +MXc€ï>ºý°Ús+ÖÁçӌʬ¸Ö@DÃa0ùP—MDÑÚh~{£oMDåªË„[בŽêö1 ‰}_6î›øŸ1Ý&Ækim›:ÍFªÙ=WnÙ8ìô¦)ÒY«HsT-]n >›ÔY1û$AÍvžý;Z%¤~ÓÃ5áe[b«ó6·”7ÂßHåã t߉ðZˆ¿:OáfZÞk—=ž§0%ÂEöxŽ“ ‹>> +·2T|ã~ÈÜç9Ïbñ|èÂuµTº´^_ gOÊ_Épt‹ÖÇӑ«‰ÛÛærmöTáûãJ 1·¿± WZRÐs÷z·Ñ€®…#z9ÑùÁ›Û⏫ÿŽõendstream +endobj +622 0 obj +1467 +endobj +623 0 obj<>>>/Annots 53 0 R>>endobj +624 0 obj<>stream +xڕWÛnÛ8}ÏW òRˆdK¾%y˦颋táuÜ],ÐJ¢l¶’¨’’ï×ï IY²b§)$v4—3ÃÃ3£Œð'€yãÄùÅo«‹áÇ&°JñÉì?$ƒ»$Åþ•µ‚Bé +JW*™CµáðÞ¯¾¡ó‚À:{᜜WøôþËâ v<ÍÕÝJ%·"áÔø//U‚I¶‡Ëø©äLø”ÅR©€Y{PÚÔڇ%ÃÌ +Ó³‚rcÆ`쇔3ëZ‘‡¬+ØmD¼„oFû²ü¬H`±ø©È8T’ \QlˆY‰uÅYq&âï S+1&f‡Lè +CkCdèÒK¯eÎA‹¼Äø¢ÀrV Yøð`šFS™erG¿,ÑÈÖF-Š”Üi²’ñµ(n)øÃêbäð°èW@¿–¿ã‘ùxD£)&Í!˜Ïü‰û–ÁdÏC­aøq7t:xÚ³ÑÌ¢ÝTUy;f2fÙFêêv6†,É]Y‡ £CæŒ= ã…3 +rßm—esVDŸ†0Ç@TW9I:bdƒ;\ßÚ!çŽKãÐ7TüÌ +¶¦¶¹€º¥à½Ìs<ïQüýYÃFûpԀÈÊC±]h± ¼`Q†T%‚ Îi‰ +9vª &òB™s†Šéï`.’—!0¿G¼SïB©ÀLoÃ%NöxXk5ÔÑKóD(WRí۞NšžÜøÝëMÅ~–‰H÷Ýþž¹Õ˺ 㭽܉jsÊÍ+û²´´Ä@ È ²–"·Ö#8ðÙ '¶œC+† x¥K8¶Öƒ²ec0!3Fähsê£Àxøsõ°<†ç7¡ ~K©Yÿ(R[Së:çE¥ÒD¨+Ådz,·Ç±ì³•y1ÊÓ½¸dÑÐ R›pËyrà'ñÖ}4úì9uàÃ'‹Ìz$ï@!+àÏHtz€ZYÀZG]LücÜ^–'ZA?þ^–‚wá÷Pž 1+QVT%ù6Ÿ3Ä d+NjŸ@´‡§= +}÷.dÓ§D‰­™2O¢ÀÌ\Ò ŸÐåÀª¡IÓԉZÛԙ[6çÕ!÷š\a˜}Xld%¦µ‘CW(8¦ˆWPÛAšQgAّØÓÊÓ}'Jxv¾çO%E*Ì(ÖÞQœ¾pÜ7@G­k*M›ñé݈ÄbjÛ2‘Q_l^Ý«ÕÑ{WflO•š¾œ¿¬#ùiéÂìðÙéâx œNpÈæ^Oñ¯ýæÆ+.MátJe!C²:á—Yv\¥©¬.JÐù4ס¶inŽÓœ°ïXä0·Þ§í»h?»ñçÇe¼ÜšÊMmwe‰«™x†û+¸lÖ¾¶w—§„AŸ’áh„[VªŸÉؒçrËO)™ª?ײƒx)®ëŒö5gqäïó’çeµïjš2^×´­Û)=\5_¹`¼²u¸”î.Ѹ.DÌ °™[áÂËßddÔµV +GÞ:óØ,µfôöJè >•B1)ʎ–ÔÈô¢b +¥ÚŒzQÉ,øÎá{µâðòRv íZ_ñç +Å£Zý£aî&ÃxÜ_ûpù‡Üï4,O²@DZËW‘<œñàöµN*S/‹cN:ŒñaµÁÖº?ñµØ²ÌuDÕEádéX_ºŒ1Y¾‚¯ï_Lù—«œÍýupýÒÚIšnvç·¨ú#вNàé,'ÃÁ' tYS»YÓ×`e™x4Þ6[ÌÛEûÖÕCàÄØe¼v±æô.3›)–UÕ'™V;âwíÂ-ñß +°@òö‚ɽ¼y8úµ7×É|â_Û=0˜:µþëâÔàr endstream +endobj +625 0 obj +1411 +endobj +626 0 obj<>>>/Annots 56 0 R>>endobj +627 0 obj<>stream +xÚ½VMoÛ8½ûWÌm –%Û±ãÜÒmºÀ»hc½äBKT̔*IÅõ¿ï I9¶£ÉvQØ0,‘3óæ½Ç‘¾õ +ÈñSÀxJßRõÞ-{Ãs(&°¬qez‰ªþ{.¹ú>Z¡=·îlù€û&Pqß`4£}·­¿æ—ó´Ü— «”ЇA}(RLW°~ýRØàûq„i¼0XÂ@Eˆ80h"¢«¸µ€9íÄ^£I°[g‡n%ô0Á€Á÷Tiw÷SŽƒ}¸ùwysïu„ Bâ9¥]p!ÜïyÍZé;v~9Õir÷ÈL•Pý†ª·2ÔÁˆ M)íAa€’iXq0ÜZQU¯¶¡»Öájë:FŸq›swýâîìUÙ¡VÄû<6¸ð̱ˆÐ…7Mó +//ŸÃàš­$?.OI6V½´3uàPtˆfÇη–·Üƒå®á¥\n"©a½M1l³È³Ëƒ< õÿ }G-jɰO‹Fˆ¹+Pl‹M )•%o<<˜•ƒÚØÈ +s«ÖÃÆè?0´ô-“r‘±-ÔBr-n•d•-¥ï:g#*üÁ¼Ê`¹ð‹þª[ ¢öêWLÖ­.ƒµ‚[ӂæÓ Åé(•ÆZ”"ElAep0‚VÕQáÐ µ TÀj*³_±D½*¸ë'˜wg§½{XêÌ{Ëȝ{áo,øzÿFÆ_á_ʜ´oRŽãÎ$ÏNJjX3…=¦¶ßäé0ŠR_2uH”þº©¯hD]áü:zötSÎrƒëd_¶“MóÍ=hžƒ0&¡X»÷¹jÜÍÝÂã)Э90ãxxífÙ˳_uè§ ŸÛ¿Ðw^\ŒÐ0 +ÑLE¼’° ÷ £{tB:Ëãè´µ÷ÍÕpH%j᯦ãb¸{¤?%ÉwI^ðևÔ)Ž҆œ‘¤A‡È½y…qÅÑž¹¯.¾0¨ÑcN¨P€RŠò«K\_¦zÅd†ú^ÌGQeøóóÇ,Lí74²® ²pÞ2o{T'/%ĸÁl”SX1¥›“ü"›A~òåÿÔûØòUendstream +endobj +628 0 obj +942 +endobj +629 0 obj<>>>>>endobj +630 0 obj<>stream +xÚµUÁrÚ0½ó{+Á…¤ÇdҙvÚNšÒ–Œ7±$W’¡ü}W’‚JfÚC‡ Øoß>½}Z~Ž +˜Ñ§€õ+(åèf3š~¸†ù 6,fëü¬ÖW°áã%dpoP9aà¶aÖ +ûvóHè%…Ggž-–ó|î+65Z(kÖú.lip+,jæ í™ÊÈÌ`ŠC­à4H¦ØN€«…Ìc—k(־ˌÌóeäpÃ,–‰‚Ì×ùÊCnܧ^zÔJÝ4¢t¨•] è9£ç"˪g'Ï{Œsø¤·¬PÎ fÎQis`†#½ #@…Æ:_OʊE4‡í6lۈg+PpàÉ‹I[x,­höôs+@ +¹õªéšÞ< œ€Õ€ÈôV[‹ž›¤ÀQw$$iÏE…JÀ^˜#4ÌìÄ8ZGê OÇãyjÜÕY/tLjBµË{òù*&¸Î’c»¶ÕÆÙÔ[”mƒ%‰}Í܏ Ú<Ácg4ø$R ÝÞ§c˜@i£c¤–wNKæÐû[fé ]«£íÌÆ<í{”Î É!d›xôÁöS\ׂì‡m#’ށ” fï™èj Hª æt­*Üu†Åˆ†ûÀö¢ú¨IVÖ4¸<î_ ‰åðèãøW‹*Èc +e€F+µÏâv¸>¨I` +¬árž™gGCWé”ñ¡ÚùÛMIwÓ)EI™ô—‘¾BEz2Ë*qž£‹Wý‹ß¾(Ù@P-Cÿ[-iiðì3¹óê:xèâ#`6Ä­i—¨’Ò8eœÖ…²¬M+<:•)H·q¼~kpN›cÿi¼5\‡5¼¢,£ÓΚ©Ý¢šö¢!kû–‹ˆöÖŲ2…F èîëæî!Ýê¾ûjØ·É=~Ar: ßúñ&©ÁÊï'®…Uoˆ_´pè&iJ“Ôó“aªÃJí¬¸è¾¹lìÿðÎü›wW/½[¼‹Ý_ùÿ\®—ùe”ÅÚ?¸ÛŒ¾~¦øZBendstream +endobj +631 0 obj +776 +endobj +632 0 obj<>>>/Annots 61 0 R>>endobj +633 0 obj<>stream +xڝUMs›0½ûWìäDgÂ7;=¥™´“CÚ4¦ÓéQ+‰"‘Äÿ¾»Âø+v3ŒO»Ú÷Þ.'!ø !Né*šÉ—|âM !¯ðM:Ë /\AÇõÂÁ,9piDÇ¡¨™ÖðÔk½Þ|ʟp{°Þî¸oÃÂÏÕ¡äŰœV1±%^B‰ü^w¾~Ò¯[V6B‚û¶ŽhÇ¦Ý àÀõ÷üú~X›C˜Ñ¢Ka㈂Þ2É…|„»NHÃ;¸¢\Cթƞû7€zU±‚ïŸ9ÀÃe^jYX#ň¡¡V3¼flU×ù$ð$•n!Ýî¿a…^ӌÂ4x¼kžjXã;ºG Gr¦ÙlÈ¿4¦½ð}ÊX/•6iú–%ʼ l‚ŒEX2¢MC…lTå²,JÕb²<ÄÞªRT«ãð /ÚN½ˆ’ƒZ ?T셉š=ÔßY þŒÅ3(i5—lË7Œ=«Ÿ]çÆ(`xVD7ôŸvY7xûÒ$ü৛¦ÅŒ’ŸÔö¤"9ëjÁ»sãÎbmF–ïø voTÌ@!êÕÖFÛ%7¯ª{ÞET®#y«“V “)ž>>>/Annots 66 0 R>>endobj +636 0 obj<>stream +xÚ½–KsÚ0Çï|Š=ÒÆ/üÈ-ɤÚI½õ¢Ø"VɎ%'÷ïJ²ÄáÐé0ƒñðÓ>þ»Òêe€ŸÒ¢ +>»Ù̖_s}Øl!Š/†$Í`SÎW°€Û£BÁšª®ù²yF4† Ð貋(½P㛊I(*Ò(ÚBÉdÑII%HúJ[²ƒ7²— j(j±eO]Káö÷ý +ã@¶n¡i™PLˆ¬ +l‹žèÓ伬 Š¢--ÔnoLU&(cCmpÖBý&¼ÞT˜Ød>²kšºU9UU]š•ƒ”âtŸ„¼²ú½>a†Ñ†ÿ„I +¸ÛÌ|ÏdžÐ_þzø†máùØ™—Ç6Á%öeë3´p¢øÜ%/šæù$Çç$8üÍI¾íº7Dèëõ¨Ñ":T{˜(V ­¹í—ŽvTڂýÑà û"Ecck\ {¯°‹9dºRöå|žÀ!Ç¥çi@C-ÊîȯB/æB)ÒMò¡‹´òr‡ÿ¼HAžØ½¾nhÁ¶{Ýÿ$>vö<=Oþm2ÝöX§.±/ÔéèvO?Á]B+Ÿë:LñÁÍ3æ•Œò#òYdëNÕ7EñßwnðpÜ!æej‡ôt®ÐÏîVùtšwäӕîè)Þ!´ò¡V~ä/P>õ­FNÏón§X3ö¼¼¬éÑolx‚#!·õ쏻Û÷ż7ÅüeŠyfä3™×R¢%«;ÙO¨O”ÏG·Š@KyÓ4<î¡"¢„Nïl=&mþ!€¡ov )9ÇÎÍ Fý, ïµ\„±Íº_‹,YfÞÏ磅sXÜÁâXÓ\-—Ǽ-À1¾†üòÛw?7wïoX:ÔdÐø8ûc3‡œáÔh‹+Ìo{Ãn€eÕ¯ý)ÙWÃ3ܜÎÛ¯°êÖGûîôýHY¶T7œ‡´¡x!S§~§‹izÜí•!±}ÝáýJVº«:Iû;dvh–(ýèR§1î}_ÿäýñóköa)Ýèendstream +endobj +637 0 obj +895 +endobj +638 0 obj<>>>/Annots 70 0 R>>endobj +639 0 obj<>stream +xÚåVMsÛ6½ûWìøäÎX4I}÷–x’6‡tœJù JHI€%H«ê¡¿=o’"eٓzêØC Ô.v÷íÛ·þó&¢?Mü›7ï·7×Íh›á›Å +Ò»M)•”Þ“  þä’6²z–e¦¢§JéoÚ~ƒ÷Œ¢È{Oâ%{?~}ÚP"4í$%FgjßT2¥ÚPÕh:ªú`šç&9ÙҘ ’•xˆ<§ofgÙAõÑ­‹Яæ(ñážTFõAԜGÓ æÐތöFZJÍQÃFjwcÙæŒø8!³TY±ËeÐW+a§lŸ¬¨•Ñdt~"aIì¬É›Z⤥LáэCk{Àm2M^·y.Ó¦*øD·®Îƒ±õm@[C•J9æ ¿¤’¢–(;S(Z‹B¦dq¹«õAÖÉCҔö!ɕÔuÀé[rçPiÊh+- ×§ágoҚ­À„I<óµø.ÿ†ÀämboÓ";¾~â<ì‡^q9œ6ŠŠvÅ~`ûå*˜¿m?°€¾€RË7퇰_Î!=ãê_´³¬Åäñ JVÒÅ=ÝvM›“­eAŸ…{Y€Í·×û}תǪ۽³0ˆh†+¾ÛîÆdõ‘9ÿ.-”†Lƒë:€Ûáˆ4‰fKd3YÆ!»Å!¿œ†n ÿå¿âèڗ›ï¯’Ýendstream +endobj +640 0 obj +1116 +endobj +641 0 obj<>>>/Annots 73 0 R>>endobj +642 0 obj<>stream +xڕTÁŽÓ0½÷+F{êJԍÓ4Ùrc+àZhW\öâ:NcäØÁvú÷Œã¤ÛF µ²defÞ{3oücF!Á…"…U¼™ÝïgËHØW@‹äÅìËy x°R{©°;9/øÄ4;ŠFh»ÿŽiPÒ!o±ÊR’†Ô}-ðšµ^Xpµùé8™8ÓÀ®ä±³|-`ûø°'ì³°$VÝ P5Á’)ÉbE÷ÌI1$-HBv+0^üòPI%0„èœ(Á› ÐHàR`ªžA?G0/¾¨  g‹H¢#>{Á§«(z)<_ò®0œC)­àÞØÓÛø%¾`ûiõqŜŽ×ù!j„èûˆ®žIíTel)ã_0^C¦…¢>‡¥N}ÿ¦eÛ)„bÆjÃØ 9¡1‘I2*Q-+©§ú¸i°j ÆöÝü&ÐãWŒ r-yq­Y¢‘Î’ßïg IМá áøúÕçd 4ß ©²$#t¸)ØEëŽDÐдH¦j­y–%N2P+EÅ:åǁkÖÀöAd‚½áµÔ8؉(þUN—,]_qz%þ"ã³Eƒ†IŠ=޲G9Ûa•ÖoàfÛsý#¹"%xYçx6@‘éj¸ X¡Kë"î‹ïڛ~êç*ɀ?ïÛÒtÿ…Áþ:L4~ù_öµFÅgaòÀÓüzÇæËÎÙ¥;HݯW9ñßÓ-˜7߇uE"†/J6÷pš˜»ÆÀAÍݨ;³ KÿíñˊŒÜáþcpJ‡q|™ýñ‹endstream +endobj +643 0 obj +612 +endobj +644 0 obj<>>>>>endobj +645 0 obj<>stream +xÚ­TMoÛ0 ½çWÛÅ'NÒ¤Ùm+2l‡u]ëbЋbӉ6Yò$9YúëGZùôÚ}Eƒ"‘(¾Gòñýè$Ч¿†cþdeçmÚé½C’@ZðÑøbi•²Ä83zåÎÒo1:Dt“a<à˜t)R!P R; ¤ó` +p^è\Ø|°Bë¤ÑüÛÓW kðK”–.w1|55hcK¡Ôrøý˜60—žÞlQãÀlǽËÔãx´§ï7>ý‚iùÀyiÖà XÌÌBËä"Êçe_Y©¹G<€â¿ +:PåFÓE¶„m¶®vô6ĵZVµœ vR/¸ Ú߂¢*‘—RŸ’Šˆ@YrsŒå×ðçðA ‘í*B2i*  ;:Çœî©ÑÖoQáòîúnђVNˆÁ`ž|Ò6,Å +©ŒilÙRèò\7£‹Ú†.4uq¸FÌÃàÈžkð`¾¡o:g*4'ñdÞß]·«wr¡…ââ÷ WW•’)µôR(ùø¸ÌÊÊǐîàsRœ•óšoy€ÄN©¢ ¥£ÃDÄï|8œ·)å’êÝÀZúe“N‹á4M”ÕUkC¢@M™,ð] +ÑÁ\8ª¥®LCL…Ü_ªÕmœÇòuH’Àt'ÒÁ(h¹‡>ëÙ,Î{h!÷C˜]¥³›Ý®ôã‹ý‹vs©ÿ}$=&6lºvɂÙÍ*(.…ó¤þ¸;­.6Œ¼ù—?²¶QkOO5zjQ˜\µÍ+"²Â7I¬QÁˆX&}Që¬ÑP 3Zû–ísí:›M“Ùð4²ö¥w¨ +r:¥Ìš.Í_ÕSkÊ5; ¥ ŒŸ× b¯w]—sbÁ«Ð‚¾^¼|qÆ;jEF¦"lßišá&1ÜJÞYg:rT‚ãw•¼ øÓ¿jÖ<šXa‹ÝP‡ÄÊXɆGэ³]òï¸uÇ¿IK¡ñÛÆ'£ ¥õ§As[›2…_s;Þ°!ò Êçà£ÐµPœ ޑáõùÙ`À‡ÃÑ4>‡þßÍo–v>w~x¹hýendstream +endobj +646 0 obj +811 +endobj +647 0 obj<>>>/Annots 124 0 R>>endobj +648 0 obj<>stream +xÚµšmoÛ6ÇßçS +t/¬Hõ´wi҇lé–Åî»#ӎ6ItE)©ûéw$Š“5-3H`ä,ï/’Gýxä磈„𑌒8%esôfutò® QFV¸’æY­_/Ew':r^u¢ì«;¡~Zý ÷1Eö¾͂Tß¹ºÄ^äxñu9ìÔ:(e»yìõšlªZ¸ÐóªU¤á힬Ǥ¿å=Y‹^tMÕ +r+ïá+A”Õ"w¢ã½P?Û-ñGiPP“L«ù“¦™‘óvu!<«þˆôÇõ{x➐êφ ¸X£&KÝOº-9ybh¬”f:ÄiY +¥.åV‡yp G§l‘9YD1èóTQðhHZŒ†§2’mu-ï'וô5¶˜5 Ày²"ŽMVD!-Oy1³ia坋v?½:b^ä:iå©F{PwÑÂ||Çë醙I ì^cy* sÅ*ü½[‹nry¬`69L÷ZËO+’qW²ž¾éXbfÐÑòԖG‡™q%»~zui†‰¡;ÖZžêÒü01®EÍ§Ï –0›,ÒòŒå)/I3cy ­§ßÓO} ´Ñqf¶–§FFscU5B3ô1L+¡{«YÃS-FuU;=C±ˆ™ÔÈu3XÃSX”ØÌ8ç=îý‘²È1"4Š|¤E€tÅHž4¥A쏞ÎÙÐç¹Øð¡îÏny§Ä¤ýŠaA)¤bá¡Î9U^òv;ð­˜^¦CÒ¨H¡)½™e:,ú͋ÚI)+`„x#©sF*=—åЈ¶¿–r†nvTJ) 2,uÎH¦o»Nv¯„0¢)…7\ᏦÎÙЩaú¤!–Ú ñÆRçŒdúA*óòX.Ï ñeúâ©sFB½hvuUV½Y¼‰9d"§Ò, NuΈª¿ +±;­«»9Þw +i•ÒBO8¾´êœXGÓ t¼JÃқW³AÖËJõ¢Aòªm¼yÕ9#²^ʒ÷•œC+êó%VçŒÐ +᥸õ úYiœŒ–¿>G­ù—³º‚WÊ iì€ú«sFf…ЈËêëùÄjáËYsú®ÅçA¨ÞG£%ĨÈ=Ð5Ôàäø0ŽÓÑòWt6|8ýbØþ:baœ„/ªM¢3bá°àԅSÁá`‡àä_¢´òN¾¶ÚLÌìJtF¼ê„©ƒÿ"oÞUõÄKN +‘Á$˜¾ R‰Îˆ„:?ÀÛDvû”"ÆIª•z×-Ñ9²:«¶/ùnuȇq¦{Ú¿l‰Îȇ8ÏLMÿÙлt‰ÎȆ×Wg¼¼3èC(Ä&ô.^¢3B¡ÝÃ:]7U;ƒDäÁ8ÕNþÕKtF´ßÌ!Ðñ` /°üõKtNäM¾-bC ¢>ï&:#Z…ód‰£B; +ýë˜èŒT¸ÜS7“¯E1 +‚¡}-û×2ÑÁp%šGÅëÈC*DyÞeLtF*œ£†i# Zjð¯b¢³AÂOêyÜ*HČ2ë±`wCw­>d‰)ågð©‹ú ›qo÷Ücæê._8¬Ëݦ|H +¬a.(Ã-MœÜñÛ½)ÂÍ÷ÕÈ`Ð\!nÿÐañJ=ë£ö +òAîÂèÁ2›*»jçÖnàÆýÃ1×̏›éðÁxd€(Ñ+sF …9ŠÈùßj& Èœ7ȅý^æ¾J‘Vö„ß(Y½Ð[Rõðýók1¬n"¬:²ÑrLì^®ÔЈ5é%¹Б57ZÁìñ!¿7º<¦´§-ÕŸ\?¨F0ÐRµä¸”M#[{Uv ï]‡bÎðvMJÞjՃ§›=Ñ'4îōûåN쀑«v O#kýH[њc„ãE!Î>]-ݱ ®{ªê÷;ìp¼Åt +®Ú²ÖVñ£N1ƒÞ1x:J^©§Ã=µ×7ƒîDYñÚF=¶C÷øÑsÃc)mq0˜ªÖ6 aבÊLì¦9«þåk=9ÙÕ˜‘÷èk[ÿVW=9Eó½Ì=xÜÀÚ¹[t2M"IVص]±”›þžÃ”b`°zLvŠ|äí`wvÖo‘ÑðÙã?,Ó»)æ:1Sþ8úΗWendstream +endobj +649 0 obj +1721 +endobj +650 0 obj<>>>/Annots 127 0 R>>endobj +651 0 obj<>stream +xÚµWKoÛ8¾ûW zJ‹ˆ±¨÷ö”¦Ø.º{˅•h[[‘tE)iþ}‡ÔÒ+Ûòb‰Qœç7œá— –øã‚šßT,Þ¬7ïp}X­q'Œñ%»º- +õôrõÏâÝj±$ø9¢$?ŽðâSrX÷ªn«ê»$6Êï~2±+¸6ú7˜}ôæPŸì­ÃºTðՈ-Áq—ö`ó/%ùñÝW$S‚å’¤J—š%´Uºš%(¥$¯NoϹ@ ŸÙ‚7B\"+ÈàiêÕÔ± ‰·\§e¾«r%¿/:J45]m9to6÷‡h¯pY^ò´Ê9èOóuÎ50[É¿†ŸeYɵ¾U‚äՓ*¿Cµeä(jlò Xš¢T +wÐ/yIÆþ ¡£ã< ZÅóœÖBÔ3®A+ÀE•ã1¾,+ )“ðC­1J Ï܅»ÆŒ:»]™Ú z±&0éMW¥½k©*f*3ÂóîãÛ/ƒ`úûFÐj¸®ie‡ÆM݃!ÅÕÒ¬[%ó1öHÔ|zjN@A}³Æx“1Ž3`x¦ç‚a…ç‚1Ïr Ɣe †É£A3-±C6òš<»¥Û5ŒgñB"àÿ>g °žçBaEæB1Ïr Ŕe„™Oœ»êFÙ¹]Äq‚žiâã ՚Uq8‹°’ÎÏவ®€ívœ•Kg‡¼½AÆÎÊ ¢úS¥¬»´²µ‚÷éI€%„ŽÇ¡IKÜêj{W0­Ԑ¾Åö5¤Ôk œ§†¸•J> UëC>ÓK|Åkÿèæý³®¸8ºý¡Tõî?'„F¿Å0„mƒƒtúБުºÈ ]Ùñɉ@Îòp…12$)äáåØù€­LyîÊ1vz ¬È3ÇJÃð€É vˆ’œl˜)¹ÈÙ¾¼ÿÒݵÝ1ä±µMöJn:bùB?ëÇû:1}áG&¶u›»Ç,Ú®öìUdSؘãöMæ=AL·Ln¸‰47þÚÓt²Ÿ›¤û£{YKwÀ:öÂIl½ñ?B»Ù{‰D,Œ›Ùw÷õó=Ü«uõdÈùm&r™ëªd•*5|b²föGǵˆ;]Ä=ƒæ¿¿Ø4ØÈendstream +endobj +652 0 obj +1059 +endobj +653 0 obj<>>>/Annots 132 0 R>>endobj +654 0 obj<>stream +xÚÍVËnÛ0¼û+öè5-ÒzöÖ@ ­¬¼,Gд +;¯šýz7}»u8‚ˆRK·G¤kñ5¬Æåæ3€ù¸(·$À t«¹Q/ ƒÿEmŽÐ@n˧zWiþÂ'ì¥ùÞÂýþ$­¸­J1¢1;çJ¦Ç‚—r-”þúë—^&V²N}Ú©V{‚2r¬Eƒj,Þº:iW‡Å8Â-ü £}ü~»Ø3Ò>„ÚTmŽ&+z$t܇)rãm®ÉÃÙ×ÌoÐG@·s¢Úǧ·J–k;ûÛ÷ß FO~¬š x™u/èJ¢È«Híîï.+÷üu´\ÞW™ ÎÓ¶VsK5#EìÆînÚWDí*Ÿ2ÅCGïkØÎHs‰KiU–Fx¶åz3vªæhù¦:,+Kãੀ”—G‹âk‹/5¥öœ¤ņݪ3.dîh么Qì ãФ¦©h´\ÙD5nOÓýwhGûÖë%h½4¹9éZ¯[žô ŽÆ¡SÞ?ôÞ¸'äãdƒÅÂù\ܺƒ»j¥9Z컬¥Tºáºj|äeËs+KêGF—óFÿ˜ƒ'cA7·Ï“?òÓ¦Kendstream +endobj +655 0 obj +758 +endobj +656 0 obj<>>>/Annots 134 0 R>>endobj +657 0 obj<>stream +xÚµVK“›8¾ûWôq’²^Æ8·<&›Tm²³;NÕr‘AÄʀD$Oþ}º% Øcï$‡-l +P?>}ÝýÁ·Y!$ýŠföj3»ÙÌ ÇçÃI4V¬ò „$_ä)^j¹„AH¦‡Ú_¿]C”¦ÂðYŽåÕ+­ö†¿,K͍y¶ùêáò*Æxi¾Âëxԅˆúiä俁5m͝ÿõÛÖ´ŽÐq<ÎñrLþ/²$"ÏQèÛGkDÄ¿d»SÆ¥j˜A¡šƒý{ápeäù†›B‹Ö +%½M:l -<ò͎Ãa[~ñ1e£ã”BóŠïLË Q n€I`=<«ÀpY–bù„¬”naÀÅ>tµÈåqNÚnÄg v6»³nGåS©Ñ·ª¸æÒ‚äv¯ô½¥\÷ÉÍcyc‚þñ”¤’W ±;攷 eŸâßïD±ƒ½¨k‚Éʂ £Ÿ`eh0 ÄõS˜\çš JJdÄm?ðٖ}¶eŠÃ³Hb¿…mn^\ì‚÷üP0œ‚Îq÷îvñé_ÀŒC,o L·ED†YJ,•…8C”Í‘FÈa+¬™C«…´ü”Ö¡$Ÿ¯(˜P±Âº]Ž4`e¹ëÕÏÏ8pãÁ»õQ½Bámà ‰xuR׃ṫ7±»!¦Žút>­ú˜ÓÇ'šÆ—KŸPèPv;i{½Í{¢”ª”Å‘ß7¼þt{wª²{’Õ—e#¤0V3«P¼>0Ù17Ö ï·X¡ÒøŒ¦}!]ø|ù{ö2;«›endstream +endobj +658 0 obj +872 +endobj +659 0 obj<>>>/Annots 136 0 R>>endobj +660 0 obj<>stream +xÚµUKs›0¾ûWì±íØ2`voM“´é#mÜ[/ +ˆX HDuüﻒâŒsé00,ûþö[ñ8 !À+„4‚EY59_OæW+cX¨I–ø’¿9Wr«Ù»·ëûÉåzÔ¥I ^¦øá­½ØúÇ!YÚ—O´ªK¦­ÿü*€•ÕcÊY“Q +(”¬€–¥µ `>ÄØBHÁN˜„+,ŒD¯³"Á<Š_ozvFº;8áõŽä²¢\LV€¡™ƒ ±NLgŠ×†KámâE´ð ­7 :½r4š½×ȹb™áèše¼àL½Ó†U f¶R=€‘8º{4…[ jš=0£]ílΜ´) pÖ]³ ٚrÛæOœl¤6šì9ƒd³Ð>~}‚(YbŒ8 °» +ِöR 7–JŠ¡oý3†*rðP‚ ƒŠšlÃÅ6ðØ`»`6ÔÀN6À½-­ìåVwp¡ ýÃ}•ò¡©õÐ>èí KZ,ºù|¹šçŠi½/M7u-‚ž(bì¾3=E¬”á´ìp8®x§ïf£¡Ñ6ŠÕ(Êb„¾£Ÿ½¦Ð³Ñ +©E§‡#ßçôñ-LIò.›u¸å2ÙCzÞÆ'W‡‹ûCåL‹}âpX$o╇ƒËa¹æ-áŸm7²ê©³ü?ûÖ·{já,²Ò•$ _úÜ-L­d†@ð‡æm¹f­Ûag}ú÷^ÎZ9²«Õ7ò'JÒq'C ™ÁùpŸ)Žf« Ò£¥%xÛc†avod–pPõ±ü/vr<¿?£^ÈïÂô,ÛHa¸‚³ %|ü}}7²0[îC^qÁµQÔH¥á uœYÛsh–FÁó__œÆH6§ˆÒ–î?'ÿ=D`endstream +endobj +661 0 obj +694 +endobj +662 0 obj<>>>/Annots 139 0 R>>endobj +663 0 obj<>stream +xÚµVËvÛ6Ýë+f™.Ȁ‹TvMãôd‘ƍ•E— Úh ‚%@+úû^¤DˏFç´²ÌCƒ;3wî ô÷*!†¿„²µûVjõ~»ºÞ®X\âýñ2ÜQ^Æex¢¬ÜÄk*Üí ¨q;X̜å|ùۏJrÚ6@_—¸©ß¼ôވOÃoÚþa½H˜—îSüϨ#™0òþ€rý«¾Æíû‘ÑÆ­#ô(ÍãgÜs†Œ¢„…ýgË @³§ÈC­åaªAöVê.ØäÇh`œmï͑„ÅgÒ<í|CµDeåƒ Ó‹J6R²Qü»T£"®ôØYÒ Y©í„Ý ÑÑ΁ÊîŽÆ¾æV˜xÎ*‹SÇ­;8 Np; +ÁȈJwµ[Ãw`ôhï´3óˆbÆ£Ýh‰·-ÞÀ t1Õ(E%\°ý ]Bg^e×èAqÇ5ƒV¤‘Ê@÷ÚØc„1u½”Râ._¥´(àîŠ1)”:ƒDÂSK·A'3¿I’Æ“àsbÂÜë±­‘Þž© áX睧ÞúØ«ðYœ[Ôì=¶>ÉýTbï4¦/Ž‹½4Gò¼d£â‘BÞÕTµÜÔ`/ÛÖWªï£U+ô`Æ +eŽzXÊ`ÙjQºYvÁn—–çV_o´ón ڏ®hږ–îežä˜DìÅG¿¯þ»Dµ±endstream +endobj +664 0 obj +879 +endobj +665 0 obj<>>>>>endobj +666 0 obj<>stream +xÚµT]oÚ0}çW\ñD§â&!%°§µ[+UZÑ6˜¦J¼˜ä¦q—ØÌ60þý®ðÑ´êÚIB2ø~œ{î9þÕ ! OIƒ!¤UçrÖ9»CÃ,§›áˆYïR«ÁoXòíÉì¡s5ëŒ.“ˆ !%tŽè«ò}°)‡läJ\ýæÕ²DãòÏ®»{êُbÖîáxÀ±N‘?Eçç.3€~ÔŸ‹Î(Ží¾ÁÛ³ãW¦¼c™ª¸,UÕ+S +eì YÒúž•¡Ëÿ„&Õbi…’uL¼'–"jÞfŽÔú²½®CZ2¡1µb`–˜Š\ £V:Eà2ƒ ’»†À³L£1+MË¥jBÞÃÂw!éÿŠïÀ¹±,rrMó)‰~f d‰v£ôO°Šº([ fp»*­ Eü x)—°8 ‘7Ô3ÌØãzGL½PY°Û¥HyYnae¨`¶ÆbE7·4¶Èîªj³ZÐT†‚nXš³RäfØ'BZÔ9OÑ0¸±?/rCø~D§–Ú‡Ó žÐ¥*K +4¨×¨ l„-B)$¾­"²*}B8¶É^€ñSÎ +b󼦽tèÔZJ€§4Šq°ÀÆQÆáÇÅÄ녘„´(­¿p@?_Læ=3?a{½Ç» ÁN ¥í„WõcÑ<6ƒ$!O½üØ âä OÍ¡ ÜÕÁOœ{2QÿÇ¥‡ý›U7:÷xO) Æ%ƒô¹n”T»µR«¡¼¶I—ʱ(‘Á´UåaE®u {\ÅGœzÝ©UPkæ½nÓ¥íÂM^|#3Z[UI`Zš” ï5m¨UÓÏý<Ì!HV'NJE¶«1Ú¨…ÝÓVÏV@Ôeó“&äxCæœ k^®Ði”ß­CÚZáݓ­5Ú5¿Ã8!çÔÃ+>~ÿ2…©ÊíÆ}‘UB +c5·Š†»årÅKW _çõ“(xæáŠ“˜Dêo¢qc‘¯?™U¿endstream +endobj +667 0 obj +765 +endobj +668 0 obj<>>>/Annots 141 0 R>>endobj +669 0 obj<>stream +xÚµUMSÛ0½çWì1Ì`c;Nlz+mh9´Ðfzà¢Ø2¨È’kɄüûîJv>a::0'Z½}ûôžògC„1Lfô_Ô£‹Åh¾EaŽßoí¤y˜A’œ‡X˜Ó3OC\àPі(Œ¨tx`ýÙå9Ä),*„ŸåøRŽ/Z½2|!j®;{²øíár– ^šgøžì€:ˆ¸‡Hã0'ù «É í?»ŒàœÖ‘z¤áq˜DUFđØ_ŸEhè8¨~æ¦hEc…V¾&ݰÁ +ßlñÈa`⏧ÜnC)Z^XñÌÁpkÀâvÛ3©t M+”å-àk!™1 ~]3â€Å̂0(OÁ¡ÄEXºfē0!R +ž=„kUp`ǨÔÒ5=b­ °juí8Ia,è +Ø3’-%‡’+”#b¾ß{D˜ïz$¦ÇÏ/ ‡2˜"ïÔ0ɲ0î?I¸õ¤‹£©+MCw6ðÌd‡">êN–À䊭 ,9<´œÑ¨¨•r“8ªû9˜^‘@ˆ¹_¾õòö]c”ÁەðÚžÝö¼à˜*½ä(÷JH‰çoXÓpÖz­ )¸²`ÖÆòš°+ÎtM‰Sxws`ü¶êa'Dé,úgˆRÜÿŽa´Ðkñq+Uõ_¢Óõzj +­l«%ªùÈéÈÓJ[P¨œnŸ6V_,ÑÝ\‘ƒË¨cÉ+ÖIKñ³~}ŸÃNŒ®¸ûó˜öŸ§dÞ`’øq¾_/æÞöª‚µî€á©tŽ×כàîº:L"ç¦[â›”ÓTIz +ñ씆Ìa)¬9ÞoþdôÙ·l§6ÈP Jö§»›[¸Õ•]‘ZËZ(¼Zf5rúÆTçSø]A¿mâîñ4¦DoýØüý´£÷‰endstream +endobj +670 0 obj +747 +endobj +671 0 obj<>>>>>endobj +672 0 obj<>stream +xÚµU]o›0}çW\õ©{€Ä„xÜÚôi“6…ýLr'bg¶iÚýú]ó’vA“ZE‘ï9ç~ÌoÁœ~ â+È÷ޗ̛=¤À"ÈJЬz(nï¹å÷¨?e¿¼uæÍ +Äa°‚(‰é9¤¿Pd֑#$޾~æûC%ŒãÏ携8åóÃ(ëì6zfv\‹Y^:|/è7ŒUƒ&×x°¨d‹‰†¤„h5³€>a·q¢ÜBZäŸa X"¶GJ¿€UPjNi(ˆ%R#ÁPYÔgM»NDÉëÊÞQ$6ؒz '¥‹Vez`gi ¶¥Ÿ80UÂæíÐ/ h”Ÿ$ËÔg×qG”…:Ÿ…Köîó5œ©5´ȉÁs+´ W’W($ŕ”Ž«¤ ;ûV4z*é\Íe}ÃÇe=Ö T= ­±(„„Ç—¦¸s5W;­¸ÜÖ|KMDŽ%ŠbÀ·µ¶¸óÌ£»}ídþ9¤I Ž:.˜v~݃aÿû,4ñ·}5„œ˜ @©'h?ȱ“Û¶}îÛÁ –ÝkQn{cŒìðJ‰WFM½ X?1*•ó +ÿp—«¹¾@<£!W Úk/Ì A/À7 e-·š]gÀ¤‹bâ,W áîç÷ lTit›Ãçb’’jN—ªo\Ö¼r~Ëóãp~ñ¡‰âˆ¶Üœ.XgâÞ_ö—endstream +endobj +673 0 obj +546 +endobj +674 0 obj<>>>/Annots 144 0 R>>endobj +675 0 obj<>stream +xÚ­W]w£6}÷¯˜ÇìžXña³oÛýhsNۓ&îÛ¾È bXIÓ_ߑ„0v‰Möô8øXèj4sg4ºù¾ða…‚Xÿ¥Õâ§íÂûš€Â6Ǚxƒ?²«Ï\¼¼Ûþµø²]¬¾]SC¸YãoŠOÃ!VúýÊÐ'½öË߬ªK®ôzïë +=›-iHã7²‚e©Q+Xú+»ø0÷»üÕÉ÷$“+Ieõ*hf/U;'„ ïÏÎÎCÌGá3çUÕ =6I.‹K“¦ØZPiSÔm!…Å„C¦a¹ÝspY¶“CáðW OÛ≃ªyZäWÀ ó‚UünneYÕºـàí³l¡Ý³ +„–¥|æ°4E´gÐožxCŽ·× „Ž+xÒ4Š%œvUՕL¿¸%m•û¦˜¤LÀŽC§ÐGtθëœÍ1žÁ¬ŽX¹DõnâU&øô\Š[ Ù2–#6?Ý|¾Ó–*¦?ØQ¿Â÷õá]ҍMš5S­ô¸_¤_n²¶/πlKÀ.2|Ýý É‘Aco7hÄO0<¤ø~ë‡1ñ{°YwLÀDs-ӄâä¤eӬ‘‚M [™8W.n´¤?†ŒÈ¿ÑÃ(BSfHñç€:ÃÆ:Ƴ8— žËÆ<Ë=S–‘ ÃAØváGèc­xØ ¯cŠBѓqŠhm®yTð\*æY²ì¨Cbú=¡WNPAC=F“c* ÈôAœK†Ï%cžåžŒ)ˆ MR@#Û-1-vØ8ÝÐw&0|áÕþ—|.PavžK…Ì¥bžåžŠ)ËHj$ºpÏç;‡±‘ú¸8Ä>T ",;*O[†¸mFeÕ©X]sÖ@!T‘qìñæê8Þ¬y€‘S¿Ê”¹ û$Xœ¸¾È Œ\–4镚Ä;’‹öNÊv$ivÏÉAJkã²m^§Oíñzö2™ziW«SisÏ¥ôv¬9ÿ¯z愁KºFK“²OÈžùR)Z4aĀžÿe»½íõ &>ýy{Oà&&^­(šèŒøÔdzY!{Ñ0*]­ú”ÚÆvJ–]Ë¡fí^ ( ƒ‡™ö@@a••RœQ-(`nµSXËíÞ„à˜™Sp²y±*'ã9CYt"†vβÍ!4]£=HoÍeӥΊ½¼hðH•R>bÀ]­‰g ºÝò°©ËOÝÃqÉÄCÇ43ß;®Z\¸{1ˆ´,tB¿]qò@Ž…3Თ7^ßCGž{‡¹ï3cÝ)_ o†D¼©$u0?à۔cFÛj©¥RÅ®4õ¡K¼,þáÆ¿q#Au#ŸŠ¬š^ç>š_ÎÒýIÖšçÏz6N«…k„ŨbLq›Ó÷2oŸuV?fU! +Õ6 ÷Pð3ÿR.íºåšŽ¯©Ø'ýE6êß,þzúê`endstream +endobj +676 0 obj +1135 +endobj +677 0 obj<>>>/Annots 146 0 R>>endobj +678 0 obj<>stream +xÚ­V[OÛ0~ï¯8BBbҚ&iz{Ü0$Æ6Z¤½Mnâ´Žl§¬ÿ~Çvš´¡ ¢òå\¾óï¸}ìEâ_“†cH‹ÞçEop9ƒ(EŽ7ã).²³ ¥¤º‘«‹?½‹E/ ðfcH¦\Çø¯(äwT{'Q0uþIQrª­ÿà2„™½Ç„ý8 À`CԀËÕ ­J= öø7÷‰CèGaïóþ©~ÉCou¯EÚwPÆÖî Õ©b¥aRx›¤©-<ØÅšÂ®y@PësS45lCAS£Á § ™»µ ˆrÆi×þØnœÓ ¤²Ô’W†ÚKÌØs¢uUЬí6Ò~Döãî +°1ų †¢Ñ°Ùq˜Û>…0†¸ÅzŒ„%ÅrââÖÔvÂ*$¼­yNՆª;)Í¡iؘvyj€e/£9©¸éÔoËò’ãä°>¨›½ß íÐy¶S"l…L¤¼Êh†‹Cš—[¨4«nWOu·Ÿµ§õ:š´¤)#Üg=ñR;Ù¥¯4¦Fr5Ù^÷™È¥*ˆU܎zt4´p¼0K’YÁ(9AN*€“8gƕ’U¹7§Épüêœ&áèsê¢[|ñjÎ÷Ñ+UËä=‡®)õ…‰³ÍÈõcw{ý V‹YcY4¨‚½8¿º†Rɕ"…U œ­C™z7¦óÛ‡~‚jBöp|ì‚m¹9°Bt [¦öŠ¢%ŠÆ*Tzʒ*”ŒX՜¿¬‡¯R›[”㍔8C{ʈñQH^QFÛWþ-Êèäï¢£ƒgyþނ8Rëqi¤R%¹†§5E:•mƒ}hÏïÌqì䃧 +k 馇Ժ A4ßGuÿSΨ0Õ4¯Yƒ¯)¹Å„O6’ù¡”ÃØ¤~½°Ëîq)µ +]rŠ +}bfÝââ¾VL])сeֈA:ŸA]$Rð-°¼ù²Á¢r–ÕêšÖ¶Q2Áøã(òð¬ÍenžjèSV0Á´A}J¥áá6@ßûõ'qØýM‘L‰;k‰þìýP~?endstream +endobj +679 0 obj +808 +endobj +680 0 obj<>>>/Annots 148 0 R>>endobj +681 0 obj<>stream +xÚµ•Ûr›0†ïý{™ÎԄƒ vï’4i;NҚ>€"V+$"‰¸}û®BœCgÚ±ÍØÖî¿ÿj?Äí"‚_$©{õâ4__l "W¸’®ñKyô©n/¸=ÔfÞä?çù" 0 ‹ƒÈ:Ãï1~4ƒj‰zk'sþ‹¢Ï?¾aãÖ±î2&Á¡:p)]hË(ô +ªÊ‹ Ֆ\êbß3ShÞX®¤!£#ŒðóƒÁ_<Ôë}ê”\³Âò;…’V+a`¿cvÇ4ð>ŠÞÅÝ(4£–•pM ^ÛFIÀ` w” z-ØÐ`Äΐdv¯ôOh4—–iԐå €³[²Š¶Â‚aÖryÜÌ;¸”sÓ×­uq´µª¦–Tˆß`[-ÑÒ<Ùï¨/Âá.‘»|ûÉ& V°"nð5’IÿKÀÖO}¨™¬£n1rM¯º23E}“§Zí 6ô00ï»áÝP–¾Ä¸s϶3IF`ÈÃÆÃð™±æDàh'|{²Ÿç›¬RoáE¾Ç +Éž,ý{¦töJš•©,X¦m¥-4È#7–I óüÊ¥H—­ä Mn֟ðýˆÍ ß‡Á½S>Ž‚¡çXií/oÑ= z‘p©[ƒwLà +^y¡Ùm§ÙmË0;¯¡uvwém\ÜGj­æx—1àòPæÙèñÝ<µâL” *`´ØAo䐿¼fªµVãlõ"«1!Ëj_Òð)d‡ˆ$üoàNº}ßÚƒP8@ú °°çBàÕç¥&VxÜΨpƒÄ£×ŽS™QŽ[‚Ç0ª–¦غw‘ %VYtÝÃÙ÷«-lUe÷î™pRÖ\¢1M­Â#þ •-ݙæó–Yº´„¸? ÚÉ |ú9üuñÇà7¦endstream +endobj +682 0 obj +688 +endobj +683 0 obj<>>>/Annots 151 0 R>>endobj +684 0 obj<>stream +xÚ­TÉnÛ0¼û+rJ¦E-^Š @—¤=4€[»ÀPTÂV"U’Jš¿ï£HÙ²ë4(6$ò-ó†3ü9¡àCa‘B6ÞLÞm'³«Ð¶î̗øRž–Ö õjû}r¹$×)™C¾\à{Š?# ÚåҘ›S²ôٗ¿XÓÖÂúüÙU+¿í¦iNF偦XúzžQœÀ”&¡Æ²Ân$݇ìNûŠsüAXndë¤V!&߁ˆÐs{'`6GSî3Ρ”Fp'ïØVpYIaîA›ÀÊÒ‹+ª„VNC°VÚ×Jùl­,ë®v‰8lë‡ÌHzHóI8Sp# 5ú^–¢5Ó +šX~À$,9dh4ý3t€âñÔÿ}ýt‘“¬WE + ¤IBñ«†MÇЧX‘÷–aðÉ҂•¬™ñÓ¹ˆá¨—¹…ª5ò~”ì‚NãMç€Õµ~°ð¨;ßérFr\æÜŸ&.ÅÃæ •¦b<èwÚߝqTˆì| rå­9˜Žþɳ üÝ?y’…ügýs1t€Ù›#ßBŽV.fCô›R2?*ÃÊFªªÕšžB;S¬ÿ\óE >:ˆg-”€vF×½¿Y‡rTNÆÁtßßö>÷:rKø´Ý®½¦tg¸xÒ-é¢ +t‰?Ä2ºDæÂWt J#)Â0Ø¢eîïR‘ +{6E¼*Ý!š!ѸxÐGü޵ñûIã¶¢Èв{'âG¿Êw#  ÿpê0gålíõ Õ-lñ6i`#xg¤{<;íáóh¬å šzÈ̓Òàý·õ6ºr ¹y땋הaN ×Lu¬îKsMirx׿xk-¡_̊HԗÉoícëûendstream +endobj +685 0 obj +681 +endobj +686 0 obj<>>>/Annots 153 0 R>>endobj +687 0 obj<>stream +xÚ­UKs›0¾ûW챙)„— έM^’¾ìÞr‘A`e„D„lÇýõ] _ñ4™é؃1ûú¾O»Ëó(„?!ÄóÍëÑçÅh¶~†Ï‡‹ª ÉüÂqê£c6Åk–øh PšÀŒkAÿë»)„ ,JL?Éð¦øp/«{º¡üjñÔÕ@Kaª$Kñ>:Èg£C„~fâg/¤n8mMüõ]ScGÔ^”øG  ËueÜð ‹ŒT)©.™(å%›‚^²m‰®¸g‘MŒ×ÚæŠ5šIç“ äУþXQè‰uÆWôrò†æòë+DiæÇ0Ž ˜â8ôC÷Ã¼“±¯„:§hsJBÁÍ5ÛPhš³’Ñ4"à–Œ,Ëªb¢‚R*k°¼ØCÀΌªˆøØqß =P2N}0|Kɹܚ2Âׁ(+°gÑzaìG-B••`hqÓ)”»\Q†ƒ‚Ñ$=•ph„C N@¦j§WXÝ?Îì+¿–²ïóŒ„slàg$¢‘Š( ÕDSÈWDTHîєdÍõãÕû*î{댃½«eœKû¾ÔÃ,œç–‚ï\÷åìÇä<¥‡z÷ûÁsÇ8íŽñ¼ÜrF…nöDœeÿÜ1.§·í‰} ƒàd¤ŒQò¿‡ú˜Þ¡Fû™Ì¥ÐJòn$kòÂêu b]/©2³Ù⮉ rÝBî°êѰe؂Kj:QniË]OΝ—IØR…­ßM ëH`V‰>™; ±ƒ6NÌ4ÆQÇéÛ÷Åìæ"ã99Jò4Š Ori‡Éa£ÚáǪt¸[úýbFÙ4¬¡íƒÛß?æê ÌJ•@Š;à¬fºԛd¶«´„ð:6jš`²!Œ“%B;Á‡¹åIy²‘¬€F¶-3’øS·°]QÑq6 UQwf­)ƒ:tºÎÎޖ¸É/¾]ÝÏü0IEv‹[æ²Ô8ü>5¬ÕŠXàD¬‰}wx]”çÂâ‰y˜$æ<ƒWÞË?G5§7cendstream +endobj +688 0 obj +778 +endobj +689 0 obj<>>>/Annots 155 0 R>>endobj +690 0 obj<>stream +xÚµVËrÚ0Ýów™ÌÇ6Əî’&i;Ü]6Š-ƒZËr$¹~}¯ü +B3v˜0†û:÷œ#‘ç‘6¾\˜øðÑu<º¼‹Àñ Î0â‡øžÍÈæ^¬–ì=¿nã‘ma,p-¼0Àgÿ$…¬¯wÚzϱBÓávCx™Seê/ïlˆLGŽ]ÏŒÇöÂià›TƎÝtØMàoÇìfBa\ÏðMÒ U‰d¥f¢hr¼&f4(â5…bìþZu)“4Ñì'…DZŠ\ÆzN6ŒW”#2 $YC.V±œZ0/ +¤ÿiÃ8U $ÐMBiªºå&–k0ôd˜‚$Ц@Š[„ã³-xÒa4L̚À[¯± Ésñ¢`+*S,…&šÖK <ŒVZp¢Y‚i[kËP•ÒŒT¹na©N9xÚjÜèñ̙]?žw…ÇKª5+V‡\!IUä RTB½¬^T¯,êmó@Ÿ+ªôÀž¡7N»Ós¢÷zsgH·¥}hÂý,~:á8uÀÅ_¸µ”¬Ðµ3Õ|Y,¸º%~2VûÏî!’ܐM€°˜/ã¾Î8íÕ)9ã}mxY3<½Þµëê(‡äÇےÏeJåŽÒ®ïÿñr'ÓwÞCuw¸2çââ†ہ†MØ.ꜭa¿ÜqéFV´du”’$¡Juª6tg€3§ì'ÉQ ȊªÊRHMÓ̀¤à†¨aêÑõƒ!ª}:v¡ªzµ!“‚›kÔViÊUÛÊï*ÌWêatî„ZËRc%2Dql~Oµ¿ÓŽ5-4ðÄB¢È·ÍV‹£<†8Þgû”ã´ysÌÛÃ'pÂÈ + t° ×s­ió!‡ecúnðÔµ"݆ƒ ñJ¡gʒ‰K(–Ò–éÁ,¹‚P÷"!—_í>ñmEÂ6™æO‚æÁÇo‹%,E¦_Œ5¯RÎ +$V-¤‚)*’×t9^`ø +\ûð/ð°[˜-c_G¿<ú€àendstream +endobj +691 0 obj +790 +endobj +692 0 obj<>>>/Annots 158 0 R>>endobj +693 0 obj<>stream +xÚµUÉnÛ0½û+¤ËZh[>vIŠ Æî¹`$ÊaK‘.I%ÍßwF”dÙMZZ86HÎúÞ,ù1I ÆOقþŠzòn3™]­ a°©P²ÈñP^Üò­¸6Û7›o“ËÍ$ŽP°L£°|‰ç¿V@5'1K¢œÌ/òz§„#ûÙU +’c¼iÊ¢±˜=r;Sf;+š›íðõ« +ac˜&qðögåé¹{Eß=»ÎÙ>Éi›Å‚Ô>WX¹óÒè Ã ¨òÜ<èAᘚ½É”ÒŠÂËGNx 5¯˜ª=S¶€Ù@%•ˆàSx¥K«%hãß;£/H¨AzzçÎ5µ(÷¥ÀÒOB?w+²„yºŠR¨!™gÃMÁš +Ã<‹ñŠh¼{•S¼M¯¾ÃwäÖ"Ù{Äka…½3ƪƃê1 Æ>G@ܕ¢âò‡ð U ÷v¯÷ÁÈyÔÕy\׿¨.¸&|Rª)E‰‡C’qRo+zÙY’Õ‹Aw¢\…¨g¡ÍÎúðÃÐH­ºÜ—^êÊØšS³õ¼£uˊÔxä%5 ‡â¿í“¡wYߗ«n~Œõ£ádÙâ¯ÃÉâù©Ã‰Îa‘%ÇcEÏyüÏ穃òÊ0ՕŽˆ¡<%‘- FGpƒÍ%Ì)N•Ô覫Rï· VÓe“Y–Ó#cÄ¿ÿWü<ùA”fendstream +endobj +694 0 obj +697 +endobj +695 0 obj<>>>>>endobj +696 0 obj<>stream +xÚµU]oÚ0}ϯ¸Ti,ÝV4UšÚ©ô“8‹»Äf¶C׿돤4T¨›`ðñ=ç\Ÿ«üŒRHð•BžÁlE}\G—«%¤Öî̸('wŠi¦öìFn¿pm¤z¾X?F×ë(‰“gñÈ"Çu†oÅ ꤡIㅭtý‹¶»†i{þr•ÀÒî#õ4#ñ*¸À4M|‘¿aªÊ—ì9§®èÜÂ?3](¾3\ +!ƒ.DxÚuÍ ×ä7˜~9=’+V¾gPHa”l4<ÕÌÔL~@´É +÷­kÃÊPPQ°¦±K©€n¥Â¿{ƒ³8³jvŠ r«k°UX R ¡þl¯ü +ö´é˜e¸cÁ›‰ÕU²ŠvÙ\À.XԖ ¸¨¤j©ítÂðÆ¹ eË:QeÀ®SßÎ Å~þ»ì¿Îº—÷FÊq£r>f8o¸±3²¹e˜m¨óº™ ;ϬāÄԖLskyÐöìá$½olÆÓ?#ߓ÷ Ð"°¥$w£ÂŸîîá^VæÉš¹:춆¯TtÔµrêÏMó,9þÜ!9Áyp€Ù2Œã·è7@p Ùendstream +endobj +697 0 obj +555 +endobj +698 0 obj<>>>/Annots 160 0 R>>endobj +699 0 obj<>stream +xÚ­VMo›@½ûWŒ89RìûÝH­ä&®zñe Þfaéîb7ýõ]Àv°“öP9¶€ùzûæÍŸ£ú„0Kì_ZŽÞ¬FÓ7ưÊɒ,è"/¯LŠõÕêÇèýjød™G~ñbN×}ƒüvÑqè/lüû_Xւi?ýÀµSÁIûg˜„A×?†)3é´>q:–™¸<‰uÇtªxm¸¬ZŸø…<ÚJ«-ƒFk|Rü3†Œ+–¾cÊÊ()4ì·Ìl™© ’zLsÁ€kÀÆÈ OQˆG(XÅ–V4uæ®÷Ülû“ÎüÈÂB\9à¹À es¹™Ò>Üæ k–òœwÑTv(ë1‚Œåس¾zt[YóSd{.lؐßèyùnÃÐ9WXº£K®ÇÌ/üŽ7ì ºÐ”y’s~öŠC¥ˆÉŠíˆJìÏéØË2*'ՀÅJ¹#̰:K™bÕ™×h +Þ<Öµ Xh2"5Šä¹E•¥Òæ7„”@†sŒùYuës¡+ƽÄnZ*ïØÏ†is'¥9˜8ž“ù偉ÃÄOþi`NjÀt‡jªk)Å4mj=˜¡'ž¹”Ó͙÷ÿ¦Áá/ϓfF;êÛGR=ZځW©,yUÀírIü¸DÚMΧ՗ÏÖ¥l‡zŽ-EcؑaÚdö'´?w!º¶í˜…1ÑPÂ,º>Ü ¸·Ät{ÝrT#ÉÏÎt­äŽ;•XUqãd©uS¶Â!™)&ЃnMÇÀ ¾*à„“{¦Hé=%G×àà:$‰iÅÞ vÏÆ@™Gúäp:wú|¨ó‚zo—o1ݞ Qb÷øËҍfá¿ ·K‹r(ÔÞÏY¢ ^<üwŞø/rÕü7³;Ú^—´“ˆøÔë7Ïj»ÉnK,,•L™Ö$ìõØ£*ÞúÊ®»<}ÔMº%‘ ‘q›†Úë’áÙ±ø×úçVK½Ý—¤aÝä9ÿÕ¿M¼ύàróh˜~^é]X†%+°s w¯hà +Þ=}ªÚ–W—ê-JÏEÑ@öY:.:¤!-É*æo¿-ïá^æfo7øëŒ¶½&é&•†/X5(l‚I7™G ‹û0ŽÁ…ÿ_¾ŽþÅ¢Òendstream +endobj +700 0 obj +879 +endobj +701 0 obj<>>>/Annots 162 0 R>>endobj +702 0 obj<>stream +xÚ­UMsÚ0½ó+ö˜Ìá/0¹%´I'‡vZ 3=ä"ìuQǶ\IN¿ïJ¶Áš´3%½ýzû´þ=òÁ£Ÿqá ’b´X&wWàG°Îèd6§—ôb…ê ÕMZˆòrýkt»yŒã€Í šÇôÐ_!d{~ë òÙܺ¸}áE•£¶ö“;®ì9ÅƀZ£ºÞJm,ڃ±ï5Nú%¥¹Î¤d®X"‹Æqyì\ϬÑ'ԉ•²l0Ñ>;B4Á×[„.³æpXóÁìR¡01â A¤X‘ Ô`È\äÀÓT¡ÖIåv¹õ!´QÜЎ,ݦÞiƒƒÅRÌx»ÝÕ²À¦ulyì]èaƎíÒdüž·¨NJ<‹µŽ]‚îJ^ Ûsu¼]õ›¶8’ÅÔó(û×eÍZÿ( Š“Z«I.6“¤®ôYa8IbB’8B¾¿.¯©B£i8l¶¤Ú9-4ŒŽU]¾`R¾¡ÊÜgÀKà-óÚ TÜlmJi Rò‰4–è¥ûj¾},?ƒODzDXL7±€ œîW9¬,ëv9g®`ʨa¬o®u]` +F©C9w‰ÓÒ´B©ŸpÂÁ’ôv õöÐ!-ÄËf'ö=–DÛ-~èDwNºßAäîáapÖàñâ~yÿflúxù–º¿Ò èÉ;ô£7§^0ÿkêÙ`gY*鎗Ý8;¸Ã»FHðûk¼+ü/"¯09L>;¬í¨ w +SXIe‰%¹ 1©‡Ã®?bÚÖ÷Þ÷Ú¶hÞ¦áG1a¦alqðñáÛ +V23ϜzqÓ™¾ð²æ¹57Vã8ðÎ|Ò¢8"¢ÝIä·Ýþ>ú‰Ò +Ãendstream +endobj +703 0 obj +658 +endobj +704 0 obj<>>>/Annots 164 0 R>>endobj +705 0 obj<>stream +xÚ­VMsÚ0½ó+v8¥ÓÁØÆè­mH¦‡tÒ@€°ePc[®$Cø÷ݵlcBzÈð1¶µûÞÛÕÓÂ߁.¾<˜„ô޲Á·õ`|·/€u‚+á/â›W{®ž¤4ŸÖËõÀupmæ;!ó^ûøQ’6ß«óϙÂò…eEÊ5åï\XÐ:RŽüÀéQÀ˜›h•EìÂÈs-F7$‘r¼aª ;‘Ž*Ԑn¹Ž”(Œ¹ Zaay×;(»Ø«ö”u±P<2bÏA<‰à °–ii8ÌìÀÈê¡®` ’y"¶¥b$Xƒ6 Cípà‡¡¥Z6ÕNŸ„•šÇ¥8b#£â)«¨‰CƒÈ+«5 +©±C”}éDçU󄕩iôٚ¤:’ŽÜÙNtМ¶åAÓÎE½Gmxv¯dYt¬2u],êºU‚°†xß*'ÐÇW.9_Åë+ªÝä´Ïy þÇ?V'°8¹Ð¦öʶ’˜Hu™¡ÎJ„ʍˆªl¤â§=ÀsN_}=݃ïùÎ&Ó{’?âQ¶w)¬hk\¼Ù†‰5dVSÄrØàîɍŒ†DUNDïD;VÔ÷oÓvˆvA[r¢½߉È`2ñZэÌóµm+«Å•À¦ä[°]ƒJ%ÌqXÙ¢Mwëô¾·G¯5øšgÅ­PsO<²õusûóОêwÍ]ãÃxÓÍdEϼír3됏4p§Ä÷̋n8Ÿ}äVrôiªàÃQfX*†ëá×G½éwu*í»uŸ¥ne-[FгRrðAª4Ð l“r;—w²LcØ1,‘jjõœí2û¬/æèñݼ¦ó<‡>ýƒÀ\øþûq+™˜Ããóõ4%vñå%K `ä3ÌÍ|—ÒŸ8p/þOù5ø>ãøendstream +endobj +706 0 obj +821 +endobj +707 0 obj<>>>>>endobj +708 0 obj<>stream +xÚ­“Aoœ0…ïüŠwL.°Ç$MÚ=´Ú*¬Ô« &q˜Ø¦éÏïx ´ªÚK…Vò2óÍø½'^¢Œže†¼@3D·utý°CÊQwT)*:´Wµ¤žÝ»úGt_G,¡B™%xUÒ9£Ÿ‘èÎpºÀrÆ|Cœ²€®• ð:=>á…où mcÔä”C?߀:–ÏëöPÜjzC®Ð*#§~J4ztF÷Ž`1èytÐqp¯B9|—&éb„Чº>@ìòäe–֝ ڕ¬âò$[oÕÊNÌ}hòB•õ.ÀJZßÚ䬚¯ŠvAÑÑJ³Éã=c4óïyðbaÿ™‡Ž~ºÈâôöÉKúßY¬bþ„d£:%CÇ/ûo˜ýUܳpèTïè,Æw÷˜Œ~2b°03ebl=>QdðÅö t³{q½Zþ§¼$oó¼ +©áîxxÄ£îÜ« ›oÚAÊ:#œ6ŸÅ8‹Þˆ—»ø†xÉÉÑÓ[ž/!~~ƒúúœendstream +endobj +709 0 obj +416 +endobj +710 0 obj<>>>/Annots 173 0 R>>endobj +711 0 obj<>stream +xÚµXKoÛ8¾çWÌ1bYoËE±@M/ûÈ6.öҋ,Ñ1[ITI*ûëw†¤K±cov ’Pñûæ=“gøø@”ÒwQŸ]-Φ·sf°Xá'iÀ¢<¿“¼Ñ¼y€ûÒ¬†{Vt’ëÍ»Å7!¬ø$œy)½pýåîZ)yɨ®m…Ô°ò²”L© (˜Ô|ŋ\³ țÚ\©'!Køz~•+^˜‡7ü)ýõ,sÅJÈ;½fHßâ¢! ¢€ÀA䅜ޅh´•×Ï(CÑMŽ+<åZ@Åk®Á݆gޔº¼‚–‰¶b äúAŠ®Už{¦^LO/­¾=ÿ=È«J<)؈n¦jYAÜA«£Í¦‘üwü -YŠ:çòà¯5G>zÍՈQ)ÐøÐ[í†J_ÂÃcH¡š¤QçN1©@¬HF:>ÀVHŽ£DµkmüOô4Q„/UšÞ¯„ÅF×¹†uþÈ^¥)§(C±&_V¬ôà×í ¹dûqqæ{>Æ1ýèÇçO%h‚$N½ j¢ÌóÝ©‚{ +r:Îðˆ\™Ñ;¢'͍:ÃKåLo}êç=‹¡ ¿ìsâJ.Y¡ù#{o³Å‡9}€é6 ck­ým0ÅXA 엃šE)é˜h5d1þ²‡^±¬#’m^^¢Q¯+́ý¼ÏÁó¼#Ⱦomê§daszÚ¬™ ú¥ÈïyÍÞ ÏñÂÏæˆn¯¡Çó Ç^lÚ›fèªÒh{x6[Ïþ!K&ߎšÌŒ—-ª9¼ŠšdÎ˔·PWRÔ'@»Ô1 ñ söB÷ÉtÚÍ)ÈT¥|ûʇiþ‡ƒ>Œç^q`…™—¸“cµÛ…âÀ8ý¹P<°†I¬qì@¦ÒQŠÛ¼rJˮНdT NÊþQt5§ÏBèS+"]ÀZ<±G&ÁÔG*½£Šmê¡",º\jj8Ï5Ó6К7XM¥«á¥3ÖðM,•ë¤Ô®±`»Š“8&֛ «Nfcs·„Q‚}ëAUHÞöŸ Üá;w˜Ô3ô;±ÎÈó¥#ð~Ÿp6GoYá`ž ¤ž üˆnM|k‹©Ñ”8CnA])×kk‰ªYDËì_Ê;F>Ž1zN%o„÷w”#pSçŠ#”ÔQ‚Æ[§4‡ ®÷§+ÂCž}÷1\(ôMËsÿÞN|UÄO°†œªˆ>¨H8wlJÑ~ÄÐ$rŒ\˜ÑÄr"9+|˜Ü,²™eÈMyyÄÀ(56¯}ç7Lg§ç >Ì?‰]æõ䈁{±£$ãìô\³Â‡IFɀâHÞòtrÿA‡X8ONH+|X‹ q 9ÐÃkÛ=Asww+ñÿ¥üùéÉi…÷Öp\cÛ}ƒ,t›Ïp€ÿb†ë}LíÙ·»ƒ[Íê€}ªÚ]'{wAU¬YÍìZQä ,m-%nnÐVyašûÈ^fÍÌíuÏR;ÝÙ.£ãF<–¬œ´™¦¡Ùß,8ú>¬·ãÅ £ßZ¼¼Øøx…ÔGkìo4@p»ð9ó¡ú6Uqì(íüÕs3ÛóÞ%wÆ{܎»hßÂ"›,q=”8gàmMW/i34V—l…wá‰Ö776跑up¢íB–À­G.­‘2;ö{äùÛl‡MIa$ُ½O“1!ùOËkÍrœÔ1Foi—»/¼7{h~Fq’βùåÕõÍÇÛñyÈkbîKûĶê“^ F¹ø® k–/Bތu;¦Do±oMf¡©HqL#ÓJücÿÂÊóçÙß3Xÿjendstream +endobj +712 0 obj +1439 +endobj +713 0 obj<>>>/Annots 177 0 R>>endobj +714 0 obj<>stream +xڝVMoã6½ûWÌ1bY’eÙÞÛ&M‚ºÛ6Ú+MQ6»©%©¸þ÷!%ÈÎfQ0@i8œ÷æÍ£¾ˆñ—À<…i¼Ý­F«Q-ðùáÏl [DsH§yÃt±Œr˜ÍñÏ(GþÕt¹ŒÒîU’ÄQÞÝQ®˜Òô˜kò˜a ¬J<:_ÌaUÜÜ ãd)9sÂí¡„ÁUë=¸­+̛0ÀZ§kæ0²ªöÀTÖiƒaRù°_VÿŒ&¬Ë3ŽOxÛØ Çlx۟~…4‚ãþ=´Vª e ‡Óªúûó ²dŠØòy- †,×ݪ‚—S\"œÆh.¬…ç_A—¾®û§gÀ§Ãj¬˜™ dœp¥¬:"´BœF°‚­+Ño¡"z^ãÙ+&=º$ÿ†è{®‡7£vÖ0=ÖŽ¡yŒ¡ÈÓÑmóq…(¥z·‡Ô¾"âZ•ÃöKüµê‚c¡ +ëòV¥E&ký†GuÐcc[SªUª7VÉÂkîLeQ˜æ¨j \QÏÁ%«|hn_¨Îõ'XóþÑڝ–<ܺÛJ¾Î¬j6ˆˆ©=ðJ +åÀ´J‘™ý¡–Óe‚ ó8÷Zžæ$Û°:j9ž-Û¶fŒgÐ8Jcb~í¶Ì© ê¹ú†Z~èèÏêõeo¨V.~jåöžzAœ z9hú¹iq4“·‡ÔRµh=Qà{ I”·ˆIQ:'µ:omñŽBÙY(±fáõËóߞ?ëý«aÖî´!¹êÓxŒ{ÁÇFXÝ\m±ÿØÝÆHåºCðföÖgÇ͕¬¥;IÆ +D+­CC([Å©¸ü¬C2ËÐÖÇÓ4àÿòuõðéj7WÁÚà XÅjq†—Èy†“Êu­(®{ў¡ñÂÆº^y Vƒ$ɕDÒ4öNxÀ6L*ë@°7a £›;GJA!Ԃ)ëe;8…AÃÏ¥nm6X­•ÄË”pXð7¬œ.t­–kº¼iÛ9È{Ò\š®Ûª n¶•#·cÈÊuji=ïO´‚·Fº}hèA}ÃÂÏ9ßI·ñ¯C›CëÃû#ºð€¸¿ÏÞ½¶;˜Îg½ÝÝ¿þþ²n*L«\8 +çýjÛ -¨%¨¸ªÒ»ƒî¶8ۛm ŸéV!“T®n1ôÚ"x.a¯[p8¥ÃñW6ö©KwÌvÐØ-m6} ;YU䛲®E!1Eµœ»®4¶¸:þWÅQ»'­¾sp™CqÞùˆµ[ïά($‘ƒ7FðÇZÔkTÌV6ƒ +ŒøÞJãi÷?ߊCIÿo8{ ÜKҚ²²æX%q»&ˆ¡.êmpF_íºöUØI(M’p‰|×ÝÁöÉIWûF\ÿ.#w„òŸ>×Äö©Ï·¤}ø;N³ºÏ|šÉã¢ËŸ$tû͐=ÿ‘xÑ¥Û៏ö¨q¦cªe%'Ù÷çiüñÍ3Dî³YÇߣÿdzr~endstream +endobj +715 0 obj +1163 +endobj +716 0 obj<>>>>>endobj +717 0 obj<>stream +xÚÝWKoã6¾ûW rY°å·cï-é&Å6I7P éi›‰Tø°×ýõ!¥Ø–4‡öR$0$’óúæ›ê¥Ñƒ.þõ`0¦ÿ4o\Í׳F7™àúëYÂp’\@¿Ÿta0™&cvñÑX4ÂÎ`0HúåV:Âç°wEªº¤¥úAU›)ô†0[ åñxóÑJµ„/r)¬ƒKïVB9™2'µ:Ÿýhtn†ÐëE‰vÿ‚$ʳìà,x+,ý Lq(˜µm¸.R R +@TÊJ¥ÍŽpi'õ…í žä|th· ™ pzߢ 3èQbGŸXš +kéV{ƒo`}ºf¡0R¹Ê¯4C3¶ Ïd.1–WqÆs©¤u£Z#Ž^¥žM¢S£Ò©Ñ‘oúIÀðönvýù­qÜ}T™|pŬLk¨µ*à‹àUèۗºžÃSsN,˶À Õy‘…Èy-ôt%Ògx:½( Šåâ ˆ¿u‚ñꆈ‰&s+²µ° \fV·jêOg›kôViG¶‚ºÇÛ¯¿ïlQÆZ`5È:Ì9–> Äjú¹´©^ãiÑF.¥bٞפ…Œ²C("1Ç>sÄ(«Ô³-Ro¤Ûbºõ<yÍ ú’i$:òa«}p›—‹…0VÍ}·b‘¬©6h«ÐŠïФ¦¸JÊõ*ë3÷&hÿåñþ$&PäøÄ4¼SHÁx&qùS°•¶.dWøz„å†ÐYèá™Ò*g°f™ a%.˜”Î%C¤#êåĹåñ6p3gHë¥Gë„}ÝÍ56!‚W¦˜©¤¦žœB¥”õÈ^BÜ û¾æÌáö!°~;:V³`Ä‘ºÃ‚B."›ˆ‚ê“KàÆ;N¢– +œò´‘¢â‹Bw:åg–BÖ꬞ºÍJRËá<6âÅS‚9s¬³t¦E4]K~ ½X sá°cÕÕþÍëtû‡2]zfvA‘ޯɔ©p‚a9yE +° +ÿ:j3±E¶`î]Y”–-BÙ¢²S½-º»Ò>ã±(̀"c˜`;ÈԍÔñJK +€cU'p؆›ežˆý§!@“1¯Ù™½ £JFx¶;™’Ä…Øo×LfŒ ’àõÑ(ýþ+¼={höîO‚AwZ±>ºß­Üϊ8õžš½§óúØÃ–Ÿ†ÒFðÂtâ-,¦–Ø^1d#rì4¾´WH÷…Ñù©)ûþlÅ.¡öGªüЏ8Æ5]»Å1’ÃÒh_´Àm QN¾LI%ÞeÚýa$e´K]×·³ëïÓrNöð¢C§ïËæñ6Ÿ^{,ޏc Møc7-b:EºÒ‚ÿYÅTÓŒ¸þ¯ZÙ!ÚñÉÞu²ÐI[–Xkeú`%mgEÔ®´Î·„&6„àù.ŽwÙ®Mÿ×Xþ_r5Ó¯µ3õZIµ;ÍG ÿóˆðo2„¦äoÝÚìÁµ7ЄÆ]`·ûs<$ä"Ÿc[Éâh ¾xiÂý5b— +ƒWðÝkßî€á»„>Hª¯’‡S'“dðÁ£¤tL'óR,¼dUW”Žö†ØE¿K~ÆÁý nC¡]îîð{ü7¦<Ë(Œv”j—bÃ1-F½d +Ý| ! +¿5þh•>6endstream +endobj +718 0 obj +1253 +endobj +719 0 obj<>>>/Annots 180 0 R>>endobj +720 0 obj<>stream +xÚ­Vmo›0þž_q3©$Ý4©ëÚjÒVuk*MZ÷Á ñ6ÃN³üû1¤@˜ÔJS¤(Á÷òÜsϝù=ò`J¢ø!ÄùèÃjtµMÝ=?~•) 7‚0 Ýø‹¥‚ï¹3(6ÆeêNióEö“ë<V˜ÆsA¿“ñj‹PJ©a§°® –BñKL`}€Ë‡»{ÐÖ rÌ×d$7€OX -å®p߬~Y€„ßnÚéÑÞý©¿pý—Ú>‡Í;Ž™›Ê! fD÷ 4h N®§uù㋝ޮÚÇ +cHx‰±æOh*FÁÖÂGž¢ÒÀÈ…æ1Ó\Šó&àÒ8R›œYà&cºö³vKðcèT–KcwPs`"Ã"\tœpêÕÅ{Kw óÐГC´¤Úퟺöçj¦t0£ƒºÅ&`/Z%‰'—Sªky*ž6M¤]ÊLU$g$ŠÌˆ£Ë•á²Àr#ËÜí7²Ðo‘Òµ›‚ãù¶–Ь‡nBü£‘x5˜eeY¥mgÍiú\‰¿wTQ­nµåpAj¸ýô½%ñˆkY¾°’0oíœå;ÒÔ3)Ra@£ê zÑÎLNsžÁ)83ß}hUao«Ì,Ö;")m¨mUš`AT*0L‘¥¤FR)Úænˆ™…VýÄ6(gߏhRƒå¼Òs0ó)Žýw"è¹G'¡…õ*b«º@°Ün4ýÒi¨ß’Û+&¢»oþ¼Þ}–5ÚIÁôö}Ã4­ó,ŽÞi5pÓîRëôˆòC:`ónÒäߕ‚]Ja³(,O–³šLš…'–ñÄNDEsu~F¿I8ÙÜpAn\´¤Ìz&¨ãI:4¸G¹tmêAó ÏPõ‡ñ"I¸)Ë9ƒ=ɂ`‰nn8È$¬¤Ž¸D¦ÑVÄâXî„V°çzkwÇ3u[½Ó}ŸueŸ€“6ăÃlÈ«ÛÕÕ·Ž Zý¸3n²LΡ{ü8.ê“Ç7Æð£97—µ ‹ã­Ääg¯ßM|`)ãâ¿f™\/ê–xž¹{ü(´×­}[¸—½g´P/’œ ®4­ Y*øÂ©Åp¼ "?'šM_xQ`Þ ŒuÕÛäëè/–°˜jendstream +endobj +721 0 obj +856 +endobj +722 0 obj<>>>/Annots 182 0 R>>endobj +723 0 obj<>stream +xڝWmsÚH þž_¡ñ':-~! ¾õڼ̈́–;œmÓ¹Yì5ìÅÞ¥»v(ýõ'íÚ&qIÂNllkµÒ#鑸qAˆG§#úKŠ“?â“àbÑľ#ˆÓÞ\ Yr ï“DU²rõ&þ‡EN°?8óG$úáv¾€‚¡<þ`«¨ XžKn 7ï€k­4^™LaÃVÜ@¹f%0ÍI1©ùCR¯¹Õ‰…ð=H¥ T¶S*ÍS×rp±Ú ^ðÀt€ ƒ¤Ú˜§Æö š'¸zçÃUAÂ$$k&W5 ËðT—¤ù©b4-:õdZÀËĪ·§ÔO”̺;Ñ3±ª4+…’Ö ߉ ÄùÉÞU‡Ðßäñ +@¹‘ìø»_Ø56…\˜ÒgÉ®âxšUé„;ØÑç:4)9Ï`˗°Ôjk0æJÅ4¸žÏ!É—¥稨TƒF.$'Eu8Œê'%Tè}PEÎߐO»ÒƒªÞ©`rg7͸66è^óÒ.Jåfêœ +aB>a¦öCÚZ™VZURª!e%àpwç¼\«tï,mqÀ7˜<¬¬(Ô%7MÊE.ƒ#Låúx|„ÁŒí‚h2™L£ÉtNxâç;xóϋ–BÙ ò#†!VP菻j qÏi>^Ó<C§yâ¾Åcô41FMü  ßS‚爳À’l«II<-1%\ρ¥)¢f ’9]vX%köÀK¶¤ ÖuqŸ Kh":ýuI70žaZ0™´79,ˆ]:òz×&Á‡Ã±K§+4û+øR÷uïW†íÊnM ´ñ0!<_£mUvh§¤M²ÃH²|Ëv†ŠÝ‘ž×÷È +*›#SÞÖ+Œõ„UxFÖM0·S›æ‘!R¥·šÿ¨¸±µB¯|¸Î0ª{1G±Æl•¶MµÙ`§úͰΩ£ïÒÑ¡³å±sG8ÕÖዞ‘”5ÐVìS‡Á\!‰¸—$µ§—ÌÉó´ðíãÇ`öùSð?Ó««él6],àíWü|¶z¶k®s„–t}¨­'»~)I†g†[ƒ×H4ŽÅ°n+äÈ´*àRs.·ÙwƱÀbËO=æßû̇ËY îk'$_ooný»7¯ƒíxîE¤-ë×|hÙ÷®ç]žÇÞ;dš[wAÂÁ+6µ£ölHõÅ]©´ä*ßsò©T³öëî™ ODFeBͶ^Öökú×EÝÔêÆ%º%喗¼ ¯åà#LvÝå°Åm!µv#U^6-é)T>ܚÊ´°}ÚÀQZV%(Óµçí~,NTZLeŒ@ÞvŽóŸ¬ØäüíR5~^%‰e”¿-7 ´M²®¹z°¥z8&nmo}YKš32׍›íZÈfÛ ë'æ½ÿ×Í:u·¶ÓЖÜ*áØKRW¾RçÅéÍNµÿcxk×½0»;(·™dÍÓ*GûïzÍ<½eZb'0M?ϐ9àù£q©ÖïäǵQ!P£qèàr5³PY¹¥´zOà ‡Ó-n3&1SIA?²¿6iÙpLO'g>ýÜxöçžü ´H¸‹endstream +endobj +724 0 obj +1224 +endobj +725 0 obj<>>>>>endobj +726 0 obj<>stream +xÚíVMoã6½ûWL÷â,)’âøë¶mÀ ,b]ôÐ%mîJ¤—¤âúßwF¢bËözôÚ8€?Èy3óæñQßz1DôŠa”Àí²²÷˼wóÁæ þe8¦OùÕ þL¢›Ob{O&“iLÿãi2†Ÿ#úû >ê”0¾UXaZAÿí׏èún¡_ʯØßÏ¿ô"â(ŸFLâi”ì#&ÿ1™&ƒ.âFXȄʰ(¸‹uó8€8æÆê(@c´e•1˜‡]P¦ã–p¿ƒøÇ1"÷gѼ ©¹©”H *]ÃÍB›¬.Dæ¤VoK6;N6S )K-/oC½?F½Ç´Z.¥Zvƒ.Á'æ˜ ‡“%^0KÞ BåÀûy¨›ªzeM Á:a jm¤rTIXóÚ4Ë»ÝJZ+m«[ߥ̑b2"„Xw'Ëgʔj/H´‹"ˈ‹¿ ½<Ž*°=:gÈñTžÌiwÜXÄ VŠÃ\u4× Ä?×d²KÇ´qyðHõt³ðÎQ·¬×¾Ú°S]A!­³€"[5Sq+bŸˆ·D0“+šù  á7RawÌ ]zÃR’;©N[ ¶¦$ƒ¦ ø¢Ó@æðªªº†@UeJ‹ôdz-ÑÖûRYPòe;†8¬½Æ{­yÕ)ƒ¼k팍[d%qrûóò%_ y%¥×"÷ÖŒ6_òWõ‡0[ÀVWÌsN$Sƒ¶!+„µ×²ß;b£Í}>5[aÉ¥òù)×bæù¼±ãz¤ÏWüqöôtèBéj²|ÒÞpäaᜑiåðù}S¼­ÒR:bî4Em; ùq[â.hŒ'â…Ø²Êç#EVºgXߐÍ."Ù ´XŸ›¸v;|©§€ÕÿúûÓçöá³Ö8á5ݐkÕwãšu¡UゾŽ&w¥$ùӏ[ý߫ϐ³g4G"$v³q„=ïí;ÂüÄj'"of 5ì w@Z㏭¶Û³La 4ۉΫ [ÄZ'()ÉF]Ÿâø|ý™ˆb#¶\Äž£=G>#/ÁUnÛCt` +g`^½€»}!qnÞ^º@{ÔeYø„|ˆHl¤¯É=µÕ›•å˜wÁ; ân>6Ó¶Y}P<QwwQSԇü³^¸ Ǽ”ŠîZ#œ&¯ø$]ûõ3WŒ’è»÷ü`4 çõz}0áæ½ßzÿÌ®4endstream +endobj +727 0 obj +996 +endobj +728 0 obj<>>>/Annots 184 0 R>>endobj +729 0 obj<>stream +xڝXQsâ6~ϯØã¥¤ŽM8H:ÎärI{3—äšÐ‡Îð"l«gK®$Cø÷ݕ°Ã5p„qb{µûíî·»Rþ=‹ ğ.Gô‹³“³‹ûkˆÆ0IñÍè*‚IÒ½9‡ÉªrL&€÷–k¼;ŸüƒòCˆ"/ߌƒ­¸ýëë ”Z-D 0xøüpן1ÃHI™Ý(KkePð8cR˜¬‚XÉ×։zÀPŸ–ÍpyªtÁ,ý"h7º d—³8ór\ð$ÁX¦mU‚Í88P†kÔ š³Ä8X0TŠÐÖ¦R­ +'îckçºÜÆqUš]§»Íc«ô +¦]¥Ñû»ÉY„\ºDtyþ ƒk FADWas—à …>“•¦ä±HÆm¶jPµTë9\܇5žçà³RvW4lDÛÐłOÏ)ijJä ºNw ò™0BÉM¨„Äl0h%`’q|Ý +)Óʜᢛ—ÛϟÁòWëU3 3<=\ +›ÁJUR¶PŸyIz­tm 6\[j§¨÷^ŽÈØ!aòmO؃Nx*$w1GɄé wɧ†ºÈÎ ÉHN²¹c( W¶‚cVÆò"ðö°Ê†uÕ\{—¾‡ßÖÉ>;°Þ ãÜø&ÕRnùÀ•KNnªÔ‰¸—®fŒO=tUÒС`«–[3*È Û û;‡p×so ºãï;ÇÁÆ#„tý…:—_yRШÕàÞÓ4æ5“s~êLNšÚ”GTkۚJ§¡Á 7H-+ +4(šœdËdJÛãE#G :<Íq~l›E–HnÝØÀîә‰yŸËD0Ùq÷£tÂõé>>>>>endobj +732 0 obj<>stream +xڕWßsâ6~Ï_±Ãù¤½ÉLÚ t&ÓtBŸJ„-ƒ[òI2„ÿ¾»’ ØØ—™L´¿´ûí·Ê÷³! ðgÓ\N LÏ~›Ÿ]ÌÆ0Â<ƓÉõæQ÷Ùj!WB&aÉAHøž+ËMX’ÀrvÍSӍÛ2ÀÀ8 P1¬ù‹x(R–À†%9‰( F¥B•.…dV(ùËùü]à†(.Y,‡Õ娺¼\œ¿kýX~\U¿ª.'Õåô'_WÕoªKV].ÒxXUªK^]Æhü¼Ãó5‚‚êŒcØ»fÉÄ7·Â®q…²\lHê]oŒ•0  Ók:•Á†o°UG¡ æøóéþRX ¢‡Þ>ÒZàe´¥¾q ÐNACµ>(qZ÷¿è:çÏd²ÿWÜ ØcŽc•$jË#b:vèE¤B»å\Ö"b2Bž“)Kë“|ZožD¾IïÁî2m*#÷Xþ]1À¶b…LGØ8Ú×:ϸýùÒ_ty°ªO´Î¡ftŠ«Ò×/Guë,ÎKÅÑÄ#£áG(ùÈe +0GÕ1_í’kì„„C@mŽcßE y‚ñn¸Gu™@ßRîE…™ô°µJñé†í4  NGÐK/áZ)SĝµÀnD"޹æÒ‚á®ñ +O¶kî+î镜<ÈöÏráE|4~oXU=¦ÏvLŸŒ•Ê1€ˆ7n}ñ” ôçV¶V^—ª«eÓ*‹sÆ%³‡•pî=”yð jòjðd±_;¸N¹™ +¨sù«oÒ ‡&:.Ï:ýNùà/ñ”²WîpÓ0ˆ]cÿž |å#¢<"KciŽ·aaȑ؜3‹pábz•§¨e\e¸Ü­$màÿ Z°%=Ÿ±›±÷—<ªy.ºõ÷žžñɀÖb†â7b%é# ê2í¤žUl·4‘ž|x)U÷‘Éœ%퓧¼Ê‹ZRB°ÈÂâôügà_ʉd)ÿ¯•ibŸd,KÔ;ÂȾŒ¥‰´Ù9â 7|©|œE¾Y÷DÛz+Šž(RìJàÄ©WëÕ;®‰YŽõ»Ã‘îu±ú*·¸é¬Ô~ˆ—*þ¸xy\ÇS´>ü0®åþ.J…Äyt¦öé'}¯×ŸŽ§–ñtŒ3Ð\ iã~~ö÷Ùÿþjr—endstream +endobj +733 0 obj +1331 +endobj +734 0 obj<>>>/Annots 187 0 R>>endobj +735 0 obj<>stream +xڍVKsã6 ¾çW`riډdËÏx{Úv»v6MÒÙ鑑 ‹­Hª$e×ýõHږíxg'Û$ñø|øÏMcú+`ºàÿRÝüôr3ú¸‚b/5,èGu÷¾ª¤^ÃGÙ¢ßuè@èŠW­ûþå/R™AQD•l²¨и…š5ÁX^Hµ¶ÝóVÈuã³ÚØ­°UOÂ7$â¡ADC´L+ì>™ñ†"qQLó ÃPRa0Ÿâ¼ 6NÕ¢piôæB˜p°mdـ°ÆíÖJïQÓ.}ìL}·¶¢B†Ã&!'SÃÏ<>ß³[àsRu-G†ë•…ÇCÎÈ¥ôÍ9ÌoŽçíXð_B͸Hòz¦6B_ŽÊ¾»Ð¬¤ÅÒ»Ëá žB'F)$T5óá0˜ï¬©ú҇Ú«èT …÷€ù:}ŒaÅ.ˆƒÙd–Ω]Ò;†ËîÆùÃéé1fÁ΂å~«®)ld"e"Á¡§*’&€´ßY©Iæž  ±N蟉Þ7ôÅa\@” +3嶆ýV|ž§ó¯ñÒHfBÛBƒmÇ<é,nPÇD°¶•© 1\©$®o%ë-K®¡Ü —'\“EÄýY—¬”1©„ìDžtъö9ï÷t¥=EÕæÔ’¥Ul ]: ®VÒsÎTèJ+_‰ê(l+¹ è3yµlDGÈr8@iÄ“·XŒÀ"jý€Åã=[™Àïýòr3ÎÇÔçø£à§_aV,ó)Ìæ\+³Å*_¦U ϱ î 1Y®¨`³ù<¦‡yT¢sׂë>^Èç‡|âóLÅ®0“ïÛ§ojˆW=Ñf³‚ì+˜ŽÙBX°›K၀‚Å4Ÿ¤-'±8ÜÄà-õµÛP·ƒ­qÂ{—Ç*'H6YEìñ>Á+¹/>>~CåÚùdœ­s¡JÚ½—­ü±3E™pÁƒLæ:,e-Ë=Áƒ+œíï8Ջ:ùÞ¨2¶ùO<m‘#‹kéhEußHÈw0¯Á\Œãò¢k{Oê=ºëä‡£ú;¸]×ÊRxºï£¦ÖA‡™Œ‡xÓt·_i'8Â)[K„ÎÑ8ºÅ%Ƕnw?†#¢<Ñ/¸œK¾®Wqнâiüƒ¬¦”¸¡œç"×K/^S‰ “Ȥ)4¯ì µ–ÿ“[Ðç­N¦Ç)÷®-ðÌõ]g¬gÎ@¯[©$wÝ«W¶T‡ÄI½‹’´èÍRµüDÙ CœBßUÐÊ¿ù}pFµmh–‡©t>òÑÖig½6¬h¸¾ 1^WS{zTá» =Vh`¥? ݋6æÜc—½î2þSÄ҈åɒÒþ’V̖ܼVÓ8ÊN]ÁûJI-ùYGoŸ dQ/[NƬ6Ÿðæt^PË;“šÝï7ÿí»G¨endstream +endobj +736 0 obj +1110 +endobj +737 0 obj<>>>>>endobj +738 0 obj<>stream +xڍTÝoÚ0篸G*AÂWî±Ý¦MÚ4¦2í¥/Æ9W‰Ú(ÿýîl %Zµ©ªˆ¬;ßïëü:˜Â„þ¦°šÁ| ²Üoùç;˜M`»‡éú6›Árµ†m1\Á6Vi¯ô3•/á‡/ÑÂcç<ÖîfûB ˜N¹s[ÇóŌ~¨{[*²§–´j‡Jso á{aoM ²RHß.Þ +¾Z‡ôðmóq߅„#0~+]˜£‹í‹1Lhö<Îl¬ñFšÊeÜLW ŽJæ³la!Ü §d?•ÌVْK~mÀï„ÃŒH¾n6®3 twÂ!»¶iŒõ.TJ¡Á¡.àÅìóômQ¢:`*.e­;Ó&ͥѥïM%r$öY}Ç6ÌF|gRbã/ bq¬ƒ=”Œ nQÕ\ܛ[߷뜿0â!.ÿpïlF¥jåÉÅ}«¥WF‹Jù. ¥»ÆÑá@—Qº(ã<ƒEc O)Uü®A©öJÆs´nÔcS)çCZ^[lIT/|ëFÁ|J MõåK¹ðlwZ2i¯ž[+mè< Óð‘a‘ÓÐ22&:».­Îu`™TÝÀZè–Óuž…€B– ‹Ã$’ ©Œ”y< +h¡þë$‘Ææèe®4ú"cæ}Pls\ôOÉÑH++ +J߇DîŽKéÝÏ‘y2Çy*¥—@6äÍQdUyël^©]Îbä…ÀÚè< é£÷Ž†Û—IÕFP$Iwÿ¾Â}µèà lGnCÛÇ˓ôRš"YU![§[_6h±ŒôïþbµÈÖÔCÕ·s>ø´üü³ôendstream +endobj +739 0 obj +743 +endobj +740 0 obj<>>>>>endobj +741 0 obj<>stream +xÚ½WQSâH~÷WtñÄ֑E|s]¼µN‘“XnÕrC2Ȝa&;3åß_÷L‚âݽܕ%IO÷×_w=þ8éAzpzN¿Éúäs|2ŽOºá>ßè\„CõÃ.œ^ŒÂs8â‡æ°¤ݰK–ÕšG7èõ ^¢÷ó‹!ÄiûA&vª€Ûp`iÊS°+a ’wÀpIß9|Šÿ<‰nºåñ6¾´é¼}1ÿä_T~ېk•pc€Õ|}šÖmx‘,¥óB)ë"™±|}ém{0"Sd!èÂ!~YƲ tŒ'ñø± +7ò¾¿ß>Þ~†ðZsØpm„’Ôî„,~þq  AI­ü{çÞâ´ô˜‹ôàHۇ…ïˆZç2£Òæs$Ð>9bér¥(% K&2S‚AoH!Êû´Oî¦ZH+ä XwÓ/0ãšR:dÃ÷©Ðþúi:£ZlDÊMS³<­—cÁ’Wª÷Áæ‡ñ‚3ØÆGu´: ü“Á΁”oöÒÓã-r|Œh9 ]ö2мŸH²5¯ƒÀxÎ3ýÁª  $Æt‰û£Ø"éGIù—u—°RÆRDê·Û)õºÆF­ÊVâS¾0ޑ˳¢ sàGÁ d–^ûç¾gïE¢•QK ÏB¦jk`¿Uç]fÄ`!S MÚV|=ï¾fÞδBˆpÉ'µLöDî&qTÎ¥óÚÚ;€DI«U9“<£iÏxâ§ðã¨Ύc'ÉDòŠ!jÁ}Ë´mÁ¢°VÉ®ä̊i¾ïØÒ¬¡­„¶ÐGÀ%³́ V%«•…‡£Ñ¥Áðäî!.µZÃ=KàaיàÒþÃ|¤ +ٗ8¥e)ªÃ¦Ès¥-¤B#Ù.„¯jË]ÛY×v˜Ҁhp5çž +µ^s|F¥Þ¢Q½$8`ìÅÍ#Cïê-§AoäsºVY±^ Wyžq˲W˜úÃ0o__Mëºë2£ƒŸy +œG¢íàçV?kAl—M=o×¥`kô¦IÌçŸÞ(ª819OÄR$Ì¢œ’šN±HK‘qƒ3Éў¬ky#‹Ä[%˜8­ÂHø¶Â®€ŠñŽczŸàPèB6+ÂmX;/š­vebù¦{ «¡q!É/ÂÂ]lŽ÷«Æ„–7é—Ê?Ùk@µnZäphTöxm- ¢Âè(‹ˆ¥"±‚åÛ£»ç_nÔQߺ=Ðw}Û({“5ÉIºe^S‰ø-M¢x´*±všï fÿ¥hR›DÈ ãÇÍþív2Žá·«h–+•}ÐØ±‡Ž©èr‹3Ն¨Z›ª_Îpâ C·/²ÆY²ÚKOa(ù£[JÎrï«ñr#štαÊÈՒ¥ëˆU£•Šiêîhl:åDíªZ$Jã^ʕLéI5]š‚q›DI‘›(?Þç^¾”ÞÕ@Kï¹Á]OöÔPMÚà~7mnB…LëlU‘¥)õŠ#øÊ?ž+G!£hÏ;·ÜA0…ƒÜ¢}ü¿Á|^»nµÊ·ð…›D‹œÔ©5Ðg%è]›Ë‹Õä!_÷\¹¸ÇÎ'¥hùO l¡ð–L— öÁ²Ð5ى˜*üâ¤K”ɘY¡ÎÎ&$8g,!àe|t/üõÃküŒ®ñïGæ|ೝp{#mÿÓ¬4÷–, éDc[×zî¿orøWmí_T0"¼óљ¯¶S0˜•ˮҵÂXÍпA²dÁœ<þ\0ìwéØÙ€žû!ýãö÷—u¬ÿï'’“$îendstream +endobj +742 0 obj +1360 +endobj +743 0 obj<>>>>>endobj +744 0 obj<>stream +xڍS]Ú0|çWìãU:>Â!!•^[µ¨´äÞîÅØ›âbŸíEêï:ôŽª×)"ñîìÌìäiÀˆ~ d)ŒgÀƒwù þHoÈ :™Í3ÈÅͺÝY94oòt>éÏoÀí°r¦…FÕ¥€R©”ò€‹P9‚;_HØÃtM>>>>>endobj +747 0 obj<>stream +xڕUïSÓ@ýÞ¿b ™Qgl®)´ü²ŽˆÅaF°Ò¢€‘k²¥É]¼»¶Väw/ SL,hÛ—Ëî»Ý·ï]¿×BhÐ7„õ¶ûEiíÝ Æš° ƒ‘ÛioÑ*~᱉Ñ,CM2Æ<ºA³ˆgÞËÁ5e4 ¨‡`Ë¥¬=cC!™»€‡ûåg85ü +w€ÀàZ abPƒ6AˆT&ЀʬPÒÀÙH$(yŠ+0›aÐ^`+àúj’¢´Rä”mÆj|ÊE‡„ãTDh‚ (%‹X4üÛ5‚˜ÞA»`Ç(K§BñÁh¬À“hgJßämœŸ{§òFª™¤•{:â|êCO i©»©à°¿×£Þ*ÌÂB£ôr$*}î«$ÁÈ.›­öãøìøÍւڎ¿ñt÷­G»_ƒh!s›Œ´JÁØXÈÝûŽù'y<‡!¢¤'/«-Ã:¨›rÍlš1ß2½ª‚¢•pÕkná ø°‰Á•]õ– ’ ¤cҔª®'Bâuû혱a‰ˆ'i:w² ²…ú«í*fxÿ¸T–·";؂0t9aMhm7 vöO{}諑q°§49c5·ŠuÄå„' nlR^}³Ùpi­Ü±ë­õ`òÜþB^9A·w?w“qÝAísí7Û÷endstream +endobj +748 0 obj +781 +endobj +749 0 obj<>>>/Annots 194 0 R>>endobj +750 0 obj<>stream +xÚµV]oÛ6}ϯ¸ËË –,;À€%Y:˜;7vQÈCi‰²¸H¤JRÑüïw/)ɎÓ†Á€`I÷óœ{õí,‚þ"˜ a4…¸8»Ùœ…ïÍ`“â›é<‚MÒ[i!­;Hµ*೐‰ª Üæ‚Kk.6¡Ï¢Èûô‡³`J^Ÿ3‘s¸ý´ZC¢¸©,”Z=‰„w1LU–J[H„æ±Í÷—`3Ži8‡õõòæŒJmÍ4‡’ŏlÇ]¨À¿¤Ì˜/CÊ÷ĵJÂ0`ÂøPB šçœ*mÂڌÙ6¹q5ðEU3‰j™+–4¦Ôó¥ºÛœ ‚F—ˆ.÷¿#lƒ9ÇÝ]kBóÄCï |7€A…ˆO£ šb홵åUÖuVlY ôε׹:÷ê>èÔ±’©ØUº.UÚõu <Öaá™b{Ïۀ¼žØCȐ6&D­ÌY̝/ÿ[7e; ±* +´2dz„*-a 6sÞ¹üÊç94ߎƒ1™w!¸*Oê¸K$íg̗ç;%ŽûÜóBY•ÁÀ´h!U [ìc‹Í ÑVã¸ù¶\:zæþÍ^UÌÞX^¾€ÃôGC_h·èÜNðšk¼W·ÀÍ?U—¶›}ï Bbn6m­ f{œïM7ºxOmùiþcõ­U±Ê©jzF Nð÷}¸fÉâ|s» +߯ +Ÿj17çmŒ®$@· +)>UY(”&,é¯Í„yuæ‹`ãÑܯC4FÍ]»x»ð#ß,£Y!Ú}¹2=ìûûÛÐCc€3z¤} Œ8c%’4Ð §žB]öEÈ:•ЪÚù9]ŠX+’œ†VXrcHunr?ÂCï|½¼9¸èH@%jŒöÍ%n_pâߐø%‡½øÐý=͎õÈß½IF³ÿAÜ<®þKЕç:Uy®ê#)i"z©¹„¾¯u&â P·L©TþÂÊè0ېd#Ü"p\&!¾‡»›»ûI+†ƒ#1tAzÑÃÅ©""q;Í +xÁaCeÚíÕÑ3wð§DýDmŒ=q(XÂOÆ¢QÇGgDlps’Ôi”‹ÝêÄ3ôNË Ÿîߛ×5û#>•~Üḗ¡ŸÐd8r’]YÏ¿7“iîUɌùõ_F?8~Ïü­ÄuIOI£@ 9R¥d¾§³À”<©À'"=|âµ2%Ñ4Å£•º ìÔøyÖ#».Nó‹Ôíð¸B*5ÿVáNMÆåá=: >lºó€„D£¡Âc9xÖ">>>>>endobj +753 0 obj<>stream +xÚ-‹± w¾â:´B©¶«6º™ÔãL¤4˜0ý}EÍ{ÓåîIèg |—·ä ÈæÔ‚1 V7e…¦¢j…îÚ¼N‹ #öÊgb +2ùq–î%çµxâWÿlÛfÈkZr|AŒKÆMÐÁ[܌S~‰èf3º³{äBÞ8•+endstream +endobj +754 0 obj +135 +endobj +755 0 obj<>>>/Annots 199 0 R>>endobj +756 0 obj<>stream +xڍTÑnÚ0}ç+®xj5qÒ§±–1$Z„ÒJ} ‰O!Îlgˆ¿ßµ +¥£š'çž{îñq~7Øø!8àúìߢFç{Ž ÑHеðƒDéMÚ0çkµ…1Kh.)ô7‚ÒÍÕmôË’@¶‰ZÚ®×C,¾ç»Ïañ4z©`¹bùæ©èî—„h®0°zÐv˯ˆŠƒ`›­†AÛ±mVÄòP«› +ž–‰’šÈéZžÖSéð<âèfÓÉ,‚çÑ` 3˜GœØÓpÝ(¨ñ?&ãñër2yhÁcö:î?= Òwý¶KPÞbÞ×Eݞå¢D;aÍ3ǁîà ±\¿k…¾íjÜ jØ +6¢/³!8ØËÇÕVïÀµµÞj•Á\ïéð+Iƒ]̲;Ð|db7IYÈ6Ë×ü«þgq±ù¤±Î:ŽcÙ¦q€üÕêØ¸.±ô$M‰«…,—Ë«2¶JwÎ~¿·Îu|d4™ñªÌò¶V6ŽrUm#ãùûDØ:m)|’¬SUÏdÙ÷×ß󓪴àí¦y¿˜ÎßUzù¼°ùvÛ&¡üKi +ežR +õ Ÿ0¤9qÓr•±äø*n8®_ç û§c¤ƒ8OM혭D,W8´àqUтg*$šŽ}Hð _k Ë*¸„5Ï2¾Ç»Ìœ»nÍÎü¶ŽÏN‘ŽŽƒèVEƐJq3 ö úÓö0J[ñ$VhË  ©ÐY®R&h¢¸8 «j%/EB/Ô¤L*ÁV¥Vc¼8‘uJ):,O²2¥Š¹¦ÕÀ&ê0™‹›­z!3\qqvƒ7aÍ2œ£b¾è¿b¹vý\†¼æÊ?LO©ÉÀù¤çl˜3„Ž«¬8BŒ¹FþÂ~˒-|Ø©U,uÄ +tÆ´ßr©d"X¡ kumãBE™®×]ðÁà ‚ð4†¶Ue»W2O¿yÿëÍïBm î†ÇÎÏÆ_FÎÃendstream +endobj +757 0 obj +772 +endobj +758 0 obj<>>>/Annots 206 0 R>>endobj +759 0 obj<>stream +xڝW]sÛ6|÷¯¸ñS:•)RßòSì:ö¤c§nd×éL_ ’P“„€’Õ_ß=Ôm%MÇI¤·w{‹%ôõ$¢uüg'—'íëE=ÌðÍ`4¤‡äݵ6äÚJʵ£™ÈTª„¡µr ܗtóé‘nîo[þ"U±Ì:VÅ"M7„½¶´Ñ9}þÓÃßÀˆ+ŒÎ(èÐYgôè¯Î`He@]Ä»Gä⼿<ÞOÈê™[ #I8ÔBñB˜¹ S†tu‘õH¾+eQÓÂIZI3Ne륒–ôÌ#mATŽÏ…‰%€©Ê…ÙÐL›ìÇ'2M¿ …´$(“‰4“²Åˆ–Úb¹ÔÆù€ýÿ»é:ñÒ¨ÜIC‰Q(ΒÈš©Ôñg·¿…Ý’N©Îç$lMG¬°c)x+¡R1M%cƒÑ®’"OdY5Ôá >ƒÌ¶Ó~b·@žZ3eÕýºêDƒ)H®ÑL)¨JO”è²’gÉrÈçL.¸LЍ®0¸F”o„[D5yI€¨FÊÙ÷èKjª”νÄuáöûèOg…u P¯T"ëoý ó år]³ÚªkjUE)Në+B! äz´-_(š,yöPSY£%t@+ç½åwLG,ƒ¹ +WÊ#ÜqýPmSjd*^˜ÜÓe@Ÿ´Î§…™çoD4Œ‚Ó7è »¿Ø±7ìà’É˾E^€ùû™Ö8àٚ¿7‡Ý ¤þ…fÔ @ôâkÊQC¿rä§§§£,œ[ž·Ûëõ:Ø«¢ýúÛoϲ}=ª<Š"”1„e«¥ßmwÇE’©œÇ$ÛìÈñ„ñgÔ¨7ä%ÃNÈËÞGzø¡Ò¥ðõ)dü~ò/§/±endstream +endobj +760 0 obj +1383 +endobj +761 0 obj<>>>/Annots 209 0 R>>endobj +762 0 obj<>stream +xÚ]QËnƒ0¼ósl1^‚€äÖVIO•ÒB=:N1!Oà ~:7îÃpžgQsDv<å2č/oüìš*ñx$¥H¼ÆÕ-܇ªo‡Ö:£œ6/j˜Tç%7§ÌÛ¤‘ü÷`q‹ ËiBב_ƒ_ýŽòendstream +endobj +763 0 obj +319 +endobj +764 0 obj<>>>>>endobj +765 0 obj<>stream +xڅW]Sã6}çWÜ·]fŒ7l€ö v`g;얖ÐÎÎð¢Ør¬bK©$'›ßs%;1t2Cléž{Ï=÷ƒ2šà'£ÓÿæÍÑõüèÃí%eç4/ñfv‘ѼxÿùÛ#}¾ùvóçÕÝ?^ß}ùDøÜ|{¸9žÿƒ g”eñÂÉô<ñ•¿¤uÊhš&ô[«%e——Y<<¡ËþìYzÆg?™ÕÖªeåqêâ2 géÖJI¦ôa%ݚVÂÃbB_tž²)XÈ&é[ø“²YՒîk‘Ë„Zå%žNº6Îóµ¯W4™fYv’NÎéñ᪳1Í¢Ç7ki·®*G+iå½,ÈÊá ]P¡œ·jÑÂ2Î.àN3òG•tdJòÌÔ*—ÚI*LÞ6Rû„p™òJè¥ÒKRž±´ñ$êÚld‘F†.÷t~œ°Ù{+E³¨å!Û³È༒=˜£ÒXj4¹ž=þÒ©¥ŽyñŒ‡±¥­i-• º0 ¿qU8`ƒ— çt½Ú[á|Ò|šNØ8¨CjiEM÷í~Ð]8ÂSÚK]DÜe+¬Àwùs\~7ÂêÃ99Á…†Cp-.± »HÈ7 î;j´˜Òœ3ò†Ÿbµª9ql˜™3å+q¾¥ÈwnÀ´ +½%ƒ;–VÖ,­hhSÆi}e¬ ôÅ'[•ÒÓûӌcŽFÞB~wn Jð¼ØRŸ•;µ°Ânß̎v^Š"}:¡~7-åBZ¶ ë¢q ž˜¾{þ]IM$c%Å3×@ÈDïb¯ØU+Ki-G «’P+ ÇRú@¯{ìØÀÈס®‡¢ž]¦J¬£DbÔñ¾`_8‹dtZ´Ë(&®ç±¥]Ã/Re@Ú(W='{h+s©Öl´µ9C’`‰‰]Jª¿»‰šÀ×ÁU>Ó|£Ø´Mˆ 1°IMZnb4}¶~²ì?k³Ù¡†ã %nœÓ¹a+^æ> + ´ir©å€t+™ÒœEé"H[¨‚+{*³.uè7^´Ä1p½¸g~5.:ÃÉ´Ü>lÈa¼Ã¥,¼ÀDcqµð*—Ö 0+¼T U+¯ºÖÈ.tÄ¿&„W +/a\ï®6¦P%ׯ˜±[œ‘?£äÿpZ^‘è“J+Šß¼ +Ą&F¥„¡Ù¢3-Õú5M@k +†5å¶·'ëe%¤ô½74ªÜ؆ªNvºh5²°“q:B¿‚¼vº +ò…¦f)wÈŇ¿T¯¥ƒ."_SªËWä7P„—+÷ +4{:£9n/óÄzz?Å S¢Ût²LäM¥À>“9®j>ZË%zOX\Øbº- f¤ BâCºªhålJÁ9CS£‹“ØaD++ôƒ¾²z-‡,É~Gi¹&œÇ5·Ë_£h´5ËCw»kc/[]J_ʃ‚Rq˜8L%†”µ‹óm%œÃ+Þ©zg1fß$"é²?7½ØbgîöÆ7H¤Ò¢N¢VpŒ§(8Ââӄ=š¢Í£Sa.²* v8/kgn`¹¿ï ñUëÃ=Ðß-Ÿ¬·I@¶QöÕWØÄ°ÏÀ lD̿ǀ $uä­ø5÷(è˜'Bènk£ŠàIÁ-݆è\ÞI‹ôñ=„ªt¡ÖªhÙC2‹ Œˆ¸[ÿªÏC‡9[í̌PñCWz, èªÜë¡0d²’Ôˆ‚AÊk)ì 58ýb·QèPßujã9eì8ýþ–[ðÁü ®CK»Fæ²±ï3—&âTg_RQÇy\–JÃ[v·c_tKtvvgfg³è}z¼دZWE£4!+_…õlà$Þ;9Ÿ†}6凧ÙM~þÿÒÍü菣ÿendstream +endobj +766 0 obj +1444 +endobj +767 0 obj<>>>>>endobj +768 0 obj<>stream +xڅX]oÛ¸}ϯäeSÀuã4MºíSÚ¦½Ú4Û¸¸X /´D[¼+‘^RŠ«¿g†”,ËÎ^-R‰š33gó÷ɌÎñgF×ôúвêäÃâäÕçßi6£Å +o®Þ^Ó"?ûr÷“¾ÜÞÝþ¸ùJ÷??|$ü½½{¸}±øßÉ9½œ½ž^ðÁÅíots÷‰>~¿û4_Ì¿ß=Ðçï?ðßû?çw_&ôiþ°ø1ÿð“_ÉÁoß?Í?Ï?Þð¶öêóerñ†^^\M/Ùðù”øåÙ¢0¾šLÛ Im6¥ÑjGʶ´ñníUEΓ« íiëü_´-LVPæl­Œ ¤ÈºßÓ¦T™ÎiÙÎâý¦õf]ÔìîûŒ +Wæ0TkìšLM•ji©)7¡öfÙÔ°ÑX>Âfjí«@n…ÿ Î/Új¯Jºo–¥Éº°§´ÀÉÓûíédáR—n;!¯WÚ÷©…9 òãÌ&x“#ŸSIs©"qVÂèlS¥rÖFàÀ?#_÷;‹ìY˜'U›'¡‹yõÐP©¶ï`EÕd$2€‚ âÙ0ƒ4ˆ–G.mœ¯ J¦žtÁ=i¿„ë˜Qår³2™â³S}…7µG>¥bЍlb¥Ke׍ZëéÈÛãÙ´×ƪ*3é?g÷HÁجlrØb‡®A‚¦2uzmû‚Òé0–Óéã ºU¨Gë©ajœdž{¸ *ÐiëšÓ.°®Ÿo2Àljî^—Š£¬@ '»îâP¸ÌÃHyÍ]Œã@­ëáÝ\¼çÈ[>5 + )“#Þ:P€¯ÔŠ*«¹¾±åƒQv„dNØcÓñÛ²•wÕ蓑×.Jg˖ÌJ¼s·hµ©1F]#kdz<3èōÆ?V‚-ÔǺÔڎÜU +‘#é<¾˜Ò ÝáÛØ7f1Øë–Ÿ]çN©ÞK¦…®~³ÄGºF+'Ðìxa×Òx)…^ ÿ†¸ÆgÌ=ˆ‚>ҙæùãÉ0\úvLH•ÎMSM˜ ž 7¯dÂß2–“5® e éÝÆ žl˜†BÁYj%œ(1O”®ýDš)ìT¦ˆÈh«<†ªnßÓ_Zox*¹TYJ®ñ³cJcÞ¨÷HÜæ#¯r/–A[ø„&§#bÍ ñã8=€Ícî¨}”ÑU’fGÉÉëx^K‡NÚ|;žÙ¾Ö…òkî×få"óoŠ6`>Ënš„j¯çŒAÄÙi“•X4`¸IlˆÃ£°º”¹ÖµÎ:^Ò¿]GßÅa^ŒúSø£# þx[v»`ÄÒuÑöWÅtv“:nÏýÁ)ÙhûŸöÚ±uú²Ÿ ·¹›U‡í§c+ƏšÍx{ǖ.ÞL¯Ɔ˜5üª|ÁÄ@á`eÊ(82ÔF +D˜“ºN¼?„vº©”ZåÝö£@½Ëh®£Ôص{ülWØ^R&„Áëý°°iö'‰÷˜ç\)oðóFùz§øY—U¤ç?¦û®]؏¢v« ㉔ö£,A•*Fª› ^àe9žþÂø\ìqs>'­:-ñÙÃ4K™Õ~é:ùdÑÅp‹ ¡UΨª“?¨ j÷2“å¶Ð–wÈ$ìiLÃaå4JïY™t›‡ÇSÚ|`™Ä„M‘Á¨ó9ä‰g~k81¯8Ï„FåÁ7½µ®3VÜwQÃÈTî19åî^ýÖiÍywüsÌóx†Ht0dI÷ –†ŽK›NCÅVÆ ä ùÊԃݿkÅC ڕ¥¯ôޘ&½¡Ë²Ûål˜ +·e¬žŒÞ>Ãð‡JðöW¦…kߑ٧<(]®¢"ÜU +ñÊòÔ7M,”õ_ 3‰\û¼¤é¥Õߍayԗžë80¹)MŽûYÏî A)}ZÉÚã»PKiuö=/îwã7¥9Òd …×j‰y ‘XÓ`¡nñ‹éÈ¡>ljä÷’ƒRÁYØnEÀ™±¾So|8h 8w)»cØH@W¨É“ÌXÚî•6úc)œµìÊ. R“áQ";W/ŒÂšÒ´À3_cª|,È읨.^þ¼ ·ª·|Ÿ»É!$تªˆó›²*ãv»¼ÆW/¯/Îÿÿ¯b.¯/§oI^½æ·‹“?NþZËendstream +endobj +769 0 obj +1826 +endobj +770 0 obj<>>>>>endobj +771 0 obj<>stream +xڝXMsÛ6½ûWì­Î ­Ø²c§íÉÉ8ifÒLZ;‡Îø‘ ‡´£ß·H‘âL;ùp‘»oß¾ý@¾Ñ)~Ñù%ÿ.Û£7wG/ß]ÐÙÝÕ|tùúŠîªã'c¿:Z '+2šüFÒgkÖV´‹wG§t²¼\\ð“4‰ªR^]P+­$±^[¹|B¦&¡ ^·Ä& ÿ>h•ž”ßÌ§"y<;_,lÜ¿àA¦é[|“óƊ5>Xª”óV­ú¬••ê[ªŒt”UzŒ´‡\öºBüˆ+MìûrôQ•R;ˆ9‘#5ç â³ãLO­ØÞڂŽj‡Dî‡,hŸòEò|+Ë}‰8¨]=àF+ŽŽ±ï±ü.ËދU#©6¶€÷Ò¶ŽÁ'{r`PK+ó(©³æQUpî7ÂÓØE㠘š´Ìè©MӘ'ø±|µ¸Ü}' ×eiÚNè-"Úe›ÏéùÖJ×]qZQn”–'VŠ*ÄàLoK‚-èi£Ê µ½ó!êS°=º[É »Õ;('©¢„iÓ +«š-õœ‡ÚäŠp¦öOjW–ˍÐkù;òPŒ*ý¤Ú*ï%—I-mA¢QÁùF +çÝJI[)¬+ÈZ+`e#ž­¨Öo‹øJ.€²P¾6ÔËJšÓiÁ" ƒ‰n³uª ¢ì¤e™0÷‰êiµ€:d*ãa/SAäQ%YRg9D(ϧ*óóÿG?IÕL>å³jUšIŠ ÃÊR" Ç…îÁ™ä“ŸÑ°/Ù / ô€;î)¢T O0|D}…~€À8&m4¢Ý–J4óÎÆÜ„çTÍ 3GÈ ¶Kg¯›PÞ>®GىQ­xK€&¨¿ÍüÜö+—úÕ*&jqÿ"Ž!3vȻͬ´£Žcl¥@ª#J 6f³´âç[ñ5´ S©jŽA”_л½ºüIll¤Ø5¡)”èÄǎŸƒÄ9<ö ƇbÚ´J£D»¦w{.Ñõ3Hë<¨°\b²V:LNª,ŷӄ±ªó.ŠÁ°kšU5bL4|z` ûÖvÑ.èˆè‘S½b4v2¨G~/eË<uZŸZò_•J—M_Éý(ђ EóR$›æt2¡mýºÈÖ¯èªÃ¸ ½?]¿jâòVÌÄùZëƒkF~G/rŽçå°$…©•OÞÙZH×\ÿó-Œ„åòI99„zÌ3X`÷ѨªØ+>nÂèI¢çùçÓTçAªXqî[µÞpOIƒvŠqì Cnž6†6Óg{ÅÐ)îXf0[DÕðXÜwÁq‚MD¤,¥hÝf¨]Î7“ÍÓ&—uge‹n謔ݯ%t9ÁðÊ«‰½Y®寕ÐùX¤-.páò;\hܼý„+¾Ø„ÂjœÌ%€lq¹°ŽÃsŽë۔îgRŒoÐ_PÛÕ€p[†%˜i B09;ÖlÔJ1hxJ¯îPƒQŒW쇿ÁqL³ûR¼eîæ·hü™{Yp(,@卯‡³–ߤÂúd …C2çÉËüÄ}žOJ^¬")u˜GPÌñó¢0—Ñ=¿ìf>‘ñ=Q]&QÝž"ª•i|ö^÷3†ø#ŠM¡®´Ïå4¯ëT“<ć–1¶lƒrD15écwfo¤cŠ"¿âô±»ÆÍÖɃ”/hÚ^&¤‹÷“º·aÊ£aÂimŠz Óý’ùÄTÄJë†{æÐ²B55«ÒÑ箚yµv*íª$yI/9Í»¾ÀÚ³ç %„xè*?¯ºæa,‡‡ê$ “È.*ðå»×é?eΖK`¸üõœqÐÛ/Ÿoév¸Ñ\WhœœUáuô§Ð½h"ø‹+¼urµ< ‚½àÃó³ +ßúBïo>Ýü}ý‘>yóñÃ[Ÿ›O·7üØÍÝÑ_Gÿ£”$xendstream +endobj +772 0 obj +1744 +endobj +773 0 obj<>>>>>endobj +774 0 obj<>stream +xڅWÛRÛH}ç+ºò”Ts áRy2 Àµ`{m±,U¼Œ¥‘=I£ÌHxý÷{zF²-™d+•J,õ½OŸný<8¡cü9¡‹SúzNQvpݝÑÉ … ?:¿¼ 0þüö9×%¥*S¥Œ©ÔTˆRæ%)k+iß¾ô(Òy¬J¥sKÂHRY¡-DuNk]ÑÛçÕR–Kih¾†heJÒ&–¦Gba¤Ìؖ6_ÂŽéðäkÿ”jVX)+ß¾P¹%û(ˆUTâ·Üu©ËªÇÀhž„5µX‚R¡²½¡5l‡éAڒ\‰4´oŠ­¢e­÷½ʒ˜‹Âe؉>KÉî5Wga`ñ#®äÁê¤\1óµ@c×¶”Y…Vˆ ̓Æt‡ZcŠ +£mf­0^¹²ô„È;î +©¡Œ 12™ˆ%-d.1ÖcíÓQ‡µR1‚ ‹@÷ããn×£ÅìÚqæ#g`”‡Yî(úÌ ‰-ÜÁ(^é;r­Š&QaèÍQ¬sß©XFèfÓ°K‡É•JS×ÝfÝ:&ö-aÖ!;mJ*âö é£L£¥†lËag|w'$?ؒv`V¢TbZW\HÎQ/ùî%Á.mž®!c§:éDÒZ<üî{xÑeŸøS ›há 91§XÙá)ˆ,MÉüC†‰©,É ïJÕlæá›;ô±ÿ-­k7ƒÎN)M"€Ôžgc¼P¹Hi#D ¦4æù"eÉVXÛ]¸ác¬¯N=DÌû뉑L-$+˜%xjåï.Elû´ŠýèrÇ7yöxc;˜¶T÷¶±_s¥;^j"3g·5ó$‡ÑóîdŒC!¯™Fød'5•GäbP^ûïDBÂT¬ ³o.Ú\ÇëÅGcåªÆG;¦¤Y3*w;ööùFp¤c—ÀÅ»â­O.Wô.ÝT’î™aPì‰ã©."šôüU¥2·Jùß>͸-‹<Î<¸’/7äf …D’(€S&–Z£GhРˆU’H§K9u++Ž¡lCp7jæ@ŒÉÜó½EDWûá Yà +Aí0€œ +Õa5y•Í¥q§à.†mK ¢#úûÑ®·#Péèº>O>1—¥‰iì}ê¹%é(ßÍYÑðm¢ÓT¯š •½¥ÈwNäzʪnÖ¦Y“-Ç Hüš*»ê¸Úl¯H±®§ÅWkýQ­:·{s˂˜µ»Š»h €eÍÿºƒýzbÎûß¶@89ޒ*»]ñ\¸“d3°î ³{´šCʯ·þ ÿÜ2ßÙ69»©q^·LÚúVòˆô{nðe{k:|Ûh¸ñ¸µ®Î|¸o–áæ¾Ø!éî±øûêt|ÿJì;­xg’ÇܺMØñB”…OŽCæÖöiŒO!^ú®m `ÎâmÛʕ¦…©õ¸À¼7ðö(²roñÑ%iÔ;|—N€¿¼ÚWƒ?ì2½¹ëìRðáé^Y/ύÊÂs_ºvÀ9º»ª¿ŠñY¼ÐhL/ƒét0 +_½Tóí|rÕÂÙI³ëàfð< (|h2ßOO4œÑãð&͂[º›ïèæa0½z,7 X¢ã¨ ¨»ñt×"ÔÆîwðwŒBšÓ§aÂüõ+ &x\?ô8xéCæ&˜„z¾<#³ó—!¢…ÖŽèe: ‡£{gýf!µà¶‡@oŸog®ao4Qa”báØµ‘õM»lš†>ÒùÕWö@7ϓÙvq¦rkQjcù>¯Dê)åìZ‡§Ç¬v?z¦û`L4y¾F­›î²ðÙÅYÿ’œàù7~„ü57Ùsendstream +endobj +775 0 obj +1880 +endobj +776 0 obj<>>>>>endobj +777 0 obj<>stream +xÚmT]OA |ϯð#HIàBšÐGߞ/guo÷؏D‘xA¥HTTJÕ¿_{“U"ÝÝîz<3¶÷稂sùUp±ÐÿׇQFgíª +ҝ.-.—nO6ºÄÁ·ÐS0|b͖ÓÐ5Ðrr#´>€!±É 9 >Òô4}Ã¤º˜Î1u$ˆ pü!yÐÕ«ŒÿP +Ø£3¤‰u{~°ŽGˆNl}žBì|¶Í»Óò\4ԒI¼¦±”œ1÷TΓd8‚DkÁ‘]¶)¬Ù°[!Ѐ@´‚bzWNªÅôÓ+@5›‚.Ÿ°çÖ"²³êT «,ò¨Eë0X6X[‹ÅÅU ÙO$t8I^Ez¿aaˆn+4†màU— ó¶¡0.²áE](õØÂ¦óÐãzßp[ >óáH²â˜×9Ñ;¥@RžSZX{5±º\X Ou´ý€×`+Šc‘alnDE¡µ"Gíâ@†õEö¹{ÐîluQüÑAûH@iÅó9š#GÒhv‡Ö^ºöFÈØõÉ+1Ñ,UJ¢IdîÌ·>––o0¡"—gMz:£©9”ܯ䀩0Ñx¡sLÈnWl5J¶RÇ¡ÙMŠŽ•ŽM‹ls ø¶ÂÊK%4Aiù7Uޝˆ×§ãÒjÀ­d6ݾ'Ž0%ãÛæè¤À5I6kŽÂô0o¢€÷nú=Þ¾¥ãÏÚÏûëb"÷Åd¶˜Î]Ì)Ò2±Œ²T´a“¸‹ºÜGUó¥ð™UË饯Éƒøõt÷òçæùàíÃýãý¯—ç›—§ç_Ðß<þ¾ù±´7YÎÎ5l±Ðŋjåsåò¡Åäªe¶¤¨†¤§ô¥ÑÕè/0oFÝendstream +endobj +778 0 obj +673 +endobj +779 0 obj<>>>>>endobj +780 0 obj<>stream +xڍWßSÛF~ç¯Ø·$3ÂÁ†âÐ> ’Ò`šÉ”>œ¥³}E¾sïNvýß÷Û=I–I3À ¶îöÛßî~úç`HGøÒxDǧ”/.&ï¯Ïh8¦É ON? iR¼½ùôHw·ŸÏ?¥›«OWŸÏïèþñâîö__^}z¸z7ùOh8LGãÁ)_ýCû`œ¥QF¿VVÓðìl˜ÑYsödpÂg/ÝjëÍ|ééíåÓ;9K×^kzp³¸Q^Óµ«l¡",ftkó›‚…áÑà[ø &õrUjº/U®é*5etáBä{ωŽFÃáðpx|4Îèñá¼gæj­ýÖÁ[h¥ýÒĨ ŠŽrxHÊT˜½™V°³Sx´ä‡F‡ž)7£¸€™ÒäÚM…Ë«¥¶1#\¦|¡ìÜØ9™ÈXÖEReé6ºh" Sÿœ°üƅ¦™ñ!’×¥VŽ­ë –ÔÔ+¿¥›û»Ñ-[î9E¶ZNµÇÕMu®*8æNژ¸h-Ž›ÎÆ6FÿJ<ëT[|¼÷Z-§¥~I†ÓTà‰x'‰4sž–( …¦¸üWè`æ6e;ªg|¹Q[ÚºÊÓ L(ܒŸ„…œG!$ƒìý€.¶(^…˜5F Ì!0‰o´Õ^•t_MáÝ5¾°5c£¶EBžWÊ+|ÖÿÌÏzhM@‡‡¸°ä B…KìD+*É7% (9„2øÐ¾Íَ=™Ø¸kêûj0©ÕªÅ[·æJçÛ:¹ŠÉ¼×V=ÿwMÖú›IȰ¨ì–¼ð5Íh³p ªâÂùÜšÏ&Z è««(W¶þ,!sZ{¨­=Dé\? _ÚÒF‚QÏÌJÉÞνM¢×3í=wðë²eÒW+ü è7”ó;,èùÔec·*r´PëTÖA:“! „ÎbºÕüñóDž}i¿†_df‚´1añô.ÛA{k³f£•Ϫà&•4Ïu”yRߏñ±s•ÏÔä…ïßà.ãz!‚<ÅÀ&-Y½IѬ¼›{µ ¿$f4Ɵ­Û´(…c„À8(ÉKj;¶uS›ÉìRK«;I÷šSš3!CBBÒ¦¦`2ò”æ¬k+S¢ÆK–8¦lxæGý‘ธž[ÞK ӝM’…=L ƒP¢odh2+<4SSšhêÆ.ԉ¯Œ¥zZgìl}sé +3Ûrëôv3ú_Å .û íÞ,´4,ʍ$E†Í4¬^…)<75—Á,;6ö)Écj—¨T”jÎM3©ÏÅV¯Upi+Mµ´íP5Å–ź½R®ÒØgø\³.m©½(Û@pdÍ(wœ'¤ÅMÿfŠÍL™†â~ÀÞyÉNõ€±eO_CU³ˆÌ"^9©©ZŒfsî€)²ëtŽïZÃ=Ã/éÁ½R{ ¥¿ðŸiÚ¥ÏpKÜL„º¿¶Ób\ðrƒˆz~Æ@Bnå­üÚ®>½ရa¸Ö]¶[J=§7 “/„MAŽ–zŽQ+**ˆ¦¨eTÖe.0ދâwàûѝ—,bþj˜Ö„óoB,‹<S&_3Cš®•RëFßUÜý!>´$HËÙº~\ʳ$ض;ÁÆOfm·èx.Ṉ̃éV1ê2$õ°R¥[×U–ßl>ÄQ—ž»®å«l Z9&f '‘ðZÁe-½yq#Ag`´ŽwE•'çdŸ³òCƒÃЋ˜•Ü?\º.B½ïßÀçUE.¼ ã5Ÿ,…DÛ½µ‘”,ô"4œ€nã*DhIV½ƒVü˜gò-P¦ùڙB<)¸Û¼D×s™{MYž…-A¸ö·°„kla0-*‘Gn*I¨­PåÍYqÊHƒÿH„l°`)2ãÅm#´Qö„‡ŽL‰+†€„ÌO0I( •\ªB$Reï;uKɰ˜¶º`*öÀf¿©éÉ+|ez´·”¼dôKõ‘¥8k䝦26/«‚£Ùh¨^îÖò1Ýö^¾)³³W'ÅF…èçÞB­°P·­ÀàÜ—ÀòBúÃ28½|¨ßG†'càŸž¦+º|¼ؽ`ž(+“FE³•7ØÀaºw8ýø+ñÉøo\rátÌ_\M~?øò+éendstream +endobj +781 0 obj +1637 +endobj +782 0 obj<>>>>>endobj +783 0 obj<>stream +xڍWMoÛ8½çW¾l 8n“i»=9_­4É&.йÐeq+‘*IÅõþú}3ԗe/¶H²DrfÞ¼y3üyt"^ãïD¼9£ÿ¤<:_½º~+NNÄ2׳÷ïÄ2}‘(¤6"U^¯ *…^9é´ò3±ÌµÇïD¯Ö:(‘ê,SN™ 2gKr%¬Kµ‘n+¬QÅJ _;%‚NÉTè `"«‹b*¤I_.ÿ>z-ŽOÞÌNɅԚ?‚Þ×%¶äÏfrmÖ´‹öz¶á%¾KO/wL6þ͚cOÏfoéØ%ÖÀº·Fl”Èå36 ¯*饨êöu±eÖ oq~|´ +g`k+VEíØjª}Ð& :[ûZÅvQ)(€6JQZ൥h`C¦)=)*g×N–„ˆðº¬Š-Žã¨ÃLÜhóƒžûerüŒn§#“ôÕÖA$¹4k6‘«n-ÅÔ8@ÏñîØÛYJÞ`¹4²°k[{NbmLt¦ºÐaoë"XUÀT2>Íë™øl7êY¹)9!EP¿PcK…Zã‰}š6~˜à ú¥’:ÈUÁ´“"±åJ5¦ÎƺpìuúF‘c›5ìЀgï¶Ã›OÊ(‡÷‘ +7 H<ñ\óu’‰u®YûƼ#n8ø< Æt€ìÿÙ#êõ¬Ku*Œ B¡Ä +¨8viÁ`o³°‘¨2Ÿc«YOÁ¸èXi}$Øk+åú3é[Ÿk.ðo +К¤¨S•FºoÈëF6±&Õ˜¥^çAtNDÛDö Ü©.ïµqʧ“¨/‘ÚÀÏXsœ9¥Zªx±±u(Uå(™ä-¼F ¶õƒ•xƒÒƒe£2FwÂħû Cí[jô`ãWéUñÜIÝM$Ë¥ŠË((Ã`YpË=Ë܈}”~Ùy2›\´J!ÚgBgk¡8´*E$’j€€ 3‰“‡ OgP}ðÃpI[Á°ÔºÊ:–û(§¨Ò§ß$²xÒ®ÜnX«’\+N£w¨a—úÆ0+MՇ³bBl«:ôJ›ú:°—— +DVÇrjS72ÜdköôRØç@} ÚxÚh¤ „ 2éAѶ.Jj_8u¢C=9I4U²íYEÕ@śØjËõGà4¢%ñ£…,ý­f¶(ìf&îåV$QY¢f ƒ{ûáµm6é{‰’<±’Z3”î ›lW0`ŒßY2c àt©ÈoC­àÛtÏ6 *LtuÔÉh$*¿"ÿÁHƒFB6‰}k…/.öªÁ¶1®·¤ìblï•õ^“Øž]#XV$PÐø²Úþ–ž‚ÕäN7q‹ÖWÈ(6bVaÇ^]èÆ¢>õW_ÅüöR\ÜÝ^.–‹»ÛGq}÷€Ÿ÷ß·Ÿ¦ârñ¸|Xœ¥O¼ðËÝåâzq1§ñÜwûç¾nL¶“Ø‹Vy¢÷ó5ÉääNª¸¤1õr߂ƒD$yŸDIU‹CDUȤG‹ÈéH²Gä¶  +ܖá’5äÕé°R€=¹³ˆ(Aؕêٍ%µIUœ‡bU´­ð°~î•m õé…,<ô +*Ž#'aÃäéåL\A+Ú-Ži +}$æC9&ÈɘWs1骡TÒÄÑçǁÄ³…±×”Í+àÊ@à ˆ°Ç¤ïhž•ÑHJ±mbø(®£G1O¤ù<ulǶ#Bu柃š4i€žPӇªL!¤µœ–,hûŒA¬ Ñ£ñ­HT&֏=óC +t³‹¹ÒMv_x2„_ƒ9O‰æ:ŽBR6Ží²Jpd $ {¼³á};d í@M\›n¦­;‘Ló”Êú4Tç–cãñÜ&‘$‘€š‚ íX?úW-׊ÚègÈ$* 4ú´GCyûkÎ>¼¡uââëý£xlwž–à&)F°å/Ò`š¥íÇq×ñ»Ó×´íì=½<={3û øÅ§Û¯âfqþ0ø.>]Ý^=ÌoÄý×ó›Å^_\Ý>^ц«åÑ_GÿüÔÌendstream +endobj +784 0 obj +1883 +endobj +785 0 obj<>>>>>endobj +786 0 obj<>stream +xڕWMoÛ8½çWÌmSÀñÆI6éÇ©éf‹Ù¢Û¸‡¹Ðms#‰*IÙÑ¿ß7CJ–eØ"@Kâ̛7o>øódFçø›ÑÍ]^SVžÜÎO~ÿë†f3š/ñæúí ÍóÓÙôÍü_¼¸J/Né‡m¨T-e¶nIU9åÆgMдÑn¡‚)ù¥Ñžì’ÂZӃY8åÚß<ž—u¡ñ¥·Ë4~皔§FÎ´Ùh2aB¦b·çt6»œ^0UµTêÜ4å„jg7&×9l« G3[ùÚdm|A©_ÕΨ ñ¤n…ñk²i•­;ìïFþø gVë@• HS¤Y¡L©G¶UΩ*´èY됃ʩ¢˜ã11:½Ä™`ñËxБéÊG“òlì\-¼®àN8Ý*",í¶ZÑքõýirrq=½b'}×Ê­ØÖRkZZ'gêuëM¦ +âØ>xÄà ,G·AÓ&+1à¥,Û%Ü…΃Îä;ƒ„¼AµŠ¾E’ÜN‹=æ‹WÕXÚÜ,ۈ!’⎋_0©µu ©.¬ÏÊàÖºgZ(‘á›Ã %c‘ƒc•àÈL@FväÙ±˜mª\G–ƒv¥à{LtÌH-ìFï$>rÛ ^Þ¢tÔ[ŒÐs9U¹oïùäÅÓëyjJüðtÏ¢DeãXðºX҂¥àí2 yšŠvηÖɚ$€Ïgªki +ÐÞ»€Ä3¡å @¯®B_>€¾+d‘B>0^Ùò=`ASŽ’íê#Šgç€×ƒÌ^¹]ÛBwÚ€sÁKå¬èÊvՁw±°Ë©V )0Å}tT˜ ál‡/Oøî—¬|•™Â„–‹" sÔ)Wºˆ,´lª()š 1ТR ¾©ë‚/Xœc¿ŒÊ伬œ*cÀô'8²øÉqrÃôÒ6ݪ)9µòLÕv­«½3düH¹¦ÚØgs¡áÛ¶ËG©žYo+ks接—¨ÂÀ1€²ÆiA5é8Ñv;w?·€ I\ +m¬Ä!]BÖd¯†ë¨Öºò±¬ñƒ‚GxxˆÑ&‰ Ãc¤¸Úúq_pºTµ^jUAØË¦·Ý§Ó¿€A¿(„“a&¢ê +NгRZÉφKÑY ·kÎ@ç׵ƿ*t²8%´Ì:€zl0€"¨‹²ûÙÀze(¸ñ´ÚY9ëEw@8 K´(Ñ¿@­qn¨â=™l’à‘S¤›R‚cûÞãid?f÷ŸÓ§7R”—ƒÎ6—Vš¢f™{Ó¦Y=Ꝓi&SBæ¯%äDbA /žpúˆZÑJ°ü€84Éá¼J#’_0(åÁÒ¢heå37Ê,ì5„Êý‘ÝùT:%ºûÒ>˜(Rº»&ý±Â¥©M@>£RÀÊëCÛvõ<~쎉Ù2¹¾mÂk§É«r঺ÒK\ã¿AYlVï¨;ܽŸ4ûw£ Wbµ?›÷ÉÙJôh ¥ñ^ÀñÚ;d¨ýtu0¼£|b­F§‘lÙ=¸áñjʸٴ1d§WÊå„‚‡hËÛ4n,sXAŸ”~À c_ØIûr7¾#Tš ï±$®»>õi‰Kñ™p»u&ÀNße¸Šñ݇qïSÌÂdèØÄ¸^´ËLš»q©–öVgã²<Ίj·ÁVŒ|Ó)ºKö¡–_[vïÑ[ó¸MМÁ¿Z­˜ÛΣªb%`¦ï˜ vjz:孎ŸFŽ3òô†(ÚØC4jÚëÔJ‚Ý£"ÞxúG ·%M´²†¡Âc/Õtl9º[_¾º[£7ËÒ;À~m0æÜTÌÅç/ßé³®0B úÊ®¬¿‘`$­òƒ› +[!_!ÍÕà^³K)Í-7#60Ùmªš_¸uM°ÜÆ×ø>íTÇ õ6ᯗ99Ù rßç:‘¯Ò[ êÎðF5rݛûve'¨kÁ2\°xføZg|/’€“ñƒÍ,ÂÆÜåS[ܓ1éÏØöゆ%; +.]ÕâHñ=ßI:o“tfW7°}ýî’íÓ§ï_é±»Q|Ìq`+hÞÓߪjTc9uvsqÎÇ8އûÛo¿ý Ïw_î¾}| ¯ßoî?áñ§»/w|èêæjú–äÀõ;~p7?ùçä?°«9endstream +endobj +787 0 obj +1681 +endobj +788 0 obj<>>>>>endobj +789 0 obj<>stream +xڍX]oÛ6}ϯ ö²pÜ8Iv{r‹´ µ]ãb(àš¢m¶é’T<ÿûKR²Då Yy¿Î9÷Ò¿Ž&ì ?v1¥_Q½›½úpÉ&6_áÉôÍ›ǟµÌo”cbÃõZ2\U¼ÀÍ8[«{©™0Ûýˆ)Oϔµò^Z§–¥d+c±–ûô†3ø$™±…ÒÜîÙÇOߨG©¥å%ûR/K%Næ?ŽÎØéäb|NÆo•ÚIÆ·ÛRIǼa¼,™«—Nþª¥Ó® VH«î¹‡GlgìÏäæÊšêàÃ88ŸŽ/ÉÀœ3[¯Œ&çk'WuÉvµ75Û)·!£´”m¹õ̬BÂ`ët}«––¢QšÜc[k֖'›ØSÏxW—o^}¸jsÞúu™5å8fßáNÅ÷ѕ®rÞªeíeϋÅ1r/Œ AáC'/ðXù«5î±;)Â+ç‹*¦YþÀ™Í–ÿIQ{žjZ¥È®—¶r´qÚÎRäÞ9ãK“Hǽ*dóAIåB˜jËõž³S~“2ZmKéefXàÉmdÖH€Ø(-O­äEpƙڊXŽʦĆUµól);ù)^ânf7:oã•,T]1}MÅ­*÷„“"€Û™•ßqKlÀΑ!9ÆnV_BIV½\7|Zîñd…Z!N¤H:×"/`˜£N­5§€¶%ˆØP›UyÉ~Õ({I$ɶ£P¢a8)N¨B·¯nËzÀüGDz§h¨ôô—0›¦ãÅIV³Ïä,†Ct¸ >™TõѶO3\6ºu½î±*øñ€ÚåC \d3ô.ùXj@ò°!/1‚?⨭ìzq½ÏÁb[.„/÷C!ôy¼;O‡Ý9©¾q ÷ñÐÎga;ä.„šiÓK_Ònžh°ˆ¡¨iàHÊqHÞ#½c4œÁ›$§a³©Ïk(6FÑøÖŸ•Ýâ/˜P™"ÈZw Ä‘TÚßah§É«xô*½™ã|ú\Öë5} +òÓ56è5áðAs5÷Èí +[AmQ 1›Ç®ëjY §gh BŒÓGÿ•4 +¨ŠÑ=Õ[[']ã"©ÇÁ›î{7÷Š:ä#‘g¶Q_ŒÃ{v²j½iBv dNiQÖiZÊßkKՄÏ+)+ ȱF_úŸ1G H:zGªE­µ CŽn~tœ+ šH£D.œäõÚýAæÎ_§‡ó1£›Ç³ötÖ&ipFc/?•å “3˜< ­!}´Ï@ è¦o(;V¶hiÝY?wÐ{ÉÙnqò'= +xoíNê=ö?wnää) +Pèv8ö*œ.;G©ðåIb +Á ê蛤£“Ɇ§o/È8{ÿíË»kΦ³t¥$q¡€ýÍuÍKZ~:¹¼ÂªÓ«ó3Zvu`1½¿eá}?s{óîëìëwöñúÓõ×Ù-ûòíÝíÍ{Ü~ýéîš\Ϗþ9úö¸/‘endstream +endobj +790 0 obj +1706 +endobj +791 0 obj<>>>>>endobj +792 0 obj<>stream +xÚ¥WMoÛ8½çW½¬8j’fãtoi‘vd‹n“.P J¢m¶©’T\ÿû}3%Y¶÷²(Ð֒8oæ½þ<¹çøs!—â͵(ê“wO'¯?\‰‹ ñ´¤G×7 ñTÎ +iDmK½ÜаVâAçNº­¦¤ßF8UióC+g˶PBÆïµ*…ú¥Š6ȼR¢°&Hm´Y±ôÉéÓ÷“sqvñ&»$oùL<ÏîƒÐ^´¦TÎkɝ |¶õʉÍڊb-ÍJy~Hö• ^Ø¥(Õž‚¶Æ‹¥®ð…6ãè'N7ºª„±AU(ï¥ÓÕVäH„âFbN¶n4ý€ Ù4•.$Y§—f'¡±óìù”\Ó³Ëë슜噠g³Û‚ŒJaÝX÷CltX½Ó© ‘¥rsñ"+]Š¥uéWJzÁ)%¶J:?§Vú%áeÝÁƒ_ä†<§4k”Ó²òÂ7ªˆÁ—Ç6÷ªàt®åIÛ5þ`·RÀé9r!M6¢Ðrø°ŽEÕ~‚k©}p:oÉv8=EÅ=*6ú” ÷˜ jY*‘o#äJT&J¼°ÍV,­k©¼^äXЦ’ràŒ»Ma©Ÿ­¨h–©%./å?Bh@ýô(³l¯¼e—Ó?8Ĕ÷ìZz!+§d¹¥¦R([I(“ï˜4šiph]<¿µ-Ž"ªtÖSì ðq‰ÙK4CûÐ>PI͈“sŽÌNq‹Õ ûW >{‡M?&Ï+Q·¨¾6EÕ¢0ÔÁ¥ ’õ«t˜ò °r²öà—*£#xr‘ô`¤Œ³™øÓnÔ Q€`‹%‘¾,TC}Ã÷¶uud©Žµ\’g¦ø(lÈÎ% Aö²ñÇǞg ˆ-kç±çڐ^ϧ‘µÝÎÇlûŽO‰ãÖ°.=Ï:AB?”3ªš3fÞ +k`§CނSDæ·>(TÄ@ët±žÂäZö·ò6%çÔ»–^UKjvVÝÕs°•uçS§@zk¹EÏ52©‡Q×*5%½u²ÔEˆÖ ‰Êxj'‚¯ˆâ‹œ,ƒ‡b7N«@¸UÜG1 +X.í$zVâT ¹#“Sp2¨W±æŽOѐ€ÔJÂ9ÑӋ̑Hç6Ö©N³ëð聬njÒïÐe ãÐ"ŒÜë‹nlŽ0\t¯ÒD‰o8I°²rt( ‹dAœéᐎ&(Ó/—=hwF—ðºTgùöŒþåñĬªÞà´R6ܦ±\H„t ߯j?ĊÆ.R>A^ƒø¾37ßgý‹&º÷èU#Q>u\ífLî9ŽÅ¿7{øËFÝÑ25 Ô2&²WÓvÊ6ô? éÿ k—¿g#õ”çö„4ÃG’ÇÅÑôˆÂÉÊþ¬ŠæàìXæ™x¢Z±$çjG¼xubW(µOá<ªŽœ<é²£ ÊGZ*€¦;ñ‚~èÕn?óÎáèÎL¼9ÊÒȈÑÄíwŽ¾Ï«D Þy ‹9 „9ƍ'M/$]ôгÔ~“vMµh—‰[”]¢qkØÚ¹ÛUþGX{\y±º#o² Kv\`êMkqs[¯ÖÁ‹Cñö㚠+O¤¤÷–´ëLü"|Æ¡F³ó8û‰”ûD¿¦³Md¤]š:~“jeiMôQªºp&Î1ÆÐ^¤ Ëv©Ÿ*-Mñ’þö`³`STý… +Ñ^ل‰ŒB§ 5,st†6VÚÂÇËžób¢*䌽‰všª+åë}w é.hÇkŽ7ذ#;¬¾˜MÌ`õ å“IS~­sâ$¨äFèåÄy§š”ÁLÙ¨Sà"’†‰¥4Ž/-~)Â篧ÛÃ2±?§ŸOçŒ%$nc]{Æp¨ŒQF혳·±ÓÑیH”Fz‚¢LwFÞÜŠy~ôNó’›ÀÍøy ÄGû +’?m¬;I Ÿ®c¿ «—õ8hbSÜò ¶ÑgLï=R0QI­Ó>×ßz,8 +†Uݺœ$)¢IЀÎîþÒæß»·´ò >PlG”5ÖZïËÖñXÜÝ9ÍnÂþ7Úá\AâGÃ4é(iL5àG½«M6á¶Ç.í5_O—2ø›ï.ƒnt{“+{ý v—±È7]‘/®ðýö Å Þýü(í2lÈçm 1#Pe°Î‹¿¤ie'5Ÿ:[\žÓ±Ÿ¾Š‡ûw_n¿|ï>Ý}¹}Ÿ¿¾{¸Çïï>=ÞÑ¡«ÅUv#øÀâ‚Ü=ü}ò/¦ >>>>>endobj +795 0 obj<>stream +xڅWÛRÛH}ç+ºò”T9&†,ìVž p-±½²X–ª¼Œ¥±=‰¤ÑÎH8úû==#ù"A¶  +,ÍôåôéÓíOFô ?#:¿àß8;¹ŠNNo/i4¢h…7¿_R”¼†¢ïxó¹yóž&« K‚b[ùo%óX’^¹•)é{•¬3™—¤ ‰4•kQ*ó‰B”ü\å+£òµl­ø`^“.7Ґ‘Ââø·÷¹.Ùõ'ú8:žq0©ÊT)*õΔµ•´ß> 8˜D±#Df$©¬ÐGa©Ö¬m7ҙ_ÖM˜Ú$Ò “µ‘»H\[eå·TnD×?|”F$*.ñVºDråFYzP±(~_S¢ IüWVº8VFgÿsw€ùl×·ÈÙV¢liÔ²*%YÍeÛUMVeUZŠ\êʦ5Û@FËTùXªrd|ä °'ÐҔ*ßF\fy¿þœ\&jêÄÈ©>¨¥¦&Q2†t  åO‘)pR̛¦˜©ªã|««4qvêOF×"-ë+lÙykHvèņK<h»Ñ8KõÂðJZDŠ%°Ò¦ãUå»wåÆèj½á›ìمÎñj+ÌÌ(ÄØÖa 4 2¸GhûT–’‹fäÊ•wܸ…eG”_¤6l.ž] ?óEp†ëXh³? Ï)ðgü»‘ð­ò‘ª„¹^¡Ðè¼XŠe*n8&â*†beâ*³ Tì)MK‘ò‡.?|hÎTŽŠ&¾UEQ¤õ AcÊQ5ó×.àIÃÊÃ(l/oÖǶ]T†Û¾—>Œ¢ UÃS÷ÉKP“1ÓÏî€ +£¹j2j½))N…ÊÜëR¿¢ҖäPU¸¡}loš{_ŽCÙpÏ2 œøA¼ðYò‘|í^3kÓXäÌöŽs«Wå–Åîˆ'¶¶¥Ì€¬BŒ,7 ÀE?š9n{ nœ2°ôÕa!5Ž#J4I&’®ËµÌ%ºÁ’“ÂÆ¥!Žq«t¤`\u?<.oÓL¬®m¨¨48¯„›#¹“ÜèËóBÅbOð‰/Ünȵ*ÚPD…¦7§‰Î]Ù(‘1¹áÞ5d7Žv[•¦r}¬¬>òŽÿ6ö½`6 8m!…¸x©ö#ȇo4ÞvÉuZô° 2ñƒïjçí§¹ec8¹^òş„žôf1C`˜˜M't2iGíû¡¿‹ltöÊØwV¸†ÄOYJ¬ì*/bdÿ³R²ìPŒ†üWẄ¯Tí@>hÀeÝë°¢vmè̔ҬØêÕHã…ÊEJ»C=a!c­/R>yÕ+‡–Hx +v¥ø'³ ¼ZK½6¢@?ÁÓQúnñ|ČO«Äw/W}—æ€ç´ãÀÑUDàÇYé–§w]U…g÷yCûyw2Á²7b#üÚqšÊc }1@×Ãp/T½°5@Þ÷í´^'uo9y›1ç=ÆD0rËCzÑ*Á-2I|Œ»Ó"»S^/k r¹¥iì~;ÚWðŽu˜;{Ö͖¥27hùёan}îlMЇ¸i @Z )@`^KšBé\؉Z­¤éƒ–H0|âÀ ÝÎÂNŠæpgæÌÿDÁ4¢y~Dl_=Óx>‡«ñÕŽŸ†8sÌ#zº¦Ýb±ç§ B]Dc¾=™ÒS8‰&Ó;gýz6'w÷ÝÏn‚pAãéÍé,$w‘æã0š‹ŽÑy8û{rsœý»ñù½£§It?{ŒöY…ñô™þœLoLœÙàŸy,¨“¯H-ÀÑÉôúáñqè +ö¦³¾.E3‡(5g[_Þ|©~oJ5ú| »œ³mº~œ/ö0N2•sŸ‹RËk}%R¾þÑßúxyö‰¯]žñó‹óáäÜMwyßÓ ?Ðüñ +%iÀ‚è䯓ÿʶendstream +endobj +796 0 obj +1902 +endobj +797 0 obj<>>>>>endobj +798 0 obj<>stream +xÚeTÁnÛ0 ½ç+x\$­“ é޲LÇÄdÉ¥¤z Öè°¶XÛa¿?ÒqƒÌE D½ÇÇǧüžp%ŸÖ X^Ã÷§I™&—õ +Š҃T®o֐ȶ1>™’¥=_AMÉcŒPáD6;ÃÐeîBÄ9¤}"F`ŠßÀDHá"ýœ\Á¬XÎʬwn³9±vÈBØoBÝS8*Ùð(ŽRûç›]u^w¶Öhmqª0Qs‹=ʆ˜´ƒqg@µè°Í íq‡FVZ¢\3Ֆ¢(=¶?#™‡7ÃÀ7ìcˆø×Ïñkz6 Lì_µì³"}2ñˆ¹0Åj-mËBQ`s'ν<¼ÿ=¼þsÿôøüøöþzxy}ƒöðüçðKá³#j¶^\)lãóɪ!WòTÊk’c‹$­Ö«ù ô€õR0Mn'ÿ°„G†endstream +endobj +799 0 obj +662 +endobj +800 0 obj<>>>>>endobj +801 0 obj<>stream +xÚ-ËA ‚0Åñû>Å;ÖAsS´ŽÛX",1‡Ž#ŒTÒE_?­xïô‡ß“PË(Âxýµ'ÝqJaZÐ(ñÀ4Ⱥ¨P­{ÛéÞôÝÐÍn²nœfœì𲏭¹ï§¼?K¢5²8ôø†4¯¡3Qòò‚TåªäE-t&—,U^©(CÎä»F)>>>>>endobj +804 0 obj<>stream +xڅTÁnÚ@½ó#.M¤à` 89”ªHMJTK½ä²ìŽÍ{ÇÝ]CùûÎz ¥‰ª + ¬eæ½7ïÍúç …1RÈ&0ƒ¬ùàöÓ=LƐÞϒ ̳;ÈÕÕŒ`IuMžÑÈîàz¯Mé®óÜ5ƒ4 ]£Ø6šÎ&üÝùV;MƒFé_ iÖA-̨¿Eh¨i+a!_®oWk0=¼6m!$r·QÐØîÚA셮ĦB`I TŒ™}YkawèÁ“Ç$*¼‡4 +¹j:If¡jI¦ÐeËÐ%ˆó`«óߓqß$Kæ¡ïû ©…B[çYªó¢ªâ$þ¤–l|ìe­ÜfáËâù¦0ˆŠUòÿ¾3£ãfX[ò$©z3×ëÕpµ¾^ƒPÊ¢s |5P‹Øêr‹vÄ6Ã0h(-µÍð¤ÄE:)̙ªGàg®,·1‹^·$ãí;òF¬øLäanxîH-…ã”þA³ a‚ó œÓ¥¹äâ*‹5y¬ŽPXª£A-è5™º¼Ër–@ÕÚhçmWÈ^o´N³Ü° bOZ¹ž4ªÚ¦ÒRøKv!¥VhBZq-B¨ó¸ y—BÛDQÿJ°àƒ8ÃÙÀHY3lgò¶ ÆÊƒ?òW—ç*-`!yŸßηŒfgû´X^„{¢r¬Šjôºfù’u30ï)¼¨2‘ŒoÏISFŸC밓ýþ–(Ük‰ÁôK¥‹å&ì ž·}0Z&Š×íìG^€F”œÚ÷œêéb_øÖßÁ»?w)ÍÆQÄ^-³l–ÜqWfÃÁc>xü}d'endstream +endobj +805 0 obj +620 +endobj +806 0 obj<>>>>>endobj +807 0 obj<>stream +xڕVÑNÛJ}ç+F}¹A"&($Ü'@TBº-ܤûÀËÆ'Û¬½îîš4gv½I0$jÕªP{ÇsæÌ™3ûó$…ýIábijòävvrþué%Ì +z3Ó/yïNW…\4FV pK„‡'¸ÉsƒÖ‹å‡7Ó§ÓÙ +½„4 ¡ýá‡Îè8 ++Ñ:X‹ 8 ]üŠh¿¢ P¡[k³‚ßd† -n,úÃáóƒöó=aê×Þøõô}Ödº,E•'0û4¦{Üb•[?'ÈéE2dб¸)Z­'uOF;i¯½/Tí—×S¨E¶âR´hkÌd!1‡{ú¯¡bàÛÍ]¬ðŒ«v‘¿¶ÒNÖP÷_v˜ë8… ã¥õ‡—‰o } ²îG±M»}pÿ}v?9Éx/l©­Kr] +Y%D Æ×ƒÁõhÂÿ¦Ãë‹ËcÁéd˜ ’!>¶SQßÞü–Ž¦Ç…Tl(þ’s…QNKíPm@X+Õ{h¡©r4ðòýá?¯§¥ÑÍbésOñ ‰«ÐéŁÎOCë„Rzm?*׃úÙ°äÅ>3)Ýj¤“öbHÇ +m¨pƒ!§Eøéž’`-•¢¤¶Ö´–nəù|+Rÿ(PÞI±ñËF±4wI{r8 +’ ù—ºQ9̑OPª%V°Ñ ,ś/œ¦O,l ¦F;քß#ú3~ò>T +B'äš:ZiÇ-ÇrNe*÷ø¥£OÕzM?³M¦0‡ÂgùÑP;ÚTÜP‹o ¯“:€=;`?œ'Èl+Î…î²ø¬K ‚Ô5á=Án¬ÃÒz³#ôF/Œ(© JŝԆrçŸzߎ}îT¬1âZÉÂ?²j~u+lêZvcB]GË ­ T%ð•è‰}èà›Ì?µe®‹+ÖÃ]ð:­ÊâEà%—]ÞçXlå®´^5µ q,ÃŽèsïPD hÄg^¼|“pöðnÜfNӔΏ.†¡.¸{yz†g]¸µ0|)eE@ÔkÚ¸ßDÕÅ觗WÑ¿8ìjć“qrƒ?¹ÛßÏNþ=ù/?¿xendstream +endobj +808 0 obj +1181 +endobj +809 0 obj<>>>>>endobj +810 0 obj<>stream +xÚ¥UïÚ8ýÎ_1©´„$H|h+¶Bºc¹.=ÝI•N&qÀ·‰ÚήòßwÆNè²ìÞO!!d{Þ¼yófø6ˆ ÄOi “dÕàÃ~°ÞÂ`Žçç/}„d¤0“ „É|Ì`N?5‡‚B ¤§ý¾ß&E°/~6OaŸ·ü‰kxäÚ% ¨ÞíÿŒoÃîá𠔭sØG¡1ä¢(¸æÒB¡tÅ첏]Ð+ä>Bn ¥©ÚZ i¹^žØ*œ‡ál†QMb¯õön¿^^’ I&{¯*~Ñï/ÛÍo=].Ù¡ôÙ?ÜÝíw`¸~¿¨¥¾êY=cn³1Ò´y)Y\Û¦aeÙÞY&0?óE¡}^IjOÌBÆ$ø Ù™©ªB㡺¢p*ó܉²¾òýçOoÏÉ=ÍÉøvQê I“`N~åZ­GÇk獕”Øs”îZß4ðFT`96Α§ØÍXž£Ó œ˜ÁZ¸Ód ‰ÁŒG‰•0™ÿë¼ Âyj®½l”Þ[ + £_ÈòÓûí Ø¶æ]û£ëA¬©$QzJëí~ýùÍ©Úxãe粉ΓÒ„r¦EÖ}e‰ã`Ð_öD÷¥xø;"ç}Σ[TW蛱Ûl?={ûuxÞ_ß-a:ƒœY†Eá{EºÈY⏡Ъ‚‹DVÕþm‚µå*š‚_M¡ú÷ÑÄä¿@Äÿbò*Ä[mÅi¿¡5€&¿öN£ûé&Ñ{ðÂzôÖyMXçO…ÿ!x£äM…c{(ÕÌ •Êo:«_ Žó®4­Õ² àwô¿5È^Ύv:ς ·YŒe¶ÁAk_dv%'FÕâØhæ>>>/Annots 214 0 R>>endobj +813 0 obj<>stream +xÚÝXYoã6~ϯàcØØ"uç-‡Óu;ÚXAû`¡µ˜µjYt):NþýŸ‰,ËŠn‘ÀÐñÍp.¿Ñ?'Yð‡‘íÉÿáää2>i߄û(~‚7^€Qœž^±É„¨OŜñ1ê‚ò§dHр +‘?ÊOñß ç ŒµÜñ[ž”¼+õÊfh”ž–Ÿä»N|bµ,¨…åÏýoÈ Z.rC©š@>a±¬âõwÀÄ÷Z–Ac@öWhUT‹0º–Ôê‡Úԋé4§è6xüÉ3a,U«)[!oçí¶öÖ[$ÂÔÎVzÚÑÅ`¹¨qȗ±ÝÛ!…~Ç!í†gé<]¼@ ÌÛ *;z³<6µˆ#ÕNèõÍM¾±þí[­p‰Æ8Æ,á—oôó ý¾42K)J3N‡"c…Ió–— câ°Qöûü<˵U°Í5à£5š„«^¤u\¸Üp…Ö _¡— ǎîk&á&Ýk ½hâm#įîzxw䜀@DöœFWEÎñBu’$¥ ¹ÜòýéºU4*°¡+Ø÷6ÍŎÓÂèÌnÚ¦|;ÂͤÉQÒvM|moÙ[÷ˆ¯BWƗغ£^G]Ôïđ^¶¦ú³H£«Î"Û tkêDƒ»¾²¿7ËE6åL°!ËQxZ²Fß.YÂÓ-÷è¿;r›°®g ¶mØBçEÿ¢)¼B™ }Õþ¿-tËkRè +]Uè$´u¡¡óè&Š€ÎBþÑïT\+¢°Î`šUÄ¯Ç +ˆ‡—4°>²]YÐHê"{U0#΁G=`ÛSÆþätÔT=±V]ºZP“kÕEVèEnp`z‡ìz¹j‹0ÆJ#:/Š€ ¿n?£èþ®mÊöÀ6"¹Ü·õ äÀ– IÝGè‘ìîÛ~v›4®Ú +Ø1M斾L>Þ wÐÆý +zG ·C=êëÑû.èjÞÐkÎ(lû ]®:t11óÀmVŒË×R²7@re¥íž1¶ 2Í$¨ovL‚ ´žWðêIc¬+ÿ_™ Ùõ‹­Á¶vç>l2Є»æ_3°4/R}(©©WŸ,wg}¹*påçŠPïͯ½j„WœÍ‹þê;—žÁ$Y®˜ÁäÎ?`«qеìG®rбônŒéXpVd/ÊÍh$?/ F §žb+€õ¾«°Ë|ãêôg©sšpd§Š"Ë´øðÜ'ªðÔ×A4`Obt’Y)x"/‘ü$˜äÒº3-ufÄü@>´¡«Øº€÷úâ .~=ù (œjþendstream +endobj +814 0 obj +1221 +endobj +815 0 obj<>>>>>endobj +816 0 obj<>stream +xÚ¥V]oâ8}çW\©/T‚‡$|<¬ÔéЙjw ÒUWB¹‰Þ&q&1eúï÷ÚNZÈti¥¥‚ë“{Ϲ_æG€&Œ}ˆóÞ§¨7ºqˆRðlËêA”ôïáê~ãx>¸q`y{}ýÓsœ BlÈÊd>)ãèÆoôi’T¬®µuÛ«0"ʸˆz¶e#‡—·ð ¸Sv2µ¦`ü“™å@Å`ýؙø–Ý ‰ïXþÅ ¾‡§'"îÿ§€«õ:úÞ½£Á›!ŸkÐèÿÔàúh?Ѱé碖 äŽUõæ²#§ñ#“U4÷<{üŽ׶܏«Ñè7Ԍnf@&*(‚ˆ'HöZ)ßî+^láê'¯!ÀÖ¬zBm§\m"‹hÇ ¼ÔðÚÀ!¦<0ˆ§,}­=‡ÁBý.*ø´ZE_ŁáSh*  Ëj;*!P©Bc@26<ËJ<ñ„Ám@½/KQIÀ`˜S.¹(hµd%ä{¬ 2(Y•Š*GR¼ÒAÿ ¢ë`t€ò€‚HµõXG'4:B \îàú.X[ Àñ1ÑXÐxwâ@E””5ЗàTGKyÆ  Š˜É-mûÀà:Íarä-ãªïR(˜<ˆêJZ¡3©r“ó‡g­Í² *ϜùÓnZ®Ì÷i㔂Kڛ5·¿¾Î`-Ry x=^%9/ð†ÁËJàò{š)CâNð‰áı?ö£Á¸˜ žÌš_7öþ³Áùƒendstream +endobj +817 0 obj +1080 +endobj +818 0 obj<>>>>>endobj +819 0 obj<>stream +xڝV]oâ8}çWÜ/Tš +”‡•:”ÎÎî dif4#!­LbÀKbgl§ ÿ~¯í@!-¥Ú!°ï¹Çç^ùgÍ?>tz捳ڇ¨výÐ߇h‰;½A¢¤­™‚„)²H©½¦0£OT* +ÑøódA.…±Hð(¶SWˆL^ +n÷sɸE%ºk_EÿÖ>>>>>endobj +822 0 obj<>stream +xÚÝVßoÚ0~篸ª/T4 h&uˆV¨-0H5Mª4™Ä¯‰Ú,ÿýÎNҒt­ú8$~Øwçïî¾û⧖ ¾]zÐ@´¾ù­Ó«>¸.øî FCðÃö„[H%ã•;*!\Æó3b›L͇ˆÅ8Ih'þo FÊ`íñ|v5½.«Ú ·DF‹™Ò "àTï…|„”H ¦©TÆÓŽÛëzS¦ðˆuŽh ª ¾€D„,2«LXr‘A’aЈIü Şǂ„ÀpEŠÄú×RËã³\@už‹ñ|t¤Ó‡¶ûpÒÌ%•bƒh/ŠuÎÍ2Öµãõ»ýÒ:XÚ!a(©R0™ù“euÐyuŽÓó±àœóÔâÀ©[U¢4ó<6ƒU‘Á’’0oZ-i"4–*WšbÖyJKdýš¦ó+Ԓho¨†¢ïCŽE@â‹ÊTÚ3«¿M؎c‘$„‡0¿ibpϘ§”Ãåj<Â)”õ@š5­\.gÓÙõÖDR¤§¥¡B e;¬!«b!EhÃÿÊ0%!9p¡aKv´$\ETJô ~:Î_W~~iˆVI#S›FÇæ…LÕ´渋ˊ"÷åCivcíNUA®÷{ò”!‡ßí†ç¹p-D¸Î T/díXZŒÑŒþÑ_€†Ì̂š=Ó[39"²’!q4šY+!Á´ÌtÚ,o‹b+XÓ ãÜ̎ñ¾¨a:ÇÅÆßº¿Ëù½±p‰:.ÒùÖ{{»Û½Úö?Óo ßøR!5ð,Yc—"„O­œ¡°Ä1m28úŒÄ…!ŠØ‹¦Aq,öê£՛T!|ݜz¢ /ïm¯Ãü^½7«á=LHªŠäwLêÌ$lƳ´ý&nsł²]XÙA¨8aê„8d©P³Áéþc2o#Xemȸ‰RZCõ¦{PèÄgTÖ4û¯•õSHÜO£d·Œ?bê{l{}µÚ€×Š£"،ãö‡HÕ³á kcÁø~±‚•ˆôÞ>>>>>endobj +825 0 obj<>stream +xÚ-‹± Dw¾âFZ mlWmtÒ¤üb¡A-D ÿÞ¢æn¹—{BQÌ¡(ש—‘lYíP +¡A«:g¨YÑ/О;ît|I¯°éGcMˆ^FçŽÒNò¾W’ý¬ì¯5,Á’Uy…/hÕf˜¼±ÆÞÂ; ›WWþ©|Hÿ 'òñ,´endstream +endobj +826 0 obj +140 +endobj +827 0 obj<>>>/Annots 221 0 R>>endobj +828 0 obj<>stream +xÚµ–Ks›0F÷þwéÌ¢Ñeì´M§ZÓ]6Ԑ˜„WAÎãßç +É7¦wú¤{l$ýžP ø¢à1à.¬òÉy89{ï#^§ÄàzÂx: ‚:-dRâN9 o‘v€RE[·¸Ãl¦z„봁¨ª’"N!Kـ\'P™”X§à{‘„¨V”÷iœÄðÊ5ÌK[áõÔәí¨ðÁ© Ç<Ûm§)«l'zøë2Ëʇ´¸ù{"ïtÈʄ0eXÌÕã]1×\„bÔ¦.T]~|@y6ædsð8­,÷Ð= J˜Mñ><£6æ{ò³]þüÅüëèÔq53_×|,¿}ߪÒ¥„/‘¬ÓG%¡K &az +Z_d‚¦IՔ…oWU¼ëÕòÔ¯„rý#ã•ϐÝzmC^ M‰wïÊ«‹óä{„òºËðŠÕ°Î+sÞ"–9Ç0Ë^·fÛÆYCSÂUåxŸPf…í÷ø¦ï<-åS¶i`^fe=VQ#W +?†""°ÇVQÛRdh#`ïJ‘oÏzüEÄ·Å IÁº”åxI• ‰ú3,>‡κ±¿êƒP_G®™ú®^Ô?°Hš»O‰[+.þw·‰>>>>>endobj +831 0 obj<>stream +xÚŕOoÚ@Åï|Š9‚Œ×ãS'i“Öî¡—­w-6Ø^wwšoßY›…`‘Z,`Þ<¿ùíÿìpñEÀì;-z’ÞèþÈ’ +AH aý»xþå3ÌÍk^kˆd.Õ yFái…CoêVš,9œÊ)ñÂ,úm#Ý4öµImÝ©*ö§e1]W•TF¿eX)Q®4˜%5 Š*ç/ ~åÖßñšðóh{Ê¢ %͍ ä‹`\ Ý+œ/¶<õ\¸@Ö¦ªÑ¸„9MWM­‰Š3DOß?-Nxkè{ÎøW¼”F^Ž«‘wàªlý=¸ZÃÿ+-º€Íb¸åzõ‘›NP{ÙY@˜põŒ‘»u€8z<æpkOeb©¸*û®%²c- ;æ%Ñfñ0ŽoÓ¡%Ft…Gâá5l>Û!®áôTñÉdOw;G)È÷·°8VsÀ¢ön˜Áph†‘0™Ö65B–ÍÍ6])YÀŒ¯Qn F9Uì­YYŽ¿¸Ú0Ë͈;×ÈSs%ôŠÐ@s-£d͐­…ȩũ–¥î\»GоìÝVwvñr+¸hóvVÿtõd™¿žnn³Ã/2”jC󜟜әÀ¬e¿Ïm3/ú>±Q|LÕîÜѝ]¦£ñþbµF÷á9OÑeìN¬Dßâ9ÌefÖ6Î +D)´QÔH剖5Ímû°íÚ¿4l ÇöG? û<û¼Kz_{¿@’9òendstream +endobj +832 0 obj +589 +endobj +833 0 obj<>>>>>endobj +834 0 obj<>stream +xڕ–Ko›@…÷þWY% à ooÛ$m¥ªrkZu‘ †x"^epÛô×÷¶…Á€,!Ûsïι~­(üPð-°=`Ùê]¸27`°íÀðÀóãÛ{XÃg!k(x)—wá+j Ti×Z¼¶˰”>Ü QYò<!ŝê=‡Dí…(!guQ ®V¢¢ŠƒÈe¥)!)ªfÃû"ˊ¾ùô¶•Èk‘¿ÀîMÖ<3´·õ@‰c8°¶¼¢ƒmTïó(ãJD7ÿ$ —¬e-Š\­<„+b,Ãñòí8áƒM(¢Pwc`‰6øííÄñjË&X…“º©gW#— Î +] “×Ìd‡RšŒWµ4›îF› <-X¤\ªŠG,¢·ÿ¨"Q¿º‚bµÔ ¬©­ï¯¶§ð1 ·ÀR›¥q×ò#hym Ëu•W«5ïI¼šÒu G™FRri°"O.XKu°¼‚VJ$^•ÆUˆ]z”’íy|Hy5g{èq6\£…³l°38¼ÄÃhG‡PS¦©¿ Z=@m›£—»¦äIÄøDøt³Á8nÝBC±kOr*l4p„M«Ç΃ú´¶Ld\ÇoyIÖ1œ3yUq›.‘*׈ÈÒCŒã珨÷ð°Ûö𚠄s¨˜âs­yÓêQ>{ÓÏ[ÃW¿•|œ‡kñ’‹¼%lÔM!Ìæ°íÔê±R‹ô#X–ñõìm YiËØF½~v8O·7ÛíýÍÓÝi(ÂÜ<²$z켿ǣ‰ëÃotèÁÜ1PUù™§ÕˆÇËSsq•ù,r“E9ãé…ùãpÐëðZՎcgIC8×úÁîÚ¡sÌóë†õúB¿–£œÎ}†(ñàKLоĐö-jèuÐñ՘nÖ·uõuõÞØ°˜endstream +endobj +835 0 obj +752 +endobj +836 0 obj<>>>>>endobj +837 0 obj<>stream +xÚµ˜_o£8Åßó)üØ®&óÇÀc;ÝÎFꮺ“t5‘V.8 ÀCgúí÷')„º˜Õ®ZE­s€ßëãkžgÙðƒ‘KäoœÏ®×³Å­‡0Fë-òm+@$ôÑ:¹X4¢Z<¦Å"+/×O3ìGp Œ¯÷ ­^EÍrô*«´¨QÌóœ‰%u¿®g¶eÃEN_¿ /”ç B+Dp "ËAœè±c'µãÚ騁V1¾íSò²Ny!z°+V ÔVͶM –(â´Ø¡ƒ8‚/i“Õb̰s­ZëÀ#0ÞwPR!~$=WI">¡xO‹ƒ?xgÉù è&…‘µÇðª=ÊFsì…à8Ǽ)Æ9è•#×±¼G­Z9zSŸaO]»ãèyP:׬úÎ2öŠDMëF˜ÖŽÊ{nzç[µîÎûÑy}WzÊ)î‡S +\©µÁ°À«\ÏÓ"fz⏛ ±¹4%&S +Z©µÄþ° å3ևǤ +ðá"ž9j«Ö¢º|{DM‹8k¶ˆ›R,z´ŸîWèê~‰öŒ&¬BÛ4cc3ÊwñiFp¶j-';3*K]G~JP‹žMø¡$ÍéŽ)tt®à®§1QE«‚ds±üºü†ˆåo.?öæEo>žJ­K /ì8Ќ:›î‹fâõžUbÔ!§ê2pÖªµÎ|·S]]g"³#sGaÏߞV°~uýýv?ø6jÍõNÑi`­Uk­9XSŽ‚k­WäQ:bθ(m|Ê0­ZçυL&ï?:núèÌܙ—¦K¢ K´RkýAF÷ÙÛÐ{¤ñwV$ýð»Vƒm¡éxnY]¿–€Ï·j]„HŒyQ°¸í¤F‚Ñó%\©uÁèºÁÐE¼KçrÙéGø—%°ò]Esåî9ñž%Mƪ1d¸¼ù‚®ÔZdœå] PhçΘoÚ1…[ò,“ݪìRïîohʒWõ8ÆÖu¥Ö;ÑùœhÁa-„çß¿mÇ4c²x:‘3a‘Wj-wÇ0iƃ†DŽË +–”4Ú Ìã¹(YœnaAə0ÐáïdÀæâØÍŒMc‡ØbX©uÓØñúå_db‘‹Ýìì3ÏKúŒÖUC<ôðÇrt¥q`{`žÄJ­µ›‰·ª2@ÿŸçw—ÍÏOè—ëÕ͘?ù’X©uþpèt’XÈ܂-+‡í²žCgoÚ*ã€LHZ¥ÖÍ"LÜ>¥œüɲí”Õ^É4\1¬EæáªÔZJÏ턫P›šäi1òêV°V–ŠºR5Tsž‘»Á„tUj-¹Ó«sEìGÿ5l&̳U©µÔ¶ßÉÖuZlù|ÇêyÂ^Ҙ©7-òÿ²LLK9Š&l¦¢èƒ½THÎç[VÊ)b98e¶…Sښ𣮆}ÀŠ=Ak5TÃSɔ6†|ÔÅxÝ&F¥2d/ ,èßòó½¹'kN²nƒü;-P !}ìûGWšpÂnÍ ß߬-nÃÃkOìÉ÷ZÓÞb•e+¾­7ºz›hZ mh&éæê¨ùᰐÈAÛÖ±‹CstÊUéV®=KÎþ>êcÄendstream +endobj +838 0 obj +1200 +endobj +839 0 obj<>>>>>endobj +840 0 obj<>stream +xڕV]oÚ0}çW\í©•J¾CÂãVÆZ©ÝXI¥>ðâ&2%qj;­¶_¿ë8PH I…A|®|νÇǼŒl°ðcCà€;8}‹FæÜۆh ¾e0 }ˆ’ ³Ü[©™“¼ŒþŒlŠÅ¸vO +(Ɇ +X]\³¼$/ñjâÁãÏÛ§+¸YŒŸ®T…cÛ5U³dá©X]ª÷ߣ‘eXHeÿxø^¨vŸøÆp'Ã×1<à–'ÀŽìюká󍚴ßÁ÷;-gU,&·”÷ô&¸&hOQÛy‚5Z|Gï º.®7;®Ja&D’c²Ñ–BÆb"SV[Ã:Í$堀ê;Fm'ÀÝӮѝ´mOÏô$mI…,yZH£$,˜Ë˜§¥…«û_óï£o…ŠøPú5º‹¾?õO‘_³BŠóM?`_£ñÉAÉj¹þávÑ£Ì>cxî2¼?94ü¶œ%4¬m¡¦‡æšQQ¿@DKÖêâËb1û²ºÔÞR$P׬ILAW ì ‘“¿ðL[õ•  H‚ʪe³ãKE«>+ø(~gOuã|Ãj´nØ;zß0;8Õ®RHƉ@FÇ=û¥â°S8^ԝʔdé?ÝÊ!‡Ñ·-#ìfîr³7 põ¼ˆ9š5'å‡ù+ã€Ê2-65qL˜¯”+oãï‚ä8]ÉZãSuõR_XzA¸Ë~skt—¹=Ìú“a)i^fãä¼Áo¢û;ØaßîÎï}nIÜ»¹o–&¼5\bî”èº- ‹µÈ#i3W9-¤Ö¦ +ÐYª/-«%IÄ[šTå}а`x"it§"Ëjé•p3c›jڃÚóÄ·›AçɝzŸ¸“5ºë<¹¡ÝØL1%cÙÎu€5¦z#x 0ߞimIŸÌõá׳FŸP`ÎÃæ¯œí©>>>>>endobj +843 0 obj<>stream +xÚ-‹Ë‚0÷÷+ÎRÅ^$R–¾Xi¢¡~@#4©K¿/UsÎj&ó$†œÇXoÒïí4­jfh .Ê,G™KèvýíÒ ñ6¾Mè°m7º)}˜p6ãËôKý ñ«Ä?S*Á‚eVá 8Í!¼EíúnJþ¨éJ!ÿ%Qendstream +endobj +844 0 obj +128 +endobj +845 0 obj<>>>/Annots 229 0 R>>endobj +846 0 obj<>stream +xÚ¥VKsÛ6¾ëWls‰2±(¾DŠ>5MäNΨ=îÁ˜„$´$À Yå×gzEòL›ñXŠûøv÷ûvýu€?¤!D õè·|4½Ë ô!_CàÇ^I:‡¼/`¹ísEÕVÍø>Šº–Rà·µz—ÿÞ1ñž8÷I‡ø#ä[¦€4 å%û +ñB¥%j +b zKñ+®éÃÁšI¥'š¡E«Œ1å…h¹¦º-åÀ¸Ò¤ª ÂK“ÝǬ‘ËV¾f›VZœ˕׿/6ï v* F*PmÓ©a-¤5ƒó…°Š XKQ¨¬ÄZwDRSpÙZyp‡.µÀ¯Gïšhf +¨(QôG<š+¢o]«Š¾UáÜ4j@ö&)ƒE>ò='d>óñåwH#χp6ó¨! Œ§{ª`åÆ7 'Î|ƒ1om̳€rÓ;¿woµnn§Ó®ë<¬`§:Grêåï½ð“Ô›Ê||’y„HˆÁÉÌËú§‹àãÈ5dq³¸ÜOïןF|H>ÎiE›­àžÆ÷“»È&3X¬ò§w·ð>ð"qYâGÎ3ƒ µ¡Ý(£Ð!¿ßÁ‡¦©Xa‰¡à“ào5¬(µ|ÿ°çØiŠ´>SakêæwOøÎhçJRRÚ(· ЧTÓÆÄ+HsV* +“iª@Ŕ6Ú;p½éqœ‹%Ç<%]“¶ÒN!ƒºáKAp¡¡@Tšþ?X¤Õ¨@Iï<ÈÊ݂ڿ¸J«`nú„™E4ø§žWhù®“¢+Ú¦$v“Ù ĔErc¶Í¾†W³<*è"²±EV¼§È.ðthL_ȀJ&i¡Ù‹™…*${¦%îëj;N‡ÉçñIò öG5Ä8üôUûc ´Ÿe^p­¸¡w}?†’>nIcÖyrol/Í,V;¥i}µ*ß` »B’7ˆ{8L:H{ñN6´¦\¿¹¼ÆÞ©xýƒp-É?!­^¿ÐBl8ûFõü€—ˆs´$,‰Rå/Wukãt¬ª€¨`'Z{d<|þã/{Ôl(CŦåN›±l¨47e%²f%ۋNcDuvd$­…¦Õ΀{auôž¥è0jêHƧ +–ôk‹ìRH{¢möc 1^âé?—ïIèóÃ哹xöqºû:q ¡²±X#ù~iTé~.óC?£à?ü§1.xßx̳žG޾lzžendstream +endobj +847 0 obj +956 +endobj +848 0 obj<>>>/Annots 236 0 R>>endobj +849 0 obj<>stream +xÚµVÛrÛ6}×WlòRwÆ¢I‘¢È¼ù–NÒ¸5û šhHB@kÔ¯ï.@Ê%ٙv<ÉÀb¹Ø={ÎÌðñ_aLÿófv“Íï%ø|¿¨'ˆoAx˜¤¸&‘‡ʙ=Š¢•·8:º¡T>eLuõ9‚ €¬Ä›ãdYqqû×Ã#’kh¥V×r ;ف‘À:Sñֈœ¬V4¢Ú(f„lñš×¶ÂTö8Ïe×03P1J¦õVªJ©~Íþžù0B¬/Ö<ï”0;Ìôlµ_J{s!m){Æ[_2àxª€Ò\}öû>.””Æ=Z»UÂíK°•í/֘o]sÛZQÀF‰Öp¥'u)ÞHÃëHςQØò5Øà’åüCÿÂ"ö"z!“Pm3ï‹A'\áÐr^ÐÕ¼¶²¾6T}ÅM~•wm—ÂËe[N+EM“( —MƒùAv6פ…Z´8OĵíÓ§°”r Õæ‹È~Ef» ‡¦E>ä@Ú ‡·5ö;mxsXÊÜæ‰)'{²Ëzx?fb@˟¿Aè'^Ëe‚·5FKüëv5<y_îŠ#{–ºº –T2¯B +2åµ\Ö\=sÈ¿‚ë\‰5Â.Z8_Éèn¬dTr"~ñiê-_E4…—v:ye:€Ó·|[± r’Køø@¤Å©Ž¦r²+ÜÀ;‹ñÎØ^i7Õ¸=;¾¯¬eOœÈôÑ2àÈ3.<7Ùe?Že„ž3ŽC¿Ëî?rc$;« *w¯Œ¼âùw¦Q×½Û°vg‡ZC‡³#‰äkŸ¸“{¯RÇzâã„ë$ñÔ9Oº„5 +Â)xjW¥’ f‘H Ë+‰+CZÉsÖS%Ù +yááì÷8ŸuàžÄ)+JX¿ý·ŒÌèNÂõaÓŒ-óº/ó«+óÃ1À+7=”Ò¼d]mûà€Z4Âè)ˆ0©ÅaÞ#j’ 7(¨nCþɵ¾Ü[Õ¡´GðüŒg°+øIƒú¦ +¡àíîÒbbQwxЏµ®§öe©e Çåïba¡OX æv§-,ô#‡Ú;YؾkP/•œ³°}¼5¨WãGƒ…tzÎÂö-ÿW [¤´öæ6{ [¤Á»˜¥Õ:‘SȞ|PI:š>XÐ{°?”ÖËŽÐß=x¨ñC‡[֟íÙÖ¶Ûtº@Ýæô\FHs?&À^ pd£øèÍøQÆ'¼?Šh`…ùOÒ¤ï7s$>æ¼=dúÂDô`6vH²$I䂜•ŒhËvÓtCm#þáÞ¼áõ§>Ä{µ'=ûs°ZøVìVя²4[†¡#ϗJS_³Þ5woÍû×RŸ2þÿúÕÀFþ˜ý ø \Éendstream +endobj +850 0 obj +1079 +endobj +851 0 obj<>>>/Annots 243 0 R>>endobj +852 0 obj<>stream +xÚ¥VKSÛH¾ó+:\–Tbù‰÷F Ù%UTeƒ³¹ä2–FöiF™áøßï×3’Í¶(@¶úñu÷׏Ÿ')ð“ÒbL“9eÕÉûÕÉ»KJ´*ðf~™Ò*?»¥k¡ótcè*¯”VÎ[á•Ñ´îÁQaMEw{ú&×ôޚ“öÍÛÕ˜šRšFSãE2gc«­rT[³.eExl\#ÊrO™hœÌi½ÿUÇ3h̓)k¤ ñWgÚxrµÌT±WzC~+)3ÖÊÌS-œÛ›Salxa „E–™Fû„µ $c¶7níáµt®3uýõó=ù£´ÀÔ}»5ÎkQI‚ÝÛÏ$òÜB‡LÞ¶â;å·¦ñ$µX—¬iee¼d'V'£d„,óŸ”ÿ|ùƒ¦Ó%"›-—ÈHEÓù(™´ŸJºç óÑ(æ+¢ ‰ÃäÎøÁ%’š Më>'!—P+K³ë¢QÊMT‡ðÝË(¸€òr’ŒQ©ØMXý´%΋.&s¶yÉu®h6Fyâvð\z PQ:ž2ºWÄÓq +½ülÔûzA~ ùÅ4I_—HT4NÇÉòUù¡ägËd6UŸ]."ç_mµ+t¼»ÙViùæ4¼w8j«q~†Z“¶TP%SD]K«_¡3.Т}oL†½&½g戧ö2úywÅÎÙ©²$Ö $´W™ðªhjۉBWxʍt,É~†®·âQ}1ã@c•ߣ£„c¦?<íšùÉ-cŽŒ†è\nj€èÏiÝøK'°7 +[Måb0TÉj ÅØðǐÝÞyL±5MýÚ¬…–]¨ â€Ý+o8-t£6Ò$ µŠÀcãtÇiŸ4rM]ë[åc@‡¶’8„»y~‚]LƑ`×Fë–_dFï挀ÕG÷WŠ6¶%eÊfMå¼Ð˜Oçtš=´Ñà)’-ÆéEZzTö®j$ÃÖÃÜ,sžZòW†ÖѬ|÷ +Iãÿ Ýa$w¦(˜) €›Ø"‚Ç\qKž…=(èÃM%r”I×{Ú¨G©£ñïgFË#×?Ì:H‰ïo¡’G–Çð¨̰ §-¿"!í¶ +ޙ^…²€;ÀÁ퇧GçÈ) +h*Áäh¥· +¡ÅUכ0H9Ilž=MFÜ#Fç®ÛrÝÖ¼+ªÛ´µ´Ãą0z®ó +©  YAØ!¨¨ò{Nð…­ûW´Ó§ŠÓ§m•£8*MüÆù1ÀλòÐ6 +†UN–qµ;҃EsÂRn·ý‘ïVä8!W¥3çT1{ä/¼× q ;®qwPÝ'ÈØ”Űú"tßXoLQ0:ŧAq#@_RæNQ¼hL‡¤¨ÀéÎÔð.ë»ø†£¤ÖÂ÷¶/Á)ÞHO§» (YqЦì¸Ç󳑍–ê©ÙÐ/ÝÙ&èO¹+±)è³Èæö'éo_ G èµÑK[áB[!ÖÆ‡`qVɘ˜®µ¤ S ÎD¼ÁÌé§Û ¾«m…[¨½&c¡b}SS.K±Çð;)u{)¯ÀxÇ{SÌ|+çÇÈÒ®Ÿk¤ ÂÿF<ʅÑ+p8Ùޟï>^¶I§ ¾cÒy¬J\ ÷¦ð;nÉÁÖ7 äÐÈs\-Aïb1ýŸ›|Ы咂‰eÚfü±¸Áendstream +endobj +853 0 obj +1281 +endobj +854 0 obj<>>>>>endobj +855 0 obj<>stream +xÚuRÁnÛ0 ½û+ÞziÄ®åIÚÆ5MÐ k‘¶v:Lµ™T«-¥ ûúIv3xÁé |z‰R†ãp‹:ºÈ£ÓÅB _ùÌx:A^žä…±– +?6Öíð~’L$ãÖ»Sz݃'I²6M¦23Zû¨ j{ÀØÜrCÁ:+=ÚB9üøþp¼Çí;.ƒ[ÔªÀ·;âÆêðÖ´N¸AÛD+V²R¿<¬“ã]]©uc%+£/¼ÙWóÏˎòèýÑAþþ2ë$l4~µý¼ÝÚ?ú_ùK£¸_1}ýTB¿\1žte˜}YÞãÞ¬x+-áCéƒrìëp-u#«@‹ÑÄל, egYfbê·Ù>b&õ1ãÒô9¼ È¥{vXYSãz‡¯ôˆ k¶Žì›@1Ï£Ûè7ò*çÌendstream +endobj +856 0 obj +445 +endobj +857 0 obj<>>>/Annots 286 0 R>>endobj +858 0 obj<>stream +xÚ͛KsÜ8€ïþ:îÒI‘’Žyl¶fk3“±½µ5G¹-'šéG¦»Tþý(m›”·Öv'U±€Ÿ› ‚ ýי*Jø«ŠZÆËõÙÛ˳×ÚB—ÅåM¡l[¸º*.¯ÿvÙ]­úb{S¼Ûnýæ°ÿéò³¿_ž•‹øÂÎÿÂ»hŠu_*n¬Š „éï>¯?ØB)üqØÏ*ü¸O»þ¦[öøCŒYÁ.NþzÐ*00žÖ f©ÕBqƒÍòúCÅF78m@¾ø±?ôëâA¨à¬¡{µ°1•åLûõ[¿û6ôßW©E{BFÍÙ­la­‹¦‚‘PƒGˆÖRåÂOÑ÷Ûåí¦æÃöýÁ^ºD4’^d/½Ð§a/6•m|R˜b5|¡Æd*Ûâÿ ~ٺðÝ$¦ÖÔLe4˜*¢±œy¾åèサ§`«œ¥ÿ®‹¶øB a©ÆO7WW»þÛЍ#såž\02™ºÖcgà 5Ä@ë’"/ýîáù :c¨Ñ‹:F‘<ÀÎû›~×o–½7ZåNËh&¹wÙÊP°Á î¿cô´QÙª¢ ¡Ñf€Åjœd’FR¦¼z˜"z®aÁA@0,fΧݫpóùaœ ÀÔ·à˜ÇbÆåöцX•8)$åÕ=ñôå'„ͬSúØg-†>߸o¯¶FQ¼üÒ'¬>AÀêÚXY̤¼ƒ³Â) y,y[ÈÝÖ>—Â|ìVbÎø0­ËÑø¾!B–jfœ)ªl`؆åê—_6ÛÕöó¿w)ÈN)»Œ©Jãc2ŒÈqC˜ª¬( ÿs{åC±jO?™Î ¸jKŸïÂîӀ«VQ²ûnÕí÷´ý˜Sqn°gapu¸¢©![7Y? «C¿óƒ…¤Öž´ƒs†‘úüµ‰K 1`g)¤½í–ö›ë=eô©Ž87X6 \;'5Ä`í´$3³©3†:uŒb¹‡½ß ßx¢˜òÄâü©3æ2µuMsœÂ\¦¡P÷Kø¾Ýý ¨çú4^ÌA+¥Æ”¾¿'­ ÷Ë_§sÐó©bD#©ž—ƒŒÃãq„a1sÞÞ«ëdú"0ÄvâÇbÆu›ëÄð¦Îx ¿c.–3êçÍþЭVÉÏ&!€´õè0XYíÝ¿?]ø¸û¢‹©M/Ó6>¨‚9 7îËeMÛRxc(Á0–R"0‹Ø%8SWt!óDr]lowË>å¾ €3.(0ïý°?솫[<à¿h¸x؃µF6–â»1P+Tb`8£S÷_·Ã®_‡ò¬+Ocg̍­VTUÐø•Zbl ÓPiýuÈ-މ€RLv#^PÈqñ¾l5T• نK¼Gä[ÂBphw³ã›@PaÏÆÀ ÀÌCê”%»ãjÃ"i c†]loß»•õ›—™œJel]Y +ý + éÔ¶®ÅýóÛÍ&cè©?íMML + LZt˜Ã(†±Ã"C·/T¦ªoŒ»’oL霁@÷Ƚ(àü†!q,63÷"æ(r "9ƒÞ›n÷#å´ €«æ.(˜÷¢—ˆJÙ¢Zڊ(Pø–X º|d( +8mиÇ +DìR†žºâêÀ +d "}Úîþ2óaž ¬ ­°|óHxwܦž§Æ–õSi¹Xï­XÚx[-ù¦õž +@Wf0(0³Û¤œ5õÆÛÞa±³Î?}LÀDwðT‰[O c†Ýã+õLKLé´»t«ÅO­É]º5ÝãG ·g +ÌÌ»kd¹jü¨‘»FÖûþjHò×V ˆyNҎý…÷Kϱ¶tòx®݋b +Cßßs<׎/GMúx`þÑHʔÜñ<`luü¡X\/æÕ“g#Ê#Ë÷±ÛtŸý‘ß8ÔéTUæZT[3Ý1Pã¾C±¶Õ¼Û†Àó"‹©:Òí‡åþÿ³Ý ]ûs5¦´MW|üæ:]½×E룀D‘8À~‡Sâ6lêMY[³HX†ÝþNÚ¦1*{‡ +Œ“w'–Y_ò Yeö˜o>„—X7¥–Ø_tM7ç7Ù=”#"XP`^Úu²?Zۍt<@’ÓrÎÀ5è’gÝËFB À½ +óñÇ + ¼Ùm—å²?Ðt{<Ö PÏ8yËîkÈoð +8†iz·]¯»Íõ« $¬ÿ?IOvÊ)~@SB™è(­¿ ˜9åŒf„„æÍšrF3&¢±BîÖæL¹€£ ápÊ)ù>cƔcψÇ + œ5åæŒ¤…jF BvXÕûÔO¹€úOå0*ªÌ#]Ò‰?#5ÄFU*‘À¤« SÚ_LLc¹Šò«}z‹1°Âg›0(01ícÙt|„ÓXié:“è>öÏþb+¨ðîï(°<ù¥bÂé>æ¨&¼ùÀ˜@­)æÀê™qF”ƪZ„ + +Mö†JvÆéÅ +õq{=ÜüH6ÀQÞùl¬ ~ñ\‡Ý¬“j3¾#tÜNªùÑÊû~ÕfYG\…)u„ +Õâ>s¼ì[(å2Vr%glx~ –°’ã—.ý!c$Ñg³†iт‚šSòÝé~ôè£ê7Ýí*¹ÖòÓ5~aE@VPQÖæSîö¹=˜uYUsƃ7Ô.«ø½ÎÅ¡Ûå|6ÂÍv„ +͌[rÙc†ðÆ +ãÇÛ~ýš Bënz("²Bå=Ïü+ë-S{zh o~lôf¹ì¿fÜ%˜¢b2âá©q¦%:ãz0°yÇ(V`ØyÿG¿Ì|:AoÕèšÉ +V¤0‰DPÖþ¡c\P`Üøö°yúýGe^\áprBjL9!„®Gd„EÙZÄbù£òÁçÓµfgƒ#Ëgk1‹ææ‚#ªQÇ +:Î÷ŸÿýDÂé¸,ÛÊo-âü·÷Ôj[K›K•.Õ2ÉT%ÊË‘«Ó2ÃWQ%ƒ„vfibêÎÏá$Š„öîCØêôê*󿝡‡X¾„ÚDáD¶áÇXù"-ã|VâH^°~6c5×L'_×D_×>êÜË$¼1*#Iۙ— +¢?fXݕ0,ž°©ŒqìŽk=±HÜÎ:VáS9Wó½jo‹ðŽ«xs½6xÞ¶KÂʼíVtšÂ¼áUMoQ¶âogÿhdzendstream +endobj +859 0 obj +2648 +endobj +860 0 obj<>>>/Annots 333 0 R>>endobj +861 0 obj<>stream +xÚÕ[ÝzÛ6 ½ÏSèr»¨+þ‰Òeš´]¿¥[šx 9L¢M¶RYn—=ý@² wӋÌZÛÏ "òD‡ðHý|"’þŠDeþßj}òfyòú]‘È4YÞ&ÂIfu²¼ùaYþ^»¤¹MΚMç6ÝöÇå'o—'é"ÿ!üÇÕ{o$™2‹^%”WO£°™ëDç ;†¡Ë„sVWÀøi06X³ÈÆ`t™À®]·{ðPÒIýsû#Š'¹ ð“”@r³(È ®¯ßiò&„S&\ñÁsïž^=£ýêqDºLHoÊmµ +±'3øù —obí¬ôk— íc7Íá+ZDÕBìŠtöÛÇr³+ë‰fÓýFL#0ÐãÁ¶½­îvmÙUÍfj_ @ î°°8 ‡…„ð4›½†Œ’{Gްp@uÙVS»Œœ‡p4 ‡û´s;BE¥V›»‰%e¨Ò=|¿¤4€0Ë (6 ²Ön ¥Rvsp[õÄ&æó­ø†i? Çsí×Nàœ¨Lí7wWŒˆÞ6íTäXvsR«Ã›ëXD bGC%x±Ø‘i$trŸ>tÜZ,tòè§»®Yþ^MÅÍ0ßokûn„Öø®\Á`¼Ï-ì²1( ˆg +6÷rx{4àYy‚M0£Áú‡YB,ÌËx:êå¬Àv7o°˜—mJÃóD˜©…Ҁóã®îª‡é=`x/çðuŒˆöwvövÊÙøGèCÎ4 œÞÚlºßÚÅáÝрl´µ}x¡­=áòvCÂþ¿ß÷OC7l´ÆJ–MwÃ=XhZGhx•PbÝpc +ïNC—5+ӓAÈÖIa`[àè2Á]?n;·~ŒÍŠÆ®]×û¶©¼skh×=`öb[ú9! ¦›hXöM4ÿÖD%°*śè14Ñ#DºLHóo¢£k!™"ÓÞ ¦~ÅDØêWnەít¤²ù¾#÷+6BƒAhÝÔê󙨖é1N?“¿]^O÷ezÀÂÍ2¢,ے+³ãꌸ+U¨ø ‰óWªéœ}_nî¦ý5̇Ìb}ç`t™à&]Æ&ûÂ[x÷p(º®yQ›*»€/’¡×åpý€ž)ï°B¦Jÿc1 æ1]¤á@žYXR4éBàq<¶.l6,‹°¦#,ºNhçUëV]õû1-礏H5ÝÃik±BIï{´†NÛëÓéjå¶Û‹&4 :;byúNz™¥¥(¼Ã‚ÁØe Ëi]7_C2òezVuEêA#0áBªÍÉb ¤“ÖýY]n1>Õ|â3ÊNYÌLÚÇ!ZŒÊ1-y~ïÛf÷ðK¹vÑê£2”&BKjÊ,¾ø¡ÅhIƒyÅÓZ>>8òš×bô„Àœ¢ý-FOHÌ)oÚæë֝ÞÜ´#3ˏžWd6MM9IXþðˆÖ@MuªH­O+Y:‡´å–m¼8‰ã–g³s·yô`FÏ#—H¡fæ8J(²µ  ïÉýÚÞ`kjì,ê\”œÉ1›(¯ ÅÈA'Î<÷aÓAïSÖ!,gð$GærÚP¢¼ç‚ÅÈA+ÂrÉeSbº˜KÒS’4víZŒdÉéµÝÿŒž(èhö]°=™ä®\]>Îi×EžŽ¨”žåféÞbÔҌ§”ë{poNBËíñö]Œ–,ð¦€cLAÖ@KŠ'“eµvÍ®›IíV¹ZZz:(|ÕB‹QËS–JHjÕb6§(»Œža¥þ‡c—Ñ3¢ó²+á¼td9¯ùJDzb£|…C‹14Á{çî¶ÜÕÝÙ}Ùn]7—*¥¦ +vÎA‹QÓô€È]”›»]y7‡“N”X÷‚šž“ÁxIK +µ“RÌïÕ%# IüÊWe´EAÿy³Úyyÿªiæ•1j)êò^+ÈbÔR’åß¶mӒ4¤ò9 (*¢‰|PÐYA‘‡M„…yŠCQ~–„ÝÐS¡ÅøYRuj¶¡9¹hš?wØ¢¯˜GIe);î ÅHe$Ê~X?ÔÕªê‚î…}×,ö\DñšôXè•-YŒ&=ögçNëꋛ™¥§PÆ?ÁC‹ÑS$Èîé±3—ÇÜ~QbuØ 4£ÁxÉÀê¢Úvn3ÓTÑô|[R‰>U¦c%Ö¿´RÉE³Ú?šY-ˆ,zIÖ'Åb¬È$ÈB‘»p_\=·£ADØË“Pò±›Ëþ„¿ðuáí¼†·ŒôXé0˱©±À >>>/Annots 379 0 R>>endobj +864 0 obj<>stream +xÚ͛ÝsÜ6ÀßýWè±}ÈFâ‡>§éå®M}ñf®7әe­ØºxW®V›Œÿû(‚ëšÜ<Ļ팧,ɟ@€þó¬Èróo‘U"“e¶ZŸ½Zž½|Ód"ϖŸ²B7YY©lyýòýx×eçìbØLÝfÚþ¸üÿÙO˳|‘ü(àÇûŸ j‘g¥Ô‹:[gM¾Ô¸Ë®€¾7a¼É^¾QYQÀï3_QÊҌ5¿ðr'øE¹æÍÿYœÐ?²NÈ/Ä¢4òº6Ÿ-R)¤iƒc·íÆ/Ý?‡ÿè·Ó0>¶ÖGX6 ¹òf¡@.U.4µ˜\E¾P{r½éï:»YÌ>:æ2¦$Ó l4#Y^/*jyÉtS™¶•¬ßL«ö`f[ëښ*OHXKóÓH(jsİÅ$¬íʽïþÜuÛéý0ØÓ§•z"&e+ko +c.Jj1ÙªÊû·—í궘’fOdõ’âé͉,Œ=ÅOWhN®à̍ç×ë~c¯:‰ý©Š„pf%”_;ÛbÂ)…6…{…¢Ôâ¥ä“9ZQÍ-&ŸYRáå{×®;:x'!`R¸¢"£"µ˜pEíEs6E5§âѕH—K´*R˜“„-&\®Ðª\=l§nýó8ì¬[(óS/%›2¡™5)…0&[^6ÕhR–Ýúþu?ZwW›'ãî’òUZ£Hj1ùª­Ê²_wÃn:Ew.–Êš•F˜]ˆ &_©Ñª|0q˜ £›“ ¢#šK€PÖ´T 6H@sUQڇcýæ&{ZW~ö¼8‹ú…?ÈO³øtŒóæA_íÆ~²!½è¸æ\©Än’š:•;Ž-¶d¦î|7ݚÛ_¿j§~ØD4Å0Z‚É nq?l£‹ÈëLÍ¢ÙÃÑÂ]tãÔ‚¯Ä»‡zӕT²Phsóbn1% 67¥ 6£y²Ì{ÕnûUƦXÓFnëîÔóšM¥J. +2üÅÜbJ6îN®dDz@À²Jv°×ý¹4Ehl>h¹‚ýÐhñþFËÏézUW±ljº+WæcË«X6Íâ@sê§ÃF†,Qsˆ×n®cÙO‡¼ Ü%B ˜ ×"80Gx±ŽîïVÌô÷5SU܉ÊZ[gUBVމʺœh7>­ 6Ö)Ÿ¹„¢~4«Õ°³>™býúD•HÙɪÀ”ea'6؞®z–åm÷´žØTð¤X ê'T»ZuÛíÿbØÕo n1!Ûfýc^“šÖµõ6¨Û`š62–jš8…ÜõªÇaL(š1@Ñv4'º„œ]q{'­´u8¨ Û`Š6á«:PÑÄ)¤ÚQ?¡îۛ.¥gŁÚæ¬gʼn^ϋ£jºI˜Yã¿ÁQh oÌÌJ‰N„yZ5l®-œ¨D݄Z>ÜGã6¯=yH£~yˆge³ñÖ³'¢Èh| ™yÜKN¤UeѐK“s‹a¿}ݯ»ÅôpO7‰æT’ Iár,ÁAÜ£©Å„Ë©ÎfÅ[ ›/V<}™9È:ІÊk9ܱåe •×ί¯A¾ŸÆ(߇¹Ò}»bqcΑæZª÷4€ñ“Ǧ㵡܃Ñÿ}æìمÏi-u"'*ªæ–`‹-W=W q(Ÿ© +Òh€¾û/Fñ4…ò@ã܋= pÀøj±éV{É祷fq/_G`5WœÈå#Qk¦¹¹ÈúŒi¾ä¢—%s>Øb‹^RAõ?c?%iÃi&<! Üόûï°ãчô,ßé= Úo_c9.6Ö[ï‹éTÜ3Ɩ\sA›ê¯f´!FbsáòÚÀ¡HMåIÉcǧ!uàÜâ±C+ô¼edóÁíTH,Ã}ÿ›¾ôåMoMÌ EUáêiÑ=À¬H[ƒÓl¯£¼ˆ¬‡ŸiBDk8»'Òf#"ÜTv;Ü×~ºÈçgC)HÂ~ $´ýŽõÛtÝÀl>œ.Èo…‚â‡ÃüЖj/G¡ÐƒŠýGM;Ä; ÷¢Iîõcª¦ß\_£é4É> ì¯ +in€xìWqýӉâ9nW·V9{ok•׋oŠ¥†ç‰Ã¨›pé³J BBö/ Q?‘ÒëÅàìå>Ï `xƊ#±ÈªAî§vÏŒO¨Ùžú©Ý;›˜-só!·ÇÂN‚Ä?‡”`®Hà Wçék;F¢?„ƒz?‡a/Á~éWÝfÛń›çƒmUÄ³ÝNI7c×­ÍQµ¢âˆ¶u¡eØŸëT Ù’=Ö ’4%=Ù¹ÖëØFOÁÛf ±—PÞ½ý=~Ùlf’‚ø¹ ^9ÙîæPÏϐv–ðv‡Ý‡¾Áòó!S v8€a7Á’ûŠ ­lö$¥n÷dŠï+U~‡ T§þæË½h‚ÇZ‡º`ãæ·›i®w+÷¨ëTê£Mê $•~•}U¾åu/™Æöº[·ãçS*ü–‰¢¶ ÷9TçÛ+ûRÆ´ß´ãC²ŠH${iâ$ê&Øë~;ýÇ]â¹³§À‘„7» ù¾¿¹\F÷™Ó ¨_/@>ÿ nMò…2f´¡ºbvñáò*›}“ýË2PH; ã6ûµÝìZ{¥”öùê‹ +_Lô}Ošú÷Ù_¹øU9endstream +endobj +865 0 obj +2541 +endobj +866 0 obj<>>>/Annots 408 0 R>>endobj +867 0 obj<>stream +xÚ͛[wܶÇßõ)ا¶^7‚|ÔÍ©{$YÕ®’“ǵDɬµK•\Ùq?}1À`1 $J­K’#ƒŸ‰™?ùÏËró/ËDÿ]¬vö;ï?TϳÅUÆT•Zf‹Ë¿-–ŸoꬽÊöÛõ¦^oú¿/þ½s¸ØÉg¹!À?Î~É4ŸåY!Ô¬ÌVË óÛµn²9à#ºëìý™1¡æÆF˜¿q~w{Ûvø{7”ÃÎÞÄ?{töæéÍì9Ÿföür œ¼€¶0m3—_NγG9d¨ñ"+f:a¿Gžží=Ž£ÃSåLœ#…ÆÄäú=êèãÞÙîÙï©H Ê+4x–òÐ`ûl£¡'Uq‰€ÎÀÇBO †§$¼à”‡aÆ!ô “g }¡}^ÓÈT)ÌOHG3† |Ø÷æ°²¼—ðeo`Նݖò.A©¥P3> T²ß®Ví:!¾0fWژ…ý–uRo¾·Ý×ÔìÂxC“Ž'C‹›×›M³¾¶ Ð3öª Z«ô{®ŠÊ®G$ר +À/>æW:w‹Y定ë»ÎLðq8?wQ´ë÷ÈeÊña,8ž™7'"¡GG’ °Ì‡³FühÖôîjyQc0‹f"€¶ PªpK‡uŵp.¦hPJ»ufRÜ(Ü-MVŠˆÞ¡›/uÊÕa8¬¬ÁÐaOS«j ù¥ØN|»ª:dí^^vuß§2MA|ǹ‚Ì«"àÎû¤Ûèp3éaoàŸîìX&UÏ&']ŒÈÆ,92ÈÆ¶ˆlLhäSeã‰.¬”è :E6æâÁÐadãY.æ 5U6İF@ÇM“‡)aRNóˆ;CÝgòçÑͨhdÛ­hl‹ˆF0Ó~¢h<Ñ•½B§ˆÆÃ\T# l‚h<ËE-¬jÄ3•˜ ͸ƒi[5• ¢ia#¡˜]e­»æêGrÞd¸)V .XØ]Ž*… 5ÁPŠG ì· S£`³ü'"KÆC5aƒAiÞÀ—NëúbÓ´k[ò—¯QLè‘`åÂFº/Ø V.} ˜®½ÉhÈ9”Æ”…ýrjÍF°ñƒ3ˆç ä fKmýÞqȨ1 •ôü¹öj‡¬L‡LV¹-;lMí!d²bO(ÿ­°ˆýˆÜý£éÓç*,À$d¨æ fßµT‚ƒÓâ 7¯»ouç╿ౠ+ \58­íÂï¼j$pº|BF.©±ˆýˆö &ë »Xö_S©žàöa‡Ç¡⮺v•º{HÃÉ%|·ŠhƀLyݚüœÒ1\©‡ç x¼¼øÒ¬k'cö3—ü*Q°r—òœÒ”ˆ6ëf˜¤_d8…QvËÉêE’S%a·œ¦]Ä ¢(ûåŸP®‡:]Q¨7Óu‹0Ô]C9YµžÅïyͪV. +t$¨b'nû­þœR~ Ê/‡ðîFl×~7 ŒÕ½(æyB5r“ž w…Ñîß]ƒè^†Ûšxå ¡¸@pÇy"æ¹~O<«¯îúú2}¯Gžfۇ%÷zD×}¿¼vûɽÿgswµ¯€ƒ6× Îæx­ï·®Ù$ê 2؆m@Ândv]ªÎ Ãa›n‹`؏°·àâ‡æ•oÿ‡—÷` nàa}f ày{µù¾ìꌤ½¶ë³ãåúny¼wLÂzôNs;Áæúï_;ÿ4”ªÇendstream +endobj +868 0 obj +2371 +endobj +869 0 obj<>endobj +870 0 obj<>endobj +871 0 obj<>endobj +872 0 obj<>endobj +873 0 obj<>endobj +874 0 obj<>endobj +875 0 obj<>endobj +876 0 obj<>endobj +877 0 obj<>endobj +878 0 obj<>endobj +879 0 obj<>endobj +880 0 obj<>endobj +881 0 obj<>endobj +882 0 obj<>endobj +883 0 obj<>endobj +884 0 obj<>endobj +885 0 obj<>endobj +886 0 obj<>endobj +887 0 obj<>endobj +888 0 obj<>endobj +889 0 obj<>endobj +890 0 obj<>endobj +891 0 obj<>endobj +892 0 obj<>endobj +893 0 obj<>endobj +894 0 obj<>endobj +895 0 obj<>endobj +896 0 obj<>endobj +897 0 obj<>endobj +898 0 obj<>endobj +899 0 obj<>endobj +900 0 obj<>endobj +901 0 obj<>endobj +902 0 obj<>endobj +903 0 obj<>endobj +904 0 obj<>endobj +905 0 obj<>endobj +906 0 obj<>endobj +907 0 obj<>endobj +908 0 obj<>endobj +909 0 obj<>endobj +910 0 obj<>endobj +911 0 obj<>endobj +912 0 obj<>endobj +913 0 obj<>endobj +914 0 obj<>endobj +915 0 obj<>endobj +916 0 obj<>endobj +917 0 obj<>endobj +918 0 obj<>endobj +919 0 obj<>endobj +920 0 obj<>endobj +921 0 obj<>endobj +922 0 obj<>endobj +923 0 obj<>endobj +924 0 obj<>endobj +925 0 obj<>endobj +926 0 obj<>endobj +927 0 obj<>endobj +928 0 obj<>endobj +929 0 obj<>endobj +930 0 obj<>endobj +931 0 obj<>endobj +932 0 obj<>endobj +933 0 obj<>endobj +934 0 obj<>endobj +935 0 obj<>endobj +936 0 obj<>endobj +937 0 obj<>endobj +938 0 obj<>endobj +939 0 obj<>endobj +940 0 obj<>endobj +941 0 obj<>endobj +942 0 obj<>endobj +943 0 obj<>endobj +944 0 obj<>endobj +945 0 obj<>endobj +946 0 obj<>endobj +947 0 obj<>endobj +948 0 obj<>endobj +949 0 obj<>endobj +950 0 obj<>endobj +951 0 obj<>endobj +952 0 obj<>endobj +953 0 obj<>endobj +954 0 obj<>endobj +955 0 obj<>endobj +956 0 obj<>endobj +957 0 obj<>endobj +958 0 obj<>endobj +959 0 obj<>endobj +960 0 obj<>endobj +961 0 obj<>endobj +962 0 obj<>endobj +963 0 obj<>endobj +964 0 obj<>endobj +965 0 obj<>endobj +966 0 obj<>endobj +967 0 obj<>endobj +968 0 obj<>endobj +969 0 obj<>endobj +970 0 obj<>endobj +971 0 obj<>endobj +972 0 obj<>endobj +973 0 obj<>endobj +974 0 obj<>endobj +975 0 obj<>endobj +976 0 obj<>endobj +977 0 obj<>endobj +978 0 obj<>endobj +979 0 obj<>endobj +980 0 obj<>endobj +981 0 obj<>endobj +982 0 obj<>endobj +983 0 obj<>endobj +984 0 obj<>endobj +985 0 obj<>endobj +986 0 obj<>endobj +987 0 obj<>endobj +988 0 obj<>endobj +989 0 obj<>endobj +990 0 obj<>endobj +991 0 obj<>endobj +992 0 obj<>endobj +993 0 obj<>endobj +994 0 obj<>endobj +995 0 obj<>endobj +996 0 obj<>endobj +997 0 obj<>endobj +998 0 obj<>endobj +999 0 obj<>endobj +1000 0 obj<>endobj +1001 0 obj<>endobj +1002 0 obj<>endobj +1003 0 obj<>endobj +1004 0 obj<>endobj +1005 0 obj<>endobj +1006 0 obj<>endobj +1007 0 obj<>endobj +1008 0 obj<>endobj +1009 0 obj<>endobj +1010 0 obj<>endobj +1011 0 obj<>endobj +1012 0 obj<>endobj +1013 0 obj<>endobj +1014 0 obj<>endobj +1015 0 obj<>endobj +1016 0 obj<>endobj +1017 0 obj<>endobj +1018 0 obj<>endobj +1019 0 obj<>endobj +1020 0 obj<>endobj +1021 0 obj<>endobj +1022 0 obj<>endobj +1023 0 obj<>endobj +1024 0 obj<>endobj +1025 0 obj<>endobj +1026 0 obj<>endobj +1027 0 obj<>endobj +1028 0 obj<>endobj +1029 0 obj<>endobj +1030 0 obj<>endobj +1031 0 obj<>endobj +1032 0 obj<>1<>2<>6<>]>>>>endobj +xref +0 1033 +0000000000 65535 f +0000000015 00000 n +0000000229 00000 n +0000001795 00000 n +0000001869 00000 n +0000001948 00000 n +0000002030 00000 n +0000002116 00000 n +0000002194 00000 n +0000002271 00000 n +0000002350 00000 n +0000002434 00000 n +0000002511 00000 n +0000002593 00000 n +0000002678 00000 n +0000002737 00000 n +0000002789 00000 n +0000002874 00000 n +0000002926 00000 n +0000003010 00000 n +0000003041 00000 n +0000003145 00000 n +0000003249 00000 n +0000003298 00000 n +0000003382 00000 n +0000003486 00000 n +0000003590 00000 n +0000003694 00000 n +0000003798 00000 n +0000003902 00000 n +0000004006 00000 n +0000004110 00000 n +0000004214 00000 n +0000004318 00000 n +0000004419 00000 n +0000004524 00000 n +0000004589 00000 n +0000004674 00000 n +0000004732 00000 n +0000004815 00000 n +0000004853 00000 n +0000004913 00000 n +0000004997 00000 n +0000005021 00000 n +0000005078 00000 n +0000005162 00000 n +0000005267 00000 n +0000005370 00000 n +0000005472 00000 n +0000005517 00000 n +0000005574 00000 n +0000005659 00000 n +0000005764 00000 n +0000005869 00000 n +0000005907 00000 n +0000005964 00000 n +0000006048 00000 n +0000006072 00000 n +0000006129 00000 n +0000006213 00000 n +0000006318 00000 n +0000006423 00000 n +0000006461 00000 n +0000006566 00000 n +0000006671 00000 n +0000006776 00000 n +0000006881 00000 n +0000006926 00000 n +0000007031 00000 n +0000007136 00000 n +0000007241 00000 n +0000007279 00000 n +0000007384 00000 n +0000007489 00000 n +0000007520 00000 n +0000007625 00000 n +0000007730 00000 n +0000007835 00000 n +0000007940 00000 n +0000008045 00000 n +0000008150 00000 n +0000008255 00000 n +0000008360 00000 n +0000008465 00000 n +0000008570 00000 n +0000008675 00000 n +0000008780 00000 n +0000008885 00000 n +0000008990 00000 n +0000009095 00000 n +0000009200 00000 n +0000009305 00000 n +0000009410 00000 n +0000009515 00000 n +0000009620 00000 n +0000009725 00000 n +0000009830 00000 n +0000009935 00000 n +0000010040 00000 n +0000010145 00000 n +0000010250 00000 n +0000010356 00000 n +0000010462 00000 n +0000010568 00000 n +0000010674 00000 n +0000010780 00000 n +0000010886 00000 n +0000010992 00000 n +0000011098 00000 n +0000011204 00000 n +0000011310 00000 n +0000011416 00000 n +0000011522 00000 n +0000011628 00000 n +0000011734 00000 n +0000011840 00000 n +0000011946 00000 n +0000012052 00000 n +0000012158 00000 n +0000012264 00000 n +0000012370 00000 n +0000012476 00000 n +0000012582 00000 n +0000012688 00000 n +0000012794 00000 n +0000013186 00000 n +0000013292 00000 n +0000013396 00000 n +0000013430 00000 n +0000013536 00000 n +0000013642 00000 n +0000013748 00000 n +0000013854 00000 n +0000013904 00000 n +0000014010 00000 n +0000014036 00000 n +0000014142 00000 n +0000014168 00000 n +0000014274 00000 n +0000014380 00000 n +0000014414 00000 n +0000014520 00000 n +0000014546 00000 n +0000014652 00000 n +0000014758 00000 n +0000014792 00000 n +0000014898 00000 n +0000014924 00000 n +0000015030 00000 n +0000015056 00000 n +0000015162 00000 n +0000015268 00000 n +0000015302 00000 n +0000015408 00000 n +0000015434 00000 n +0000015540 00000 n +0000015566 00000 n +0000015672 00000 n +0000015778 00000 n +0000015812 00000 n +0000015918 00000 n +0000015944 00000 n +0000016050 00000 n +0000016076 00000 n +0000016182 00000 n +0000016208 00000 n +0000016314 00000 n +0000016419 00000 n +0000016524 00000 n +0000016629 00000 n +0000016733 00000 n +0000016837 00000 n +0000016941 00000 n +0000017047 00000 n +0000017129 00000 n +0000017235 00000 n +0000017340 00000 n +0000017446 00000 n +0000017488 00000 n +0000017593 00000 n +0000017699 00000 n +0000017733 00000 n +0000017838 00000 n +0000017864 00000 n +0000017970 00000 n +0000017996 00000 n +0000018102 00000 n +0000018206 00000 n +0000018240 00000 n +0000018292 00000 n +0000018379 00000 n +0000018415 00000 n +0000018502 00000 n +0000018554 00000 n +0000018641 00000 n +0000018683 00000 n +0000018740 00000 n +0000018827 00000 n +0000018878 00000 n +0000018965 00000 n +0000018999 00000 n +0000019053 00000 n +0000019140 00000 n +0000019197 00000 n +0000019284 00000 n +0000019344 00000 n +0000019430 00000 n +0000019472 00000 n +0000019525 00000 n +0000019612 00000 n +0000019638 00000 n +0000019743 00000 n +0000019849 00000 n +0000019954 00000 n +0000020060 00000 n +0000020110 00000 n +0000020216 00000 n +0000020322 00000 n +0000020428 00000 n +0000020534 00000 n +0000020640 00000 n +0000020746 00000 n +0000020812 00000 n +0000020865 00000 n +0000020952 00000 n +0000021009 00000 n +0000021096 00000 n +0000021202 00000 n +0000021308 00000 n +0000021413 00000 n +0000021471 00000 n +0000021577 00000 n +0000021681 00000 n +0000021787 00000 n +0000021891 00000 n +0000021996 00000 n +0000022102 00000 n +0000022168 00000 n +0000022213 00000 n +0000022300 00000 n +0000022345 00000 n +0000022432 00000 n +0000022477 00000 n +0000022564 00000 n +0000022606 00000 n +0000022711 00000 n +0000022817 00000 n +0000022923 00000 n +0000023029 00000 n +0000023135 00000 n +0000023241 00000 n +0000023346 00000 n +0000023452 00000 n +0000023558 00000 n +0000023664 00000 n +0000023770 00000 n +0000023876 00000 n +0000023982 00000 n +0000024088 00000 n +0000024194 00000 n +0000024299 00000 n +0000024405 00000 n +0000024511 00000 n +0000024617 00000 n +0000024723 00000 n +0000024829 00000 n +0000024935 00000 n +0000025041 00000 n +0000025147 00000 n +0000025253 00000 n +0000025358 00000 n +0000025464 00000 n +0000025570 00000 n +0000025676 00000 n +0000025782 00000 n +0000025888 00000 n +0000025994 00000 n +0000026100 00000 n +0000026206 00000 n +0000026312 00000 n +0000026418 00000 n +0000026524 00000 n +0000026629 00000 n +0000026735 00000 n +0000026841 00000 n +0000026946 00000 n +0000027050 00000 n +0000027404 00000 n +0000027509 00000 n +0000027614 00000 n +0000027720 00000 n +0000027826 00000 n +0000027932 00000 n +0000028038 00000 n +0000028143 00000 n +0000028248 00000 n +0000028353 00000 n +0000028458 00000 n +0000028563 00000 n +0000028669 00000 n +0000028775 00000 n +0000028881 00000 n +0000028987 00000 n +0000029093 00000 n +0000029199 00000 n +0000029305 00000 n +0000029411 00000 n +0000029517 00000 n +0000029623 00000 n +0000029729 00000 n +0000029835 00000 n +0000029941 00000 n +0000030047 00000 n +0000030153 00000 n +0000030259 00000 n +0000030365 00000 n +0000030471 00000 n +0000030577 00000 n +0000030683 00000 n +0000030789 00000 n +0000030895 00000 n +0000031001 00000 n +0000031107 00000 n +0000031213 00000 n +0000031319 00000 n +0000031425 00000 n +0000031531 00000 n +0000031637 00000 n +0000031743 00000 n +0000031849 00000 n +0000031955 00000 n +0000032060 00000 n +0000032164 00000 n +0000032268 00000 n +0000032654 00000 n +0000032760 00000 n +0000032866 00000 n +0000032972 00000 n +0000033078 00000 n +0000033184 00000 n +0000033290 00000 n +0000033396 00000 n +0000033502 00000 n +0000033608 00000 n +0000033714 00000 n +0000033820 00000 n +0000033926 00000 n +0000034032 00000 n +0000034138 00000 n +0000034244 00000 n +0000034350 00000 n +0000034456 00000 n +0000034562 00000 n +0000034668 00000 n +0000034774 00000 n +0000034880 00000 n +0000034986 00000 n +0000035092 00000 n +0000035198 00000 n +0000035304 00000 n +0000035410 00000 n +0000035516 00000 n +0000035622 00000 n +0000035728 00000 n +0000035833 00000 n +0000035939 00000 n +0000036045 00000 n +0000036151 00000 n +0000036257 00000 n +0000036363 00000 n +0000036469 00000 n +0000036575 00000 n +0000036681 00000 n +0000036787 00000 n +0000036893 00000 n +0000036998 00000 n +0000037104 00000 n +0000037209 00000 n +0000037313 00000 n +0000037417 00000 n +0000037795 00000 n +0000037901 00000 n +0000038006 00000 n +0000038111 00000 n +0000038216 00000 n +0000038321 00000 n +0000038427 00000 n +0000038533 00000 n +0000038639 00000 n +0000038744 00000 n +0000038849 00000 n +0000038954 00000 n +0000039059 00000 n +0000039164 00000 n +0000039269 00000 n +0000039374 00000 n +0000039479 00000 n +0000039584 00000 n +0000039689 00000 n +0000039794 00000 n +0000039899 00000 n +0000040004 00000 n +0000040109 00000 n +0000040214 00000 n +0000040319 00000 n +0000040424 00000 n +0000040529 00000 n +0000040634 00000 n +0000040739 00000 n +0000040981 00000 n +0000041015 00000 n +0000041049 00000 n +0000043757 00000 n +0000043806 00000 n +0000043855 00000 n +0000043904 00000 n +0000043953 00000 n +0000044002 00000 n +0000044051 00000 n +0000044100 00000 n +0000044149 00000 n +0000044198 00000 n +0000044247 00000 n +0000044296 00000 n +0000044345 00000 n +0000044394 00000 n +0000044443 00000 n +0000044492 00000 n +0000044541 00000 n +0000044590 00000 n +0000044639 00000 n +0000044688 00000 n +0000044737 00000 n +0000044786 00000 n +0000044835 00000 n +0000044884 00000 n +0000044933 00000 n +0000044982 00000 n +0000045031 00000 n +0000045080 00000 n +0000045129 00000 n +0000045178 00000 n +0000045227 00000 n +0000045276 00000 n +0000045325 00000 n +0000045374 00000 n +0000045423 00000 n +0000045472 00000 n +0000045521 00000 n +0000045570 00000 n +0000045619 00000 n +0000045668 00000 n +0000045717 00000 n +0000045766 00000 n +0000045815 00000 n +0000045864 00000 n +0000045913 00000 n +0000045962 00000 n +0000046011 00000 n +0000046060 00000 n +0000046109 00000 n +0000046158 00000 n +0000046207 00000 n +0000046256 00000 n +0000046305 00000 n +0000046354 00000 n +0000046403 00000 n +0000046452 00000 n +0000046501 00000 n +0000046550 00000 n +0000046599 00000 n +0000046648 00000 n +0000046697 00000 n +0000046746 00000 n +0000046795 00000 n +0000046844 00000 n +0000046893 00000 n +0000046942 00000 n +0000046991 00000 n +0000047040 00000 n +0000047089 00000 n +0000047138 00000 n +0000047187 00000 n +0000047236 00000 n +0000047285 00000 n +0000047334 00000 n +0000047383 00000 n +0000047432 00000 n +0000047481 00000 n +0000047530 00000 n +0000047579 00000 n +0000047628 00000 n +0000047677 00000 n +0000047726 00000 n +0000047775 00000 n +0000047824 00000 n +0000047873 00000 n +0000047922 00000 n +0000047971 00000 n +0000048020 00000 n +0000048069 00000 n +0000048118 00000 n +0000048167 00000 n +0000048216 00000 n +0000048265 00000 n +0000048314 00000 n +0000048363 00000 n +0000048412 00000 n +0000048461 00000 n +0000048510 00000 n +0000048559 00000 n +0000048608 00000 n +0000048657 00000 n +0000048706 00000 n +0000048755 00000 n +0000048804 00000 n +0000048853 00000 n +0000048902 00000 n +0000048951 00000 n +0000049000 00000 n +0000049049 00000 n +0000049098 00000 n +0000049147 00000 n +0000049196 00000 n +0000049245 00000 n +0000049294 00000 n +0000049343 00000 n +0000049392 00000 n +0000049441 00000 n +0000049490 00000 n +0000049539 00000 n +0000049588 00000 n +0000049637 00000 n +0000049686 00000 n +0000049735 00000 n +0000049784 00000 n +0000049833 00000 n +0000049882 00000 n +0000049931 00000 n +0000049980 00000 n +0000050029 00000 n +0000050078 00000 n +0000050127 00000 n +0000050176 00000 n +0000050225 00000 n +0000050274 00000 n +0000050323 00000 n +0000050372 00000 n +0000050421 00000 n +0000050470 00000 n +0000050519 00000 n +0000050568 00000 n +0000050617 00000 n +0000050666 00000 n +0000050715 00000 n +0000050764 00000 n +0000050813 00000 n +0000050862 00000 n +0000050911 00000 n +0000050960 00000 n +0000051009 00000 n +0000051058 00000 n +0000051107 00000 n +0000051156 00000 n +0000051205 00000 n +0000051254 00000 n +0000051303 00000 n +0000051352 00000 n +0000051401 00000 n +0000051450 00000 n +0000051499 00000 n +0000051548 00000 n +0000051597 00000 n +0000051646 00000 n +0000051695 00000 n +0000052548 00000 n +0000052702 00000 n +0000059059 00000 n +0000059081 00000 n +0000059176 00000 n +0000059278 00000 n +0000059298 00000 n +0000059445 00000 n +0000060355 00000 n +0000060376 00000 n +0000060570 00000 n +0000062069 00000 n +0000062091 00000 n +0000062233 00000 n +0000062662 00000 n +0000062683 00000 n +0000062797 00000 n +0000062993 00000 n +0000063014 00000 n +0000063156 00000 n +0000064063 00000 n +0000064084 00000 n +0000064226 00000 n +0000065750 00000 n +0000065772 00000 n +0000065914 00000 n +0000066909 00000 n +0000066930 00000 n +0000067044 00000 n +0000067242 00000 n +0000067263 00000 n +0000067419 00000 n +0000068376 00000 n +0000068397 00000 n +0000068572 00000 n +0000069488 00000 n +0000069509 00000 n +0000069669 00000 n +0000070628 00000 n +0000070649 00000 n +0000070800 00000 n +0000071289 00000 n +0000071310 00000 n +0000071452 00000 n +0000072101 00000 n +0000072122 00000 n +0000072306 00000 n +0000073844 00000 n +0000073866 00000 n +0000074059 00000 n +0000075541 00000 n +0000075563 00000 n +0000075737 00000 n +0000076750 00000 n +0000076771 00000 n +0000076940 00000 n +0000077787 00000 n +0000077808 00000 n +0000077992 00000 n +0000078795 00000 n +0000078816 00000 n +0000079000 00000 n +0000079966 00000 n +0000079987 00000 n +0000080171 00000 n +0000081358 00000 n +0000081380 00000 n +0000081555 00000 n +0000082238 00000 n +0000082259 00000 n +0000082429 00000 n +0000083311 00000 n +0000083332 00000 n +0000083509 00000 n +0000085301 00000 n +0000085323 00000 n +0000085499 00000 n +0000086629 00000 n +0000086651 00000 n +0000086828 00000 n +0000087657 00000 n +0000087678 00000 n +0000087844 00000 n +0000088787 00000 n +0000088808 00000 n +0000088975 00000 n +0000089740 00000 n +0000089761 00000 n +0000089927 00000 n +0000090877 00000 n +0000090898 00000 n +0000091040 00000 n +0000091876 00000 n +0000091897 00000 n +0000092063 00000 n +0000092881 00000 n +0000092902 00000 n +0000093044 00000 n +0000093661 00000 n +0000093682 00000 n +0000093858 00000 n +0000095064 00000 n +0000095086 00000 n +0000095253 00000 n +0000096132 00000 n +0000096153 00000 n +0000096310 00000 n +0000097069 00000 n +0000097090 00000 n +0000097247 00000 n +0000097999 00000 n +0000098020 00000 n +0000098196 00000 n +0000099045 00000 n +0000099066 00000 n +0000099252 00000 n +0000100113 00000 n +0000100134 00000 n +0000100301 00000 n +0000101069 00000 n +0000101090 00000 n +0000101232 00000 n +0000101858 00000 n +0000101879 00000 n +0000102046 00000 n +0000102996 00000 n +0000103017 00000 n +0000103184 00000 n +0000103913 00000 n +0000103934 00000 n +0000104110 00000 n +0000105002 00000 n +0000105023 00000 n +0000105165 00000 n +0000105652 00000 n +0000105673 00000 n +0000105839 00000 n +0000107349 00000 n +0000107371 00000 n +0000107556 00000 n +0000108790 00000 n +0000108812 00000 n +0000108982 00000 n +0000110306 00000 n +0000110328 00000 n +0000110504 00000 n +0000111431 00000 n +0000111452 00000 n +0000111628 00000 n +0000112923 00000 n +0000112945 00000 n +0000113116 00000 n +0000114183 00000 n +0000114204 00000 n +0000114381 00000 n +0000115891 00000 n +0000115913 00000 n +0000116074 00000 n +0000117476 00000 n +0000117498 00000 n +0000117665 00000 n +0000118846 00000 n +0000118868 00000 n +0000119020 00000 n +0000119834 00000 n +0000119855 00000 n +0000120043 00000 n +0000121474 00000 n +0000121496 00000 n +0000121648 00000 n +0000122278 00000 n +0000122299 00000 n +0000122431 00000 n +0000123283 00000 n +0000123304 00000 n +0000123480 00000 n +0000124638 00000 n +0000124660 00000 n +0000124774 00000 n +0000124980 00000 n +0000125001 00000 n +0000125149 00000 n +0000125992 00000 n +0000126013 00000 n +0000126180 00000 n +0000127634 00000 n +0000127656 00000 n +0000127813 00000 n +0000128203 00000 n +0000128224 00000 n +0000128366 00000 n +0000129881 00000 n +0000129903 00000 n +0000130036 00000 n +0000131933 00000 n +0000131955 00000 n +0000132078 00000 n +0000133893 00000 n +0000133915 00000 n +0000134048 00000 n +0000135999 00000 n +0000136021 00000 n +0000136154 00000 n +0000136898 00000 n +0000136919 00000 n +0000137061 00000 n +0000138769 00000 n +0000138791 00000 n +0000138934 00000 n +0000140888 00000 n +0000140910 00000 n +0000141043 00000 n +0000142795 00000 n +0000142817 00000 n +0000142950 00000 n +0000144727 00000 n +0000144749 00000 n +0000144882 00000 n +0000146720 00000 n +0000146742 00000 n +0000146875 00000 n +0000148848 00000 n +0000148870 00000 n +0000149013 00000 n +0000149746 00000 n +0000149767 00000 n +0000149881 00000 n +0000150095 00000 n +0000150116 00000 n +0000150249 00000 n +0000150940 00000 n +0000150961 00000 n +0000151122 00000 n +0000152374 00000 n +0000152396 00000 n +0000152566 00000 n +0000153525 00000 n +0000153546 00000 n +0000153721 00000 n +0000155013 00000 n +0000155035 00000 n +0000155214 00000 n +0000156365 00000 n +0000156387 00000 n +0000156557 00000 n +0000157596 00000 n +0000157617 00000 n +0000157768 00000 n +0000158681 00000 n +0000158702 00000 n +0000158816 00000 n +0000159027 00000 n +0000159048 00000 n +0000159216 00000 n +0000159996 00000 n +0000160017 00000 n +0000160169 00000 n +0000160829 00000 n +0000160850 00000 n +0000160992 00000 n +0000161815 00000 n +0000161836 00000 n +0000161959 00000 n +0000163230 00000 n +0000163252 00000 n +0000163375 00000 n +0000164223 00000 n +0000164244 00000 n +0000164358 00000 n +0000164557 00000 n +0000164578 00000 n +0000164755 00000 n +0000165782 00000 n +0000165803 00000 n +0000165979 00000 n +0000167129 00000 n +0000167151 00000 n +0000167299 00000 n +0000168651 00000 n +0000168673 00000 n +0000168814 00000 n +0000169330 00000 n +0000169351 00000 n +0000169508 00000 n +0000172227 00000 n +0000172249 00000 n +0000172406 00000 n +0000174417 00000 n +0000174439 00000 n +0000174596 00000 n +0000177208 00000 n +0000177230 00000 n +0000177387 00000 n +0000179829 00000 n +0000179851 00000 n +0000179908 00000 n +0000180013 00000 n +0000180157 00000 n +0000180260 00000 n +0000180378 00000 n +0000180499 00000 n +0000180613 00000 n +0000180717 00000 n +0000180882 00000 n +0000180990 00000 n +0000181105 00000 n +0000181210 00000 n +0000181318 00000 n +0000181426 00000 n +0000181535 00000 n +0000181651 00000 n +0000181749 00000 n +0000181918 00000 n +0000182074 00000 n +0000182174 00000 n +0000182289 00000 n +0000182413 00000 n +0000182521 00000 n +0000182677 00000 n +0000182799 00000 n +0000182930 00000 n +0000183051 00000 n +0000183210 00000 n +0000183308 00000 n +0000183470 00000 n +0000183605 00000 n +0000183731 00000 n +0000183907 00000 n +0000184024 00000 n +0000184142 00000 n +0000184270 00000 n +0000184401 00000 n +0000184523 00000 n +0000184641 00000 n +0000184797 00000 n +0000184895 00000 n +0000185042 00000 n +0000185190 00000 n +0000185294 00000 n +0000185447 00000 n +0000185568 00000 n +0000185692 00000 n +0000185832 00000 n +0000185972 00000 n +0000186100 00000 n +0000186267 00000 n +0000186365 00000 n +0000186492 00000 n +0000186626 00000 n +0000186781 00000 n +0000186878 00000 n +0000186984 00000 n +0000187094 00000 n +0000187208 00000 n +0000187317 00000 n +0000187431 00000 n +0000187543 00000 n +0000187654 00000 n +0000187766 00000 n +0000187881 00000 n +0000187992 00000 n +0000188103 00000 n +0000188215 00000 n +0000188332 00000 n +0000188446 00000 n +0000188555 00000 n +0000188663 00000 n +0000188778 00000 n +0000188894 00000 n +0000188999 00000 n +0000189112 00000 n +0000189221 00000 n +0000189327 00000 n +0000189443 00000 n +0000189559 00000 n +0000189669 00000 n +0000189786 00000 n +0000189893 00000 n +0000190002 00000 n +0000190111 00000 n +0000190222 00000 n +0000190333 00000 n +0000190448 00000 n +0000190554 00000 n +0000190662 00000 n +0000190767 00000 n +0000190886 00000 n +0000191003 00000 n +0000191112 00000 n +0000191224 00000 n +0000191333 00000 n +0000191445 00000 n +0000191555 00000 n +0000191666 00000 n +0000191777 00000 n +0000191889 00000 n +0000191997 00000 n +0000192105 00000 n +0000192197 00000 n +0000192358 00000 n +0000192479 00000 n +0000192606 00000 n +0000192734 00000 n +0000192853 00000 n +0000193008 00000 n +0000193115 00000 n +0000193234 00000 n +0000193339 00000 n +0000193488 00000 n +0000193586 00000 n +0000193697 00000 n +0000193826 00000 n +0000193956 00000 n +0000194085 00000 n +0000194253 00000 n +0000194351 00000 n +0000194477 00000 n +0000194601 00000 n +0000194766 00000 n +0000194888 00000 n +0000195003 00000 n +0000195099 00000 n +0000195226 00000 n +0000195356 00000 n +0000195471 00000 n +0000195641 00000 n +0000195814 00000 n +0000195917 00000 n +0000196032 00000 n +0000196163 00000 n +0000196261 00000 n +0000196391 00000 n +0000196515 00000 n +0000196683 00000 n +0000196843 00000 n +0000196970 00000 n +0000197112 00000 n +0000197241 00000 n +0000197378 00000 n +0000197516 00000 n +0000197651 00000 n +0000197775 00000 n +0000197936 00000 n +0000198042 00000 n +0000198169 00000 n +0000198297 00000 n +0000198420 00000 n +0000198543 00000 n +0000198658 00000 n +0000198760 00000 n +0000198881 00000 n +0000199044 00000 n +0000199183 00000 n +0000199335 00000 n +0000199493 00000 n +0000199650 00000 n +0000199782 00000 n +0000199893 00000 n +trailer +<]>> +startxref +200122 +%%EOF diff --git a/doc/sam.shtml b/doc/sam.shtml new file mode 100644 index 0000000000..d96e2ff2cb --- /dev/null +++ b/doc/sam.shtml @@ -0,0 +1,3890 @@ + + + + + + CUPS Software Administrators Manual + + + +

Preface

+ +

This software administrators manual provides printer administration +information for the Common UNIX Printing SystemTM +("CUPSTM"), version 1.1.1. + + + + +

Document Overview

+ +

This software administrators manual is organized into the following sections:

+ + + +

Notation Conventions

+ +

Various font and syntax conventions are used in this guide. Examples and +their meanings and uses are explained below: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Example   Description
 
lpstat
+ lpstat(1)
   The names of commands; the first mention of a command or + function in a chapter is followed by a manual page section + number.
 
/var
+ /usr/share/cups/data/testprint.ps
   File and directory names.
 
Request ID is Printer-123   Screen output.
 
lp -d printer filename ENTER   Literal user input; special keys like ENTER are + in ALL CAPS.
 
12.3   Numbers in the text are written using the period (.) to indicate + the decimal point.
+ + +

Abbreviations

+ +The following abbreviations are used throughout this manual: + +
    +
    + +
    kb +
    Kilobytes, or 1024 bytes
      + +
    Mb +
    Megabytes, or 1048576 bytes
      + +
    Gb +
    Gigabytes, or 1073741824 bytes
      + +
    +
+ +

Other References

+ +
    +
    + +
    CUPS Software Programmers Manual + +
    A programmer guide for interfacing with and/or extending the CUPS + software.
      + +
    CUPS Software Users Manual + +
    An end-user guide for using the CUPS software.
      + +
    +
+ + + + + +

2 - Building and Installing CUPS

+ +

This chapter shows how to build and install the Common UNIX Printing System. +If you are installing a binary distribution from the CUPS web site, proceed to +the section titled, Installing a Binary Distribution. + +

Installing a Source Distribution

+ +

This section describes how to compile and install CUPS on your system +from the source code. + +

Requirements

+ +

You'll need ANSI-compliant C and C++ compilers to build CUPS on your +system. As its name implies, CUPS is designed to run on the UNIX +operating system, however the CUPS interface library and most of the +filters and backends supplied with CUPS should also compile and run +under Microsoft Windows. + +

For the image file filters and PostScript RIP, you'll need the JPEG, +PNG, TIFF, and ZLIB libraries. CUPS will build without these, but with +significantly reduced functionality. Easy Software Products maintains a +mirror of the current versions of these libraries at: + +

+ +

If you make changes to the man pages you'll need GNU groff or another +nroff-like package. GNU groff is available from: + +

+ +

The documentation is formatted using the HTMLDOC software. If you need to +make changes you can get the HTMLDOC software from: + +

+ +

Compiling CUPS

+ +

CUPS uses GNU autoconf to configure the makefiles and source code +for your system. Type the following command to configure CUPS for your +system: + +

    +./configure ENTER
    +
+ +

The default installation will put the CUPS software in the +/etc, /usr, and /var directories on +your system, which will overwrite any existing printing commands on +your system. Use the --prefix option to install the CUPS +software in another location: + +

    +./configure --prefix=/some/directory ENTER
    +
+ +

If the PNG, JPEG, TIFF, and ZLIB libraries are not installed in a +system default location (typically /usr/include and +/usr/lib) you'll need to set the CFLAGS, +CXXFLAGS, and LDFLAGS environment variables +prior to running configure: + +

    +setenv CFLAGS "-I/some/directory" ENTER
    +setenv CXXFLAGS "-I/some/directory" ENTER
    +setenv LDFLAGS "-L/some/directory" ENTER
    +./configure ... ENTER
    +
+ +

or: + +

    +CFLAGS="-I/some/directory"; export CFLAGS ENTER
    +CXXFLAGS="-I/some/directory"; export CXXFLAGS ENTER
    +LDFLAGS="-L/some/directory"; export LDFLAGS ENTER
    +./configure ... ENTER
    +
+ +

Once you have configured things, just type: + +

    +make ENTER
    +
+ +

to build the software. + + +

Installing the Software

+ +

Use the "install" target to install the software: + +

    +make install ENTER
    +
+ +
+ + + +
+ WARNING: + +

Installing CUPS will overwrite your existing printing + system. If you experience difficulties with the CUPS software + and need to go back to your old printing system, you will need + to reinstall the old printing system from your operating system CDs. +

+ +

Running the Software

+ +

Once you have installed the software you can start the CUPS server by +typing: + +

    +/usr/sbin/cupsd ENTER
    +
+ + +

Installing a Binary Distribution

+ +

CUPS comes in a variety of binary distribution formats. Easy +Software Products provides binaries in TAR format with installation and +removal scripts ("portable" distributions), and in RPM and DPKG formats +for Red Hat and Debian-based distributions. Portable distributions are +available for all platforms, while the RPM and DPKG distributions are +only available for Linux. + +

+ + + +
+ WARNING: + +

Installing CUPS will overwrite your existing printing + system. If you experience difficulties with the CUPS software + and need to go back to your old printing system, you will need + to remove the CUPS software with the provided script and/or + reinstall the old printing system from your operating system CDs. +

+ + +

Installing a Portable Distribution

+ +

To install the CUPS software from a portable distribution you will +need to be logged in as root; doing an su is good enough. +Once you are the root user, run the installation script with: + +

    +./cups.install ENTER
    +
+ +

After asking you a few yes/no questions the CUPS software will be +installed and the scheduler will be started automatically. + + +

Installing an RPM Distribution

+ +

To install the CUPS software from an RPM distribution you will need +to be logged in as root; doing an su is good enough. Once +you are the root user, run RPM with: + +

    +rpm -e lpr
    +rpm -i cups-1.1-linux-M.m.n-intel.rpm ENTER
    +
+ +

After a short delay the CUPS software will be +installed and the scheduler will be started automatically. + +

Installing an Debian Distribution

+ +

To install the CUPS software from a Debian distribution you will +need to be logged in as root; doing an su is good enough. +Once you are the root user, run dpkg with: + +

    +dpkg -i cups-1.1-linux-M.m.n-intel.deb ENTER
    +
+ +

After a short delay the CUPS software will be installed and the +scheduler will be started automatically. + + +

3 - Printer Management

+ +

This chapter describes how to add your first printer and how to +manage your printers. + +

The Basics

+ +

Each printer queue has a name associated with it; the printer name +must start with a letter and can contain up to 127 letters, numbers, +and the underscore (_). Case is not significant, e.g. "PRINTER", "Printer", +and "printer" are considered to be the same name. + +

Printer queues also have a device associated with them. The device can be +a parallel port, a network interface, and so forth. Devices within CUPS use +Uniform Resource Identifiers ("URIs") which are a more general form of +Uniform Resource Locators ("URLs") that are used in your web browser. For +example, the first parallel port in Linux usually uses a device URI of +parallel:/dev/lp1. + + +

You can see a complete list of supported devices by running the +lpinfo(8) command: + +

    +lpinfo -v ENTER
    +file file
    +network socket
    +network http
    +network ipp
    +network lpd
    +direct parallel:/dev/lp1
    +serial serial:/dev/ttyS1?baud=115200
    +serial serial:/dev/ttyS2?baud=115200
    +direct usb:/dev/usb/lp0
    +network smb
    +
+ +

The -v option specifies that you want a list of available +devices. The first word in each line is the type of device (direct, file, +network, or serial) and is followed by the device URI or method name for +that device. File devices have device URIs of the form +file:/directory/filename while network devices use the more +familiar method://server or method://server/path +format. + +

Finally, printer queues usually have a PostScript Printer Description +("PPD") file associated with them. PPD files describe the capabilities of +each printer, the page sizes supported, etc., and are used for PostScript +and non-PostScript printers. CUPS includes PPD files for HP LaserJet, HP +DeskJet, EPSON 9-pin, EPSON 24-pin, and EPSON Stylus printers. + +

Adding Your First Printer

+ +

CUPS provides two methods for adding printers: a command-line +program called lpadmin(8) and a Web interface. The +lpadmin command allows you to perform most printer +administration tasks from the command-line and is located in +/usr/sbin. The Web interface is located at: + +

+ +

and steps you through printer configuration. If you don't like +command-line interfaces, try the Web interface instead. + +

Adding Your First Printer from the Command-Line

+ +

Run the lpadmin command with the -p option to add a +printer to CUPS: + +

    +/usr/sbin/lpadmin -p printer -E -v device -m ppd ENTER
    +
+ +

For an HP DeskJet printer connected to the parallel port this would look +like: + +

    +/usr/sbin/lpadmin -p DeskJet -E -v parallel:/dev/lp1 -m deskjet.ppd ENTER
    +
+ +

Similarly, an HP LaserJet printer using a JetDirect network interface at +IP address 11.22.33.44 would be added with the command: + +

    +/usr/sbin/lpadmin -p LaserJet -E -v socket://11.22.33.44 -m laserjet.ppd ENTER
    +
+ +

As you can see, deskjet.ppd and laserjet.ppd are +the PPD files for the HP DeskJet and HP LaserJet drivers included with CUPS. +You'll find a complete list of PPD files and the printers they will work with +in Appendix C, "Printer Drivers". + +

Adding Your First Printer from the Web

+ +

The CUPS web server provides a user-friendly "wizard" interface for +adding your printers. Rather than figuring out which device URI and PPD file +to use, you can instead click on the appropriate listings and fill in some +simple information. Enter the following URL in your web browser to begin: + +

+ +

Click on the Add Printer button to add a printer. + +

Managing Printers from the Command-Line

+ +

The lpadmin command enables you to perform most printer +administration tasks from the command-line. You'll find lpadmin +in the /usr/sbin directory. + +

Adding and Modifying Printers

+ +

Run the lpadmin command with the -p option +to add or modify a printer: + +

    +/usr/sbin/lpadmin -p printer options ENTER
    +
+ +

The options arguments can be any of the following: + +

    +
    + +
    -c class + +
    Adds the named printer to printer class class. + If the class does not exist then it is created. + +
    -i interface + +
    Copies the named interface script to the printer. + Interface scripts are used by System V printer drivers. Since + all filtering is disabled when using an interface script, scripts + generally should not be used unless there is no other driver for + a printer. + +
    -m model + +
    Specifies a standard printer driver which is usually a PPD + file. A list of all available models can be displayed using the + lpinfo command with the -m option. A + list of printer drivers included with CUPS can be found in + Appendix C, "Printer Drivers". + +
    -r class + +
    Removes the named printer from printer class class. + If the resulting class becomes empty then it is removed. + +
    -v device-uri + +
    Sets the device for communicating with the printer. If a + job is currently printing on the named printer then the job + will be restarted and sent to the new device. + +
    -D info + +
    Provides a textual description of the printer, e.g. + "John's Personal Printer". + +
    -E + +
    Enables the printer and accepts job. This option is + equivalent to running the enable(1) and + accept(8) commands on the printer. + +
    -L location + +
    Provides a textual location for the printer, e.g. + "Computer Lab 5". + +
    -P ppd-file + +
    Specifies a local PPD file for the printer driver. + +
    +
+ +

Deleting Printers

+ +

Run the lpadmin command with the -x option +to delete a printer: + +

    +/usr/sbin/lpadmin -x printer ENTER
    +
+ +

Setting the Default Printer

+ +

Run the lpadmin command with the -d option +to set a default printer: + +

    +/usr/sbin/lpadmin -d printer ENTER
    +
+ +

The default printer can be overridden by the user using the +lpoptions(1) command. + +

Starting and Stopping Printers

+ +

The enable and disable commands start and stop +printer queues, respectively: + +

    +/usr/bin/enable printer ENTER
    +/usr/bin/disable printer ENTER
    +
+ +

Printers that are disabled may still accept jobs for printing, but won't +actually print any files until they are restarted. This is useful if the +printer malfunctions and you need time to correct the problem. Any queued +jobs are printed after the printer is enabled (started). + +

Accepting and Rejecting Print Jobs

+ +

The accept and reject commands accept and reject +print jobs for the named printer, respectively: + +

    +/usr/sbin/accept printer ENTER
    +/usr/sbin/reject printer ENTER
    +
+ +

As noted above, a printer can be stopped but accepting new print +jobs. A printer can also be rejecting new print jobs while it finishes +those that have been queued. This is useful for when you must perform +maintenance on the printer and will not have it available to users for +a long period of time. + +

Managing Printers from the Web

+ +

The Web interface is located at: + +

+ +

From there you can perform all printer management tasks with a few +simple mouse clicks. + + +

4 - Printer Classes

+ +

This chapter describes what printer classes are and how to manage them. + +

The Basics

+ +

CUPS provides collections of printers called printer classes. Jobs +sent to a class are forwarded to the first available printer in the class. +Classes can themselves be members of other classes, so it is possible for +you to define very large, distributed printer classes for high-availability +printing. + +

CUPS also supports implicit classes. Implicit classes work just +like printer classes, but they are created automatically based upon the +available printers and classes on the network. This allows you to setup +multiple print servers with identical printer configurations and have the +client machines send their print jobs to the first available server. If +one or more servers go down, the jobs are automatically redirected to the +servers that are running, providing fail-safe printing. + +

Managing Printer Classes from the Command-Line

+ +

Run the lpadmin command with the -p and -c options +to add a printer to a class: + +

    +/usr/sbin/lpadmin -p printer -c class ENTER
    +
+ +

The class is created automatically if it doesn't exist. To remove a +printer from a class use the -r option: + +

    +/usr/sbin/lpadmin -p printer -r class ENTER
    +
+ +

To remove the entire class just use the -x option: + +

    +/usr/sbin/lpadmin -x class ENTER
    +
+ +

Managing Printer Classes from the Web Interface

+ +

The Web interface is located at: + +

+ +

The Add Class and Modify Class interfaces provide a +list of available printers; click on the printers of interest to add them to +the class. + +

Implicit Classes

+ +

A noted earlier, implicit classes are created automatically from the +available network printers and classes. To disable this functionality, +set the ImplicitClasses +directive to Off in the cupsd.conf file. You +will find more information on doing this in +Chapter 6, "Printing System +Management". + + +

5 - Client Setup

+ +

This chapter discusses several ways to configure CUPS clients for +printing. + +

The Basics

+ +

A client is any machine that sends print jobs to another machine for +final printing. Clients can also be servers if they communicate directly with +any printers of their own. + +

CUPS supports several methods of configuring client machines: + +

+ +

Manual Configuration of Print Queues

+ +

The most tedious method of configuring client machines is to configure +each remote queue by hand using the lpadmin command: + +

    +lpadmin -p printer -E -v ipp://server/printers/printer ENTER
    +
+ +

The printer name is the name of the printer on the server +machine. The server name is the hostname or IP address of the +server machine. Repeat the lpadmin command for each remote +printer you wish to use. + +

Specifying a Single Server for Printing

+ +

CUPS can be configured to run without a local spooler and send all +jobs to a single server. However, if that server goes down then all +printing will be disabled. Use this configuration only as absolutely needed. + +

The default server is normally "localhost". To override the default +server create a file named /etc/cups/client.conf and add +a line reading: + +

    +ServerName server
    +
+ +

to the file. The server name can be the hostname or IP address +of the default server. + +

The default server can also be customized on a per-user basis. To set a +user-specific server create a file named ~/.cupsrc and add a line +reading: + +

    +ServerName server
    +
+ +

to the file. The server name can be the hostname or IP +address of the default server. + +

Automatic Configuration of Print Queues

+ +

CUPS supports automatic client configuration of printers on the same +subnet. To configure printers on the same subnet, do nothing. +Each client should see the available printers within 30 seconds +automatically. The printer and class lists are updated automatically as +printers and servers are added or removed. + +

If you want to see printers on other subnets as well, use the +BrowsePoll directive as +described next. + +

Specifying Multiple Servers for Printing

+ +

If you have CUPS servers on different subnets, then you should configure +CUPS to poll those servers. Polling provides the benefits of automatic +configuration without significant configuration on the clients, and multiple +clients on the same subnet can share the same configuration information. + +

Polling is enabled by specifying one or more +BrowsePoll directives in the +/etc/cups/cupsd.conf file. For information on making these +changes, see Chapter 6, "Printing System +Management". + + +

6 - Printing System Management

+ +

This chapter shows how you can configure the CUPS server. + +

The Basics

+ +

Several text files are used to configure CUPS. All of the server +configuration files are located in the /etc/cups directory: + +

    +
    + + +
    classes.conf + +
    This file contains information on each printer class. + Normally you manipulate this file using the + lpadmin command or the Web interface.
      + + +
    client.conf + +
    This file provides the default server name for client + machines. See Chapter 5, "Client + Setup" for more information.
      + + +
    cupsd.conf + +
    This file controls how the CUPS server + (/usr/sbin/cupsd) operates and is normally edited by + hand.
      + + +
    mime.convs + +
    This file contains a list of standard file conversion filters + and their costs. You normally do not edit this file.
      + + +
    mime.types + +
    This file contains a list of standard file formats and how to + recognize them. You normally do not edit this file.
      + + +
    printers.conf + +
    This file contains information on each printer. Normally + you manipulate this file using the lpadmin command + or the Web Interface.
      + +
    +
+ +

Restarting the CUPS Server

+ +

Once you have made a change to a configuration file you need to +restart the CUPS server by sending it a HUP signal or using the +supplied initialization script. The CUPS distributions install the +script in the init.d directory with the name +cups. The location varies based upon the operating system: + +

    +/etc/rc.d/init.d/cups restart ENTER
    +/etc/init.d/cups restart ENTER
    +/sbin/init.d/cups restart ENTER
    +
+ +

Changing the Server Configuration

+ +

The /etc/cups/cupsd.conf file contains configuration +directives that control how the server functions. Each directive +is listed on a line by itself followed by its value. Comments are +introduced using the number sign ("#") character at the beginning of a +line. Since the server configuration file consists of plain text, you +can use your favorite text editor to make changes to it. + + +

Server Directives

+ +

The cupsd.conf file contains many directives that +determine how the server operates: + +

+ + +

AccessLog

+
+ +

Examples

+ +
    +AccessLog /var/log/cups/access_log
    +AccessLog /var/log/cups/access_log-%s
    +AccessLog syslog
    +
+ +

Description

+ +

The AccessLog directive sets the name of the access log +file. If the filename is not absolute then it is assumed to be relative +to the ServerRoot directory. The +access log file is stored in "common log format" and can be used by any +web access reporting tool to generate a report on CUPS server activity. + +

The server name can be included in the filename by using +%s in the name. + +

The special name "syslog" can be used to send the access information +to the system log instead of a plain file. + +

The default access log file is /var/log/cups/access_log. + + +

Allow

+
+ +

Examples

+ +
    +Allow from All
    +Allow from None
    +Allow from *.domain.com
    +Allow from .domain.com
    +Allow from host.domain.com
    +Allow from nnn.*
    +Allow from nnn.nnn.*
    +Allow from nnn.nnn.nnn.*
    +Allow from nnn.nnn.nnn.nnn
    +Allow from nnn.nnn.nnn.nnn/mm
    +Allow from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
    +
+ +

Description

+ +

The Allow directive specifies a hostname, IP address, +or network that is allowed access to the server. Allow +directives are cummulative, so multiple Allow directives +can be used to allow access for multiple hosts or networks. The +/mm notation specifies a CIDR netmask: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
mmnetmaskmmnetmask
00.0.0.08255.0.0.0
1128.0.0.016255.255.0.0
2192.0.0.024255.255.255.0
......32255.255.255.255
+ +

The Allow directive must appear inside a +Location directive. + + +

AuthClass

+
+ +

Examples

+ +
    +AuthClass Anonymous
    +AuthClass User
    +AuthClass System
    +AuthClass Group
    +
+ +

Description

+ +

The AuthClass directive defines what level of authentication +is required: + +

    + +
  • Anonymous - No authentication should be performed + (default.) + +
  • User - A valid username and password is required. + +
  • System - A valid username and password is + required, and the username must belong to the "sys" group; this + can be changed using the + SystemGroup directive. + +
  • Group - A valid username and password is + required, and the username must belong to the group named by + the AuthGroupName directive. + +
+ +

The AuthClass directive must appear inside a +Location directive. + + +

AuthGroupName

+
+ +

Examples

+ +
    +AuthGroupName mygroup
    +AuthGroupName lp
    +
+ +

Description

+ +

The AuthGroupName directive sets the group to use for +Group authentication. + +

The AuthGroupName directive must appear inside a +Location directive. + + +

AuthType

+
+ +

Examples

+ +
    +AuthType None
    +AuthType Basic
    +AuthType Digest
    +
+ +

Description

+ +

The AuthType directive defines the type of authentication to +perform: + +

    + +
  • None - No authentication should be performed + (default.) + +
  • Basic - Basic authentication should be + performed using the UNIX password and group files. + +
  • Digest - Digest authentication should be + performed using the /etc/cups/passwd.md5 file. + +
+ +

When using Basic or Digest authentication, +clients connecting through the localhost interface can also +authenticate using certificates. + +

The AuthType directive must appear inside a +Location directive. + + +

BrowseAddress

+
+ +

Examples

+ +
    +BrowseAddress 255.255.255.255:631
    +BrowseAddress 192.0.2.255:631
    +BrowseAddress host.domain.com:631
    +
+ +

Description

+ +

The BrowseAddress directive specifies an address to +send browsing information to. Multiple BrowseAddress +directives can be specified to send browsing information to different +networks or systems. + +

The default address is 255.255.255.255:631 which will +broadcast the information to all networks the server is connected to. + +

+ + + +
+ NOTE: + +

If you are using HP-UX 10.20 and a subnet that is not 24, + 16, or 8 bits, printer browsing (and in fact all broadcast + reception) will not work. This problem appears to be fixed in + HP-UX 11.0. +

+ + +

BrowseAllow

+
+ +

Examples

+ +
    +BrowseAllow from all
    +BrowseAllow from none
    +BrowseAllow from 192.0.2
    +BrowseAllow from 192.0.2.0/24
    +BrowseAllow from 192.0.2.0/255.255.255.0
    +BrowseAllow from *.domain.com
    +
+ +

Description

+ +

The BrowseAllow directive specifies a system or network +to accept browse packets from. The default is to accept browse packets +from all hosts. + +

Host and domain name matching require that you enable the +HostNameLookups directive. + +

IP address matching supports exact matches, partial addresses that +match networks using netmasks of 255.0.0.0, 255.255.0.0, and 255.255.255.0, +or network addresses using the specified netmask or bit count. + + +

BrowseDeny

+
+ +

Examples

+ +
    +BrowseDeny from all
    +BrowseDeny from none
    +BrowseDeny from 192.0.2
    +BrowseDeny from 192.0.2.0/24
    +BrowseDeny from 192.0.2.0/255.255.255.0
    +BrowseDeny from *.domain.com
    +
+ +

Description

+ +

The BrowseDeny directive specifies a system or network +to reject browse packets from. The default is to deny browse packets +from no hosts. + +

Host and domain name matching require that you enable the +HostNameLookups directive. + +

IP address matching supports exact matches, partial addresses that +match networks using netmasks of 255.0.0.0, 255.255.0.0, and 255.255.255.0, +or network addresses using the specified netmask or bit count. + + +

BrowseOrder

+
+ +

Examples

+ +
    +BrowseOrder allow,deny
    +BrowseOrder deny,allow
    +
+ +

Description

+ +

The BrowseOrder directive specifies the order of allow/deny +processing. The default order is deny,allow: + +

    + +
  • allow,deny - Browse packets are accepted unless + specifically denied. + +
  • deny,allow - Browse packets are rejected unless + specifically allowed. + +
+ + +

BrowseInterval

+
+ +

Examples

+ +
    +BrowseInterval 0
    +BrowseInterval 30
    +
+ +

Description

+ +

The BrowseInterval directive specifies the maximum amount of +time between browsing updates. Specifying a value of 0 seconds disables +outgoing browse updates but allows a server to receive printer information +from other hosts. + +

The BrowseInterval value should always be less than the +BrowseTimeout value. Otherwise +printers and classes will disappear from client systems between updates. + + +

BrowsePoll

+
+ +

Examples

+ +
    +BrowsePoll 192.0.2.2:631
    +BrowsePoll host.domain.com:631
    +
+ +

Description

+ +

The BrowsePoll directive polls a server for available +printers once every +BrowseInterval seconds. +Multiple BrowsePoll directives can be specified to poll +multiple servers. + +

If BrowseInterval is set to 0 then the server is polled +once every 30 seconds. + + +

BrowsePort

+
+ +

Examples

+ +
    +BrowsePort 631
    +BrowsePort 9999
    +
+ +

Description

+ +

The BrowsePort directive specifies the UDP port number +used for browse packets. The default port number is 631. + +

+ + + +
+ NOTE: + +

You must set the BrowsePort to the same value + on all of the systems that you want to see. +

+ + +

BrowseRelay

+
+ +

Examples

+ +
    +BrowseRelay 193.0.2.1 192.0.2.255
    +BrowseRelay 193.0.2.0/255.255.255.0 192.0.2.255
    +BrowseRelay 193.0.2.0/24 192.0.2.255
    +BrowseRelay *.domain.com 192.0.2.255
    +BrowseRelay host.domain.com 192.0.2.255
    +
+ +

Description

+ +

The BrowseRelay directive specifies source and destination +addresses for relaying browsing information from one host or network to +another. Multiple BrowseRelay directives can be specified +as needed. + +

BrowseRelay is typically used on systems that bridge +multiple subnets using one or more network interfaces. It can also be +used to relay printer information from polled servers with the line: + +

    +BrowseRelay 127.0.0.1 255.255.255.255
    +
+ +

This effectively provides access to printers on a WAN for all clients +on the LAN(s). + + +

BrowseShortNames

+
+ +

Examples

+ +
    +BrowseShortNames Yes
    +BrowseShortNames No
    +
+ +

Description

+ +

The BrowseShortNames directive specifies whether or not +short names are used for remote printers when possible. Short names are +just the remote printer name, without the server ("printer"). If more than +one remote printer is detected with the same name, the printers will have +long names ("printer@server1", "printer@server2".) + +

The default value for this option is Yes. + + +

BrowseTimeout

+
+ +

Examples

+ +
    +BrowseTimeout 300
    +BrowseTimeout 60
    +
+ +

Description

+ +

The BrowseTimeout directive sets the timeout for +printer or class information that is received in browse packets. Once a +printer or class times out it is removed from the list of available +destinations. + +

The BrowseTimeout value should always be greater than the +BrowseInterval value. Otherwise +printers and classes will disappear from client systems between updates. + + +

Browsing

+
+ +

Examples

+ +
    +Browsing On
    +Browsing Off
    +
+ +

Description

+ +

The Browsing directive controls whether or not network printer +browsing is enabled. The default setting is On. + +

+ + + +
+ NOTE: + +

If you are using HP-UX 10.20 and a subnet that is not 24, + 16, or 8 bits, printer browsing (and in fact all broadcast + reception) will not work. This problem appears to be fixed in + HP-UX 11.0. +

+ + +

DataDir

+
+ +

Examples

+ +
    +DataDir /usr/share/cups
    +
+ +

Description

+ +

The DataDir directive sets the directory to use for data +files. + + +

DefaultCharset

+
+ +

Examples

+ +
    +DefaultCharset utf-8
    +DefaultCharset iso-8859-1
    +DefaultCharset windows-1251
    +
+ +

Description

+ +

The DefaultCharset directive sets the default character set +to use for client connections. The default character set is +utf-8 but is overridden by the character set for the language +specified by the client or the DefaultLanguage directive. + + +

DefaultLanguage

+
+ +

Examples

+ +
    +DefaultLanguage de
    +DefaultLanguage en
    +DefaultLanguage es
    +DefaultLanguage fr
    +DefaultLanguage it
    +
+ +

Description

+ +

The DefaultLanguage directive specifies the default language +to use for client connections. Setting the default language also sets the +default character set if a language localization file exists for it. The +default language is "en" for English. + + +

Deny

+
+ +

Examples

+ +
    +Deny from All
    +Deny from None
    +Deny from *.domain.com
    +Deny from .domain.com
    +Deny from host.domain.com
    +Deny from nnn.*
    +Deny from nnn.nnn.*
    +Deny from nnn.nnn.nnn.*
    +Deny from nnn.nnn.nnn.nnn
    +Deny from nnn.nnn.nnn.nnn/mm
    +Deny from nnn.nnn.nnn.nnn/mmm.mmm.mmm.mmm
    +
+ +

Description

+ +

The Deny directive specifies a hostname, IP address, or +network that is allowed access to the server. Deny +directives are cummulative, so multiple Deny directives +can be used to allow access for multiple hosts or networks. The +/mm notation specifies a CIDR netmask: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
mmnetmaskmmnetmask
00.0.0.08255.0.0.0
1128.0.0.016255.255.0.0
2192.0.0.024255.255.255.0
......32255.255.255.255
+ +

The Deny directive must appear inside a +Location directive. + + +

DocumentRoot

+
+ +

Examples

+ +
    +DocumentRoot /usr/share/doc/cups
    +DocumentRoot /foo/bar/doc/cups
    +
+ +

Description

+ +

The DocumentRoot directive specifies the location of +web content for the HTTP server in CUPS. If an absolute path is not +specified then it is assumed to be relative to the +ServerRoot directory. The +default directory is /usr/share/doc/cups. + +

Documents are first looked up in a sub-directory for the primary +language requested by the client (e.g. /usr/share/doc/cups/fr/...) +and then directly under the DocumentRoot directory +(e.g. /usr/share/doc/cups/...), so it is possible to localize +the web content by providing subdirectories for each language needed. + + +

ErrorLog

+
+ +

Examples

+ +
    +ErrorLog /var/log/cups/error_log
    +ErrorLog /var/log/cups/error_log-%s
    +ErrorLog syslog
    +
+ +

Description

+ +

The ErrorLog directive sets the name of the error log +file. If the filename is not absolute then it is assumed to be relative +to the ServerRoot directory. The +default error log file is /var/log/cups/error_log. + +

The server name can be included in the filename by using +%s in the name. + +

The special name "syslog" can be used to send the error information +to the system log instead of a plain file. + + +

Group

+
+ +

Examples

+ +
    +Group sys
    +Group system
    +Group root
    +
+ +

Description

+ +

The Group directive specifies the UNIX group that +filter and CGI programs run as. The default group is sys, +system, or root depending on the operating +system. + + +

HostNameLookups

+
+ +

Examples

+ +
    +HostNameLookups On
    +HostNameLookups Off
    +
+ +

Description

+ +

The HostNameLookups directive controls whether or not +CUPS looks up the hostname for connecting clients. The default is +Off to avoid the potential server performance problems +with hostname lookups. Turn this option On only if +absolutely required. + + +

ImplicitClasses

+
+ +

Examples

+ +
    +ImplicitClasses On
    +ImplicitClasses Off
    +
+ +

Description

+ +

The ImplicitClasses directive controls whether implicit +classes are created based upon the available network printers and classes. +The default setting is On but is automatically turned +Off if Browsing is +turned Off. + + +

KeepAlive

+
+ +

Examples

+ +
    +KeepAlive On
    +KeepAlive Off
    +
+ +

Description

+ +

The KeepAlive directive controls whether or not to support +persistent HTTP connections. The default is On. + +

HTTP/1.1 clients automatically support persistent connections, while +HTTP/1.0 clients must specifically request them using the +Keep-Alive attribute in the Connection: +field of each request. + + +

KeepAliveTimeout

+
+ +

Examples

+ +
    +KeepAliveTimeout 60
    +KeepAliveTimeout 30
    +
+ +

Description

+ +

The KeepAliveTimeout directive controls how long a +persistent HTTP connection will remain open after the last request. The +default is 60 seconds. + + +

Listen

+
+ +

Examples

+ +
    +Listen 127.0.0.1:631
    +Listen 192.0.2.1:631
    +
+ +

Description

+ +

The Listen directive specifies a network address and port +to listen for connections. Multiple Listen directives can be +provided to listen on multiple addresses. + +

Description

+ +

The Listen directive is similar to the +Port directive but allows you to restrict +access to specific interfaces or networks. + + +

Location

+
+ +

Examples

+ +
    +<Location />
    +...
    +</Location>
    +
    +<Location /admin>
    +...
    +</Location>
    +
    +<Location /printers/name>
    +...
    +</Location>
    +
+ +

Description

+ +

The Location directive specifies access control and +authentication options for the specified HTTP resource or path. More +information can be found later in this chapter in +"Printing System Security". + + +

LogLevel

+
+ +

Examples

+ +
    +LogLevel debug
    +LogLevel error
    +LogLevel info
    +LogLevel none
    +LogLevel warn
    +
+ +

Description

+ +

The LogLevel directive specifies the level of logging +for the ErrorLog file. The +following values are recognized: + +

    + +
  • debug - Log everything. + +
  • info - Log all requests and state changes (default). + +
  • warn - Log errors and warnings. + +
  • error - Log only errors. + +
  • none - Log nothing. + +
+ + +

MaxClients

+
+ +

Examples

+ +
    +MaxClients 100
    +MaxClients 1024
    +
+ +

Description

+ +

The MaxClients directive controls the maximum number of +simultaneous clients that will be allowed by the server. The default is +100 clients. + +

+ + + +
+ NOTE: + +

Since each print job requires a file descriptor for the + status pipe, the CUPS server internally limits the + MaxClients value to 1/3 of the available file descriptors + to avoid possible problems when printing large numbers of jobs. +

+ + +

MaxLogSize

+
+ +

Examples

+ +
    +MaxLogSize 1048576
    +MaxLogSize 1m
    +MaxLogSize 0
    +
+ +

Description

+ +

The MaxLogSize directive controls the maximum size of each +log file. Once a log file reaches or exceeds the maximum size it is closed +and renamed to filename.O. This allows you to rotate the logs +automatically. The default size is 1048576 bytes (1MB). + +

Setting the maximum size to 0 disables log rotation. + + +

MaxRequestSize

+
+ +

Examples

+ +
    +MaxRequestSize 10485760
    +MaxRequestSize 10m
    +MaxRequestSize 0
    +
+ +

Description

+ +

The MaxRequestSize directive controls the maximum size of +print files, IPP requests, and HTML form data in HTTP POST requests. The +default limit is 0 which disables the limit check. + + +

Order

+
+ +

Examples

+ +
    +Order Allow,Deny
    +Order Deny,Allow
    +
+ +

Description

+ +

The Order directive defines the default access control. +The following values are supported: + +

    + +
  • Allow,Deny - Allow requests from all + systems except for those listed in a Deny + directive. + +
  • Deny,Allow - Allow requests only from + those listed in an Allow directive. + +
+ +

The Order directive must appear inside a +Location directive. + + +

PageLog

+
+ +

Examples

+ +
    +PageLog /var/log/cups/page_log
    +PageLog /var/log/cups/page_log-%s
    +PageLog syslog
    +
+ +

Description

+ +

The PageLog directive sets the name of the page log +file. If the filename is not absolute then it is assumed to be relative +to the ServerRoot directory. The +default page log file is /var/log/cups/page_log. + +

The server name can be included in the filename by using +%s in the name. + +

The special name "syslog" can be used to send the page information +to the system log instead of a plain file. + + +

Port

+
+ +

Examples

+ +
    +Port 631
    +Port 80
    +
+ +

Description

+ +

The Port directive specifies a port to listen on. +Multiple Port lines can be specified to listen on multiple +ports. The default port is 631. + +

Description

+ +

The Port directive will listen for connections on all +network interfaces. To limit connections to a single interface use the +Listen directive with the interface +address. + + +

PreserveJobHistory

+
+ +

Examples

+ +
    +PreserveJobHistory On
    +PreserveJobHistory Off
    +
+ +

Description

+ +

The PreserveJobHistory directive controls whether +the history of completed, cancelled, or aborted print jobs is stored +on disk. + +

A value of On (the default) preserves job information +until the administrator purges it with the cancel +command. + +

A value of Off removes the job information as soon as +each job is completed, cancelled, or aborted. + + +

PreserveJobFiles

+
+ +

Examples

+ +
    +PreserveJobFiles On
    +PreserveJobFiles Off
    +
+ +

Description

+ +

The PreserveJobFiles directive controls whether the +document files of completed, cancelled, or aborted print jobs are +stored on disk. + +

A value of On preserves job files until the +administrator purges them with the cancel command. Jobs +can be restarted (and reprinted) as desired until they are purged. + +

A value of Off (the default) removes the job files as +soon as each job is completed, cancelled, or aborted. + + +

Printcap

+
+ +

Examples

+ +
    +Printcap
    +Printcap /etc/printcap
    +
+ +

Description

+ +

The Printcap directive controls whether or not a +printcap file is automatically generated and updated with a list of +available printers. If specified with no value (the default), then no +printcap file will be generated. + +

When a filename is specified (e.g. /etc/printcap), the +printcap file is written whenever a printer is added or removed. The +printcap file can then be used by applications that are hardcoded to +look at the printcap file for the available printers. + + +

RequestRoot

+
+ +

Examples

+ +
    +RequestRoot /var/spool/cups
    +RequestRoot /foo/bar/spool/cups
    +
+ +

Description

+ +

The RequestRoot directive sets the directory for +incoming IPP requests and HTML forms. If an absolute path is not +provided then it is assumed to be relative to the +ServerRoot directory. The +default request directory is /var/spool/cups. + + +

RIPCache

+
+ +

Examples

+ +
    +RIPCache 8m
    +RIPCache 1g
    +RIPCache 2048k
    +
+ +

Description

+ +

The RIPCache directive sets the size of the memory +cache used by Raster Image Processor ("RIP") filters such as +imagetoraster and pstoraster. The size can +be suffixed with a "k" for kilobytes, "m" for megabytes, or +"g" for gigabytes. The default cache size is "8m", or 8 megabytes. + + +

ServerAdmin

+
+ +

Examples

+ +
    +ServerAdmin user@host
    +ServerAdmin root@foo.bar.com
    +
+ +

Description

+ +

The ServerAdmin directive identifies the email address for the +administrator on the system. By default the administrator email address is +root@server, where server is the server name. + + +

ServerBin

+
+ +

Examples

+ +
    +ServerBin /usr/lib/cups
    +ServerBin /foo/bar/lib/cups
    +
+ +

Description

+ +

The ServerBin directive sets the directory for +server-run executables. If an absolute path is not provided then it is +assumed to be relative to the +ServerRoot directory. The +default executable directory is /usr/lib/cups or +/usr/lib32/cups (IRIX 6.5). + + +

ServerName

+
+ +

Examples

+ +
    +ServerName foo.domain.com
    +ServerName myserver.domain.com
    +
+ +

Description

+ +

The ServerName directive specifies the hostname that is +reported to clients. By default the server name is the hostname. + + +

ServerRoot

+
+ +

Examples

+ +
    +ServerRoot /etc/cups
    +ServerRoot /foo/bar/cups
    +
+ +

Description

+ +

The ServerRoot directive specifies the absolute path to +the server configuration and state files. It is also used to resolve +relative paths in the cupsd.conf file. The default server +directory is /etc/cups. + + +

SystemGroup

+
+ +

Examples

+ +
    +SystemGroup sys
    +SystemGroup system
    +SystemGroup root
    +
+ +

Description

+ +

The SystemGroup directive specifies the system +administration group for System authentication. More +information can be found later in this chapter in +"Printing System Security". + + +

TempDir

+
+ +

Examples

+ +
    +TempDir /var/tmp
    +TempDir /foo/bar/tmp
    +
+ +

Description

+ +

The TempDir directive specifies an absolute path for +the directory to use for temporary files. The default directory is +/var/tmp. + +

Temporary directories must be world-writable and should have the +"sticky" permission bit enabled so that other users cannot delete +filter temporary files. The following commands will create an +appropriate temporary directory called /foo/bar/tmp: + +

    +mkdir /foo/bar/tmp ENTER
    +chmod a+rwxt /foo/bar/tmp ENTER
    +
+ + +

Timeout

+
+ +

Examples

+ +
    +Timeout 300
    +Timeout 90
    +
+ +

Description

+ +

The Timeout directive controls the amount of time to +wait before an active HTTP or IPP request times out. The default +timeout is 300 seconds. + + +

User

+
+ +

Examples

+ +
    +User lp
    +User guest
    +
+ +

Description

+ +

The User directive specifies the UNIX user that +filter and CGI programs run as. The default user is lp. + + +

Printing System Security

+ +

CUPS provides support for address, certificate, and password (Basic +and Digest) based authentication and access control. Certificate and +password authentication provide ways to limit access to individual +people or groups. + +

Address based access control allows you to limit access to specific +systems, networks, or domains. While this does not provide authentication, +it does allow you to limit the potential users of your system efficiently. + +

CUPS maintains a list of locations that have access control and/or +authentication enabled. Locations are specified using the +Location directive: + +

+ +

Locations generally follow the directory structure of the +DocumentRoot directory, however +CUPS does have several virtual locations for administration, classes, jobs, +and printers: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
LocationDescription
/adminThe path for all administration operations.
/classesThe path for all classes.
/classes/nameThe resource for class name.
/jobsThe path for all jobs.
/jobs/idThe resource for job id.
/printersThe path for all printers.
/printers/nameThe path for printer name.
/printers/name.ppdThe PPD file path for printer name.
+ +

Authentication Using Certificates

+ +

CUPS supports a local certificate-based authentication scheme that +can be used in place of Basic or Digest +authentication by clients connecting through the localhost +interface. Certificate authentication is not supported or allowed from +clients on any other interface. + +

Certificates are 128-bit random numbers that refer to an internal +authentication record in the server. A client connecting via the +localhost interface sends a request with an +authorization header of: + +

    +Authorization: Local 0123456789ABCDEF0123456789ABCDEF
    +
+ +

The server then looks up the local certificate and authenticates +using the username associated with it. + +

Certificates are generated by the server automatically and stored in +the /etc/cups/certs directory using the process ID of the +CGI program started by the server. Certificate files are only readable +by the User and +Group defined in the +cupsd.conf file. When the CGI program ends the certificate +is removed and invalidated automatically. + +

The special file /etc/cups/certs/0 defines the root +certificate which can be used by any client running as the super-user +or another user that is part of the group defined by the +SystemGroup directive. The +root certificate is automatically regenerated every 5 minutes. + +

Using Basic Authentication

+ +

Basic authentication uses UNIX users and passwords to authenticate +access to resources such as printers and classes, and to limit access +to administrative functions. + +

+ + + +
+ NOTE: + +

Basic authentication sends the username and password Base64 + encoded from the client to the server, so it offers no + protection against eavesdropping. This means that a malicious + user can monitor network packets and discover valid users and + passwords that could result in a serious compromise in network + security. Use Basic authentication with extreme care. +

+ +

The CUPS implementation of Basic authentication does not allow access +through user accounts without a password. If you try to authenticate +using an account without a password, your access will be immediately +blocked. + +

Once a valid username and password is authenticated by CUPS, any +additional group membership requirements are checked. + +

+ + + +
+ NOTE: + +

The root user is considered by CUPS to be a member of every + group. +

+ + +

Use the AuthType directive to enable Basic authentication: + +

    +AuthType Basic
    +
+ + +

Using Digest Authentication

+ +

Digest authentication uses users and passwords defined in the +/etc/cups/passwd.md5 file to authenticate access to +resources such as printers and classes, and to limit access to +administrative functions. + +

+ + + +
+ NOTE: + +

Unlike Basic authentication, Digest passes the MD5 sum + (basically a complicated checksum) of the username and password + instead of the strings themselves. Also, Digest authentication + does not use the UNIX password file, so if an attacker does + discover the original password it is less likely to result in a + serious security problem so long as you use a different UNIX + password than the corresponding Digest password. + +

The current CUPS implementation of Digest authentication + uses the client's hostname or IP address for the "nonce" value. + The nonce value is an additional string added to the username + and password to make guessing the password more difficult. The + server checks that the nonce value matches the client's hostname + or address and rejects the MD5 sum if it doesn't. Future versions + of CUPS will support Digest "session" authentication which adds + the request data to the MD5 sum, providing even better + authentication and security. + +

Digest authentication does not guarantee that an attacker + cannot gain unauthorized access, but it is safer than Basic + authentication and should be used in place of Basic + authentication whenever possible. Support for Digest + authentication in web browsers is not yet universally + available. +

+ + +

The lppasswd(1) command is used to add, change, or +remove accounts from the passwd.md5 file. To add a +user to the default system group, type: + +

    +lppasswd -a user ENTER
    +Password: (password) ENTER [password is not echoed]
    +Password again: (password) ENTER [password is not echoed]
    +
+ + +

Once added, a user can change his/her password by typing: + +

    +lppasswd ENTER
    +Old password: (password) ENTER [password is not echoed]
    +Password: (password) ENTER [password is not echoed]
    +Password again: (password) ENTER [password is not echoed]
    +
+ + +

To remove a user from the password file, type: + +

    +lppasswd -x user ENTER
    +
+ +

Once a valid username and password is authenticated by CUPS, any +additional group membership requirements are checked. + +

+ + + +
+ NOTE: + +

The root user is considered by CUPS to be a member of every + group. +

+ +

Use the AuthType directive to enable Digest authentication: + +

    +AuthType Digest
    +
+ +

System and Group Authentication

+ +

The AuthClass directive controls +the level of authentication to perform. System and +Group authentication extend the normal user-based authentication +to require membership in a UNIX group. For System authentication +each user must belong to the sys, system, or +root group; the actual group depends on the operating system. + +

For Group authentication each user must belong to the +group named by the AuthGroupName +directive: + +

    +<Location /path>
    +AuthType Digest
    +AuthClass Group
    +AuthGroupName mygroup
    +</Location>
    +
+ +

The named group must be a valid UNIX user group, usually defined in the +/etc/group or /etc/netgroup files. Additionally, when +using Digest authentication you need to create user accounts with the named +group: + +

    +lppasswd -g mygroup -a user ENTER
    +Password: (password) ENTER [password is not echoed]
    +Password again: (password) ENTER [password is not echoed]
    +
+ + +

Printer Accounting

+ +

CUPS maintains a log of all accesses, errors, and pages that are + +

The log files are normally stored in the /var/log/cups +directory. You can change this by editing the +/etc/cups/cupsd.conf configuration file. + +

The access_log File

+ +

The access_log file lists each HTTP resource that is accessed +by a web browser or CUPS/IPP client. Each line is in the so-called "Common +Log Format" used by many web servers and web reporting tools: + +

    +host group user date-time \"method resource version\" status bytes
    +
    +127.0.0.1 - - [20/May/1999:19:20:29 +0000] "POST /admin/ HTTP/1.1" 401 0
    +127.0.0.1 - mike [20/May/1999:19:20:31 +0000] "POST /admin/ HTTP/1.1" 200 0
    +
+ +

The host field will normally only be an IP address unless you +have enabled the HostNameLookups +directive in the cupsd.conf file. + +

The group field always contains "-" in CUPS. + +

The user field is the authenticated username of the requesting user. +If no username and password is supplied for the request then this field +contains "-". + +

The date-time field is the date and time of the request in local time +and is in the format: + +

    +[DD/MON/YYYY:HH:MM:SS +ZZZZ]
    +
+ +

where ZZZZ is the timezone offset in hours and minutes from Greenwich +Mean Time (a.k.a. GMT a.k.a. ZULU.) + +

The method field is the HTTP method used ("GET", "PUT", "POST", etc.) + +

The resource field is the filename of the requested resource. + +

The version field is the HTTP specification version used by the +client. For CUPS clients this will always be "HTTP/1.1". + +

The status field contains the HTTP result status of the +request. Usually it is "200", but other HTTP status codes are possible. +For example, 401 is the "unauthorized access" status in the example +above. + +

The bytes field contains the number of bytes in the request. +For POST requests the bytes field contains the number of bytes +that was received from the client. + +

The error_log File

+ +

The error_log file lists messages from the scheduler (errors, +warnings, etc.): + +

    +level date-time message
    +
    +I [20/May/1999:19:18:28 +0000] Job 1 queued on 'DeskJet' by 'mike'.
    +I [20/May/1999:19:21:02 +0000] Job 2 queued on 'DeskJet' by 'mike'.
    +I [20/May/1999:19:22:24 +0000] Job 2 was cancelled by 'mike'.
    +
+ +

The level field contains the type of message: + +

    + +
  • E - An error occurred. + +
  • W - The server was unable to perform some action. + +
  • I - Informational message. + +
  • D - Debugging message. + +
+ +

The date-time field contains the date and time of when the page +started printing. The format of this field is identical to the data-time +field in the access_log file. + +

The message fields contains a free-form textual message. + +

The page_log File

+ +

The page_log file lists each page that is sent to a printer. +Each line contains the following information: + +

    +printer user job-id date-time page-number num-copies job-billing
    +
    +DeskJet root 2 [20/May/1999:19:21:05 +0000] 1 0 acme-123
    +
+ +

The printer field contains the name of the printer that +printed the page. If you send a job to a printer class, this field will +contain the name of the printer that was assigned the job. + +

The user field contains the name of the user (the IPP +requesting-user-name attribute) that submitted this file for +printing. + +

The job-id field contains the job number of the page being printed. +Job numbers are reset to 1 whenever the CUPS server is started, so don't depend +on this number being unique! + +

The date-time field contains the date and time of when the page +started printing. The format of this field is identical to the data-time +field in the access_log file. + +

The page-number and num-pages fields contain the page number +and number of copies being printed of that page. For printer that can not +produce copies on their own, the num-pages field will always be 1. + +

The job-billing field contains a copy of the +job-billing attribute provided with the IPP +create-job or print-job requests or "-" if none +was provided. + + +

File Typing and Filtering

+ +

CUPS provides a MIME-based file typing and filtering mechanism to +convert files to a printable format for each printer. On startup the +CUPS server reads MIME database files from the /etc/cups +directory (or a directory specified by the +ServerRoot directive) to build +a file type and conversion database in memory. These database files are +plain ASCII text and can be edited with your favorite text editor. + +

The mime.types and mime.convs files define the +standard file types and filters that are available on the system. + +

mime.types

+ +

The mime.types file defines the known file types. Each line +of the file starts with the MIME type and may be followed by one or +more file type recognition rules. For example, the +text/html file type is defined as: + +

    +text/html       html htm \
    +                printable(0,1024) + \
    +                (string(0,"<HTML>") string(0,"<!DOCTYPE"))
    +
+ +

The first two rules say that any file with an extension of +.html or .htm is a HTML file. The third rule +says that any file whose first 1024 characters are printable text and +starts with the strings <HTML> or +<!DOCTYPE is a HTML file as well. + +

The first two rules deal solely with the name of the file being +typed. This is useful when the original filename is known, however for +print files the server doesn't have a filename to work with. The third +rule takes care of this possibility and automatically figures out the +file type based upon the contents of the file instead. + +

The available tests are: + +

    + +
  • ( expr ) - Parenthesis for expression grouping + +
  • + - Logical AND + +
  • , or whitespace - Logical OR + +
  • ! - Logical NOT + +
  • match("pattern") - Pattern match on filename + +
  • extension - Pattern match on "*.extension" + +
  • ascii(offset,length) - True if bytes are valid + printable ASCII (CR, NL, TAB, BS, 32-126) + +
  • printable(offset,length) - True if bytes are + printable 8-bit chars (CR, NL, TAB, BS, 32-126, 160-254) + +
  • string(offset,"string") - True if bytes are + identical to string + +
  • contains(offset,range,"string") - True if the + range of bytes contains the string + +
  • char(offset,value) - True if byte is identical + +
  • short(offset,value) - True if 16-bit integer + is identical (network or "big-endian" byte order) + +
  • int(offset,value) - True if 32-bit integer is + identical (network or "big-endian" byte order) + +
  • locale("string") - True if current locale + matches string + +
+ +

All numeric values can be in decimal (123), octal (0123), or hexadecimal +(0x123) as desired. + + +

Strings can be in quotes, all by themselves, as a string +of hexadecimal values, or some combination: + +

    +"string"
    +'string'
    +string
    +<737472696e67>
    +<7374>ring
    +
+ +

As shown in the text/html example, rules can continue on +multiple lines using the backslash (\) character. A more complex example is +the image/jpeg rules: + +

    +image/jpeg      jpeg jpg jpe string(0,<FFD8FF>) &&\
    +                (char(3,0xe0) char(3,0xe1) char(3,0xe2) char(3,0xe3)\
    +                 char(3,0xe4) char(3,0xe5) char(3,0xe6) char(3,0xe7)\
    +                 char(3,0xe8) char(3,0xe9) char(3,0xea) char(3,0xeb)\
    +                 char(3,0xec) char(3,0xed) char(3,0xee) char(3,0xef))
    +
+ +

This rule states that any file with an extension of +.jpeg, .jpg, or .jpe is a JPEG file. +In addition, any file starting with the hexadecimal string +<FFD8FF> (JPEG Start-Of-Image) followed by a +character between and including 0xe0 and 0xef +(JPEG APPn markers) is also a JPEG file. + +

mime.convs

+ +

The mime.convs file defines all of the filter programs that +are known to the system. Each line consists of: + +

    +source destination cost program
    +
    +text/plain application/postscript 50 texttops
    +application/vnd.cups-postscript application/vnd.cups-raster 50 pstoraster
    +image/* application/vnd.cups-postscript 50 imagetops
    +image/* application/vnd.cups-raster 50 imagetoraster
    +
+ +

The source field is a MIME type, optionally using a wildcard for +the super-type or sub-type (e.g. "text/plain", "image/*", "*/postscript"). + +

The destination field is a MIME type defined in the +mime.types file. + +

The cost field defines a relative cost for the filtering +operation from 1 to 100. The cost is used to choose between two +different sets of filters when converting a file. For example, to convert +from image/jpeg to application/vnd.cups-raster, +you could use the imagetops and pstoraster +filters for a total cost of 100, or the imagetoraster filter +for a total cost of 50. + +

The program field defines the filter program to run; the +special program "-" can be used to make two file types equivalent. The +program must accept the standard filter arguments and environment +variables described in the CUPS Interface Design Description and CUPS +Software Programmers Manual: + +

    +program job user title options [filename]
    +
+ +

If specified, the filename argument defines a file to read +when filtering, otherwise the filter must read from the standard input. +All filtered output must go to the standard output. + + +

Adding Filetypes and Filters

+ +

Adding a new file type or filter is fairly straight-forward. Rather +than adding the new type and filter to the mime.types and +mime.convs files which are overwritten when you upgrade to a +new version of CUPS, you simple need to create new files with +.types and .convs extensions in the +/etc/cups directory. We recommend that you use the product +or format name, e.g.: + +

    +myproduct.types
    +myproduct.convs
    +
+ +

If you are providing a filter for a common file format or printer, +add the company or author name: + +

    +acme-msword.types
    +acme.msword.convs
    +
+ +

This will help to prevent name collisions if you install many +different file types and filters. + +

Once you choose the names for these files, create them using your +favorite text editor as described earlier in this chapter. Once you +have created the files, restart the cupsd process as +described earlier in "Restarting the CUPS Server". + +

Printer Drivers and PPD Files

+ +

Most CUPS printer drivers utilize one or more printer-specific filters +and a PPD file for each printer model. Printer driver filters are registered +via the PPD file using cupsFilter attributes: + +

    +*cupsFilter: "application/vnd.cups-raster 0 rastertohp"
    +
+ +

The filter is specified using the source file type only; the destination +file type is assumed to be printer/name - suitable for sending +to the printer. + +

Writing Your Own Filter or Printer Driver

+ +

CUPS supports an unlimited number of file formats and filters, and can +handle any printer. If you'd like to write a filter or printer driver for +your favorite file format or printer, consult the CUPS Software Programmers +Manual for step-by-step instructions. + + +

7 - Printing with Other Systems

+ +

This chapter describes how to print from client systems that use the +LPD, Mac OS, or Windows printing protocols. + +

The Basics

+ +

CUPS is based on the IPP protocol, so any system that supports IPP +can send jobs to and receive jobs from CUPS automatically. However, not +all systems support IPP yet. This chapter will show you how to connect +these systems to your CUPS server, either to accept jobs from your +server for printing, or to send jobs to your server. + +

Printing from LPD Clients

+ +

CUPS supports limited functionality for LPD-based clients. With LPD you can +print files to specific printers, list the queue status, and so forth. However, +the automatic client configuration and printer options are not supported by +the LPD protocol, so you must manually configure each client for the printers +it needs to access. + +

The cups-lpd(8) program provides support for LPD clients. +To enable LPD support on your server, edit the /etc/inetd.conf +file and add a line reading: + +

    +printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd
    +
+ +

The path to the cups-lpd may vary depending on your +installation. + +

Once you have added this line, send the inetd(8) process +a HUP signal or reboot the system: + +

    +killall -HUP inetd ENTER [IRIX and some versions of Linux]
    +kill -HUP pid ENTER [Others]
    +reboot ENTER [For all systems if the HUP signal fails]
    +
+ +

Printing to LPD Servers

+ +

CUPS provides the lpd backend for printing to LPD-based +servers and printers. Use a device URI of lpd://server/name +to print to a printer on an LPD server, where server +is the hostname or IP address of the server and name is +the queue name. + +

Microsoft Windows NT provides an LPD service under the name "TCP/IP +Printing Services". To enable LPD printing on NT, open the "Services" +control panel, select the "TCP/IP Printing Services" service, and click +on the "Start" button. Any shared printer will then be available via +the LPD protocol. + +

Printing from Mac OS Clients

+ +

CUPS does not provide Mac OS support directly. However, there are several +free and commercial software packages that do. + +

Columbia Appletalk Package (CAP)

+ +

Because the CAP LaserWriter server (lwsrv(8)) does +not support specification of PPD files, we do not recommend that you +use CAP with CUPS. However, you can run the lpsrv program +for limited printing with the command: + +

    +lwsrv -n "Name" -p printer -a /usr/lib/adicts -f /usr/lib/LW+Fonts
    +
+ +

where Name is the name you want to use when sharing the +printer, and printer is the name of the CUPS print queue. + + +

XINET KA/Spool

+ +

To use your system as a print server for Mac OS clients, +configure each printer using a papserver(8) in the +/usr/adm/appletalk/services file, specifying the +corresponding PPD file in the /etc/cups/ppd directory for +each printer. For a printer named MyPrinter the entry +would look like: + +

    +/usr/etc/appletalk/papserver -I -L -P /etc/cups/ppd/MyPrinter.ppd \
    +"Printer Description" MyPrinter
    +
+ +
+ + + +
+ NOTE: + +

Enter the text above on a single line without the backslash (\) + character. +

+ +

NetATalk

+ +

To use your system as a print server for Mac OS clients, +configure each printer in the papd.conf file, specifying the +corresponding PPD file in the /etc/cups/ppd directory for +each printer. For a printer named MyPrinter the entry +would look like: + +

    +Printer Description:MyPrinter@MyServer:\
    +        :pr=|/usr/bin/lp -d MyPrinter:\
    +        :op=daemon:\
    +        :pd=/etc/cups/ppd/MyPrinter.ppd
    +
+ + + +

Printing to Mac OS Servers

+ +

CUPS currently does not provide a backend to communicate with a Mac OS +server. However, you can write and install a short shell script +in the /usr/lib/cups/backend directory that sends a print file +using the appropriate command. The following is a short script that will +run the papif command provided with CAP. + +

After copying this script to /usr/lib/cups/backend/cap, +specify a device URI of cap://server/printer to use this +backend with a print queue. + + +

    +
    +"/usr/lib/cups/backend/cap"
    +#!/bin/sh
    +#
    +# Usage: cap job user title copies options [filename]
    +#
    +
    +# No arguments means show available devices...
    +
    +if test ${#argv} = 0; then
    +	echo "network cap \"Unknown\" \"Mac OS Printer via CAP\""
    +	exit 0
    +fi
    +
    +# Collect arguments...
    +
    +user=$2
    +copies=$4
    +
    +if test ${#argv} = 5; then
    +	# Get print file from stdin; copies have already been handled...
    +	file=/var/tmp/$$.prn
    +	copies=1
    +	cat > $file
    +else
    +	# Print file is on command-line...
    +	file=$6
    +fi
    +
    +# Create a dummy cap.printers file for this printer based
    +# upon a device URI of "cap://server/printer"...
    +
    +echo $PRINTER/$DEVICE_URI | \
    +	awk -F/ '{print $1 "=" $5 ":LaserWriter@" $4}' > /var/tmp/$$.cap
    +
    +CAPPRINTERS=/var/tmp/$$.cap; export CAPPRINTERS
    +
    +# Send the file to the printer, once for each copy. This assumes that you
    +# have properly initialized the cap.printers file...
    +
    +while [ $copies -gt 0 ]; do
    +	papif -n $user < $file
    +
    +        copies=`expr $copies - 1`
    +done
    +
    +# Remove any temporary files...
    +if test ${#argv} = 5; then
    +	/bin/rm -f $file
    +fi
    +
    +/bin/rm -f /var/tmp/$$.cap
    +
    +exit 0
    +
+ + +

Printing from Windows Clients

+ +

While CUPS does not provide Windows support directly, the free +SAMBA software package does. SAMBA version 2.0.6 is the first release +of SAMBA that supports CUPS. You can download SAMBA from: + +

+ +

To configure SAMBA for CUPS, edit the smb.conf file and +replace the existing printing commands and options with the line: + +

    +printing = cups
    +
+ +

That's all there is to it! Remote users will now be able to browse and +print to printers on your system. + +

Printing to Windows Servers

+ +

CUPS can print to Windows servers in one of two ways. The first way uses +the LPD protocol on the CUPS system and the "TCP/IP Printing Services" on +the Windows system. You can find out more about this configuration in the +LPD section earlier in this chapter. + +

The second way is through the Microsoft Server Message Block ("SMB") +protocol. Support for this protocol is provided with the free SAMBA +software package. You can download SAMBA from: + +

+ +

To configure CUPS for SAMBA, run the following command: + +

    +ln -s `which smbspool` /usr/lib/cups/backend/smb ENTER
    +
+ +

The smbspool(1) program is provided with SAMBA starting +with SAMBA 2.0.6. Once you have made the link you can configure your +printers with one of the following device URIs: + +

    +smb://workgroup/server/sharename
    +smb://server/sharename
    +smb://user:pass@workgroup/server/sharename
    +smb://user:pass@server/sharename
    +
+ +

The workgroup name need only be specified if your +system is using a different workgroup. The user:pass +strings are required when printing to Windows NT servers or to shares +with passwords enabled under Windows 95 and 98. + + +

A - Software License Agreement

+ + + + +

B - Common Network Settings

+ +

This appendix covers many of the popular TCP/IP network interfaces +and printer servers available on the market today. + +

Configuring a Network Interface

+ +

When you first install a network printer or print server on your +LAN, you need to set the Internet Protocol ("IP") address. On most +higher-end "workgroup" printers, you can set the address through the +printer control panel. However, in most cases you will want to assign +the addresses remotely from your workstation. This makes administration +a bit easier and avoids assigning duplicate addresses accidentally. + +

To setup your printer or print server for remote address assignment, +you'll need the Ethernet Media Access Control ("MAC") address, also +sometimes called a node address, and the IP address you want to use for +the device. The Ethernet MAC address can often be found on the printer +test page or bottom of the print server. + + +

Configuring the IP Address Using ARP

+ +

The easiest way to set the IP address of a network device is to use +the arp(8) command. The arp sends an Address +Resolution Protocol ("ARP") packet to the specified Ethernet MAC address, +setting the network device's IP address: + +

    +arp -s ip-address ethernet-address ENTER
    +arp -s host.domain.com 08:00:69:00:12:34 ENTER
    +arp -s 192.0.2.2 08:00:69:00:12:34 ENTER
    +
+ +

Configuring the IP Address Using RARP

+ +

The most flexible way to remotely assign IP addresses under UNIX +is through the Reverse Address Resolution Protocol ("RARP"). RARP +allows a network device to request an IP address using its Ethernet +MAC address, and one or more RARP servers on the network will +respond with an ARP packet with the IP address the device can use. + +

RARP should be used when you have to manage many printers or print +servers, or when you have a network device that does not remember its +IP address after a power cycle. If you just have a single printer or +print server, the arp command is the way to go. + +

Some UNIX operating systems use a program called +rarpd(8) to manage RARP. Others, like Linux, support this +protocol in the kernel. For systems that provide the rarpd +program you will need to start it before RARP lookups will work: + +

    +rarpd ENTER
    +
+ +

Under IRIX you can enable this functionality by default using: + +

    +chkconfig rarpd on ENTER
    +
+ +

Both the rarpd program and kernel RARP support read a +list of Ethernet and IP addresses from the file /etc/ethers. +Each line contains the Ethernet address (colon delimited) followed by +an IP address or hostname like: + +

    +08:00:69:00:12:34 myprinter.mydomain.com
    +08:00:69:00:12:34 192.0.2.2
    +
+ +

Add a line to this file and cycle the power on the printer or print +server to set its address. + + +

Configuring the IP Address Using BOOTP

+ +

The BOOTP protocol is used when you need to provide additional information +such as the location of a configuration file to the network interface. Using +the standard bootpd(8) program supplied with UNIX you simply need to +add a line to the /etc/bootptab file; for IRIX: + +

    +myprinter 08:00:69:00:12:34 192.0.2.2 myprinter.boot
    +
+ + +

Newer versions of bootpd use a different format: + +

    +myprinter:ha=080069001234:ip=192.0.2.2:t144=myprinter.boot
    +
+ +

The myprinter.boot file resides in the /usr/local/boot +directory by default. If you do not need to provide a boot file you may leave +the last part of the line blank. + + +

+ + + +
+ NOTE: + +

Some versions of UNIX do not enable the BOOTP service by + default. The /etc/inetd.conf usually contains a + line for the BOOTP service that can be uncommented if + needed. +

+ +

Verifying the Printer Connection

+ +

To test that the IP address has been successfully assigned and that the +printer is properly connected to your LAN, type: + +

    +ping ip-address ENTER
    +
+ +

If the connection is working properly you will see something like: + +

    +ping myprinter ENTER
    +PING myprinter (192.0.2.2): 56 data bytes
    +64 bytes from 192.0.2.2: icmp_seq=0 ttl=15 time=5 ms
    +64 bytes from 192.0.2.2: icmp_seq=1 ttl=15 time=3 ms
    +64 bytes from 192.0.2.2: icmp_seq=2 ttl=15 time=3 ms
    +64 bytes from 192.0.2.2: icmp_seq=3 ttl=15 time=3 ms
    +
+ +

If not, verify that the printer or print server is connected to the +LAN, it is powered on, the LAN cabling is good, and the IP address is +set correctly. You can usually see the current IP address and network +status by printing a configuration or test page on the device. + + +

Common Network Interface Settings

+ +

Once you have set the IP address you can access the printer or print +server using the ipp, lpd, or +socket backends. The following is a list of common network +interfaces and printer servers and the settings you should use with +CUPS: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Model/ManufacturerDevice URI(s)
Apple LaserWriterlpd://address/PASSTHRU
Axis w/o IPP
+ (see directions)
socket://address:9100
+ socket://address:9101
+ socket://address:9102
Axis w/IPPipp://address/LPT1
+ ipp://address/LPT2
+ ipp://address/COM1
Castelle LANpressTMlpd://address/pr1
+ lpd://address/pr2
+ lpd://address/pr3
DPI NETPrintlpd://address/pr1
+ lpd://address/pr2
+ lpd://address/pr3
EFI® Fiery® RIPlpd://address/print
EPSON® Multiprotocol Ethernet Interface Boardsocket://address
Extended System ExtendNETlpd://address/pr1
+ lpd://address/pr2
+ lpd://address/pr3
Hewlett Packard JetDirect w/o IPPsocket://address:9100
+ socket://address:9101
+ socket://address:9102
Hewlett Packard JetDirect w/IPPipp://address/ipp
+ ipp://address/ipp/port1
+ ipp://address/ipp/port2
+ ipp://address/ipp/port3
Intel® NetportExpress XL, PRO/100lpd://address/LPT1_PASSTHRU
+ lpd://address/LPT2_PASSTHRU
+ lpd://address/COM1_PASSTHRU
LexmarkTM MarkNetlpd://address/ps
Linksys EtherFast®
+ (see directions)
socket://address:4010
+ socket://address:4020
+ socket://address:4030
Kodak®lpd://address/ps
QMS® CrownNetTMlpd://address/ps
Tektronix® PhaserShareTMsocket://address:9100
XEROX® 4512 NIClpd://address/PORT1
XEROX® XNIClpd://address/PASSTHRU
XEROX® (most others)socket://address:5503
+ +

Configuring Axis Print Servers

+ +

The Axis print servers can be configured using ARP, RARP, or BOOTP. +However, on models that do not provide IPP support an additional step +must be performed to configure the TCP/IP portion of the print server +for use with CUPS. + + +

Each print server contains a configuration file named +config that contains a list of network parameters used by +the server. To modify this file you must first download it from the +print server using the ftp(1) program: + +

    +ftp ip-address ENTER
    +Connected to ip-address.
    +220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
    +ftp> user root ENTER
    +331 User name ok, need password
    +Password: pass ENTER (this is not echoed)
    +230 User logged in
    +ftp> get config ENTER
    +local: config remote: config
    +200 PORT command successful.
    +150 Opening data connection for config (192,0,2,2),
    +(mode ascii).
    +226 Transfer complete.
    +##### bytes received in #.## seconds (##### Kbytes/s)
    +ftp> quit ENTER
    +221 Goodbye.
    +
+ + +

Next, edit the file with your favorite text editor and locate the +lines beginning with: + +

    +RTN_OPT.     : YES
    +RTEL_PR1.    : 0
    +RTEL_PR2.    : 0
    +RTEL_PR3.    : 0
    +RTEL_PR4.    : 0
    +RTEL_PR5.    : 0
    +RTEL_PR6.    : 0
    +RTEL_PR7.    : 0
    +RTEL_PR8.    : 0
    +
+ + +Change the RTN_OPT line to read: + +
    +RTN_OPT.     : NO
    +
+ + +

This disables the Reverse TELNET protocol and enables the standard +TELNET protocol on the print server. Next, assign a port number for +each parallel and serial port on the server as follows: + +

    +RTEL_PR1.    : 9100
    +RTEL_PR2.    : 9101
    +RTEL_PR3.    : 9102
    +RTEL_PR4.    : 9103
    +RTEL_PR5.    : 9104
    +RTEL_PR6.    : 9105
    +RTEL_PR7.    : 9106
    +RTEL_PR8.    : 9107
    +
+ + +

This essentially makes the Axis print server look like a Hewlett +Packard JetDirect EX print server. Save the file and then upload the +new config file using the ftp command: + +

    +ftp ip-address ENTER
    +Connected to ip-address.
    +220 Axis NPS ### FTP Printer Server V#.## MON DD YEAR ready.
    +ftp> user root ENTER
    +331 User name ok, need password
    +Password: pass ENTER (this is not echoed)
    +230 User logged in
    +ftp> put config CONFIG ENTER
    +local: config remote: CONFIG
    +200 PORT command successful.
    +150 Opening data connection for config (192,0,2,2), (mode ascii).
    +226 Transfer complete.
    +##### bytes received in #.## seconds (##### Kbytes/s)
    +ftp> get hardreset ENTER
    +local: hardreset remote: hardreset
    +200 PORT command successful.
    +421 Axis NPS ### hard reset, closing connection.
    +ftp> quit ENTER
    +221 Goodbye.
    +
+ +

Your Axis print server is now ready for use! + +

Configuring Linksys Print Servers

+ +

The Linksys print servers can be configured using ARP, RARP, or +BOOTP. Like older Axis print servers, an additional step must be +performed to configure the TCP/IP portion of the print server for use +with CUPS. + + +

Each print server contains a configuration file named +CONFIG that contains a list of network parameters used by +the server. To modify this file you must first download it from the +print server using the ftp(1) program: + +

    +ftp -n ip-address ENTER
    +Connected to ip-address.
    +220 Print Server Ready.
    +Remote system type is Print.
    +ftp> get CONFIG ENTER
    +local: CONFIG remote: CONFIG
    +200 Command OK.
    +150 Open ASCII Mode Connection.
    +WARNING! 68 bare linefeeds received in ASCII mode
    +File may not have transferred correctly.
    +226 Transfer complete.
    +##### bytes received in #.## seconds (##### Kbytes/s)
    +ftp> quit ENTER
    +221 Goodbye.
    +
+ + +

Next, edit the file with your favorite text editor and locate the +lines beginning with: + +

    +0100 L1_PROUT:P1
    +0120 L2_PROUT:P1
    +0140 L3_PROUT:P1
    +
+ +

Change the port number for +each parallel and serial port on the server as follows: + +

    +0100 L1_PROUT:P1
    +0120 L2_PROUT:P2
    +0140 L3_PROUT:P3
    +
+ + +

This maps each virtual printer with a physical port. Save the file and then upload the +new CONFIG file using the ftp command: + +

    +ftp -n ip-address ENTER
    +Connected to ip-address.
    +220 Print Server Ready.
    +Remote system type is Print.
    +ftp> put CONFIG ENTER
    +local: CONFIG remote: CONFIG
    +200 Command OK.
    +150 Open ASCII Mode Connection.
    +226 Transfer complete.
    +##### bytes received in #.## seconds (##### Kbytes/s)
    +ftp> quit ENTER
    +221 Goodbye.
    +
+ +

Your Linksys print server is now ready for use! + + +

C - Printer Drivers

+ +

This appendix lists the printer drivers that are provided with CUPS. + +

Printer Drivers

+ +

CUPS includes the following printer drivers: + +

+ +

EPSON 9-pin Dot Matrix

+ +

The EPSON 9-pin Dot Matrix driver (epson9.ppd) supports +9-pin dot matrix printers that implement the ESC/P command set. It +provides 60x72, 120x72, and 240x72 DPI output in black only. + +

EPSON 24-pin Dot Matrix

+ +

The EPSON 24-pin Dot Matrix driver (epson9.ppd) supports +24-pin dot matrix printers that implement the ESC/P command set. It +provides 120x180, 180x180, 360x180, and 360x360 DPI output in black +only. + +

EPSON Stylus Color

+ +

The EPSON Stylus Color driver (stcolor.ppd) supports +EPSON Stylus Color printers that implement the ESC/P2 command set. It +provides 180, 360, and 720 DPI output in black and color (CMYK). + +

EPSON Stylus Photo

+ +

The EPSON Stylus Photo driver (stphoto.ppd) supports +EPSON Stylus Photo printers that implement the ESC/P2 command set. It +provides 180, 360, and 720 DPI output in black and color (CMYKcm). + +

HP DeskJet

+ +

The HP DeskJet driver (deskjet.ppd) supports HP DeskJet +printers that implement the PCL command set. It provides 150, 300, and +600 DPI output in black and color (CMYK). + +

The DeskJet printers that implement the HP-PPA command set (720C, +722C, 820C, and 1100C) are not supported due to a complete lack +of documentation and support from Hewlett Packard. + +

The duplexer provided with the HP DeskJet 900 series printers is also +not supported for similar reasons. + +

HP LaserJet

+ +

The HP LaserJet driver (laserjet.ppd) supports HP +LaserJet printers that implement the PCL command set. It provides 150, +300, and 600 DPI output in black only and supports the duplexer if +installed. + +

LaserJet printers that do not implement PCL (3100, 3150) are not +supported due to a complete lack of documentation and support from +Hewlett Packard. + + +

D - List of Files

+ +

This appendix lists the files and directories that are installed for +the Common UNIX Printing System. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
PathnameDescription
/etc/cups/certs/The location of authentication certificate files for local + HTTP clients.
/etc/cups/classes.confThe printer classes configuration file for the scheduler.
/etc/cups/cupsd.confThe scheduler configuration file.
/etc/cups/interfaces/The location of System V interface scripts for printers.
/etc/cups/mime.convsThe list of standard file filters included with ESP Print Pro.
/etc/cups/mime.typesThe list of recognized file types for ESP Print Pro.
/etc/cups/ppd/The location of PostScript Printer Description ("PPD") files for + printers.
/etc/cups/printers.confThe printer configuration file for the scheduler.
/usr/bin/cancelThe System V cancel job(s) command.
/usr/bin/disableThe System V disable printer command.
/usr/bin/enableThe System V enable printer command.
/usr/bin/lpThe System V print command.
/usr/bin/lpoptionsSets user-defined printing options and defaults.
/usr/bin/lppasswdAdds, changes, or removes Digest password accounts.
/usr/bin/lpqThe Berkeley status command.
/usr/bin/lprThe Berkeley print command.
/usr/bin/lprmThe Berkeley cancel job(s) command.
/usr/bin/lpstatThe System V status command.
/usr/include/cups/CUPS API header files.
/usr/lib32/libcups.a
+ /usr/lib32/libcupsimage.a
Static libraries (IRIX 6.5)
/usr/lib/libcups.a
+ /usr/lib/libcupsimage.a
Static libraries (all others)
/usr/lib/libcups.sl.2
+ /usr/lib/libcupsimage.sl.2
Shared libraries (HP-UX)
/usr/lib32/libcups.so.2
+ /usr/lib32/libcupsimage.so.2
Shared libraries (IRIX 6.5)
/usr/lib/libcups.so.2
+ /usr/lib/libcupsimage.so.2
Shared libraries (all others)
/usr/lib/cups/backend/Backends for various types of printer connections.
/usr/lib/cups/cgi-bin/CGI programs for the scheduler.
/usr/lib/cups/daemon/Daemons for polling and LPD support.
/usr/lib/cups/filter/Filters for various types of files.
/usr/lib/locale/The location of language-specific message files. (System V)
/usr/lib/nls/msg/The location of language-specific message files. (Compaq Tru64 UNIX)
/usr/share/locale/The location of language-specific message files. (Linux, *BSD)
/usr/sbin/acceptThe accept-jobs command.
/usr/sbin/cupsdThe CUPS print scheduler.
/usr/sbin/lpadminThe System V printer administration tool.
/usr/sbin/lpcThe Berkeley printer administration tool.
/usr/sbin/lpinfoThe get-devices and get-ppds command.
/usr/sbin/lpmoveThe move-jobs command.
/usr/sbin/rejectThe reject-jobs command.
/usr/share/catman/a_man/
+ /usr/share/catman/u_man/
Man pages (IRIX)
/usr/share/man/Man pages (Compaq Tru64 UNIX, HP-UX, Solaris)
/usr/man/Man pages (all others)
/usr/share/cups/data/The location of filter data files.
/usr/share/cups/data/testprint.psThe PostScript test page file.
/usr/share/cups/fonts/The location of PostScript fonts for the PostScript RIP.
/usr/share/cups/model/The location of PostScript Printer Description ("PPD") files and + interface scripts that may be used to setup a printer queue.
/usr/share/cups/pstoraster/Other PostScript RIP initialization files.
/usr/share/cups/pstoraster/FontmapThe font mapping file (converts filenames to fontnames)
/usr/share/cups/templates/The location of HTML template files for the web interfaces.
/usr/share/doc/cups/Documentation and web page data for the scheduler.
/var/log/cups/The location of scheduler log files.
/var/spool/cups/The location of print files waiting to be printed.
+ + +

E - Troubleshooting Common Problems

+ +

This appendix covers some of the common problems first-time users +encounter when installing and configuring CUPS. + +

Commercial support for CUPS is available from Easy Software Products. +For more information please contact us at: + +

+ +

My Applications Don't See the Available Printers

+ +

Many applications read the /etc/printcap file to +get a list of available printers. + +

The default CUPS configuration does not create the +/etc/printcap file automatically. To enable automatic +creation and updating of this file, use the +Printcap directive described in +Chapter 6, "Printing System Management". + +

CUPS Doesn't Recognize My Username or Password!

+ +

CUPS will ask you for a UNIX username and password when you perform +printer administration tasks remotely or via a web browser. The default +configuration requires that you use the root username and +the corresponding password to authenticate the request. + +

CUPS does not allow you to authenticate an administration request +with an account that has no password for security reasons. If you do +not have a password on your root account then you won't be +able to add printers remotely or via the web interface! + + +

To disable password authentication you need to edit the +/etc/cups/cupsd.conf file and comment out the +lines reading: + +

    +AuthType Basic
    +AuthClass System
    +
+ +for the /admin location. Then restart the CUPS server as +described in Chapter 8, "Printing System +Management". + +
+ + + +
+ NOTE: + +

Disabling password checks will allow any local user to + change your printer and class configuration, but remote + administration from another machine will still not be allowed. +

+ +

I Can't Do Administration Tasks from Another Machine!

+ +

The default CUPS configuration limits administration to the local +machine. To open up access, edit the /etc/cups/cupsd.conf +and comment out the lines reading: + +

    +Order deny,allow
    +Deny from all
    +Allow from 127.0.0.1
    +
+ +for the /admin location. Then restart the CUPS server as +described in Chapter 8, "Printing System +Management". + +
+ + + +
+ NOTE: + +

Allowing administration access from all hosts is a potential + security risk. Please read Chapter + 6, "Printing System Management" for a description of these + risks and ways to minimize them. +

+ + +

I Can't Do Administration Tasks from My Web Browser!

+ +

This problem is usually caused by: + +

    + +
  1. not specifying the correct password for the + root account. + +
  2. accessing the CUPS server using the hostname or IP + address of the server without enabling remote access for + administration functions. This can be corrected by following + the instructions in the "I Can't Do + Administration Tasks from Another Machine!" section earlier + in this appendix. + +
  3. not setting a password on the root account. CUPS will not + authenticate a user account that does not have a password for + security reasons. + +
  4. authenticating using an account other than root, but the + account you are using is not a member of the system group. + +
  5. configuring CUPS to use Digest authentication, but + your web browser does not support Digest authentication. + +
+ +

Connection Refused Messages

+ +

Under normal circumstances, "connection refused" messages for a +networked printer should be expected from time to time. Most network +interfaces only allow a single connection to be made at any given time +(one job at a time) and will refuse access to all other systems while +the first connection is active. CUPS automatically retries the +connection once every 30 seconds. + +

If the problem persists and you are unable to print any jobs to the printer, +verify that another machine is not maintaining a connection with the printer, +and that you have selected the proper port or printer name for the printer. + +

Also, most external print servers will refuse connections if the connected +printer is turned off or is off-line. Verify that the affected printer is +turned on and is online. + +

Write Error Messages

+ +

If you get "write error" messages on a printer queue the printer +interface (usually a Hewlett Packard JetDirect interface) has timed out +and reset the network connection from your workstation. + +

The error is caused by that startup delay between the initial setup +of the printer or plotter and the first page of print data that is +sent. + + +

To correct the problem, change the idle timeout on the interface to at least +180 seconds or 3 minutes. To change the timeout on a Hewlett Packard +JetDirect interface, type: + +

    +telnet ip-address ENTER
    +
    +Trying ip-address...
    +Connected to ip-address.
    +Escape character is `^]'.
    +
    +Please type [Return] two times, to initialize telnet configuration
    +For HELP type "?"
    +> idle-timeout: 180 ENTER
    +> quit ENTER
    +
+ + + diff --git a/doc/sdd.html b/doc/sdd.html new file mode 100644 index 0000000000..d927be93a8 --- /dev/null +++ b/doc/sdd.html @@ -0,0 +1,590 @@ + + + + CUPS Software Design Description + + + + + + + +

+

CUPS Software Design Description


+CUPS-SDD-1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
1 Scope + +2 References + +3 Design Overview + +A Glossary + +
+

1 Scope

+

1.1 Identification

+ This software design description document provides general information + on the architecture and coding of the Common UNIX Printing System + ("CUPS") Version 1.1. +

1.2 System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+

1.3 Document Overview

+ This software design description document is organized into the + following sections: +
    +
  • 1 - Scope
  • +
  • 2 - References
  • +
  • 3 - Design Overview
  • +
  • A - Glossary
  • +
+

2 References

+

2.1 CUPS Documentation

+

The following CUPS documentation is referenced by this document:

+
    +
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • +
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • +
  • CUPS-IPP-1.1: CUPS Implmentation of IPP
  • +
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • +
  • CUPS-SDD-1.1: CUPS Software Design Description
  • +
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual
  • +
  • CUPS-SSR-1.1: CUPS Software Security Report
  • +
  • CUPS-STP-1.1: CUPS Software Test Plan
  • +
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • +
  • CUPS-SVD-1.1.x: CUPS Software Version Description
  • +
+

2.2 Other Documents

+

The following non-CUPS documents are referenced by this document:

+ +

3 Design Overview

+ CUPS is composed of 9 software sub-systems that operate together to + perform common printing tasks: +
    +
  • Backends
  • +
  • Berkeley Commands
  • +
  • CGI
  • +
  • CUPS Application Programmers Interface
  • +
  • CUPS Imaging Library
  • +
  • Daemons
  • +
  • Filters
  • +
  • Scheduler
  • +
  • System V Commands
  • +
+

3.1 Backends

+ The backends implement communications over a number of different +interfaces. All backends are called with a common set of arguments: +
    +
  • Device URI - the Uniform Resource Identifier for the output device + (e.g. parallel:/dev/plp, ipp://hostname/resource +).
  • +
  • Job Identifier - the job identifier for this job (integer).
  • +
  • User Name - the user associated with this job (name string).
  • +
  • Title - the title/job-name associated with this job (name string).
  • +
  • Copies - the number of copies required (integer).
  • +
  • Options - the options associated with this job (space separated + option strings).
  • +
  • Filename (optional) - the file to print; if this option is not + specified, the backend must read the print file from the standard + input.
  • +
+

Backends are named using the scheme of the URI, so a URI of +"ipp://hostname/resource" would be processed by the "ipp" backend.

+

3.1.1 ipp

+

The ipp backend sends the specified job to a network printer or +host using the Internet Printing Protocol. The URI is as specified by +the printer-uri-supported attribute from the printer or +host.

+

3.1.2 lpd

+

The lpd backend sends the specified job to a network printer or +host using the Line Printer Daemon protocol. The URI is of the form:

+
    +
    lpd://hostname/queue
    +
    +
+

3.1.3 parallel

+

The parallel backend sends the specified job to a local printer +connected via the specified parallel port device. The URI is of the +form:

+
    +
    parallel:/dev/file
    +
    +
+

3.1.4 serial

+

The serial backend sends the specified job to a local printer +connected via the specified serial port device. The URI is of the +form:

+
    +
    serial:/dev/file?option[+option+...]
    +
    +
+ The options can be any combination of the following: +
    +
  • baud=rate - Sets the baud rate for the device.
  • +
  • bits=7 or 8 - Sets the number of data bits.
  • +
  • parity=even - Sets even parity checking.
  • +
  • parity=odd - Sets odd parity checking.
  • +
  • parity=none - Turns parity checking off.
  • +
+

3.1.5 socket

+

The socket backend sends the specified job to a network host using +the AppSocket protocol commonly used by Hewlett-Packard and Tektronix +printers. The URI is of the form:

+
    +
    socket://hostname[:port]
    +
    +
+ The default port number is 9100. +

3.1.6 usb

+

The usb backend sends the specified job to a local printer +connected via the specified usb port device. The URI is of the form:

+
    +
    usb:/dev/file
    +
    +
+

3.2 Berkeley Commands

+

The Berkeley commands provide a simple command-line interface to +CUPS to submit and control print jobs. It is provided for compatibility +with existing software that is hardcoded to use the Berkeley commands.

+

3.2.1 lpc

+ The lpc command allows users and administrators to check the status +and control print queues. The version provided with CUPS supports the +following commands: +
    +
  • quit - Quits the lpc command.
  • +
  • status - Shows the status of printers and jobs in the queue.
  • +
+

3.2.2 lpq

+

The lpq command shows the current queue status.

+

3.2.3 lpr

+

The lpr command submits a job for printing. The CUPS version of +lpr silently ignores the "i", "t", "m", "h", and "s" options.

+

3.2.4 lprm

+

The lprm removes one or more print jobs.

+

3.3 CGI

+

The Common Gateway Interface (CGI) programs provide a web-based +status interface to monitor the status of printers, classes, and jobs. +Each of the CGIs utilize HTML template files that can be customized to +provide alternate appearances.

+

3.3.1 admin.cgi

+

The admin CGI provides administration interfaces for printers and +classes. The user can add, modify, delete, start, stop, and configure +printers and classes using "wizard" interfaces.

+

3.3.2 classes.cgi

+

The classes CGI lists the available printer classes and any pending +jobs for the class. The user can click on individual classes to limit +the display and click on jobs to see the job status.

+

3.3.3 jobs.cgi

+

The jobs CGI lists the queued print jobs in order of priority. The +list can be limited by printer or job.

+

3.3.4 printers.cgi

+

The printers CGI lists the available printer queues and any pending +jobs for the printer. The user can click on individual printers to +limit the display and click on jobs to see the job status.

+

3.4 CUPS Application Programmers Interface

+

The CUPS Application Programmers Interface ("API") provides common +convenience, HTTP, IPP, language, and PPD functions used by the CUPS +software.

+

3.4.1 Convenience Functions

+

Convenience functions are provided to submit an IPP request, send a +print file, cancel a job, get a list of available printers, get a list +of available classes, get the default printer or class, get the default +server name, get the local username, and get a password string.

+

3.4.2 HTTP Functions

+

The HTTP functions provide functions to connect to HTTP servers, +issue requests, read data from a server, and write data to a server.

+

3.4.3 IPP Functions

+

The IPP function provide functions to manage IPP request data and +attributes, read IPP responses from a server, and write IPP requests to +a server.

+

3.4.4 Language Functions

+

The language functions provide a standard interface for retrieving +common textual messages for a particular locale and determining the +correct encoding (e.g. US ASCII, UTF-8, ISO-8859-1, etc.)

+

3.4.5 PPD Functions

+

The PostScript Printer Description functions manage PPD files, +select options, check for option conflicts, and emit selected options +in the correct order.

+

3.5 CUPS Imaging Library

+

The CUPS imaging library provides colorspace conversion, color +management, image management, scaling, image file, and raster functions +used by the CUPS raster filters.

+

3.5.1 Colorspace Conversion Functions

+

The colorspace conversion functions handle conversion of grayscale +and RGB colors to grayscale, RGB, K, CMY, CMYK, and CMYKcm colorspaces.

+

3.5.2 Color Management Functions

+

The color management functions handle gamut mapping and density +correction. These are integrated with the colorspace conversion +functions so that colorspace conversion and color management are +processed in a single step.

+

3.5.3 Image Management Functions

+

The image management functions manage a tiled image database that +is swapped to/from disk as needed.

+

3.5.4 Scaling Functions

+

The scaling functions provide image scaling services using +nearest-neighbor sampling and bilinear interpolation as appropriate.

+

3.5.5 Image File Functions

+

The image file functions handle loading of all image file formats.

+

3.5.6 Raster Functions

+

The raster functions manage streams of CUPS raster data (described +in the Interface Design Document) used by non-PostScript printer +drivers and raster filters.

+

3.6 Daemons

+

The daemons provide additional network functions for the scheduler. +Currently only two daemons are provided with CUPS.

+

3.6.1 Line Printer Daemon

+

The line printer daemon provides remote LPD client support and is +run by the inetd(8) daemon as needed.

+

3.6.2 Polling Daemon

+

The polling daemon is used to poll a remote server for a list of +available printers and provide it to the scheduler for addition. A +separate polling daemon is run by the scheduler for every remote system +listed for polling in the scheduler configuration file.

+

3.7 Filters

+

The filters implement file conversion services for CUPS. All +filters are called with a common set of arguments:

+
    +
  • Printer name - the name of the destination printer (name string).
  • +
  • Job Identifier - the job identifier for this job (integer).
  • +
  • User Name - the user associated with this job (name string).
  • +
  • Title - the title/job-name associated with this job (name string).
  • +
  • Copies - the number of copies required (integer).
  • +
  • Options - the options associated with this job (space separated + option strings).
  • +
  • Filename (optional) - the file to print; if this option is not + specified, the filter must read the input file from the standard + input.
  • +
+

Filters are added to the MIME conversion data file and implement +all necessary conversions from one file type to another.

+

3.7.1 hpgltops

+

The hpgltops filter converts HP-GL/2 files into PostScript.

+

3.7.2 imagetops

+

The imagetops filter converts image files into PostScript.

+

3.7.3 imagetoraster

+

The imagetoraster filter converts image files into CUPS raster +data.

+

3.7.4 pdftops

+

The pdftops filter converts PDF files into PostScript.

+

3.7.5 pstops

+

The pstops filter inserts printer-specific commands from PPD files +and performs page filtering as requested by the user.

+

3.7.6 pstoraster

+

The pstoraster filter converts PostScript program data into CUPS +raster data.

+

3.7.7 rastertoepson

+

The rastertoepson filter handles converting CUPS raster data to +ESC/P and supports both color and black-and-white printers.

+

3.7.8 rastertohp

+

The rastertohp filter handles converting CUPS raster data to HP-PCL +and supports both color and black-and-white printers.

+

3.7.9 texttops

+

The texttops filter converts text files into PostScript.

+

3.8 Scheduler

+

The scheduler is a fully-functional HTTP/1.1 and IPP/1.1 server +that manages the printers, classes, and jobs in the system. It also +handles a simple broadcast-based directory service so that remote print +queues and classes can be accessed transparently from the local system.

+

3.8.1 Authorization

+

The authorization module is responsible for performing access +control and authentication for all HTTP and IPP requests entering the +system.

+

3.8.2 Classes

+

The classes module is responsible for managing printer classes in +the system. Each class is a collection of local and/or remote printers. + The classes module also reads and writes the classes configuration +file.

+

3.8.3 Client

+

The client module is responsible for all HTTP client +communications. It handles listening on selected interfaces, accepting +connections from prospective clients, processing incoming HTTP +requests, and sending HTTP responses to those requests. The client +module also is responsible for executing the external CGI programs as +needed to support web-based printer, class, and job status monitoring +and administration.

+

Once authorized, all IPP requests are sent to the IPP module.

+

3.8.4 Configuration

+

The configuration module is responsible for reading the CUPS +configuration file and initializing the appropriate data structures and +values. The configuration module also stops CUPS services before +reading the configuration file and restarts them after the +configuration file has been read.

+

3.8.5 Devices

+

The devices module is responsible for managing the list of +available devices for the CUPS-Get-Devices operation.

+

3.8.6 Directory Services

+

The directory services module sends and recieves printer state +information over a broadcast socket. Remote printers and classes are +automatically added to or removed from the local printer and class +lists as needed.

+

The directory services module can only recieve printer state +information over a single UDP port, however it can broadcast to +multiple addresses and ports as needed.

+

3.8.7 IPP

+

The IPP module handles IPP requests and acts accordingly. URI +validation is also performed here, as a client can post IPP data to any +URI on the server which might sidestep the access control or +authentication of the HTTP server.

+

3.8.8 Jobs

+

The jobs module manages print jobs, starts filter and backend +processes for jobs to be printed, and monitors status messages from +those filters and backends.

+

3.8.9 Logging

+

The logging module manages the access, error, and page log files +that are generated by the scheduler.

+

3.8.10 Main

+

The main module is responsible for timing out and dispatching input +and output for client connections. It also watches for incoming +SIGHUP and SIGCHLD signals, reloads the server +configuration files as needed, and handles child process errors and +exits.

+

3.8.11 MIME

+

The Multimedia Internet Mail Exchange module manages a MIME type +and conversion database that supports file typing by extension and +content and least-cost file filtering from a source to a destination +file type.

+

3.8.12 PPDs

+

The PPDs module is responsible for managing the list of available +PPD files for the CUPS-Get-PPDs operation.

+

3.8.13 Printers

+

The printers module is responsible for managing printers and PPD +files in the system. The printers module also reads and writes the +printers configuration file.

+

3.9 System V Commands

+

The System V commands provide a robust command-line interface to +CUPS to submit and control printers and jobs.

+

3.9.1 accept

+

The accept command tells the scheduler to accept new jobs for +specific printers.

+

3.9.2 cancel

+

The cancel command tells the scheduler to cancel one or more jobs +that are queued for printing.

+

3.9.3 disable

+

The disable command tells the scheduler to stop printing jobs on +the specified printers.

+

3.9.4 enable

+

The enable command tells the scheduler to start printing jobs on +the specified printers.

+

3.9.5 lp

+

The lp command submits submits files for printing. Unlike the +standard System V lp command, a single CUPS lp command will generate a +separate job ID for each file that is printed. Also, the Solaris "f", +"H", "P", "S", and "y" options are silently ignored.

+

3.9.6 lpadmin

+

The lpadmin command manages printer queues and classes. The +Solaris "A", "F", "I", "M", "P", "Q", "S", "T", "U", "W", "f", "l", +"m", "o", "s", "t", and "u" options are not supported, and new options +"P" (PPD file) and "E" (enable and accept) are provided to configure +CUPS-specific features.

+

3.9.7 lpinfo

+

The lpinfo command lists the available PPD files or devices as +selected by the user.

+

3.9.8 lpmove

+

The lpmove command moves a print job to a new destination.

+

3.9.9 lpoptions

+

The lpoptions command manages user-defined printers and options.

+

3.9.10 lpstat

+

The lpstat command lists printers, classes, and jobs as requested +by the user.

+

3.9.11 reject

+

The reject command tells the scheduler not to accept new jobs for +specific printers.

+

A Glossary

+

A.1 Terms

+
+
C
+
A computer language.
+
parallel
+
Sending or receiving data more than 1 bit at a time.
+
pipe
+
A one-way communications channel between two programs.
+
serial
+
Sending or receiving data 1 bit at a time.
+
socket
+
A two-way network communications channel.
+
+

A.2 Acronyms

+
+
ASCII
+
American Standard Code for Information Interchange
+
CUPS
+
Common UNIX Printing System
+
ESC/P
+
EPSON Standard Code for Printers
+
FTP
+
File Transfer Protocol
+
HP-GL
+
Hewlett-Packard Graphics Language
+
HP-PCL
+
Hewlett-Packard Page Control Language
+
HP-PJL
+
Hewlett-Packard Printer Job Language
+
IETF
+
Internet Engineering Task Force
+
IPP
+
Internet Printing Protocol
+
ISO
+
International Standards Organization
+
LPD
+
Line Printer Daemon
+
MIME
+
Multimedia Internet Mail Exchange
+
PPD
+
PostScript Printer Description
+
SMB
+
Server Message Block
+
TFTP
+
Trivial File Transfer Protocol
+
+ + diff --git a/doc/sdd.pdf b/doc/sdd.pdf new file mode 100644 index 0000000000..b9305ab5d8 --- /dev/null +++ b/doc/sdd.pdf @@ -0,0 +1,1024 @@ +%PDF-1.2 +%âãÏÓ +1 0 obj<>endobj +2 0 obj<>endobj +3 0 obj<>endobj +4 0 obj<>endobj +5 0 obj<>endobj +6 0 obj<>endobj +7 0 obj<>endobj +8 0 obj<>endobj +9 0 obj<>endobj +10 0 obj<>endobj +11 0 obj<>endobj +12 0 obj<>endobj +13 0 obj<>endobj +14 0 obj<>endobj +15 0 obj[12 0 R +14 0 R +]endobj +16 0 obj<>endobj +17 0 obj<>endobj +18 0 obj<>endobj +19 0 obj<>endobj +20 0 obj<>endobj +21 0 obj<>endobj +22 0 obj<>endobj +23 0 obj<>endobj +24 0 obj<>endobj +25 0 obj<>endobj +26 0 obj<>endobj +27 0 obj<>endobj +28 0 obj<>endobj +29 0 obj<>endobj +30 0 obj<>endobj +31 0 obj<>endobj +32 0 obj<>endobj +33 0 obj<>endobj +34 0 obj<>endobj +35 0 obj<>endobj +36 0 obj<>endobj +37 0 obj<>endobj +38 0 obj<>endobj +39 0 obj<>endobj +40 0 obj<>endobj +41 0 obj<>endobj +42 0 obj<>endobj +43 0 obj<>endobj +44 0 obj<>endobj +45 0 obj<>endobj +46 0 obj<>endobj +47 0 obj<>endobj +48 0 obj<>endobj +49 0 obj<>endobj +50 0 obj<>endobj +51 0 obj<>endobj +52 0 obj<>endobj +53 0 obj<>endobj +54 0 obj[17 0 R +19 0 R +21 0 R +23 0 R +25 0 R +27 0 R +29 0 R +31 0 R +33 0 R +35 0 R +37 0 R +39 0 R +41 0 R +43 0 R +45 0 R +47 0 R +49 0 R +51 0 R +53 0 R +]endobj +55 0 obj<>endobj +56 0 obj<>endobj +57 0 obj<>endobj +58 0 obj<>endobj +59 0 obj<>endobj +60 0 obj<>endobj +61 0 obj<>endobj +62 0 obj<>endobj +63 0 obj<>endobj +64 0 obj<>endobj +65 0 obj<>endobj +66 0 obj<>endobj +67 0 obj<>endobj +68 0 obj<>endobj +69 0 obj<>endobj +70 0 obj<>endobj +71 0 obj<>endobj +72 0 obj<>endobj +73 0 obj<>endobj +74 0 obj<>endobj +75 0 obj<>endobj +76 0 obj<>endobj +77 0 obj<>endobj +78 0 obj<>endobj +79 0 obj<>endobj +80 0 obj<>endobj +81 0 obj<>endobj +82 0 obj<>endobj +83 0 obj<>endobj +84 0 obj<>endobj +85 0 obj<>endobj +86 0 obj<>endobj +87 0 obj<>endobj +88 0 obj<>endobj +89 0 obj<>endobj +90 0 obj<>endobj +91 0 obj<>endobj +92 0 obj<>endobj +93 0 obj<>endobj +94 0 obj<>endobj +95 0 obj<>endobj +96 0 obj<>endobj +97 0 obj<>endobj +98 0 obj<>endobj +99 0 obj<>endobj +100 0 obj[55 0 R +56 0 R +57 0 R +58 0 R +59 0 R +60 0 R +61 0 R +62 0 R +63 0 R +64 0 R +65 0 R +66 0 R +67 0 R +68 0 R +69 0 R +70 0 R +71 0 R +72 0 R +73 0 R +74 0 R +75 0 R +76 0 R +77 0 R +78 0 R +79 0 R +80 0 R +81 0 R +82 0 R +83 0 R +84 0 R +85 0 R +86 0 R +87 0 R +88 0 R +89 0 R +90 0 R +91 0 R +92 0 R +93 0 R +94 0 R +95 0 R +96 0 R +97 0 R +98 0 R +99 0 R +]endobj +101 0 obj<>endobj +102 0 obj<>endobj +103 0 obj<>endobj +104 0 obj<>endobj +105 0 obj<>endobj +106 0 obj<>endobj +107 0 obj<>endobj +108 0 obj<>endobj +109 0 obj<>endobj +110 0 obj<>endobj +111 0 obj<>endobj +112 0 obj<>endobj +113 0 obj<>endobj +114 0 obj<>endobj +115 0 obj<>endobj +116 0 obj<>endobj +117 0 obj<>endobj +118 0 obj<>endobj +119 0 obj<>endobj +120 0 obj<>endobj +121 0 obj<>endobj +122 0 obj<>endobj +123 0 obj<>endobj +124 0 obj<>endobj +125 0 obj<>endobj +126 0 obj<>endobj +127 0 obj<>endobj +128 0 obj<>endobj +129 0 obj<>endobj +130 0 obj<>endobj +131 0 obj<>endobj +132 0 obj<>endobj +133 0 obj<>endobj +134 0 obj<>endobj +135 0 obj<>endobj +136 0 obj[101 0 R +102 0 R +103 0 R +104 0 R +105 0 R +106 0 R +107 0 R +108 0 R +109 0 R +110 0 R +111 0 R +112 0 R +113 0 R +114 0 R +115 0 R +116 0 R +117 0 R +118 0 R +119 0 R +120 0 R +121 0 R +122 0 R +123 0 R +124 0 R +125 0 R +126 0 R +127 0 R +128 0 R +129 0 R +130 0 R +131 0 R +132 0 R +133 0 R +134 0 R +135 0 R +]endobj +137 0 obj<>endobj +138 0 obj<>endobj +139 0 obj<>endobj +140 0 obj<>endobj +141 0 obj<>endobj +142 0 obj<>endobj +143 0 obj<>endobj +144 0 obj<>endobj +145 0 obj<>endobj +146 0 obj<>endobj +147 0 obj<>endobj +148 0 obj<>endobj +149 0 obj<>endobj +150 0 obj<>endobj +151 0 obj<>endobj +152 0 obj<>endobj +153 0 obj<>endobj +154 0 obj<>endobj +155 0 obj<>endobj +156 0 obj<>endobj +157 0 obj<>endobj +158 0 obj<>endobj +159 0 obj<>endobj +160 0 obj<>endobj +161 0 obj<>endobj +162 0 obj<>endobj +163 0 obj<>endobj +164 0 obj<>endobj +165 0 obj<>endobj +166 0 obj<>endobj +167 0 obj<>endobj +168 0 obj<>endobj +169 0 obj<>endobj +170 0 obj<>endobj +171 0 obj<>endobj +172 0 obj<>endobj +173 0 obj<>endobj +174 0 obj<>endobj +175 0 obj<>endobj +176 0 obj<>endobj +177 0 obj<>endobj +178 0 obj<>endobj +179 0 obj<>endobj +180 0 obj<>endobj +181 0 obj<>endobj +182 0 obj<>endobj +183 0 obj<>endobj +184 0 obj<>endobj +185 0 obj<>endobj +186 0 obj<>endobj +187 0 obj<>endobj +188 0 obj<>endobj +189 0 obj<>endobj +190 0 obj<>endobj +191 0 obj<>endobj +192 0 obj<>endobj +193 0 obj<>endobj +194 0 obj<>endobj +195 0 obj<>endobj +196 0 obj<>endobj +197 0 obj<>endobj +198 0 obj<>endobj +199 0 obj<>endobj +200 0 obj<>endobj +201 0 obj<>endobj +202 0 obj<>endobj +203 0 obj<>endobj +204 0 obj<>endobj +205 0 obj<>endobj +206 0 obj<>endobj +207 0 obj<>endobj +208 0 obj<>endobj +209 0 obj<>endobj +210 0 obj<>endobj +211 0 obj<>endobj +212 0 obj<>endobj +213 0 obj<>endobj +214 0 obj<>endobj +215 0 obj<>endobj +216 0 obj<>endobj +217 0 obj<>endobj +218 0 obj<>endobj +219 0 obj<>endobj +220 0 obj<>endobj +221 0 obj<>endobj +222 0 obj<>>>>>endobj +223 0 obj<>stream +xÚìÏsë8rÇIŠºÌ‰öŒî´üt§çyšÝ­ÚJñÙfvçÖ$ÁÊ!•S*Ç6•üÿ±~X"H€èn$è5¦jêÙE|ˆÆ·@ƒúÇOßòýÛßò?=å¿ýžÿçÿô,~*ÅOÿÈÛÿù×?þøÛï¿ÿºÏÿü—_Ÿò§§§·kýñõ¥ù÷¯|­ÿöœþº?•ßNå÷SùË©¼œÊ¿žÊ¿üÇ×?òÿýŸÿû¯¯ÿ–ÿíÛ׿ç‡oß¾>ÃKþ=ÿãõ§öcøä²+âõi»Ý>ÜËÛ?¶ß_—Î%^¶wY¤*w÷¯ËäOj¤Üöû¸ē‰é½Ü?–KáÂC]о/ëå!"—x[ÎõœE¼r˜ë‰KåÒ!˜¾rÛg޹^òȾü\ÆÕÊÏ3s=GžJRÎÉõ-òVâÃl\ŽuЄõV¾ÌÂ%²( + ‚B¹ü29×$X,0X –€Åƒ %ƒ/° ¬(ÚMÄåÝoÙ9h6×ÄXo`å\ûhò’LÀõ#𡬼sÕÑ,åÏ\M6A!|…gi,A +Ú Ñ ê£s5Ѭåà‹+›— 9Ä`™ãÅ`ž‹,öD.1?V{àÊàŠRç\uD98æY\‰c®}HÙ8媣`Jé++D91WT蚐°ŒÒË TÔ  LÔ‹Š4ðZåªBÃ2t,OãQ ÔxŒsÆq‰±FãzX¢Æ#F,Ï%£FL×]w÷Ûí—×cy>|ðÛa0IwÅ÷_†ƒüxÂ[‡ÿîŠG’þÅ˃ŸßÝuoœ*=[ í,¸ö~ºªÛk[ça=xì.Bú±àæØ\ìPƒ–.Î$[q¹¸¡==·aMJ&³»XéԜ.K™\¬@ž› É貘ÇUùÑv‡]¶cqeSÙà՛eN¤ܯjؤ½s’  ®|²¡ÅϼJé\Í Xd°˜ÎEùØÍÉÜZ9ƹfÂ"‚­¨\Õ FÈ1ŒȕυEÛи'’ –Y¹0p7ñú¥uZj+Cg‘¼c,Òé« …«rÎX•½ÅÍÁ‘jÄ¥{.B J<—°ÒlKÃ7D=Ì:¸ÎåÛÁÉ %i=•œkˆàBf½ .Ú`Ø`¹Š¹2O”,Á W­Ç’ó ìÍПR4q‡ãÚa…„–¤8®´&1Š«žÙ#3ì€á«aÚz/8 [c¸²0Dƒ¢õ ‚«æfóuXiæ*B J‡íÌ\Y OjOjäªÃê.d‡%F®"°îBú°ÒĕÖ]È'½1p5Á¸dZ“RW\wá¢ÄÄÀ•6ºÐRVŽr‰» 7æw£\u€Ý…[FJG¹*OŠ…²¢d”+ (2$*ÇVå'ÆB ÃRåÓ©¹Z’ Wå“s! q5ÂÀÚÛ=W¢È£­ÔrAˆ"v@;-W¨jàLi­ã¡ªnè¯t\5-4”=Ùí§ž±¿ÿ.Ï´’T¹Æúù=¾aÀ +¢6(®–KH·Kh%ºÖRÕÓbQ®•–ër›®Îa‡Àà ¯Çé¹ £^ >ÜÌіœáµCrí´\MçùÖ 1£$UsÑys¥Z®³í%·NH)}¢æÊ‰Îkœ+ÑsÝ´BPf=ègŒàp‡åz7.×MÛk¼b”¾Tq5ÔÊÀµÑrÝD° ¬•T؇ô¹WŠçZ鹊÷G”Q&ß V<זByW¤çª/ŸÕPÌ1PRWF4C#×NËu¾×úü+ü’QØV +.A5C#WªçڟòáªÕr[¬àª©fhäŠõ\盽§5Rì•K,×êZ[Éu6Ž;êÊ12BªWNZ,×:{—'%WG¤(³ÔgO@• ž«x j®Š5K5†ˆëWC6Ãq®ZÂp ÖbI…Ó5 ÊFÒâ¹Ä»Y¨¹®&EZ,ip-â\9%pžê¹*֚Nè(; +\n£á¬5;c+\ŒôÅq®æ" +®K‰kvª‰@“¤¥pµ¥×qgéB™ÐdcMãº(½Ž«àôWòD@“ë¢ô:®Œ3¾êÙwCÅuQz WÍÛÃÈ0’ ¤h#!r]”^ÃUðûMÏ%s Æð2r•^Õñ6g +ÌÃ’lì¨\g¥Ws5Ì]Œ +㘁´¶ÑR¹ÎJ¯æ½ØER2WÁ^f®“Ò«¹rfæŽÀ8f DQ)ëd݅~^¹e¢IàkSYŽ­\§Öç*®³Ý Fȑ#š ”(ªT?º²k ±ÌukDŸ+?krN7Ä="àVÌµë>š>h¸Þ;а›‚]†Yw¹k6+IlºŠšô¸ Wuáiè†X!dr¸Ñ˜ÄjøCýsȵèÝJ´§•¸rŽlH[âã‹:\…’K\[°'¢@Ø¢C­I¤€]Ÿ«VrU×Ê=öEèà£ÃDïû¯´ùÖṌŸêsí¯#èùVž«áxåÛ-â;^WÈ\OÌɱonn0¾d=äª\ÝT”‚lˆ{ó€¼0ÚT¹WWojò$ ð\{–l lbÕ¹.¶*qeÝKž„‰×ñÒáÊY²Ñ˜×Ó{Šyq—KΈÚ{ÈhzªX¯üPy8Å:F—« »òúh9ÔNþnï5ùÒ*¹Ä€+“,¯ñª è¨Wo'ÍéŧñýGH©\SßËy°†ÇeŽæãvQ°2Ÿ,’+çEQÁse¼(*t.a#‡s5–r*W͍çª>š^¸ +vt6מ͕4™¿peM/\œ¥ùp‰'óg®úÃÉ<–k2ߝÎ-‡͋ó·•Ü:\[æ»uîªßFwÒ²ßmµwpœOm›.Ò,²Î-ï\·u›þà,•\×FÍÕI¿\¹r¶ûRãkT§×ćk¥äjÔûËÛ}©4fÜkbÄኔ\¹z߁¿h£¶W]nj¯‰;×NÁU UPn9Ár­4áËNŕr¸RW6|ŒŽ¹Î«Ëë51áp%C®wшﲫÝÊ-§h®š+Vqõó¡¸g¯r~ô'/ÙÅlp\ëQ®Ó¿^òHjÁZv,¥Šk£tEr<Џ¨ëdÞ7ÛnlÌ\—᯻?"éx@·‰+×à¢Zr—Ûj{‡àꤥÈ]|Ëíé71âp .’7.y<€ +£®[‘"K~­lâŽÃÕ¿(—óM +-áðì8—Ðpz®”ÃÕ¿¨7RNf™*Œj1\·Ùÿj®˜ÃÕ»¨ðTà¹b\Šã|f.ÅEußÁnßÊ#`ÂÃĞk¨Šã|f.ÝÀT5_ŽÜp ×^­óŠã|®áE…ÒÁ&ŒJ[=Ì®9·r‡Çù\Ër¥#Bq­Q\µÚ՚8JqœÁ5¼HËU;â*”ñÆË- é5qxœÁ5¼(S:"×Ã%¢"ÎSÇù0\ƒ‹´\?Œê´áò;ô¼RqœÃ5¸¨[ývGסµœm”MçÃp .Òr?ŒjÕ£YU4ñ"Ú4®þE\-š+Uý6.5MìçCqõ/Òr¹ê^,ÕMìçCqõ/Òríùáa«68Íòþ ‰ýã|(®þEY/Mõʕ;ãŠK W'T•šØ;·ãê]ÄçJ\ñ®óۋ_¾,{lÔMìçÃqõ.Ê;Š-qen¸:ù‡Ýxã¼ì‘ª›Ø;·ãê]4ˆ£*,WÚâæ)­Š«ó~(EO¢Må’/Ú÷#¢âÂùåªÇ¸äã|H.ÅÀn÷X®µW£‹ç¯AeNä’/ªúC%;s Ï\BsŠCqœÉ%_T÷$[DX®W;Ê.é"Ñ Í« ¸—|Q&°üÂeÎ=Üy䒎óa¹ä‹ +E2þW=/WÁá’.ªn»Ê·EÞÙ¹j—t‘è¶²¾Æ6ÓJ\‚Ã%_”ßö¿ž#W铫{œÍ%_T ö+Càª8\òE½H0?qÙL—Q\Ù8WÃá’/’gÆé>®Îq>ès¥”ºór=ŸÞa?bšK©;3×Cÿøšü²¡ÎæuÕ»ꝪHqPJÛ:k®|¾!çéw·§†u\y1Ô׏áŒF~™WsÛìø9QeäÚÉÔ—Pì(É/4¬®KüuòÈȵ™‚ TSë¼;Àz齺 ®u+ M?\™j« ºã “Òdúu\©l)^¸š÷§»nÝî«ko»õʺ ®Dºµ®êºQ(¾unڑÀ[v…².Ÿ«öÉUtv¬÷7ïÒqY·äsM]Õ2¿ú®òöNå“+ª›v^Ȭ©K㊯ۧoƒ8ñƕu—áòžÒߌ§©KãJ®£0qÙÄóҟá¦×VËIÚªº$®Õõq¼=™t®êöÓ5ä$mU]WÚ}tk;.CúáõÏÍÝ[ÙtĪ윑Ò×%qÏ]ÓÆ+W¢ûѧ“T<¶ÔçÊ/ƒô8„wÞ¸2]:ÎeO¹éÀd#©;x®ýåóŽŸ|ðÆuŽš¸1‘†‘¶.‰«¸ÈÐÑÒKo\—½Îûƒ:À:eR¼Ë¹¶.‰ nÙ¯qëë¢Z{þ⇬ã‹õu•\ÃÄÎEu¯G÷叫“Òkmñîm®¾X_—ÂU_ `ü`;®±}½n=é½ÄÕ0‹V[—ÂÕ\~<ºeK®±}ØByŽCš—ƺ.]_ˆ¾ç²Ú_ÚÌÒ|Õ¢¯Kàj/Žùô[\½,Ú¸ôdЍKá:;æ“[öÉÕyіL¡ú’9]] +×Ù1×'ï“ëý ì —J•l:ZÇuvÌõ©¾—1ïë9Sš\ùPÔuñ~ùäËãÿc—‹|¶—‡á¤¦ÒLrTu \ÕÉOnÙ?×­µ«^(u@Õ%póÉ-OÁõ. +‰vЌÕ%póÉ-[raß-Z‹ÁX]—x÷b멸n‰×f®^]×Ù1ŸEr”Ë&ûø*™ìе\cu)\o&˜4·õS/\²{ãb§®.…ëM2âúì-¹JÜú¡k¬.…ëØÓUt}Q7®D²­x”KW—Âçð±‰ËæÜM.ý9Õù±º®ê|²&±çڍO¿6ÝyÈJË5V—ÂUߜº7®ªÛŸûÞmz«Kájn³Q.›sˆçkãï·M­–k¬®!ž—Þ¶%ä]A ®qö¶ ©Ÿ,ŽÕ¥puÞ ë«™«õ¹F꒸r—Õ¹ìf¤jŸk¤.ƒ«´çZãÒmú¡ÿ VÑ×%qƒßxàjô +3àj¸ëQ2\ŸÊ(—Õû7䵘_ÚQ.}]—îý¬n¹:}l \Úº$®úêÓǹ¬²Þè!Ón”ØÔµ*–ïí¹Ê×ëMóU|–ïY +¶X¾ë“kz.ó떗ÉUüÓr•‹ä2/pÉe3aþ䚞Ëjb¹h®õ"¹Ä?-WºH.ólõA¹’ere0ðµü>ŽO®¸ö0ðÅ}Ïn‘\ðA¹ª Z~¯Ù\Åô²×å÷ÐÍULMÞá¾70¸@ªrÃ\ e’ºÒò{9ç*Š+[\Àa +%°ß{ZÀ‘›ì ù=Å¡­´e&=@~¯thG„â‚¥Âèo‘ßoXÀQã¸÷}ô•±mç˜Á8lc®Á9æ½Qæ#/Á9°Üè–ã‚s`™±Åš3‡}€²×ÀXcV@éK`3Ëڬހò9°ÊÜX@=€ÀXa6.@l`3°½9êT˜ËÍ"8á Kèmœ£ Jè„m®gƒú¡€S˜ „A:àª%ô¢©€ìڐ„>G˜ ‡bH}fv_ï\bAB/0Ò -Vè׋‘Ã]‡+_Ž V˜Ȑ+ A,0 +-V裥ÈaÜ媗#ˆ(Â-ôDˆ *âƒ-ôéBäpÝåB} Â(»‚-ôÇ¥€VÏP„#C̾:\ÕB")£œ· Å }ºÙHd.„Ð'‹TæB,Ýċu+_†pd8üƒ"âȇxà B8j¤—Â!Gl#´A `1Û¨«>BðÌØå +h)‚¸xí\Åú,(ÖCéÑg­¡% ÇÜ ýŽhIÂ1ó3?ú•‚+~€áï€d¼s°=z @KŽy>r’s˜y€Õø©bå™a÷H*:sˆH؇–(30Ê&ÐúyÖ9eˆιÈQDs‘ƒ²Ôā9£Ò7”AОQéI+Ò@½t>¥Ï)Mª’ζÚ&HšÔ¡9›!"li¥åڇkˆ´åhél¨vc! »ô™ ±¢g83âžö¼nų¢ †®@žâÌcˆñqCË`3Ĉ9qx@Ë`iˆf(Í4€ó`¦Ÿ¬Tԇ -g€M>kΩj-k€MœdY“½´¬6± +ÈcX]>±rz‹€5D'VFÔ +œéöÔ1GNÀY™8樼A:©ÔgB©œÇ Üϙ.H,8ޏÃtºc wàÊêd†kÍÁ…Tú‰:,c=càÔ4Æ €?R§é°ŒÖÛNÓaә_‚& :C¢Åqí±`»0ºk…äªé0‘qƒph­ ±÷UKó„ªY.´v†èuâ,øV­!zÕzìÓÝ ¹ð†èQ:j ›ÖÖãrfWŠØ ¬OKüñÍPË%¢¹-±±’.h­ ѓ&æV>¬­'BõÊXZ?Þ¹±´°öõ^†˜È,e \<1÷3–½í#×½{&ܸ¥rU¤s©ÍJÉ\"š LdöܹK0‘;¸)82‡i\o\´;¼•Ÿ'–‘P¬.t¬Â^¿¹1p1_uFÃÒÇàd}¡ãNSbé¥ +\EiW°/)áøf08Ô&[õ cœFwžÿf<[l2êR6W›qÀúßtŽ*OôÛø\‹+Š¿S;‹añcq€‰‹ÙaQt_zî¬ñ¹‘‘«ˆ¸ÿ¥ó/9k·6\"â—{”56¼OßYqYtØqœ=šÌñ…Ie˜>˜¹l:ìŒöªÿ짌ý¹K.ê4Li¯ƒ~/ÛÌæqµ¶\Mä¦ÜÝo·Û/¯oåe»}È,?mcÍå¢ÃœSþ#†KȵqÀe'‰³tŽ+¼Û9á +®ÃÌK_8.±´îBrvm¦(ˆ=$W›…ÄupÇU/«»Ð\¬•O_ºäj‚áÚ´.¹‚ÑzÜöžKdKÑxw gÑ q!Øý^ +—XŒÒ¸°DôÖ!‰kvKÄgиš…X!•kæø—°MäšÕ)¹/T®9½3eû‰Ê5c`OJš#sÍ6Ähi/t®™†1±ŒÁ5Ï#îí2¸fbÔ,%=pÍ`sM®ôT9×ÄÚÁÈdr‰<\)´ášRY©Ã\®éÀx™dl.FÚÏ$ŽËšk¢Éóā×þ9椰áòoŠü,M+.ß`ɧv\~UÑ&Yؒ˧ƒ¶Ê¶åòf—ŒoÍEΡö41qÏåcÚb™®î†Ë½,ڟ›pÂÕ +·¶øhß"7\o¶è®Ë’CW+Âé,—\ŽºìþІÆÕŠ'küâª-.¹ø©ÕªGw-qËe‘^Hݞ“‹Kæ–ʇìþ‹ë6øà"æÅÇ[ï¹ðÃõV^qÙññýw/·÷Æuê5ƒAÞm_}ÝÛ'ש۞¶wê~z|õy_ß\çŽ;žpØ>ÜËývûøúêý–“pÍPàÿÿÿârõä +äÿÿUÌM‚0à=§˜¥&¶vJÃÏR×õD +ÖJÚªáöR7ÆÕ$oÞ÷Ž2ڟsà d©ÌÍ@v8]«ÓûwkÊéa +çfõ쵙¶ò±ÒU` #M€`LyГ¦(R E‚‚¦@xBEx—­[~ە5ÝóæÝ·(â¿3/Vw˜ç)ጱÆê:¨•Sö¥º@K]¢t“ðÿendstream +endobj +224 0 obj +6279 +endobj +225 0 obj<>>>endobj +226 0 obj<>stream +xÚ+ä2T0BCc3JÎår +ár á +äHÉHendstream +endobj +227 0 obj +31 +endobj +228 0 obj<>>>/Annots 15 0 R>>endobj +229 0 obj<>stream +xÚ¥UÛnÛ8}÷W ú”kՒ¯Ù·¦Îf½hS5rŠ>ø…¦(› %º$eÃýúΐt}iº(PذAÍ휙ÃÑ×N +=ü¤0Π?^wnç×ÿÜ@փy…–Ñxóò*…‚델žñÖt¬Ýþ ɼ=IaVŠÆÉJræ¤n‚ëÒ4ºfãdD®óµ´`uåvÌ(…•«†þ¸‘ +„Ró¶ÆT°1z+Ñ+ÑÃȦҦöé¿n-€¾–Np×b2֔Àu)›èŠÌK§ý€ò­®kŒ{z˜}†ÜHD‹žÅÞ:QÃâêÕÛ§¼xµ¸†OÂX*¤’ŸgÉ 0Ρ¶Âl¥Ø‘ïݼÓKzØSúIéçñ£4™Àp%=¨a0!8ᤠ?6j8è{¬æØm[*Ï"pÅöÂvÄZdÃQwɬ(e˜w± M`æ`Í,,… ^o…BŸ–{ð:lVpuÇìþ—tðÃl‚”L– へ¼ÀýèPÃ$ý™Óñ&ñ+šÈ.[îì9¶Þ8M©µÃ‰ƒu8ufÊc_¬V­—µ†)æ½M©õi-N8³_H…´ÇûÉÇÜ +ó,”Ø£Àêt•l*Ò S1.ld£ Ÿ Y/Óù5Âe‡$æZ‘ðfyNºcÁ‡ˆ7„Àc¶"gÏ ¾èeÀÿµ-V„9z¿CØ} ”Æ” ’;x—O©@:Åçl%àViþLæâý-šÿò¹ßl6>F¨‹+–<',ÿ„›Jƒw Sl"lBNY}Qܶ’*ªk'ÝŒÀQâ¡jNCaJº}l=+K ؔ6ρ"‚[½³Ä™ÀäÚºÂ/ˆ¤.ªMOöÉÏp ~B{»%ÝDt‹©.ÖU'nmSŠp—^œ%qÅysՆ É[ët-¿a¥m\¸tîžà~°.Å[cp›©}„¥«Ÿ½†É°·¸¾àF ` ȚfUI¼ú³œï}KÉN(5ºéžô+öUR°zƒÁ¥‘„Ó ëßÜ·÷./><\T=Äù‘nªbE¨õh|îÿَ}˜öøé~üÃWúi³bo;ÕþÆTZ)½ów_x•Ù¿C-káÆÉŽã\d£1œƒÁ\÷ôǏ y) +“£¨˜‡òÛ¡} ¦çýùÍø7¯4Þd³¦I4u#ÛqšÄw÷‘Ù`ÒKn05=Žûýcç;¯¢m +endstream +endobj +230 0 obj +938 +endobj +231 0 obj<>>>>>endobj +232 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Õ³P072PIÑPp VÎO+)O,JUpI-ÎLÏQÉE™%™ùyš!Y\º-ºP=F 1c=30ßPA!89¿ $ìÂÈ,y âendstream +endobj +233 0 obj +115 +endobj +234 0 obj<>>>/Annots 54 0 R>>endobj +235 0 obj<>stream +xÚµ˜MSã8†ïü +ÙªÄcɉ?¸†-¨Éb3§½G ފí¬íÿŸnɝ…È!°EU(%[J÷«W­ü{™ œy‚9.K²“‹èäÛuÀ„Í¢%|âz>‹§‚=È¥,ežÈêè…pO#cgb Yœ]>ÎC6+’m&ó:®Ó"×ø„qÞà³\Ä£gɖÅz]¼¤ùJ?¸ ²´be;ë‚=½²úÞj™38i 1®5ÁØ ×c»3Ÿâ ãËûù˜[üLÏwYäËtµ-õ|÷q¯$ÆfóuœïƇ…sGϽÁog3<|­j™±Û¼–å2N$›É*]åø/)ÓMŸ›M1§ë¿Í6ë>_ŒÁǏžßcLëW»ðbY¿Ä¥dç‹,ÍÓª†üe…ùÙÆë#â殮þéç{–>/‹UgJëèu‡ï­;”ɶLëWØ›¢¬ˆÍߋÉêXᅏ{ÒðXÉÏîçìý°?!**îMíZWëíè½ ~Ôϲ쬡:Ðò"ïXCÅpŸö…«èĶlð>|áøòphÙÌñXHÆ<Ûò›Áš…ïЮ~×Ҝû8ç.å'ƒ˜{O àÀššyBïamzþ€jz\ïØ7Õ¼‹óÕÎé¾#±è9-ìj‘b-q?8FÏØŸÅ‹óE'ŸPÖìÇFêf¡ú›B¼oÊñ¯ò¤X ¯a਌óêÃGH Õ­ ÅßlӅ<.Î}±kµ Pfq^§É_Πp{¢jî*Á¨Áû™*…4´ïu¾O÷ƒ=€SÝV þL°»Ü¦]aT˜ºÞ¨í¢oŠx]AßTÂFÖWŽ\6'ÚÍÿ§#ȘÝéH L:jh-M¨´‘fœ¨#¯›kŸŽ<²î:°—%ðtUª5ñ„ÞÅîÖÈx:OJ`¯·[ÜtêD¥þˆ=¨C3^K%Q¸ °°.·I½…^®­øF ™Åzڅ0Ëü3¢v±ùlE­&Q7´Ö¬&šcÿì>s¤Ñ94„™'ðÞ½ŒY ¶"ž‘§„>dÌë¡DÖìF#Oln\t£Ž?@NÐ·Ä hn°âì| f×u†œ±‹¸Jµígé +3;OYUûN‹ÝÇõÉà·JiÇݼ‚ýçWî‰oÃw°ñ3§QÐ_'¿Ý7UXendstream +endobj +236 0 obj +1339 +endobj +237 0 obj<>>>>>endobj +238 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Õ³P072PIÑPp VÎO+)O,JUpI-ÎLÏQÉE™%™ùyš!Y\º-ºP=& 1C =S0ßHA!(5-µ(5/9µ$çÂÈߨ"îendstream +endobj +239 0 obj +120 +endobj +240 0 obj<>>>>>endobj +241 0 obj<>stream +xÚµVMsã6 ½ûW`rrf"ù³þHO›¤Ûqg§»Í:{ò…– ™ITH*žüû¤äÈj6­:íøB‘ €÷øøi01ý&°œÂlQ>¸ÙF×0Ã6¡“ÅrÛx8ƒ;42-àó3êg‰ÇËíw²›Ãdâí‚é*œ²åíׯ D*/•ÁTk0*±G¡Lµ̋±˜°aA•¨…E°*E{@M  ­Déœ}䪀RËÂÊ"+Ì£¹ö¡£:´‹Lᜣ曆%œç6¼Ñ#±9¿G)Of>å7/¡~Ä _à–r}oßþºégϤ}(ËLFÂJ‚üE«T‹÷r fS/‹Y8s´•» l´= ìk#y™aŽ…u"¬Šúa (*PTùž$îX& j¶”ÍC™>dÙ«3~$²Œªá(í3hÁÎ Zv(tZqäþJ¿Ãg!<Üo  ê¢U!]!Ý£Q•¦£MLŽe")u:p6ª²ee!öwwC Ó°v€ª¿ÞÁbJª ªÖŸû+5:Ó7>>>>>endobj +244 0 obj<>stream +xÚµVMoÛ8½ûWÌ1‹B²%;¶`Qôk±½µ÷Ô큢¨š5EÊ$e×ÿ¾3¤¤Ø®ëM,@ ù8oÞãÌHÛQüÉ`:§_^^¯Fã¿&p«ŠVæKü«¼i˜eJ u?.Ån\I%þX}Càd3B&Mò¦Y:'¬d*‚feš dAÕZt(ß]⿺tài£\VR”ðÍà 0P†#´±R{a­÷ØIvv¤‹Úë3•\¤€l”²gÓ4'þOÿ¼éÀTátel}3}ԝä3TØñQ÷KÓxiôçñù"MÓ/§2£ó^hÄ9àLC!€é*¨ ©­?&¡”ÙKýµË„wÁò%¦ŒÑb2ÿæóô©FÀMÁÚòϸ–÷k–yqšÔ $ð |´˜ŽaH{Xé¼:å>rì"±ôîœxpy…Z·uwˆªKæPŒßcÅJ”þpÎ+vBÿ‚•¶ ž¾|ƒ&?¥)Ë_0âÎÿA¨¾p©«ÖbqÑ¡¿UzÖ¡]%ÝÅJ¢.½g°ûüµ. €§u©~oìÖÆyh¥AÈWMó£4ÖxÍ¢ú¯VD‰ò¬7‹ü-öJxŸ|@VfKl™Vbã­Ñò{?\hlø­Vi܏ǔ¡fµø|Oƒâzû–¢b­òq¤tՋ„wÙdræðäÔÝ9ª+®X‹»Ï=ý(ä3Ž> waÞ/“¦yԚÃka7B‰¼Á›Åërt§ƒ¥šwhªŒ,q8‚“u£D¿“(©áã‚üxóéÃ=][Ô҇Ú@K°6:‹È·8RŽT¿÷$ºc)ÃÔC†'p!5Î^ú5ˆïÒy*[g*¿gùÖ,œ\crCG‘‹6˜÷“Œkõ§¨†_©Üí#£—#&ë‚DVÖRcv8´ .a¡Õãý{æ[wÁ‰m+ZÑõÉ#áëæÌ—Á‘ ?XëچJȝ¾•O}= #jÛâ-%ð1æ‘Î'MÅ!R§‡ìšÌ9’ŽÕÜO…`•VM€þkæø¯j¶Wog;܎øyk­èî²é¸–]”ìö6]âgT…E“ú{+œüªéÁ­  +t:‰‡’E>¡3sZ›M')}¬ _XGŸXïV££‡êjendstream +endobj +245 0 obj +863 +endobj +246 0 obj<>>>>>endobj +247 0 obj<>stream +xÚ­VÛnÛ8}÷W ô”²_'Ùô²võ¾õ…¦F»©’” ÷ëw†´d¯Ò*-Ppds.gΜêëd×ô7ƒÕ7 ëÉ›Éë÷w0[¦¢“›[z(¯żX€nÜ«Í:_Âl–ΧóŸožOAÚº¦ßnk<øb·PYS&(³+€mþY‚=:¯¬[E_¯4š  vÆ:ôÈ0SYYàš?ž²œ!PâaâԜ.óØ&P0_$„ç +¦ó»¢¯aəêñ"jpXÛ=° ×„&áçj.2¬Nî‹y—a¿¾¸é<CTóð ŽðhºJH„ÏWäúù%²;'jÏ{U"qxÀít+<¯A„փ꽂%xF‚Ét¥óCÄoDOtç µðéy‹åÀ;!Ÿ¸ €0xhƒÒꟛ¿ÿ‚€u£ -TÔnŠ …-‚l}°5Y–Œã„wØMy û‹¦Aᄑ8Ú¤E1QÖÊr§F:mo—اŸ”N°Î,ù³‰ƒXù‰†¤ÆÖ£‹5‰²Ì‰ÏRUÇJÔp(7b؅œˆ¶MâPZS©]ÛId€b“è!;¨o•Ù¦qæ=Âqº4̃¦ÒÓԈ½PZlu©·ch¡AS20V@d'tÁ”H­ä¿4 ¹é­Ð}h’€V4õ1T©<©æx¢"…HÉÈÌ#F#Þ I±ãd,’PǙˆÁÿOÃ×[Òæyt‰~è’JK3a +ÇT0{uºŽeãöØóG Q€q˜Ë^/@í…òR×b/4ídûËmëAüž¾=߅˴å⤉\§ÝVsÚ~ó¯ËŸ +AË3»_?fi}¦e Ó¢¥ñÜ£QHk'§…¶Yçð¸^§Z ³kÅÓH¯×o¡jŒ +s¥:8ÞVá Ž©aI[ìáœÞwá~ ‹KÛsj·J,(®Øt­F®®)҇çe„,“ÎyM笉:Ý¿9쐜’Äm5\ÐCÕùý….û˃ ¢\°­—cmž[0é¾#êg+µ3ÕV’.YÂÑ*¶"!i(䁗Tçø"‘x{"qöæMq 7Ëë.5éÓ©Ið=½Pð?éT|G`ïirš®æ×ç÷›îgy{]ÜA>>>>>endobj +250 0 obj<>stream +xڕVMsÓ0½çWìf·Îw(d +C é.нq¶äJrKþ=»’¤I(aÚiéiõÞÛ硓À5ý$ÐñoZvÞ.;W·7 `¹¦Ñ„²Wýx÷àãr9‡ÛZ¥Nje_/tI Ýޘ¡Ë àºBeô£Ìð`ÅiHµR˜:~ôp‹æ@Z[#|¨Ñ:úlPd '`mt ¢AF|?ݚô‰Ý+TOF: X +Û"ãÀt/ªÛ»‰w²ú0›_¦Šq­„óšJ¡D€ ÿ@†¹ çŒ\Õ[Ie+:‹¶Ñv¤©Q +{m¡íåðI¨¼fn—-Zði +é>Gl„É@*‡f-R‚iC¤H>J•Sf˒røÛÕ¢€­¥`ÖÃTÂ8™Ö…0Gb Š½Ö )t)GsD(ÕÆp­ JuƋ?^aœÇp¿€7‹élÁýò¶;‰`¶øÒL†7Ý$tiüãõ‹¾ a>w‘%smÝ"5²r07^9¼Cë¸öF5%Àqײàd[,˜»öHúœn0ýåÍKÜ ëB¦\ë$þÈ,¥kB`Ö!ïŸù¢MvXã†~¿×JÂô~¾€Y)r¶ï“\a¶gôÆ£V±? ›E8Ж¥› mlÅÙ'úܸÄ+ +ˍ%*ùølÅRš)æqÿ {êÝË.-°Úzáž\‹ý³/uÀ0N`ºg<Ý1¾(÷gµÛÝâٞ^CnÄÖî +úۇ·MnÚÝ^ÄÜ{1ýü=ús¬à§´<àñ±½ >ï\¿\çAªN%梬!ªŠ‹"tª²ÒmÛJ$p ˒lƒ~DX®Ü'é6œº#¥ÿòÖj:$Ü_rÀ NXóÅT§ä uÊÉT%ò$†Š§zÙǾoü_Kþt:Ðë‰êÅà±endstream +endobj +251 0 obj +855 +endobj +252 0 obj<>>>>>endobj +253 0 obj<>stream +xÚµVMsÛ6½ëWìQž©h‹²%99¥vܺã´j­ÜxPBJ Ú£Ÿ]|²ÆQ>:ÏÈ$¸»ï½ÅîŸGS¸À¿),r˜Í¡lF¿®Gçw×0½„u…_æK|àãYv•]Á}öîd?*Ôʞ­?¡Ã%L§Áa’/Èa½ ½yEæU2‡Sj͸T[аº~aªMÜÍBàÉ$¿Îz.sø‡Y'Ìwñ0ÁtàÐ0EpÖÁKn>®“gŽA1æÂ–Fn©Àa˜{…_+V +¸VnÜê²k„rÅtVpb€¸ÓY–òfJ«ÉJ[÷ˆZ­‘Êù$ŒÌDÏMÖøï@ô"ª˜åIôn™h^WŠ£VlK?I.€q.I4«A ÷¬Í¿yÀT{e¶Ü ÞÕÂdpÓƒ’ê=h…?èчdFIŒ ž¥ÛùžÚµy6…©¬b‚žW“uŸ5o„Y0øê<¬n¡¬%rÛµ­6ÎçU¢A§7Œ‹ˆ1ưŽãeqö|œ@˜Ål TvZO+]×TÆß”ÒFÀô¨dÀiÿX’c…y¢zÀa¨ß:ß!OLÖlS÷ɵ“öX:Šƒ:¶§ßÖ.VBï¥e†¹×hdí¥¿@^ûžæ˶ñQ~>®Œ7¶Î©Ôª’ÛÁ‘ŠoøS5¿ aCzOÖ|l"m-¨!à A(j3¡¬ÊR„Š÷u +ï0ëÉ+JC©’ú6÷£üicfëÛÞ¾ ¬ÊÈ*_â÷I>ä‹|¾€£òJ…¯X#`â3ãq‹é«ÚI2“ª¾{ U˜Îâ,{ yÀê5¼?ôî9R••ÄXñ.Êa1ÌÜxZ/ƄºæG‘>b†áÏAVGïÌZ]JæRZ`þƒ¨µtu‚qô|Ž!'>àÿx£[‰¥÷«k6( w¬ ËF|î¤AğÎÝ_m˜Æ@Ç·ZlK‡Pêa]¢:û£ðtœûìãˆÕx 2¾hFQ5¾YŸ”Ʊۊ’j‰ÿ’|¨p›gž¯Ü/JÕv¡- }‘-N•ÑM‡3<{¼“ôuwЭ8ÌÂô$Ç÷Þv»?À=uôS.Jà° 'Ùà€c8h%z†9sûÖ瀡Ö‘'N„žp»v[;ݞº$“”ªÀÄYø}5ùíá<÷,pœ)D®x#N¯®0‹óٌ¢†ûË£®Ü3e'ÝOü Æï•Ofp™,ò‹áJ÷Õ;Ýåò"»oyMïï×£¿G_|ã*1endstream +endobj +254 0 obj +985 +endobj +255 0 obj<>>>>>endobj +256 0 obj<>stream +xÚµUÛnÛ0 }ÏWðqæ4ν[/h=xHö²,ÇêdIåuÙ׏²ì¤M‹x+0$@™ä9<¼øq”„>)̖áËëїíèâöÒ9lKz²\Ó¡ø0¯ÆS5Û o,~Ü>ÕÒ4Z%ÓU°ÚVâh¥T^8àFÿÎc|nµ7ôî¤õãð›L/ÇàYÔ1¤ˆÃàÑn˜ÀÕ÷lqÁ<;Oc¶(²ï,^Ag×·ïÉ|‡ñ9 ÔØâYG8Â%h—¥äĤ®™.ÈЙ²ìº£Cw`…+«É«Ó‡<¥ÞCpⱤOn:£6 ä|žÀB;ŸÁ²%8X¸£ÑkéZQVfçXÝÖê=\u¦Þ‹FŸáó®§T‘XA³ŽZèˆÓÍæê"k…ÅÆZrȍ¯ÈMîOµTŒÿHè>yª¤}íð|.ëÇÊþE"•ýÇ,î²$»úúßÓ¸/~ùïM^õFx04W«.ÜlÚ£®aÃ+Q4ê͖¤–í`±·Iƒe£Ô>)ͽ4š)¸Ûn³‹tœ¶"ÝgñLAÜh:˜š8š(lG¥—ãpłۃÉñDH©[ÜS=ê1Ü{` +Í¡n PÖV ȝa§ª%9CQ@!à4Fû–ƒäÂDNÔ¦¯Ð@7qðOp;^À™†\ã\`ˆëÓh™Ú«}܁Ÿ2œ4èXž©ñšDùÜøÊ8ù›åΚ=·ƒÚõƒøN 5eNiUõ«]R-ÍÐÞÕj¢YÉc˜àÀT,×iSáú5‡ t·ûžU ò]w|Ółh¹˜ÅüâìlLéŸH!¸(w:ü´]Øe›D§d5Ÿt.ç“-¤Éñíúòõz³}ýª¿d˜endstream +endobj +257 0 obj +678 +endobj +258 0 obj<>>>>>endobj +259 0 obj<>stream +xڍVÛr9}÷Wô㦠+HÀ6¶_×Îf½µUëñMJf¤‰¤Á!_¿§% lO¶x`µºÏ9}ãÛٔ>à3¥«ÏI7g¿/ÎÞÿqCÓ Z¬p2¿ÆCõÛùäz2£ÛZ…ÀáÝâ l.h:Í6ãٕØ,6L:[P㪮f2<‡ÖÙ`–ø¹ržeÕÚØ5µÞØÈ~ÅXŠðv!r3¡Joò™xQ¤]]³ŽÆYr+A€¸Ós€BäÚiU“²Õ{ðܸȽû0¡Wp©:8ª*È-zö&â0jgWfÝy•"®L͓Lû Íxv3ًsq Û8¨ H£êšþ\,zK횦³F' ri¸5àÕ*Y‘è‹2\¨’ø¯”æ0"¥5·QìAÌf­¼k ” ­¼Ùöa—¸䂱À! šço1áÛ +G'‹a"'²:(ëïïö)9–#eäMø;ë.—ìðwP²Èõí§û“ @¼öªABYæŠ+ º¶u>Ò3/ÇKð²ÔÅ(g:Óøâ–¢Šˆ5Ñy ('ªuhë`RbÎæ9ñÿX äØyóƒ«QÊàýÃA%RžE¤˜Eàt˜—ÓÝàPUýT¨o—T{/ãíÓÃã+žƒn4ª6?Šñ‰Ìª…ÐÐP¡Å*tóŽÂ¥ë[UƒyÉðkÐR¢CtmÈ0û­A­Ñ’“qž„~0"Gåcj߆ÔJfJ|=™o”„a›‚ 'à’î8ᐾÊÿgØ éYÌ.R[ej%&½1íó2þÄq|ûH×òQ¾ }NwÆ£¡ßÑcQwˆÅÞxŸŠBHº;µá-Nú¡-ÝÆț,°Ûâµ¢¥wªÒ +LƒÓ_9NèsšÇ/º5Oç佟¹Ò,è&'1ÐëÚ¯ôq™ë[üJC+陦~hï(é|4N›v˜³V bºPþ5c’¸øt÷@2jF´qÏ,G&ž0|ô«¦«£i¥Ž« +¥J‰›SofûJfÊ@zg¿<~žP2å´Kk'? ¿ì«©Êk§ìšÓ6ï7¤¥àeƒæPá8V&yC»õºìè7xÖÙâ”ê!#bïÏ¨[ʕ4RÅJÅÔ¹k¶2žPË]N¯Þ°8ìÓp]bO//¡ý|~#ñóxt«ø,Nî8˜µ•/íMÛ¯¾q¾2¾š}8ü=þ7zquót8Ê‹‹³Ïþ ‘@endstream +endobj +260 0 obj +1065 +endobj +261 0 obj<>>>>>endobj +262 0 obj<>stream +xÚ­–Ýoâ8Àßù+Fœ@ÄÄóñ›/'?9Lè“ÃlÎ_Y þØ >]@~ ›’væw´(®fÙ]–OàY(óió$®!ϓÄxzË›W„ж¡²E£”‡¾¶Æ«-ý-­ƒ *ev`›ÂP(_‹ _ùž2u{—vyÉòR+4¤5ePd*ƒ%Iio‚\ç³lÊÎ÷l}ÔRFÚè'NZЫõòÛÓËê¿ôWÑåGÁû§?Î%½Úr=¢°´…‡@{toè±T»Æ ¦„Rib bÅˆœ¿Ò-¢èuµ³½tÎ:™ð§ +>K §jŒ§‹ìTž—Ϗ=õxn4å %`i:ƒK¨áñ§$‚‹U #vÌ-B8Ô)(. +ÏsP…b+`•Á/¬žÀH^xØÒÞ©€i:½q +ö¶ b6=»€utý­ˆ·øUÈÙüt'-[iž 7UPӂ³ÛƇãÎX+CIa¨R¤~âÒðÕ7ÛJ…®3Õþy¼$òÝn{Çq‘å ¤Ä:ô+ Ù  Öí1B§'ÚņOR÷Ñk¬¡¯QªRɱŸe +R‰º‡% \bi¥,%‘;É:LL|€ ?l°ˆŒú¬mÆç>OM[+q Î[w^—m{9¥ ‹ßÌ×5 ¹À”.# þ¦Ðu®;–Ôɾ»žŽ¢®$ðb´úH %áŠÓløè%…3§æÏ½Òvhø(ã±óX‹¸¤aù½£¯í#ÛEù6ò"ƒ/t„Œ"ÍÚjáhkXG0|âŸÕptæ}¸Ƨ( C°u|ˆíçɺ úôp¦æ,ڔ޵Ëon²;˜/fl$MþږaϪÈOt¾H§¢IÖ'•ñítÂ:ù”o^OçTŽÉ»¡îMèq3økð/äÁâxendstream +endobj +263 0 obj +886 +endobj +264 0 obj<>>>>>endobj +265 0 obj<>stream +xڕTÁnâ0½ó£œŠD²„PÇÝm+ía%*R텋q&ÔÈ±ÓØ¡Ú¿ß‡@Å!Ò +é‘xfüÆožó1IaN¿òd+õäG1ùö²t EE‘Õšʇ,Ù$+Ѝ(ke¦Å‰r–¦}N¼È9§xÇ!¤­kaJ GtдÊxlá£ÃŽ^9$µp]\·³Z´ÊAô=šAôÂð‹á7Öá•a͘œ(Ó,Y0iTðúÆŠA3Ô –Á1x¦ºlã•5ÔF‹`¬×5m=–}ŠÁÏk +‘Ãþa»}‚JiÜOïèÎϜ‚F4†z!%6~? û7­=«Kð–T1•:v´úóm»‹]ƒRUJB…ÂÓªKzeoêNjMrÕ?'u•©ì¨üœpU_+çx +ˆ³P:48Łm¡Ä³’<5J’CEç°ïgMtµ=ãh?œps½Yï8Ù‹"‚Þ%:¯Œ`ÑÇY7´ée8£ÄÃïÈçŠK¬”¡³^lÙòR1NŸÎioç…%焻) T³Áø½×H„ ‹t5ÜéOÌ-žhh#­ô ×V>>>>>endobj +268 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Õ³P072PIÑPp VÎO+)O,JUpI-ÎLÏQÉE™%™ùyš!Y\º-ºP=†& ACs=K°€±ž¥ž™‚BNAbJn&X‡kW `"Ñendstream +endobj +269 0 obj +121 +endobj +270 0 obj<>>>>>endobj +271 0 obj<>stream +xڝ•QsÚ0 ÇßùzÜH Ð=BÚô õ.éÝ^]GM=›Ù¦Œ}ú*cíÝâÒ9ŽDâ'ýeIùՋáœ>1L0ƒ¨{³¢w6ÿƒs(žÈ2ž\BQ~™Âµ2Îq»ûZülâÉÞ¡?EƒÖ%Š¡@[»½Çâøà1˜DãÆ#Ù[F ÅëÇÃßA˜z½ñhAq]mx…Ñ{Nÿ­ûš[®ªn`Žº”ºcÁ¢@ùÒܔÜs¨EðÏ\“êGéÓ^Öá€r¡ìÆþ–ïõFKÁ½4ځ 0<¢ß"jð[kk*Ëk +çÐJþ_ê>¡É±BRE鶪4¥oìªC]ô¾%ÚÃA4Ú7Ŧ½ ôÅ4O²,GMÕt^¹çºä¶„Ä”O$>Óô]·éÐoêž&¥ +¢“–w‡JH ¡î²À¬Ô¾©k¾së3͓3Ö MY~÷äÛh]€ãbÕ$zmùúY +‹ÃD†Ñ,ù›Ž*¡½5êTþígøûÚ­y<Ÿ¥Å¼Þvͤº’©©+ +îV07V¹Œ€=vÚ g˜å÷ÛqàêØqîmŵüÓì»êf/Hù±¬Wë j™-ÓnÖr£šåTJÇ",¹Tþþp€Y(IfœÏ…•kÿ7Ut탰ô|9 m[ûB¤%Ò Úv¦hqXEpj KۚN'4½—o±£Ã–„wïàÑd]Ò%K|Ñ>>>>>endobj +274 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Õ³P072PIÑPp VÎO+)O,JUpI-ÎLÏQÉE™%™ùyš!Y\º-ºP=†f Ac=#°€£‚‚{N~qqbQ%HÆ5„+ ¹<"yendstream +endobj +275 0 obj +119 +endobj +276 0 obj<>>>/Annots 100 0 R>>endobj +277 0 obj<>stream +xÚ՛Ërܶ†÷z +,“EÆÄ\ËG9ªr*Š¥<=¢”IæÎØ)¿}pé&€9#¶²°‡±«dA ~Ý  çÏ+Îÿ—3+˜4l¹¹zûpõæ¦e¢aOŒëvÁ™±Š=<~÷Ð}\÷l÷Ä®wÛc¿=¾øýê¿WÍ¢ñŒð…‡/~ f¤^8¶an!àû5»ô“îÃ3{s£çáÿ ßÕÿoœ½ˆÏÈ “n¡k~²…Ý/wû>„õ?iÂÏsÿÃ_|sÿZ^"!Æ¿ºáÕc^ý͍!ýX!½%(¹˜Ð²€lü³ê v@±ÛG?ð«§Õ²;®vÛ@5ï0])íšv¡Fíb^4(ƛ…JŠ J1à´á‰Š“ÌHb÷_Ç~ó2­xý¥ô“´Â%;â~þÜŸWý_§ø¢ƒð„âº5^MP<5²âºµ¾—„âÈáMШPìÝnùiã§éËÀ’á‰*%‚Hìú×»û‰1Ñ‹kF¥„`¸²³6Ju%³sNÂU(•|  3rœ¡•ÖHb?ë‡ ±eñKß,jš“™…RÇù¯Ú‹ûBïè(¸õ_ÁQÄïÏ9 +¸$Ü Tœ~%+Y““x×VÏۗIÅÓ1²ÚfwÆ#Û9zMÌöcp¶ÇÆYÓ¨äc%íc€Øº_Í{$±·Ýò~û˜æªšv/ g…3å§FpmÈñS^ÓobT˓ïórM V<òސßV(°Œ­öû€âf û•BY›’Ôø.±Qe]ò\A(A $ªD`l½ü +eTÌÓ»ÄF!”Ñ) BIJ( qV\…;Àؾºõº_žÔóȗ(™4O®9¾Il2éQ$E‰.BþRÀž$:ôê‹ 5Ÿ„Ò"I›œp|“Ø(D’ntæþ™€ÄEHç*ØÆ;ïϏq&5ó‰Éhvá±Qˆ$tvᆠHáèâv€±O‡3ôLf:IPœç”85rJ¬¸@N¥ÄÈñ;Z[sÀ $ö¶þè×ý— Ù3"í] ;¯w›M‡©†óËý²ÒóR¶.‚ÔÈóR¶-A¦Hâ^ˆ¶F`>b.㼔óÚ3SJùæ R£PÊԉÊ,“2‹ +v*ýù¯Z½I$Ës,HB$ßÅ¡LT^$îWš­Q`˜j˜ãt²„RÚ倐…Rº]ŒŠJ.ÄEãU­P`XPj“ >£›;¤ßñ 5r<Ê`< NS‘cC‚ZqÀ $výãmœNí¬ÖÝ?œ\R^=6ŠÉÏu’h´WWá¡ +v€±îq³Ú.–Ï«øä f%’âìÐc£I4(éЁÃUpÕ(ÙŠ-×ÝáÐF‰.?Á(]8óF×μ1èÌ%í́ĥ¹•Dc¿ï>Ž +Íe“HÈ$Z‘=yjd™D+ѓKғ#‰û¹!kØñVr?¬¶Ç~¥ÒžJ„¶¸„LìąkЉ+‰#'úWœdFÒkîÅUãbKv„ýg¿_ÃõïÄ[AÙ0шS&t@èݰ{ºÍƏáËÐã¡*œÆTPè€ÐÛ0'žºe¼þ÷»ç¯»÷ –…19¥F±,ŒÅ¤È„¤P›akØñ"ôz·ýÜoWáZnb¨ +Lª+(vêͧí2 þ厎ÒXËÂR£ÐXãª"Cr¸hOA`OËêwÂO{–Â–,ì ÎÈzÿå}e›#`júª# "# ’8wA••ìc·wS{˜ gj : ítî^ð6”’Z˜"Š +SGQa1Š*:Љ«pV¡ÀŽ7Ïï»íó§îyÊW Otíø›Žn=uäÅõ¦Tæ2_¤F¡2Wc &Ïj‘ÄEØ¡V(°ãóÝÝ»)Ÿ‘ZŸþ^ØhµÀâr» Gd“ÉjÉye81ªˆØÁ[r_qOFŽ•9§F1:v,Ðdƒ¤pÓ$kرr ŽÐÔJȀMQ×8켟º­8D±^AñÃ#¿”j&tPgƒüW_]Ô(™¢Z!5ŠQ2cµ‚&“&$…¼ÑÖ(°cµBðXýtfj3·ñ¶Æaà½n”2%ŒR8©™ÐŸO ¾ú6‚&UÔJ¤F1Lj¬•Ðd…$.ÐV(°c­Äý²[OmôL%;¸Å\6”̲¨´HBf9VZh2ãBÌUyZi1Â^¹§Âõ@…ÃÀ»Y­'Säü¼§µr|é1ENô¹í´üÖÙ@K —(*>R£.1uK.ÃÙL{ªÝá8U‘Y>¿(PѰô%%Ž©1ol.Lœóf¬1DjŒœ¤gÉ3‹¼ëú j2¿Ú?bB¶EÝH[—´cՈ!RÀ¤ÝT{Z3‚$ö~µí©Í¢tHƒK˜u—ލ§òÚüÆé/f ¥1ŒõÍ?B ‘ã9:^ÅQ7Ö«2'Lº#)9Ɋõ*w»5CUþ¥¸ ™FIóæV¨j.URLx ãò>Ú¸jmÆêK}x)A\8W(!Ɉu)>΅;•TU6×Û_b.ê¢HE×5*œ…%@¸ ‰—>-PIöÛþy}Üí“\nrÚ¨¢6EÕ¥)j¬L±ti0¦(˾Nk±,e’0H™K_eò†8,ÊQ„;¹Ã\ŒS‡<ç†Zn©„û¿ L¬.Oâ 1ûU^n%mò5ãÇt|,á‡peÚêzñ~÷tü«zü”‡ÿg9¬öøÉ#)BþñƒM·ÿ+í—«¿º#€endstream +endobj +278 0 obj +2356 +endobj +279 0 obj<>>>/Annots 136 0 R>>endobj +280 0 obj<>stream +xÚ՚MsÛ6@ïþ8¶‡(X€àÇѵãL:͌[«½+2m3#‰*E§u}ì.¸àÌt*:ÉH³YêI|—ÀB¿Ÿö/]ºëíÙ˳·WPR,ï˜f¢¬ +±¼ýn¹ú´iE'.úÝØîÆÃ÷ËÏgï–gr!-Ã=€{øå½¨ÔBŠR›E-¶¢)íqãøÏ^0܋·W…pïX){¬{…}C½¨…øê»Dà­­&}ÊLìoïÆ~ï?´=ÊØ³¶ÿ»8ᐁJ-ÊI è̜$¥mL’LN‘@Uö9AQž`b˜ÉÓz#ÙØ!Ž|9¹(ØQ™sD$(ÔB§(Ì3Ì;V‡±±Ð6yZS9Iƞ€bII¦©lL’ªŒ$&©*EQž`}»?ô;-¥ÍœÊSÖP­í#òAd¨žQóC°£Â¤ ʉ‡½Bå©ËQÖOلZŽA䧒¡^79CD]ØË,Aažablÿ_MÁ¶wkɔ¾Ìw+€NÍÞZ©¸`EÑK­íÆ]d1‡ÒD7ë‡ööqC…¨˜CÁþ–Ae/’©vc ª¢àÚ]Û)HfP l‘)Så &ÎLJ~èþZ•%}*kY=ZFUÛ‘ \µ]%Îè!Αå &.6«Ã¡Ó%IPE…Û‘$¨Y‘Î)"¨ÒŽ”DùšuvæëXª:áýì›IÕnDŠd±˜$åæÚL‚ҍ—Ey‚¹Â]wÿ8Ìá2Ëè)fÙ=ESÑÎβ™änmMŠ¢<ÁÄeû¥[¿¦Ë¬¨ªPª1ˆ$Uu(Õ¹i6“À—äEy‚‰Ënh×v¦ýôub ±Èì6Aòļi‡ ¾°ŸõÿŸõ\¡æcy.M¨ù¹™:“Œ3£(O0ñáúÚ¡ œI={‘'¡ìcy2“¥Ü|9®Ï‘€(Ž~ì?ùA£à䋽+ÒU(ûDŠtÊ~nÊÎ$Ðÿ@Qž`â§þþ¾ÛÝûË«žÁpÊ:RVl©ì§Å(’¤L(þ ”¡èån +Q?‡ñÄW¿+ÚcÌ,º,*ã +,ž‡"O ¢©:d=1 o“1Œ žøøá㻹ô¢rŽtScÁõç€Qp¤ýZŽ©œ£ ¦;B@¡‘ ­FªÝM¦‘ÀœÆµ.¥‰$nžc»=r÷́½Y&8Êî·c_\x­k#º…DBâuÑo·«Ý­ÿæ +ן<á7—Ù¦+ ¢m¾™4Ù~“°_Ÿ (O0±Z¯Ûý8£~}ÎQaÂBƒÈQQò¤É65˜DŽbå &֫ݺݼ"GZ…E‘#­ùFÒd»L-í¥“ (O0qÛÜ¤f1ÇÍZ²Söi €AdIIv”kj0§m óˆínô:F‘Œ¶_1ˆüÈi‹µÉö5˜Òubåy‹uã·3@Îf‘ôQª‰¶Y1¢T£CÙÎõ6˜ÚMôåy›u³_Ýnq 0…’Î8ª¢mV "Gµ e;ח`(ó…y†YGÝW«5§©Œ6Z1ˆ4•U¨Ü¹Æ“°eŸ (Ï­›ý¶ÿÒΨ•˜sd¢­V "GfH¹®s Îy¾ÕJ(ë§ß».4N!áäSÿœMû£~ƒQ䧐¡nç[L¹M£˜g5ÆÕ8«…dΔ*£æ F‘)UEóílSb‚)WÀ›®Cû¹]¿S҉’´ýç&Щ½½2ô³+wmžs5ìâÔLìɔOófâûM8¬†'¼ðf5'øW‹æø¢jÜ"4®m…Á¤‘½f—çPû êüØ"/BlEín„ Òxa.ÛaK?È:Á†Å ­ÂMC<©J'½ ¨hÇðüØz/z©Åî§5 ˆò¼ùx¾úÝӖ{0+i¨+œ£œ~YÓ2Úÿb·g.~½¾7ýÝøÇjhÅe{èîwîi=t{Þ]}Æ ¢7®UºŽTþ|ö7HKêendstream +endobj +281 0 obj +1586 +endobj +282 0 obj<>endobj +283 0 obj<>endobj +284 0 obj<>endobj +285 0 obj<>endobj +286 0 obj<>endobj +287 0 obj<>endobj +288 0 obj<>endobj +289 0 obj<>endobj +290 0 obj<>endobj +291 0 obj<>endobj +292 0 obj<>endobj +293 0 obj<>endobj +294 0 obj<>endobj +295 0 obj<>endobj +296 0 obj<>endobj +297 0 obj<>endobj +298 0 obj<>endobj +299 0 obj<>endobj +300 0 obj<>endobj +301 0 obj<>endobj +302 0 obj<>endobj +303 0 obj<>endobj +304 0 obj<>endobj +305 0 obj<>endobj +306 0 obj<>endobj +307 0 obj<>endobj +308 0 obj<>endobj +309 0 obj<>endobj +310 0 obj<>endobj +311 0 obj<>endobj +312 0 obj<>endobj +313 0 obj<>endobj +314 0 obj<>endobj +315 0 obj<>endobj +316 0 obj<>endobj +317 0 obj<>endobj +318 0 obj<>endobj +319 0 obj<>endobj +320 0 obj<>endobj +321 0 obj<>endobj +322 0 obj<>endobj +323 0 obj<>endobj +324 0 obj<>endobj +325 0 obj<>endobj +326 0 obj<>endobj +327 0 obj<>endobj +328 0 obj<>endobj +329 0 obj<>endobj +330 0 obj<>endobj +331 0 obj<>endobj +332 0 obj<>endobj +333 0 obj<>endobj +334 0 obj<>endobj +335 0 obj<>endobj +336 0 obj<>endobj +337 0 obj<>endobj +338 0 obj<>endobj +339 0 obj<>endobj +340 0 obj<>endobj +341 0 obj<>endobj +342 0 obj<>endobj +343 0 obj<>endobj +344 0 obj<>endobj +345 0 obj<>endobj +346 0 obj<>endobj +347 0 obj<>endobj +348 0 obj<>endobj +349 0 obj<>endobj +350 0 obj<>endobj +351 0 obj<>endobj +352 0 obj<>endobj +353 0 obj<>endobj +354 0 obj<>endobj +355 0 obj<>endobj +356 0 obj<>endobj +357 0 obj<>endobj +358 0 obj<>endobj +359 0 obj<>endobj +360 0 obj<>endobj +361 0 obj<>endobj +362 0 obj<>endobj +363 0 obj<>endobj +364 0 obj<>1<>2<>4<>]>>>>endobj +xref +0 365 +0000000000 65535 f +0000000015 00000 n +0000000226 00000 n +0000001792 00000 n +0000001866 00000 n +0000001948 00000 n +0000002026 00000 n +0000002103 00000 n +0000002182 00000 n +0000002258 00000 n +0000002339 00000 n +0000002398 00000 n +0000002450 00000 n +0000002535 00000 n +0000002587 00000 n +0000002671 00000 n +0000002702 00000 n +0000002803 00000 n +0000002888 00000 n +0000002989 00000 n +0000003074 00000 n +0000003175 00000 n +0000003260 00000 n +0000003361 00000 n +0000003446 00000 n +0000003533 00000 n +0000003618 00000 n +0000003705 00000 n +0000003790 00000 n +0000003877 00000 n +0000003962 00000 n +0000004028 00000 n +0000004113 00000 n +0000004179 00000 n +0000004264 00000 n +0000004330 00000 n +0000004415 00000 n +0000004481 00000 n +0000004566 00000 n +0000004632 00000 n +0000004717 00000 n +0000004783 00000 n +0000004868 00000 n +0000004934 00000 n +0000005019 00000 n +0000005085 00000 n +0000005170 00000 n +0000005236 00000 n +0000005321 00000 n +0000005387 00000 n +0000005472 00000 n +0000005538 00000 n +0000005623 00000 n +0000005689 00000 n +0000005774 00000 n +0000005924 00000 n +0000006028 00000 n +0000006133 00000 n +0000006238 00000 n +0000006343 00000 n +0000006447 00000 n +0000006552 00000 n +0000006657 00000 n +0000006761 00000 n +0000006866 00000 n +0000006971 00000 n +0000007076 00000 n +0000007181 00000 n +0000007286 00000 n +0000007391 00000 n +0000007496 00000 n +0000007601 00000 n +0000007706 00000 n +0000007811 00000 n +0000007916 00000 n +0000008021 00000 n +0000008126 00000 n +0000008231 00000 n +0000008336 00000 n +0000008441 00000 n +0000008546 00000 n +0000008651 00000 n +0000008756 00000 n +0000008861 00000 n +0000008966 00000 n +0000009071 00000 n +0000009176 00000 n +0000009281 00000 n +0000009386 00000 n +0000009491 00000 n +0000009596 00000 n +0000009701 00000 n +0000009806 00000 n +0000009911 00000 n +0000010016 00000 n +0000010121 00000 n +0000010226 00000 n +0000010331 00000 n +0000010435 00000 n +0000010538 00000 n +0000010641 00000 n +0000010974 00000 n +0000011080 00000 n +0000011186 00000 n +0000011292 00000 n +0000011398 00000 n +0000011504 00000 n +0000011610 00000 n +0000011715 00000 n +0000011821 00000 n +0000011927 00000 n +0000012033 00000 n +0000012139 00000 n +0000012245 00000 n +0000012351 00000 n +0000012457 00000 n +0000012563 00000 n +0000012669 00000 n +0000012775 00000 n +0000012881 00000 n +0000012987 00000 n +0000013093 00000 n +0000013198 00000 n +0000013304 00000 n +0000013410 00000 n +0000013516 00000 n +0000013622 00000 n +0000013728 00000 n +0000013834 00000 n +0000013940 00000 n +0000014046 00000 n +0000014152 00000 n +0000014258 00000 n +0000014364 00000 n +0000014468 00000 n +0000014573 00000 n +0000014678 00000 n +0000014976 00000 n +0000015010 00000 n +0000015044 00000 n +0000016191 00000 n +0000016240 00000 n +0000016289 00000 n +0000016338 00000 n +0000016387 00000 n +0000016436 00000 n +0000016485 00000 n +0000016534 00000 n +0000016583 00000 n +0000016632 00000 n +0000016681 00000 n +0000016730 00000 n +0000016779 00000 n +0000016828 00000 n +0000016877 00000 n +0000016926 00000 n +0000016975 00000 n +0000017024 00000 n +0000017073 00000 n +0000017122 00000 n +0000017171 00000 n +0000017220 00000 n +0000017269 00000 n +0000017318 00000 n +0000017367 00000 n +0000017416 00000 n +0000017465 00000 n +0000017514 00000 n +0000017563 00000 n +0000017612 00000 n +0000017661 00000 n +0000017710 00000 n +0000017759 00000 n +0000017808 00000 n +0000017857 00000 n +0000017906 00000 n +0000017955 00000 n +0000018004 00000 n +0000018053 00000 n +0000018102 00000 n +0000018151 00000 n +0000018200 00000 n +0000018249 00000 n +0000018298 00000 n +0000018347 00000 n +0000018396 00000 n +0000018445 00000 n +0000018494 00000 n +0000018543 00000 n +0000018592 00000 n +0000018641 00000 n +0000018690 00000 n +0000018739 00000 n +0000018788 00000 n +0000018837 00000 n +0000018886 00000 n +0000018935 00000 n +0000018984 00000 n +0000019033 00000 n +0000019082 00000 n +0000019131 00000 n +0000019180 00000 n +0000019229 00000 n +0000019278 00000 n +0000019327 00000 n +0000019376 00000 n +0000019425 00000 n +0000019474 00000 n +0000019523 00000 n +0000019572 00000 n +0000019621 00000 n +0000019670 00000 n +0000019719 00000 n +0000019768 00000 n +0000019817 00000 n +0000019866 00000 n +0000019915 00000 n +0000019964 00000 n +0000020013 00000 n +0000020062 00000 n +0000020111 00000 n +0000020160 00000 n +0000020389 00000 n +0000020541 00000 n +0000026891 00000 n +0000026913 00000 n +0000027008 00000 n +0000027110 00000 n +0000027130 00000 n +0000027285 00000 n +0000028294 00000 n +0000028315 00000 n +0000028428 00000 n +0000028614 00000 n +0000028635 00000 n +0000028790 00000 n +0000030200 00000 n +0000030222 00000 n +0000030335 00000 n +0000030526 00000 n +0000030547 00000 n +0000030697 00000 n +0000031737 00000 n +0000031758 00000 n +0000031917 00000 n +0000032851 00000 n +0000032872 00000 n +0000033003 00000 n +0000033967 00000 n +0000033988 00000 n +0000034119 00000 n +0000035045 00000 n +0000035066 00000 n +0000035216 00000 n +0000036272 00000 n +0000036293 00000 n +0000036424 00000 n +0000037173 00000 n +0000037194 00000 n +0000037325 00000 n +0000038461 00000 n +0000038483 00000 n +0000038623 00000 n +0000039580 00000 n +0000039601 00000 n +0000039732 00000 n +0000040326 00000 n +0000040347 00000 n +0000040460 00000 n +0000040652 00000 n +0000040673 00000 n +0000040813 00000 n +0000041481 00000 n +0000041502 00000 n +0000041615 00000 n +0000041805 00000 n +0000041826 00000 n +0000041981 00000 n +0000044408 00000 n +0000044430 00000 n +0000044585 00000 n +0000046242 00000 n +0000046264 00000 n +0000046319 00000 n +0000046424 00000 n +0000046569 00000 n +0000046676 00000 n +0000046797 00000 n +0000046907 00000 n +0000047057 00000 n +0000047168 00000 n +0000047276 00000 n +0000047431 00000 n +0000047568 00000 n +0000047666 00000 n +0000047777 00000 n +0000047893 00000 n +0000048007 00000 n +0000048121 00000 n +0000048219 00000 n +0000048378 00000 n +0000048476 00000 n +0000048587 00000 n +0000048698 00000 n +0000048797 00000 n +0000048942 00000 n +0000049046 00000 n +0000049165 00000 n +0000049281 00000 n +0000049388 00000 n +0000049568 00000 n +0000049684 00000 n +0000049806 00000 n +0000049927 00000 n +0000050053 00000 n +0000050161 00000 n +0000050323 00000 n +0000050449 00000 n +0000050583 00000 n +0000050717 00000 n +0000050842 00000 n +0000050970 00000 n +0000051081 00000 n +0000051230 00000 n +0000051344 00000 n +0000051453 00000 n +0000051602 00000 n +0000051705 00000 n +0000051822 00000 n +0000051943 00000 n +0000052058 00000 n +0000052172 00000 n +0000052290 00000 n +0000052411 00000 n +0000052529 00000 n +0000052632 00000 n +0000052784 00000 n +0000052892 00000 n +0000053007 00000 n +0000053121 00000 n +0000053242 00000 n +0000053357 00000 n +0000053483 00000 n +0000053594 00000 n +0000053706 00000 n +0000053821 00000 n +0000053934 00000 n +0000054047 00000 n +0000054160 00000 n +0000054264 00000 n +0000054411 00000 n +0000054512 00000 n +0000054626 00000 n +0000054741 00000 n +0000054855 00000 n +0000054965 00000 n +0000055080 00000 n +0000055194 00000 n +0000055308 00000 n +0000055425 00000 n +0000055540 00000 n +0000055642 00000 n +0000055777 00000 n +0000055875 00000 n +0000055976 00000 n +trailer +<<9aacd5ebf47636316abaf4d573ca59e2>]>> +startxref +56204 +%%EOF diff --git a/doc/sdd.shtml b/doc/sdd.shtml new file mode 100644 index 0000000000..fde16b10e7 --- /dev/null +++ b/doc/sdd.shtml @@ -0,0 +1,550 @@ + + + + + + CUPS Software Design Description + + + +

Scope

+ +

Identification

+ +This software design description document provides general information +on the architecture and coding of the Common UNIX Printing System +("CUPS") Version 1.1. + + + +

Document Overview

+ +This software design description document is organized into the +following sections: + +
    + +
  • 1 - Scope + +
  • 2 - References + +
  • 3 - Design Overview + +
  • A - Glossary + +
+ + + +

Design Overview

+ +CUPS is composed of 9 software sub-systems that operate together to +perform common printing tasks: + +
    + +
  • Backends + +
  • Berkeley Commands + +
  • CGI + +
  • CUPS Application Programmers Interface + +
  • CUPS Imaging Library + +
  • Daemons + +
  • Filters + +
  • Scheduler + +
  • System V Commands + +
+ +

Backends

+ +The backends implement communications over a number of different interfaces. +All backends are called with a common set of arguments: + +
    + +
  • Device URI - the Uniform Resource Identifier for the output device + (e.g. parallel:/dev/plp, + ipp://hostname/resource). + +
  • Job Identifier - the job identifier for this job (integer). + +
  • User Name - the user associated with this job (name string). + +
  • Title - the title/job-name associated with this job (name string). + +
  • Copies - the number of copies required (integer). + +
  • Options - the options associated with this job (space separated + option strings). + +
  • Filename (optional) - the file to print; if this option is not + specified, the backend must read the print file from the standard + input. + +
+ +

Backends are named using the scheme of the URI, so a URI of +"ipp://hostname/resource" would be processed by the "ipp" backend. + +

ipp

+ +

The ipp backend sends the specified job to a network printer or host using +the Internet Printing Protocol. The URI is as specified by the +printer-uri-supported attribute from the printer or host. + +

lpd

+ +

The lpd backend sends the specified job to a network printer or host using +the Line Printer Daemon protocol. The URI is of the form: + +

    lpd://hostname/queue
    +
+ +

parallel

+ +

The parallel backend sends the specified job to a local printer connected +via the specified parallel port device. The URI is of the form: + +

    parallel:/dev/file
    +
+ +

serial

+ +

The serial backend sends the specified job to a local printer connected +via the specified serial port device. The URI is of the form: + +

    serial:/dev/file?option[+option+...]
    +
+ +The options can be any combination of the following: + +
    + +
  • baud=rate - Sets the baud rate for the device. + +
  • bits=7 or 8 - Sets the number of data bits. + +
  • parity=even - Sets even parity checking. + +
  • parity=odd - Sets odd parity checking. + +
  • parity=none - Turns parity checking off. + +
+ +

socket

+ +

The socket backend sends the specified job to a network host using the +AppSocket protocol commonly used by Hewlett-Packard and Tektronix +printers. The URI is of the form: + +

    socket://hostname[:port]
    +
+ +The default port number is 9100. + +

usb

+ +

The usb backend sends the specified job to a local printer connected +via the specified usb port device. The URI is of the form: + +

    usb:/dev/file
    +
+ +

Berkeley Commands

+ +

The Berkeley commands provide a simple command-line interface to CUPS +to submit and control print jobs. It is provided for compatibility with +existing software that is hardcoded to use the Berkeley commands. + +

lpc

+ +The lpc command allows users and administrators to check the status and +control print queues. The version provided with CUPS supports the following +commands: + +
    + +
  • quit - Quits the lpc command. + +
  • status - Shows the status of printers and jobs in the queue. + +
+ +

lpq

+ +

The lpq command shows the current queue status. + +

lpr

+ +

The lpr command submits a job for printing. The CUPS version of lpr silently +ignores the "i", "t", "m", "h", and "s" options. + +

lprm

+ +

The lprm removes one or more print jobs. + +

CGI

+ +

The Common Gateway Interface (CGI) programs provide a web-based +status interface to monitor the status of printers, classes, and jobs. +Each of the CGIs utilize HTML template files that can be customized to +provide alternate appearances. + +

admin.cgi

+ +

The admin CGI provides administration interfaces for printers and +classes. The user can add, modify, delete, start, stop, and configure +printers and classes using "wizard" interfaces. + +

classes.cgi

+ +

The classes CGI lists the available printer classes and any pending +jobs for the class. The user can click on individual classes to limit +the display and click on jobs to see the job status. + +

jobs.cgi

+ +

The jobs CGI lists the queued print jobs in order of priority. The +list can be limited by printer or job. + +

printers.cgi

+ +

The printers CGI lists the available printer queues and any pending +jobs for the printer. The user can click on individual printers to +limit the display and click on jobs to see the job status. + +

CUPS Application Programmers Interface

+ +

The CUPS Application Programmers Interface ("API") provides common +convenience, HTTP, IPP, language, and PPD functions used by the CUPS +software. + +

Convenience Functions

+ +

Convenience functions are provided to submit an IPP request, send a +print file, cancel a job, get a list of available printers, get a list +of available classes, get the default printer or class, get the default +server name, get the local username, and get a password string. + +

HTTP Functions

+ +

The HTTP functions provide functions to connect to HTTP servers, +issue requests, read data from a server, and write data to a server. + +

IPP Functions

+ +

The IPP function provide functions to manage IPP request data and +attributes, read IPP responses from a server, and write IPP requests to +a server. + +

Language Functions

+ +

The language functions provide a standard interface for retrieving +common textual messages for a particular locale and determining the +correct encoding (e.g. US ASCII, UTF-8, ISO-8859-1, etc.) + +

PPD Functions

+ +

The PostScript Printer Description functions manage PPD files, +select options, check for option conflicts, and emit selected options +in the correct order. + +

CUPS Imaging Library

+ +

The CUPS imaging library provides colorspace conversion, color +management, image management, scaling, image file, and raster functions +used by the CUPS raster filters. + +

Colorspace Conversion Functions

+ +

The colorspace conversion functions handle conversion of grayscale +and RGB colors to grayscale, RGB, K, CMY, CMYK, and CMYKcm colorspaces. + +

Color Management Functions

+ +

The color management functions handle gamut mapping and density +correction. These are integrated with the colorspace conversion +functions so that colorspace conversion and color management are +processed in a single step. + +

Image Management Functions

+ +

The image management functions manage a tiled image database that is +swapped to/from disk as needed. + +

Scaling Functions

+ +

The scaling functions provide image scaling services using +nearest-neighbor sampling and bilinear interpolation as appropriate. + +

Image File Functions

+ +

The image file functions handle loading of all image file formats. + +

Raster Functions

+ +

The raster functions manage streams of CUPS raster data (described +in the Interface Design Document) used by non-PostScript printer +drivers and raster filters. + +

Daemons

+ +

The daemons provide additional network functions for the scheduler. +Currently only two daemons are provided with CUPS. + +

Line Printer Daemon

+ +

The line printer daemon provides remote LPD client support and is +run by the inetd(8) daemon as needed. + +

Polling Daemon

+ +

The polling daemon is used to poll a remote server for a list of +available printers and provide it to the scheduler for addition. A +separate polling daemon is run by the scheduler for every remote +system listed for polling in the scheduler configuration file. + +

Filters

+ +

The filters implement file conversion services for CUPS. All filters +are called with a common set of arguments: + +

    + +
  • Printer name - the name of the destination printer (name string). + +
  • Job Identifier - the job identifier for this job (integer). + +
  • User Name - the user associated with this job (name string). + +
  • Title - the title/job-name associated with this job (name string). + +
  • Copies - the number of copies required (integer). + +
  • Options - the options associated with this job (space separated + option strings). + +
  • Filename (optional) - the file to print; if this option is not + specified, the filter must read the input file from the standard + input. + +
+ +

Filters are added to the MIME conversion data file and implement all +necessary conversions from one file type to another. + +

hpgltops

+ +

The hpgltops filter converts HP-GL/2 files into PostScript. + +

imagetops

+ +

The imagetops filter converts image files into PostScript. + +

imagetoraster

+ +

The imagetoraster filter converts image files into CUPS raster data. + +

pdftops

+ +

The pdftops filter converts PDF files into PostScript. + +

pstops

+ +

The pstops filter inserts printer-specific commands from PPD files and +performs page filtering as requested by the user. + +

pstoraster

+ +

The pstoraster filter converts PostScript program data into CUPS +raster data. + +

rastertoepson

+ +

The rastertoepson filter handles converting CUPS raster data to +ESC/P and supports both color and black-and-white printers. + +

rastertohp

+ +

The rastertohp filter handles converting CUPS raster data to HP-PCL +and supports both color and black-and-white printers. + +

texttops

+ +

The texttops filter converts text files into PostScript. + +

Scheduler

+ +

The scheduler is a fully-functional HTTP/1.1 and IPP/1.1 server that +manages the printers, classes, and jobs in the system. It also handles +a simple broadcast-based directory service so that remote print queues +and classes can be accessed transparently from the local system. + +

Authorization

+ +

The authorization module is responsible for performing access +control and authentication for all HTTP and IPP requests entering the +system. + +

Classes

+ +

The classes module is responsible for managing printer classes in +the system. Each class is a collection of local and/or remote +printers. The classes module also reads and writes the classes +configuration file. + +

Client

+ +

The client module is responsible for all HTTP client +communications. It handles listening on selected interfaces, accepting +connections from prospective clients, processing incoming HTTP +requests, and sending HTTP responses to those requests. The client +module also is responsible for executing the external CGI programs as +needed to support web-based printer, class, and job status monitoring +and administration. + +

Once authorized, all IPP requests are sent to the IPP module. + +

Configuration

+ +

The configuration module is responsible for reading the CUPS +configuration file and initializing the appropriate data structures and +values. The configuration module also stops CUPS services before +reading the configuration file and restarts them after the +configuration file has been read. + +

Devices

+ +

The devices module is responsible for managing the list of available +devices for the CUPS-Get-Devices operation. + +

Directory Services

+ +

The directory services module sends and recieves printer state +information over a broadcast socket. Remote printers and classes are +automatically added to or removed from the local printer and class +lists as needed. + +

The directory services module can only recieve printer state information +over a single UDP port, however it can broadcast to multiple addresses and +ports as needed. + +

IPP

+ +

The IPP module handles IPP requests and acts accordingly. URI +validation is also performed here, as a client can post IPP data to any +URI on the server which might sidestep the access control or +authentication of the HTTP server. + +

Jobs

+ +

The jobs module manages print jobs, starts filter and backend +processes for jobs to be printed, and monitors status messages from +those filters and backends. + +

Logging

+ +

The logging module manages the access, error, and page log files +that are generated by the scheduler. + +

Main

+ +

The main module is responsible for timing out and dispatching input +and output for client connections. It also watches for incoming +SIGHUP and SIGCHLD signals, reloads the +server configuration files as needed, and handles child process errors +and exits. + +

MIME

+ +

The Multimedia Internet Mail Exchange module manages a MIME type and +conversion database that supports file typing by extension and content +and least-cost file filtering from a source to a destination file type. + +

PPDs

+ +

The PPDs module is responsible for managing the list of available +PPD files for the CUPS-Get-PPDs operation. + +

Printers

+ +

The printers module is responsible for managing printers and PPD +files in the system. The printers module also reads and writes the +printers configuration file. + +

System V Commands

+ +

The System V commands provide a robust command-line interface to +CUPS to submit and control printers and jobs. + +

accept

+ +

The accept command tells the scheduler to accept new jobs for specific +printers. + +

cancel

+ +

The cancel command tells the scheduler to cancel one or more jobs that are +queued for printing. + +

disable

+ +

The disable command tells the scheduler to stop printing jobs on the +specified printers. + +

enable

+ +

The enable command tells the scheduler to start printing jobs on the +specified printers. + +

lp

+ +

The lp command submits submits files for printing. Unlike the standard +System V lp command, a single CUPS lp command will generate a separate +job ID for each file that is printed. Also, the Solaris "f", "H", "P", "S", +and "y" options are silently ignored. + +

lpadmin

+ +

The lpadmin command manages printer queues and classes. The Solaris +"A", "F", "I", "M", "P", "Q", "S", "T", "U", "W", "f", "l", "m", "o", +"s", "t", and "u" options are not supported, and new options "P" (PPD +file) and "E" (enable and accept) are provided to configure +CUPS-specific features. + +

lpinfo

+ +

The lpinfo command lists the available PPD files or devices as selected +by the user. + +

lpmove

+ +

The lpmove command moves a print job to a new destination. + +

lpoptions

+ +

The lpoptions command manages user-defined printers and options. + +

lpstat

+ +

The lpstat command lists printers, classes, and jobs as requested by the +user. + +

reject

+ +

The reject command tells the scheduler not to accept new jobs for specific +printers. + + + + + diff --git a/doc/spm.html b/doc/spm.html new file mode 100644 index 0000000000..13bf3a95d8 --- /dev/null +++ b/doc/spm.html @@ -0,0 +1,7254 @@ + + + + CUPS Software Programmers Manual + + + + + + + +


+

CUPS Software Programmers Manual


+CUPS-SPM-1.1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
Preface + +1 - Printing System Overview + +2 - The CUPS API + +3 - Writing Filters + +4 - Writing Printer Drivers + +5 - Writing Backends + +A - Software License Agreement + +B - Constants + +C - Structures + +D - Functions + +
+

Preface

+

This software programmers manual provides software programming +information for the Common UNIX Printing System ("CUPS") Version 1.1.1.

+

System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+ + +

Document Overview

+

This software programmers manual is organized into the following +sections:

+ +

Notation Conventions

+

Various font and syntax conventions are used in this guide. Examples +and their meanings and uses are explained below: +

+ + + + + + + + + + + + +
Example   Description
 
lpstat +
lpstat(1)
   The names of commands; +the first mention of a command or function in a chapter is followed by +a manual page section number.
 
/var +
/usr/share/cups/data/testprint.ps
    +File and directory names.
 
Request ID is Printer-123 +   Screen output.
 
lp -d printer filename ENTER +   Literal user input; special keys like ENTER are + in ALL CAPS.
 
12.3   Numbers in the text are +written using the period (.) to indicate the decimal point.
+
+ + +

+

Abbreviations

+ The following abbreviations are used throughout this manual: +
    +
    +
    kb
    +
    Kilobytes, or 1024 bytes +
     
    +
    Mb
    +
    Megabytes, or 1048576 bytes +
     
    +
    Gb
    +
    Gigabytes, or 1073741824 bytes +
     
    +
    +
+

Other References

+
    +
    +
    CUPS Software Administrators Manual
    +
    An administration guide for the CUPS software. +
     
    +
    CUPS Software Users Manual
    +
    An end-user guide for using the CUPS software. +
     
    +
    +
+

1 - Printing System Overview

+

This chapter provides an overview of how the Common UNIX Printing +System works.

+

The Printing Problem

+

For years the printing problem has plagued UNIX. Unlike +Microsoft® Windows® or Mac OS, UNIX has no standard interface or system +in place for supporting printers. Among the solutions currently +available, the Berkeley and System V printing systems are the most +prevalent.

+

These printing systems support line printers (text only) or +PostScript printers (text and graphics), and with some coaxing they can +be made to support a full range of printers and file formats. However, +because each varient of the UNIX operating system uses a different +printing system than the next developing printer drivers for a wide +range of printers and operating systems is extremely difficult. That +combined with the limited volume of customers for each UNIX varient has +forced most printer vendors to give up supporting UNIX entirely.

+

CUPS is designed to eliminate the printing problem. One +common printing system can be used by all UNIX varients to support the +printing needs of users. Printer vendors can use its modular filter +interface to develop a single driver program that supports a wide range +of file formats with little or no effort. Since CUPS provides both the +System V and Berkeley printing commands, users (and applications) can +reap the benefits of this new technology with no changes.

+

The Technology

+

CUPS is based upon an emerging Internet standard called the Internet +Printing Protocol. IPP has been embraced by dozens of printer and +printer server manufacturers and is supported by Microsoft Windows +2000.

+

IPP defines a standard protocol for printing as well as managing +print jobs and printer options like media size, resolution, and so +forth. Like all IP-based protocols, IPP can be used locally or over the +Internet to printers hundreds or thousands of miles away. Unlike other +protocols, however, IPP also supports access control, authentication, +and encryption, making it a much more capable and secure printing +solution than older ones.

+

IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") +which is the basis of web servers on the Internet. This allows users to +view documentation, check status information on a printer or server, +and manage their printers, classes, and jobs using their web browser.

+

CUPS provides a complete IPP/1.1 based printing system that provides +Basic, Digest, and local certificate authentication and user, domain, +or IP-based access control. TLS encryption will be available in future +versions of CUPS.

+

Jobs

+

Each file or set of files that is submitted for printing is called a +job. Jobs are identified by a unique number starting at 1 and are +assigned to a particular destination, usually a printer. Jobs can also +have options associated with them such as media size, number of copies, +and priority.

+

Classes

+

CUPS supports collections of printers known as classes. Jobs +sent to a class are forwarded to the first available printer in the +class.

+

Filters

+

Filters allow a user or application to print many types of files +without extra effort. Print jobs sent to a CUPS server are filtered +before sending them to a printer. Some filters convert job files to +different formats that the printer can understand. Others perform page +selection and ordering tasks.

+

CUPS provides filters for printing many types of image files, +HP-GL/2 files, PDF files, and text files. CUPS also supplies PostScript +and image file Raster Image Processor ("RIP") filters that convert +PostScript or image files into bitmaps that can be sent to a raster +printer.

+

Backends

+

Backends perform the most important task of all - they send the +filtered print data to the printer.

+

CUPS provides backends for printing over parallel, serial, and USB +ports, and over the network via the IPP, JetDirect (AppSocket), and +Line Printer Daemon ("LPD") protocols. Additional backends are +available in network service packages such as the SMB backend included +with the popular SAMBA software.

+

Backends are also used to determine the available devices. On +startup each backend is asked for a list of devices it supports, and +any information that is available. This allows the parallel backend to +tell CUPS that an EPSON Stylus Color 600 printer is attached to +parallel port 1, for example.

+

Printer Drivers

+

Printer drivers in CUPS consist of one of more filters specific to a +printer. CUPS includes sample printer drivers for Hewlett-Packard +LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, +and Stylus Photo printers. While these drivers do not generate optimal +output for the different printer models, they do provide basic printing +and demonstrate how you can write your own printer drivers and +incorporate them into CUPS.

+

Networking

+

Printers and classes on the local system are automatically shared +with other systems on the network. This allows you to setup one system +to print to a printer and use this system as a printer server or spool +host for all of the others. Users may then select a local printer by +name or a remote printer using "name@server".

+

CUPS also provides implicit classes, which are collections of +printers and/or classes with the same name. This allows you to setup +multiple servers pointing to the same physical network printer, for +example, so that you aren't relying on a single system for printing. +Because this also works with printer classes, you can setup multiple +servers and printers and never worry about a single point of failure +unless all of the printers and servers go down!

+

2 - The CUPS API

+

This chapter describes the CUPS Application Programmers Interface +("API").

+

The CUPS API Library

+

The CUPS library provides a whole collection of interfaces needed to +support the internal needs of the CUPS software as well as the needs of +applications, filters, printer drivers, and backends.

+

Unlike the rest of CUPS, the CUPS API library is provided under the +GNU Library General Public License. This means that you can use the +CUPS API library in both proprietary and open-source programs.

+

Programs that use the CUPS API library typically will include the +<cups/cups.h> header file:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +jobid = cupsPrintFile("myprinter", "filename.ps", "title",
    +                      num_options, options);
    +
    +
+

Use the -lcups compiler option when linking to the CUPS +API library:

+
    +
    +cc -o program program.c -lcups ENTER
    +
    +
+

Additional options and libraries may be required depending on the +operating system and the location of the CUPS API library.

+

Detecting the CUPS API Library in GNU Autoconf

+

GNU autoconf is a popular configuration tool used by many programs. +Add the following lines to your configure.in file to check for the +CUPS API library in your configuration script:

+
    +
    +AC_CHECK_LIB(socket,socket,
    +if test "$uname" != "IRIX"; then
    +	LIBS="-lsocket $LIBS"
    +else
    +	echo "Not using -lsocket since you are running IRIX."
    +fi)
    +AC_CHECK_LIB(nsl,gethostbyaddr,
    +if test "$uname" != "IRIX"; then
    +	LIBS="-lnsl $LIBS"
    +else
    +	echo "Not using -lnsl since you are running IRIX."
    +fi)
    +
    +AC_CHECK_LIB(cups,httpConnect)
    +
    +
+

Printing Services

+

The CUPS API library provides some basic printing services for +applications that need to print files.

+

Include Files

+

The include file used by all of these functions is +<cups/cups.h>:

+
    +
    +#include <cups/cups.h>
    +
    +
+

Printing a File

+

The CUPS API provides two functions for printing files. The first is +cupsPrintFile which prints a single named file:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +int jobid;
    +
    +...
    +
    +jobid = cupsPrintFile("name", "filename", "title", 0, NULL);
    +
    +
+

The name string is the name of the printer or class to +print to. The filename string is the name of the file to +print. The title string is the name of the print job, e.g. +"Acme Word Document".

+

The return value is a unique ID number for the print job or 0 if +there was an error.

+

Printing Multiple Files

+

The second printing function is cupsPrintFiles:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +int        jobid;
    +int        num_files;
    +const char *files[100];
    +...
    +
    +jobid = cupsPrintFiles("name", num_files, files, "title", 0, NULL);
    +
    +
+

Instead of passing a filename string as with cupsPrintFile() +, you pass a file count (num_files) and filename pointer +array (files) for each file that you want to print.

+

As with cupsPrintFile(), the return value is a unique +ID for the print job.

+

Cancelling Jobs

+

The cupsCancelJob() function cancels a queued print +job:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +int jobid;
    +int status;
    +...
    +
    +status = cupsCancelJob("name", jobid);
    +
    +
+

The name string specifies the destination and is used +to determine the server to send the request to. The jobid + value is the integer returned from a previous cupsPrintFile() + or cupsPrintFiles() call.

+

cupsCancelJob() returns 1 if the job was +successfully cancelled and 0 if there was an error.

+

Getting the Available Printers and Classes

+

The cupsGetDests() function can be used to get a list +of the available printers, classes, and instances that a user has +defined:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +int         num_dests;
    +cups_dest_t *dests;
    +
    +...
    +
    +num_dests = cupsGetDests(&dests);
    +
    +
+

Each destination is stored in a cups_dest_t structure +which defines the printer or class name, the instance name (if any), if +it is the default destination, and the default options the user has +defined for the destination:

+
    +
    +typedef struct               /**** Destination ****/
    +{
    +  char          *name,       /* Printer or class name */
    +                *instance;   /* Local instance name or NULL */
    +  int           is_default;  /* Is this printer the default? */
    +  int           num_options; /* Number of options */
    +  cups_option_t *options;    /* Options */
    +} cups_dest_t;
    +
    +
+

The destinations are sorted by name and instance for your +convenience. Once you have the list of available destinations, you can +lookup a specific destination using the cupsGetDest() + function:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +int         num_dests;
    +cups_dest_t *dests;
    +cups_dest_t *mydest;
    +
    +...
    +
    +mydest = cupsGetDest("name", "instance", num_dests, dests);
    +
    +
+

The name string is the printer or class name. You can +pass a value of NULL to get the default destination.

+

The instance string is the user-defined instance name. +Pass NULL to select the default instance, e.g. "name" +instead of "name/instance".

+

Printing with Options

+

All of the previous printing examples have passed 0 and +NULL for the last two arguments to the cupsPrintFile() + and cupsPrintFiles() functions. These last two arguments +are the number of options and a pointer to the option array:

+
    +
    +int cupsPrintFile(const char *name, const char *filename, const char *title,
    +                  int num_options, cups_option_t *options);
    +int cupsPrintFiles(const char *name, int num_files, const char **files,
    +                   const char *title, int num_options,
    +		   cups_option_t *options);
    +
    +
+

The cups_option_t structure holds each option and its +value. These are converted as needed and passed to the CUPS server when +printing a file.

+

The simplest way of handling options is to use the num_options + and options members of the cups_dest_t + structure described earlier:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +int         jobid;
    +int         num_dests;
    +cups_dest_t *dests;
    +cups_dest_t *mydest;
    +
    +...
    +
    +mydest = cupsGetDest("name", "instance", num_dests, dests);
    +
    +jobid  = cupsPrintFile(mydest->name, "filename", "title",
    +                       mydest->num_options, mydest->options);
    +
    +
+

This effectively uses the options a user has previous selected +without a lot of code.

+

Setting Printer Options

+

Options can also be set by your program using the +cupsAddOption() function:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +int           num_options;
    +cups_option_t *options;
    +
    +...
    +
    +num_options = 0;
    +options     = NULL;
    +
    +...
    +
    +num_options = cupsAddOption("name", "value", num_options, &options);
    +num_options = cupsAddOption("name", "value", num_options, &options);
    +num_options = cupsAddOption("name", "value", num_options, &options);
    +num_options = cupsAddOption("name", "value", num_options, &options);
    +
    +
+

The name string is the name of the option, and the +value string is the value for that option.

+

Each call to cupsAddOption() returns the new number of +options. Since adding two options with the same name overwrites the +first value with the second, do not assume that calling +cupsAddOptions() 20 times will result in 20 options.

+

Call cupsFreeOptions once you are done using the +options:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +int           num_options;
    +cups_option_t *options;
    +
    +...
    +
    +cupsFreeOptions(num_options, options);
    +
    +
+

Getting Errors

+

If any of the CUPS API printing functions returns an error, the +reason for that error can be found by calling cupsLastError() + and cupsErrorString(). cupsLastError() + returns the last IPP error code that was encountered. +cupsErrorString() converts the error code to a localized message +string suitable for presentation to the user:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +int jobid;
    +
    +...
    +
    +if (jobid == 0)
    +  puts(cupsErrorString(cupsLastError()));
    +
    +
+

PPD Services

+

CUPS includes functions to access and manipulate PostScript Printer +Description ("PPD") files that are used with the printer drivers in +CUPS.

+

Each PPD file enumerates the available features provided by a +printer, including conflict information for specific options (e.g. +can't duplex output on envelopes.)

+

Include Files

+

Include the <cups/ppd.h> header file to use the PPD +functions:

+
    +
    +#include <cups/ppd.h>
    +
    +
+

This header file is also included by the <cups/cups.h> + header file.

+

Getting a PPD File for a Printer

+

The cupsGetPPD() function retrieves the PPD file for +the named printer or class:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +const char *filename;
    +
    +filename = cupsGetPPD("name");
    +
    +
+

The name string is the name of the printer or class, +including the remote server name as appropriate (e.g. +"printer@server".)

+

The return value is a pointer to a filename in static storage; this +value is overwritten with each call to cupsGetPPD(). If +the printer or class does not exist, a NULL pointer will +be returned.

+

Loading a PPD File

+

The ppdOpenFile() function "opens" a PPD file and loads +it into memory:

+
    +
    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +
    +ppd = ppdOpenFile("filename");
    +
    +
+

The filename string is the name of the file to load, +such as the value returned by the cupsGetPPD() function.

+

The return value is a pointer to a structure describing the contents +of the PPD file or NULL if the PPD file could not be read.

+

Freeing PPD File Information

+

Once you are done using a PPD file, call the ppdClose() + function to free all memory that has been used:

+
    +
    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +
    +...
    +
    +ppdClose(ppd);
    +
    +
+

The PPD File Structure

+

Each PPD file contains a number of capability attributes, printer +options, and conflict definitions. The page size options also include +the physical margins for the printer and the minimum and maximum sizes +for the printer. All of this information is stored in the +ppd_file_t structure.

+

Capabilities

+

Each PPD file contains a number of informational attributes that +describe the capabilities of the printer. These are provided in the +ppd_file_t structure in the following members: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + +
MemberTypeDescription
accurate_screensint +1 = supports accurate screens
color_deviceint1 = +color device
colorspaceppd_cs_t +Default colorspace: PPD_CS_CMYK, PPD_CS_CMY, PPD_CS_GRAY, PPD_CS_RGB, +PPD_CS_RGBK, PPD_CS_N
contone_onlyint1 = +printer is continuous tone only
num_emulations +
emulations
int +
ppd_emul_t *
Emulations supported by the printer
flip_duplexint1 = +need to flip odd pages when duplexing
num_fonts +
fonts
int +
char **
The fonts available on the printer.
jcl_begin +
jcl_ps +
jcl_end
char *Job Control +Language commands for PostScript output
landscapeint +Landscape orientation, -90 or 90 degrees
lang_encodingchar * +The character used for the option strings
lang_versionchar * +The language used for the options strings (English, French, etc.)
language_levelint +PostScript language level, 1 to 3
manual_copiesint1 = +Copies are done manually
model_numberint +Driver-specific model number.
patcheschar *Patch +commands to send to the printer
manufacturerchar * +The Manufacturer attribute from the PPD file, if any
modelnamechar *The +ModelName attribute from the PPD file
nicknamechar *The +NickName attribute from the PPD file, if any
productchar *The +Product attribute from the PPD file, if any
shortnicknamechar * +The ShortNickName attribute from the PPD file, if any
throughputintNumber +of pages per minute
ttrasterizerchar * +The TruType font rasterizer (Type42)
variable_sizesint1 += supports variable sizes
+
+

+

Options and Groups

+

PPD files support multiple options, which are stored in +ppd_option_t and ppd_choice_t structures by the PPD +functions.

+

Each option in turn is associated with a group stored in the +ppd_group_t structure. Groups can be specified in the PPD file; +if an option is not associated with a group then it is put in a +"General" or "Extra" group depending on the option.

+

Groups can also have sub-groups; CUPS currently limits the depth of +sub-groups to 1 level to reduce programming complexity.

+

Conflicts

+

PPD files support specification of conflict conditions between +different options. Conflicts are stored in ppd_conflict_t + structures which specify the options that conflict with each other.

+

Page Sizes

+

PPD files specify all of the available pages sizes and the physical +margins associated with them. These sizes are stored in ppd_size_t + structures and are available in the num_sizes and +sizes members of the ppd_file_t structure. You can +lookup a particular page size with the ppdPageWidth(), +ppdPageLength(), and ppdPageSize() functions:

+
    +
    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +ppd_size_t *size;
    +float      width;
    +float      length;
    +
    +...
    +
    +size   = ppdPageSize(ppd, "size");
    +width  = ppdPageWidth(ppd, "size");
    +length = ppdPageLength(ppd, "size");
    +
    +
+

The size string is the named page size option. The +width and length are in points; there are 72 points per inch. The +ppd_size_t structure contains the width, length, and margin +information:

+
    +
    +typedef struct    /**** Page Sizes ****/
    +{
    +  int   marked;   /* Page size selected? */
    +  char  name[41]; /* Media size option */
    +  float width,    /* Width of media in points */
    +        length,   /* Length of media in points */
    +        left,     /* Left printable margin in points */
    +        bottom,   /* Bottom printable margin in points */
    +        right,    /* Right printable margin in points */
    +        top;      /* Top printable margin in points */
    +} ppd_size_t;
    +
    +
+

Custom Page Sizes

+

Besides the standard page sizes listed in a PPD file, some printers +support variable or custom page sizes. If variables_sizes + is non-zero, the custom_min, custom_max, and +custom_margins members of the ppd_file_t structure +define the limits of the variable sizes.

+

To get the resulting media size, use a page size string of +Custom.widthxlength, where width and +length are integer values in points:

+
    +
    +Custom.612x792   [8.5 inches wide, 11 inches long]
    +Custom.1224x792  [17 inches wide, 11 inches long]
    +
    +
+

Marking Options

+

Before marking any user-defined options, call the +ppdMarkDefaults() function to mark the default options from the +PPD file:

+
    +
    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +
    +...
    +
    +ppdMarkDefaults(ppd);
    +
    +
+

Then call the ppdMarkOption() function to mark +individual options:

+
    +
    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +int        conflicts;
    +
    +...
    +
    +conflicts = ppdMarkOption(ppd, "name", "value");
    +
    +
+

The name and value strings choose a +particular option and choice, respectively. The return value is 0 if +there are not conflicts created by the selection.

+

CUPS also provides a convenience function for marking all options in +the cups_option_t structure:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +ppd_file_t    *ppd;
    +int           num_options;
    +cups_option_t *options;
    +int           conflicts;
    +
    +...
    +
    +conflicts = cupsMarkOptions(ppd, num_options, options);
    +
    +
+

The cupsMarkOptions() function also handles mapping the +IPP job template attributes to PPD options. The return value is the +number of conflicts present.

+

Checking for Conflicts

+

The ppdMarkOption() and cupsMarkOptions() + functions return the number of conflicts with the currently marked +options.

+

Call the ppdConflicts() function to get the number of +conflicts after you have marked all of the options:

+
    +
    +#include <cups/cups.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +int        conflicts;
    +
    +...
    +
    +conflicts = ppdConflicts(ppd);
    +
    +
+

The return value is the number of conflicting options, or 0 if there +are no conflicts.

+

3 - Writing Filters

+

This chapter describes how to write a file filter for CUPS.

+

Overview

+

File filters are programs that convert from one or more MIME types +to another type. Filters use a common command-line and environment +interface that allows them to be joined as needed to print files to any +type of printer.

+

Security Considerations

+

Filters are normally run as a non-priviledged user, so the major +security consideration is resource utilization - filters should not +depend on unlimited amounts of memory and disk space.

+

Users and Groups

+

The default CUPS configuration runs filters as user "lp" and group +"other".

+

Temporary Files

+

Temporary files should be created in the directory specified by the +"TMPDIR" environment variable. The +cupsTempFile() function can be used to safely choose +temporary files in this directory.

+

Sending Messages to the User

+

The CUPS scheduler collects messages sent to the standard error file +by the filter. These messages are relayed to the user based upon the +scheduler LogLevel directive.

+

The type of message is determined by an initial prefix sent on each +line:

+
    +
  • DEBUG: - a debug message
  • +
  • INFO: - an informational message
  • +
  • WARNING: - a warning message
  • +
  • ERROR: - an error message
  • +
  • PAGE: - a page accounting message
  • +
+

If the line of text does not begin with any of the above prefixes, +it is treated as a debug message. Text following the prefix is copied +to the printer-state-message attribute for the printer, +and also added to the error_log unless it is an +informational or page accounting message.

+

Page Accounting

+

Page accounting messages are used to inform the server when one or +more pages are printed. Each line has the form:

+
    +
    +PAGE: page-number copy-count
    +
    +
+

The page-number field is the current page number, starting at +1. The copy-count field specifies the number of copies of that +page that was produced.

+

Page account messages are added to the page_log file and +cause the job-sheets-completed attribute to be updated for +the job.

+

Command-Line Arguments

+

Every filter accepts exactly 6 or 7 command-line arguments:

+
    +
    +printer job user title copies options [filename]
    +
    +
  • printer - The name of the printer queue (normally + this is the name of the program being run)
  • +
  • job - The numeric job ID for the job being printed
  • +
  • user - The string from the originating-user-name + attribute
  • +
  • title - The string from the job-name + attribute
  • +
  • copies - The numeric value from the + number-copies attribute
  • +
  • options - String representations of the job template +attributes, separated by spaces. Boolean attributes are provided as +"name" for true values and "noname" for false values. All other +attributes are provided as "name=value" for single-valued attributes +and "name=value1,value2,...,valueN" for set attributes
  • +
  • filename - The request file
  • +
+

The filename argument is only provided to the first filter in +the chain; all filters must be prepared to read the print file +from the standard input if the filename argument is omitted.

+

Copy Generation

+

The copies argument specifies the number of copies to produce +of the input file. In general, you should only generate copies if the +filename argument is supplied. The only exception to this are +filters that produce device-independent PostScript output (without any +printer commands from the printer's PPD file), since the PostScript +filter pstops is responsible for copy generation.

+

Environment Variables

+

Every filter receives a fixed set of environment variables that can +be used by the filter:

+
    +
  • CHARSET - The character set used by the client for + this print file
  • +
  • CONTENT_TYPE - The original document type, such as + "application/postscript"
  • +
  • CUPS_DATADIR - The location of CUPS data files
  • +
  • CUPS_SERVERROOT - The location of CUPS configuration + files
  • +
  • DEVICE_URI - The output device URI
  • +
  • LANG - The language used by the client for this print +file
  • +
  • PATH - The execution path exported to the filter
  • +
  • PPD - The full filename of the printer's PPD file
  • +
  • PRINTER - The name of the printer queue
  • +
  • RIP_CACHE - The maximum amount of memory each filter + should use
  • +
  • SOFTWARE - The name of the CUPS software, typically + "CUPS/1.1"
  • +
  • TZ - The local timezone
  • +
  • USER - The name of the current user
  • +
+

Dissecting the HP-GL/2 Filter

+

The HP-GL/2 filter (hpgltops) provided with CUPS is a +complex program that converts HP-GL/2 files into device-independent +PostScript output. Since it produces device-independent PostScript +output, it does not need to handle copy generation or writing printer +options from the printer's PPD file.

+

Initializing the Filter

+

The first task of any filter is to ensure that the correct number of +command-line arguments are present:

+
    +
    +if (argc < 6 || argc > 7)
    +{
    +  fputs("ERROR: hpgltops job-id user title copies options [file]\n", stderr);
    +  return (1);
    +}
    +
    +
+

After this you open the print file or read from the standard input +as needed:

+
    +
    +FILE *fp;
    +
    +/*
    + * If we have 7 arguments, print the file named on the command-line.
    + * Otherwise, send stdin instead...
    + */
    +
    +if (argc == 6)
    +  fp = stdin;
    +else
    +{
    + /*
    +  * Try to open the print file...
    +  */
    +
    +  if ((fp = fopen(argv[6], "rb")) == NULL)
    +  {
    +    perror("ERROR: unable to open print file - ");
    +    return (1);
    +  }
    +}
    +
    +
+

Once the print file has been opened, options can be processed using +the cupsParseOptions() and cupsGetOption() functions:

+
    +
    +int           num_options;
    +cups_option_t *options;
    +const char    *val;
    +
    +/*
    + * Process command-line options and write the prolog...
    + */
    +
    +options     = NULL;
    +num_options = cupsParseOptions(argv[5], 0, 
    +
    +if ((val = cupsGetOption("blackplot", num_options, options)) != NULL)
    +  shading = 0;
    +
    +if ((val = cupsGetOption("fitplot", num_options, options)) != NULL)
    +  FitPlot = 1;
    +
    +if ((val = cupsGetOption("penwidth", num_options, options)) != NULL)
    +  PenWidth = (float)atoi(val) * 0.001f;
    +
    +
+

After the options have been processed, the filter writes PostScript +code to the standard output based on the print file, closes the print +file (as needed), and returns 0 to the scheduler.

+

PostScript Output

+

Filters that produce PostScript output must generate output +conforming to the Adobe Document Structuring Conventions, 3.0. In +general this means the beginning of each file must begin with:

+
    +
    +%!PS-Adobe-3.0
    +%%BoundingBox: left bottom right top
    +%%Pages: (atend)
    +%%EndComments
    +
    +
+

The left, bottom, right, and top values +are integers in points from the lower-lefthand corner of the page.

+

Pages must be surrounded by:

+
    +
    +%%Page: number number
    +gsave
    +...
    +grestore
    +showpage
    +
    +
+

And the end of each file must contain:

+
    +
    +%%Trailer
    +%%Pages: number-pages
    +%%EOF
    +
    +
+

These comments allow the PostScript filter to correctly perform page +accounting, copy generation, N-up printing, and so forth.

+

4 - Writing Printer Drivers +

+

This chapter discusses how to write a printer driver, which is a +special filter program that converts CUPS raster data into the +appropriate commands and data required for a printer.

+

Overview

+

Raster printers utilitize PPD files that specify one or more +device-specific filters that handle converting print files for the +printer. The simplest raster printer drivers provide a single filter +that converts CUPS raster data to the printer's native format.

+

CUPS Raster Data

+

CUPS raster data (application/vnd.cups-raster) consists +of a stream of raster page descriptions produced by one of the RIP +filters, such as pstoraster or imagetoraster.

+

Each page of data begins with a page dictionary structure called +cups_raster_header_t. This structure contains the +colorspace, bits per color, media size, media type, hardware +resolution, and so forth.

+

After the page dictionary comes the page data which is a +full-resolution, uncompressed bitmap representing the page in the +printer's output colorspace.

+

Page Accounting

+

Printer drivers must handle all page accounting. This means they +must send "PAGE:" messages to the standard error file for each page +(and in many cases, copy) sent to the printer.

+

Color Management

+

Printer drivers can implement their color management via the +cupsColorProfile attributes in the PPD file or internally in the +driver from a device-independent colorspace. In general, color +management performed by the RIP filters is more efficient than that +performed inside printer drivers.

+

For example, the pstoraster filter often only has to +perform a color conversion once each time the color is used for +multiple output pixels, while the raster filter must convert every +pixel on the page.

+

Device and Bitmap Variables

+

Besides the standard PostScript page device dictionary variables +defined in the Adobe PostScript Level 3 reference manual, the CUPS +filters support additional variables that are passed in the page device +dictionary header for the page and in some cases control the type of +raster data that is generated: +

+ + + + + + + + + + + + + + +
VariableTypeDescription
cupsWidthread-only integerWidth of bitmap in +pixels
cupsHeightread-only integer Height of bitmap +in pixels
cupsMediaTyperead-write integer +Device-specific media type code
cupsBitsPerColorread-write integerNumber of +bits per color; 1, 2, 4, and 8 are currently supported
cupsBitsPerPixelread-only integer Number of +bits per pixel; 1 to 32
cupsBytesPerLineread-only integerNumber of +bytes per line of raster graphics
cupsColorOrderread-write enumThe order of +color values in the bitmap: +
    +
  • CUPS_ORDER_CHUNKED - CMYK CMYK CMYK
  • +
  • CUPS_ORDER_BANDED - CCC MMM YYY KKK
  • +
  • CUPS_ORDER_PLANAR - CCC ... MMM ... YYY ... KKK ...
  • +
+
cupsColorSpaceread-write enumThe colorspace +of the bitmap: +
    +
  • CUPS_CSPACE_W - White (luminance)
  • +
  • CUPS_CSPACE_RGB - Red, green, blue
  • +
  • CUPS_CSPACE_RGBA - Red, green, blue, alpha
  • +
  • CUPS_CSPACE_K - Black
  • +
  • CUPS_CSPACE_CMY - Cyan, magenta, yellow
  • +
  • CUPS_CSPACE_YMC - Yellow, magenta, cyan
  • +
  • CUPS_CSPACE_CMYK - Cyan, magenta, yellow, black
  • +
  • CUPS_CSPACE_YMCK - Yellow, magenta, cyan, black
  • +
  • CUPS_CSPACE_KCMY - Black, cyan, magenta, yellow
  • +
  • CUPS_CSPACE_KCMYcm - Black, cyan, magenta, yellow, + light cyan, light magenta
  • +
  • CUPS_CSPACE_GMCK - Metallic yellow (gold), metallic +magenta, metallic cyan, black
  • +
  • CUPS_CSPACE_GMCS - Metallic yellow (gold), metallic +magenta, metallic cyan, metallic grey (silver)
  • +
  • CUPS_CSPACE_WHITE - White pigment (black as white +pigment)
  • +
  • CUPS_CSPACE_GOLD - Gold foil (black as gold foil)
  • +
  • CUPS_CSPACE_SILVER - Silver foil (black as silver +foil)
  • +
+
cupsCompressionread-write integer +Device-specific compression type code
cupsRowCountread-write integerDevice-specific +row count value
cupsRowFeedread-write integerDevice-specific +row feed value
cupsRowStepread-write integerDevice-specific +row step value
+
+

+

Bitmaps with a colorspace of CUPS_CSPACE_KCMYcm and more than 1 bit +per color are transmitted to the raster driver in KCMY colorspace; the +driver is responsible for producing the correct separation of normal +and light cyan and magenta inks.

+

Dissecting the HP-PCL Driver

+

The HP-PCL driver provided with CUPS (rastertohp) +converts bitmap data from the raster filters into HP-PCL commands for +most PCL-compatible printers. The actual format of the raster data is +controlled by the PPD file being used - deskjet.ppd or +laserjet.ppd.

+

PPD Files

+

PPD files play an important part of all raster printer drivers. +Options defined in the PPD file contain PostScript commands that +control the raster data that is sent to the printer driver.

+

A typical CUPS printer driver will include ColorModel, +InputSlot, PageSize, PageRegion, and +Resolution options. Each option is shown using the standard PPD +format:

+
    +
    +*OpenUI *PageSize/Media Size: PickOne
    +*OrderDependency: 10 AnySetup *PageSize
    +*DefaultPageSize: Letter
    +*PageSize Letter/US Letter: "<<
    +/PageSize [612 792]
    +/ImagingBBox null
    +>> setpagedevice"
    +*End
    +*PageSize Legal/US Legal: "<<
    +/PageSize [612 1008]
    +/ImagingBBox null
    +>> setpagedevice"
    +*End
    +*PageSize A4/A4: "<<
    +/PageSize [595 842]
    +/ImagingBBox null
    +>> setpagedevice"
    +*End
    +*CloseUI: *PageSize
    +
    +
+

The OpenUI keyword specifies the new option. The first +name is the option with an asterisk (*) in front of it. The first name +is usually followed by a slash (/) and a human-readable version of the +option name.

+

Every option must have a default value, specified using the +DefaultOption keyword.

+

Each option begins with the option name followed by the computer and +human-readable values. The PostScript commands follow these inside +double quotes. PostScript commands can be provided on a single line:

+
    +
    +*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>> setpagedevice"
    +
    +
+

or broken down on separate lines using the End keyword +to terminate them:

+
    +
    +*PageSize A4/A4: "<<
    +/PageSize [595 842]
    +/ImagingBBox null
    +>> setpagedevice"
    +*End
    +
    +
+

The choice of the two formats is usually esthetic. However, each +line in a PPD file must not exceed 255 characters, so if your +PostScript commands are long you may need to break them up on separate +lines.

+

Reading Raster Data

+

As with any filter, your printer driver should handle raster data +from a filename specified on the command-line or from the standard +input. The cupsRasterOpen() + function opens a raster stream for printing:

+
    +
    +int           fd;   /* File descriptor */
    +cups_raster_t *ras; /* Raster stream for printing */
    +
    +
    +/*
    + * Check for valid arguments...
    + */
    +
    +if (argc < 6 || argc > 7)
    +{
    + /*
    +  * We don't have the correct number of arguments; write an error message
    +  * and return.
    +  */
    +
    +  fputs("ERROR: rastertopcl job-id user title copies options [file]\n", stderr);
    +  return (1);
    +}
    +
    +/*
    + * Open the page stream...
    + */
    +
    +if (argc == 7)
    +{
    +  if ((fd = open(argv[6], O_RDONLY)) == -1)
    +  {
    +    perror("ERROR: Unable to open raster file - ");
    +    sleep(1);
    +    return (1);
    +  }
    +}
    +else
    +  fd = 0;
    +
    +ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
    +
    +
+

Once you have opened the raster stream you just need to read each +page and print it:

+
    +
    +cups_raster_header_t header;
    +int                  y;
    +unsigned char        data[8192];
    +
    +while (cupsRasterReadHeader(ras, &header))
    +{
    +  ... initialize the printer ...
    +  for (y = header.cupsHeight; y > 0; y ++)
    +  {
    +    cupsRasterReadPixels(ras, data, header.cupsBytesPerLine);
    +    ... send raster line to printer ...
    +  }
    +}
    +
    +
+

After you have processed all pages, close the raster stream and +return:

+
    +
    +cupsRasterClose(ras);
    +
    +return (0);
    +
    +
+

5 - Writing Backends

+

This chapter describes how to write a backend for CUPS. Backends +communicate directly with printers and allow printer drivers and +filters to send data using any type of connection transparently.

+

Overview

+

Backends are special filters that communicate with printers +directly. They are treated slightly differently than filters, however, +and have some unique requirements.

+

Security Considerations

+

Backends are run as the root user, so special care must be taken to +avoid potential security violations. In particular, remember that a +backend will be able to manipulate disk files, devices, and other +resources that potentially could damage a system or printer.

+

Command-Line Arguments

+

Besides the standard filter arguments, backends are also run with no +arguments to get a list of available devices. This discovery process is +described later in this chapter.

+

Copy Generation

+

Like filters, backends should send multiple copies of the print file +only if a filename is supplied on the command-line. Otherwise the +backend should assume that the upstream filter has already added the +necessary commands or data to produce the multiple copies.

+

Page Accounting

+

Backend filters generally do not do page accounting, however they +should at a minimum produce a single page message for each copy that is +produced when a filename is present on the command-line. This is +because the user selected "raw" printing and no other accounting +information is possible.

+

Exclusive Access

+

Backends that talk to local character or block devices should open +the device file in exclusive mode (O_EXCL) to cooperate +with other printers defined for the same device.

+

Retries

+

All backends must retry connections to the device. This +includes backends that talk to local character or block devices, as the +user may define more than one printer queue pointing at the same +physical device.

+

To prevent excess CPU utilitization, the backend should go to sleep +for an amount of time between retries; the CUPS-supplied backends retry +once every 30 seconds.

+

Dissecting the Serial Port Backend

+

The serial port backend provides support for serial printers. Since +it does everything a good backend needs to do, it provides an excellent +example of what to do.

+

Supporting Device Discovery

+

As previously noted, backends are special filter programs that talk +to printer devices. Another task a backend must perform is to list the +available devices it supports. The backend lists the available devices +when no additioanl arguments are supplied on the command-line (i.e. +just the command name...)

+

The serial backend lists devices by looking at serial port files in +the /dev directory, by consulting a hardware inventory +(IRIX), and in some cases by trying to open the ports to see if they +actually exist.

+

Once it finds a serial port it writes a single line for each port to +the standard error file. Each line looks like this:

+
    +
    +serial serial:/dev/ttyS0?baud=115200 "Unknown" "Serial Port 1"
    +
    +
+

The first word "serial" is the device class; this identifies +the class of device which can be used to categorize it in user +interfaces. CUPS currently recognizes the following classes:

+
    +
  • "file" - a disk file.
  • +
  • "direct" - a parallel or fixed-rate serial data port, currently +used for Centronics, IEEE-1284, and USB printer ports.
  • +
  • "serial" - a variable-rate serial port.
  • +
  • "network" - a network connection, typically via AppSocket, HTTP, +IPP, LPD, or SMB/CIFS protocols.
  • +
+

After the device class is the device URI, in this case +"serial:/dev/ttyS0?baud=115200". This is the URI that should be used by +the user to select this port. For serial ports, the "baud=115200" +specifies the maximum baud rate supported by the port - the actual +value will vary based on the speed the user selects for the printer.

+

The last two strings are the model and description for the port. The +"Unknown" string means that the printer model is unknown - some devices +are able to provide a make and model such as "HP DeskJet" that allows +users and software to choose an appropriate printer driver more easily. +Both the model and description must be enclosed inside double quotes.

+

Opening the Serial Port

+

As noted previously, all backends should open device files in +exclusive mode, and retry as needed until the port is available. The +serial port does this using a do-while loop:

+
    +
    +do
    +{
    +  if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL)) == -1)
    +  {
    +    if (errno == EBUSY)
    +    {
    +      fputs("INFO: Serial port busy; will retry in 30 seconds...\n", stderr);
    +      sleep(30);
    +    }
    +    else
    +    {
    +      perror("ERROR: Unable to open serial port device file");
    +      return (1);
    +    }
    +  }
    +}
    +while (fd < 0);
    +
    +
+

If the port is busy or in use by another process, the backend will +go to sleep for 30 seconds and try again. If another error is detected +a message is sent to the user and the backend aborts the print job +until the problem can be corrected.

+

Writing Data to the Port

+

Network and character devices pose an interesting problem when +writing data to the port - they may not be able to write all of the +bytes in your buffer before returning. To work around this problem you +must loop until all bytes have been written:

+
    +
    +while (nbytes > 0)
    +{
    +  if ((wbytes = write(fd, bufptr, nbytes)) < 0)
    +    if (errno == ENOTTY)
    +      wbytes = write(fd, bufptr, nbytes);
    +
    +  if (wbytes < 0)
    +  {
    +    perror("ERROR: Unable to send print file to printer");
    +    break;
    +  }
    +
    +  nbytes -= wbytes;
    +  bufptr += wbytes;
    +}
    +
    +
+

The check for the ENOTTY error is needed on some +platforms to clear an error from a previous ioctl() call.

+

Finishing Up

+

Once you have sent the print file, return 0 if the file printed +successfully or 1 if it did not. This will allow the scheduler to stop +the print job if there is a device error, preserving the print job for +later printing once the problem has been corrected.

+

A - Software License Agreement

+

Common UNIX Printing System License +Agreement

+

Copyright 1997-2000 by Easy Software Products +
44141 AIRPORT VIEW DR STE 204 +
HOLLYWOOD, MARYLAND 20636-3111 USA +
+
Voice: +1.301.373.9603 +
Email: cups-info@cups.org +
WWW: http://www.cups.org

+

Introduction

+

The Common UNIX Printing SystemTM, ("CUPSTM"), +is provided under the GNU General Public License ("GPL") and GNU +Library General Public License ("LGPL"), Version 2. A copy of these +licenses follow this introduction.

+

The GNU LGPL applies to the CUPS API library, located in the "cups" +subdirectory of the CUPS source distribution and in the +"/usr/include/cups" directory and "libcups.a", "libcups.sl", or +"libcups.so" files in the binary distributions.

+

The GNU GPL applies to the remainder of the CUPS distribution, +including the "pstoraster" filter which is based upon GNU Ghostscript +5.50 and the "pdftops" filter which is based upon Xpdf 0.90.

+

For those not familiar with the GNU GPL, the license basically +allows you to:

+
    +
  • Use the CUPS software at no charge.
  • +
  • Distribute verbatim copies of the software in source or binary +form.
  • +
  • Sell verbatim copies of the software for a media fee, or sell +support for the software.
  • +
  • Distribute or sell printer drivers and filters that use CUPS so +long as source code is made available under the GPL.
  • +
+

What this license does not allow you to do is make changes or +add features to CUPS and then sell a binary distribution without source +code. You must provide source for any new drivers, changes, or +additions to the software, and all code must be provided under the GPL +or LGPL as appropriate.

+

The GNU LGPL relaxes the "link-to" restriction, allowing you to +develop applications that use the CUPS API library under other licenses +and/or conditions as appropriate for your application.

+

Trademarks

+

Easy Software Products has trademarked the Common UNIX Printing +System, CUPS, and CUPS logo. These names and logos may be used freely +in any direct port or binary distribution of CUPS. To use them in +derivative products, please contract Easy Software Products for written +permission. Our intention is to protect the value of these trademarks +and ensure that any derivative product meets the same high-quality +standards as the original.

+

Binary Distribution Rights

+

Easy Software Products also sells rights to the CUPS source code +under a binary distribution license for vendors that are unable to +release source code for their drivers, additions, and modifications to +CUPS under the GNU GPL and LGPL. For information please contact us at +the address shown above.

+

The Common UNIX Printing System provides a "pstoraster" filter that +utilizes the GNU GhostScript 5.50 core to convert PostScript files into +a stream of raster images. For binary distribution licensing of this +software, please contact:

Miles Jones +
Director of Marketing +
Artifex Software Inc. +
454 Las Gallinas Ave., Suite 108 +
San Rafael, CA 94903 USA +
Voice: +1.415.492.9861 +
Fax: +1.415.492.9862 +
EMail: info@arsoft.com
+

+

The "pdftops" filter is based on the Xpdf 0.90 software. For binary +distribution licensing of this software, please contact:

+ Derek B. Noonburg +
Email: derekn@foolabs.com +
WWW: +http://www.foolabs.com/xpdf/

+

Support

+

Easy Software Products sells software support for CUPS as well as a +commercial printing product based on CUPS called ESP Print Pro. You can +find out more at our web site:

+ + + +

GNU GENERAL PUBLIC LICENSE

+

Version 2, June 1991

+
+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+
+
+
+
+

Preamble

+

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too.

+

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things.

+

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it.

+

For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights.

+

We protect your rights with two steps: (1) copyright the software, +and (2) offer you this license which gives you legal permission to +copy, distribute and/or modify the software.

+

Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, +we want its recipients to know that what they have is not the original, +so that any problems introduced by others will not reflect on the +original authors' reputations.

+

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all.

+

The precise terms and conditions for copying, distribution and +modification follow.

+

GNU GENERAL PUBLIC LICENSE +
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+
    +
  1. This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you".
  2. +

    Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does.

    +
  3. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy an appropriate copyright notice +and disclaimer of warranty; keep intact all the notices that refer to +this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the +Program.
  4. +

    You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee.

    +
  5. You may modify your copy or copies of the Program or any portion of +it, thus forming a work based on the Program, and copy and distribute +such modifications or work under the terms of Section 1 above, provided +that you also meet all of these conditions: +
      +
    1. You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change.
    2. +
    3. You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any part +thereof, to be licensed as a whole at no charge to all third parties +under the terms of this License.
    4. +
    5. if the modified program normally reads commands interactively when +run, you must cause it, when started running for such interactive use +in the most ordinary way, to print or display an announcement including +an appropriate copyright notice and a notice that there is no warranty +(or else, saying that you provide a warranty) and that users may +redistribute the program under these conditions, and telling the user +how to view a copy of this License. (Exception: if the Program itself +is interactive but does not normally print such an announcement, your +work based on the Program is not required to print an announcement.)
    6. +
    +
  6. +

    These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it.

    +

    Thus, it is not the intent of this section to claim rights or +contest your rights to work written entirely by you; rather, the intent +is to exercise the right to control the distribution of derivative or +collective works based on the Program.

    +

    In addition, mere aggregation of another work not based on the +Program with the Program (or with a work based on the Program) on a +volume of a storage or distribution medium does not bring the other +work under the scope of this License.

    +
  7. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: +
      +
    1. Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections 1 +and 2 above on a medium customarily used for software interchange; or,
    2. +
    3. Accompany it with a written offer, valid for at least three years, +to give any third party, for a charge no more than your cost of +physically performing source distribution, a complete machine-readable +copy of the corresponding source code, to be distributed under the +terms of Sections 1 and 2 above on a medium customarily used for +software interchange; or,
    4. +
    5. Accompany it with the information you received as to the offer to +distribute corresponding source code. (This alternative is allowed +only for noncommercial distribution and only if you received the +program in object code or executable form with such an offer, in accord +with Subsection b above.)
    6. +
    +
  8. +

    The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that +is normally distributed (in either source or binary form) with the +major components (compiler, kernel, and so on) of the operating system +on which the executable runs, unless that component itself accompanies +the executable.

    +

    If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent access +to copy the source code from the same place counts as distribution of +the source code, even though third parties are not compelled to copy +the source along with the object code.

    +
  9. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such parties +remain in full compliance.
  10. +
  11. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying the +Program or works based on it.
  12. +
  13. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License.
  14. +
  15. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program.
  16. +

    If any portion of this section is held invalid or unenforceable +under any particular circumstance, the balance of the section is +intended to apply and the section as a whole is intended to apply in +other circumstances.

    +

    It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice.

    +

    This section is intended to make thoroughly clear what is believed +to be a consequence of the rest of this License.

    +
  17. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License may +add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among countries +not thus excluded. In such case, this License incorporates the +limitation as if written in the body of this License.
  18. +
  19. The Free Software Foundation may publish revised and/or new +versions of the General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns.
  20. +

    Each version is given a distinguishing version number. If the +Program specifies a version number of this License which applies to it +and "any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a +version number of this License, you may choose any version ever +published by the Free Software Foundation.

    +
  21. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally.
  22. +
+

NO WARRANTY

+
    +
  1. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. + EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS +WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  2. +
  3. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES.
  4. +
+

END OF TERMS AND CONDITIONS

+ + +

GNU LIBRARY GENERAL PUBLIC LICENSE

+

Version 2, June 1991

+
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+

Preamble

+

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users.

+

This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too.

+

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things.

+

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the library, or if you modify it.

+

For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights.

+

Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library.

+

Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations.

+

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all.

+

Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License, which was designed for utility +programs. This license, the GNU Library General Public License, +applies to certain designated libraries. This license is quite +different from the ordinary one; be sure to read it in full, and don't +assume that anything in it is the same as in the ordinary license.

+

The reason we have a separate public license for some libraries is +that they blur the distinction we usually make between modifying or +adding to a program and simply using it. Linking a program with a +library, without changing the library, is in some sense simply using +the library, and is analogous to running a utility program or +application program. However, in a textual and legal sense, the linked +executable is a combined work, a derivative of the original library, +and the ordinary General Public License treats it as such.

+

Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better.

+

However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended +to permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to +achieve this as regards changes in header files, but we have achieved +it as regards changes in the actual functions of the Library.) The +hope is that this will lead to faster development of free libraries.

+

The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library.

+

Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one.

+

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+

0. This License Agreement applies to any software +library which contains a notice placed by the copyright holder or other +authorized party saying it may be distributed under the terms of this +Library General Public License (also called "this License"). Each +licensee is addressed as "you".

+

A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables.

+

The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".)

+

"Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library.

+

Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does and +what the program that uses the Library does.

+

1. You may copy and distribute verbatim copies of +the Library's complete source code as you receive it, in any medium, +provided that you conspicuously and appropriately publish on each copy +an appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the Library.

+

You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee.

+

2. You may modify your copy or copies of the +Library or any portion of it, thus forming a work based on the Library, +and copy and distribute such modifications or work under the terms of +Section 1 above, provided that you also meet all of these conditions:

+
    +
  1. The modified work must itself be a software library.
  2. +

    +

  3. You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change.
  4. +

    +

  5. You must cause the whole of the work to be licensed at no charge +to all third parties under the terms of this License.
  6. +

    +

  7. If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses the +facility, other than as an argument passed when the facility is +invoked, then you must make a good faith effort to ensure that, in the +event an application does not supply such function or table, the +facility still operates, and performs whatever part of its purpose +remains meaningful.
  8. +

    (For example, a function in a library to compute square roots has a +purpose that is entirely well-defined independent of the application. + Therefore, Subsection 2d requires that any application-supplied +function or table used by this function must be optional: if the +application does not supply it, the square root function must still +compute square roots.)

    +
+

These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it.

+

Thus, it is not the intent of this section to claim rights or +contest your rights to work written entirely by you; rather, the intent +is to exercise the right to control the distribution of derivative or +collective works based on the Library.

+

In addition, mere aggregation of another work not based on the +Library with the Library (or with a work based on the Library) on a +volume of a storage or distribution medium does not bring the other +work under the scope of this License.

+

3. You may opt to apply the terms of the ordinary +GNU General Public License instead of this License to a given copy of +the Library. To do this, you must alter all the notices that refer to +this License, so that they refer to the ordinary GNU General Public +License, version 2, instead of to this License. (If a newer version +than version 2 of the ordinary GNU General Public License has appeared, +then you can specify that version instead if you wish.) Do not make +any other change in these notices.

+

Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy.

+

This option is useful when you wish to copy part of the code of the +Library into a program that is not a library.

+

4. You may copy and distribute the Library (or a +portion or derivative of it, under Section 2) in object code or +executable form under the terms of Sections 1 and 2 above provided that +you accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections 1 +and 2 above on a medium customarily used for software interchange.

+

If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to distribute +the source code, even though third parties are not compelled to copy +the source along with the object code.

+

5. A program that contains no derivative of any +portion of the Library, but is designed to work with the Library by +being compiled or linked with it, is called a "work that uses the +Library". Such a work, in isolation, is not a derivative work of the +Library, and therefore falls outside the scope of this License.

+

However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. Section +6 states terms for distribution of such executables.

+

When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law.

+

If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.)

+

Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, whether +or not they are linked directly with the Library itself.

+

6. As an exception to the Sections above, you may +also compile or link a "work that uses the Library" with the Library to +produce a work containing portions of the Library, and distribute that +work under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications.

+

You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things:

+
    +
  1. Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that uses +the Library", as object code and/or source code, so that the user can +modify the Library and then relink to produce a modified executable +containing the modified Library. (It is understood that the user who +changes the contents of definitions files in the Library will not +necessarily be able to recompile the application to use the modified +definitions.)
  2. +

    +

  3. Accompany the work with a written offer, valid for at least three +years, to give the same user the materials specified in Subsection 6a, +above, for a charge no more than the cost of performing this +distribution.
  4. +

    +

  5. If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place.
  6. +

    +

  7. Verify that the user has already received a copy of these + materials or that you have already sent this user a copy.
  8. +
+

For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major components +(compiler, kernel, and so on) of the operating system on which the +executable runs, unless that component itself accompanies the +executable.

+

It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute.

+

7. You may place library facilities that are a work +based on the Library side-by-side in a single library together with +other library facilities not covered by this License, and distribute +such a combined library, provided that the separate distribution of the +work based on the Library and of the other library facilities is +otherwise permitted, and provided that you do these two things:

+
    +
  1. Accompany the combined library with a copy of the same work based +on the Library, uncombined with any other library facilities. This +must be distributed under the terms of the Sections above.
  2. +

    +

  3. Give prominent notice with the combined library of the fact that +part of it is a work based on the Library, and explaining where to +find the accompanying uncombined form of the same work.
  4. +
+

8. You may not copy, modify, sublicense, link with, +or distribute the Library except as expressly provided under this +License. Any attempt otherwise to copy, modify, sublicense, link with, +or distribute the Library is void, and will automatically terminate +your rights under this License. However, parties who have received +copies, or rights, from you under this License will not have their +licenses terminated so long as such parties remain in full compliance.

+

9. You are not required to accept this License, +since you have not signed it. However, nothing else grants you +permission to modify or distribute the Library or its derivative works. + These actions are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Library (or any work based +on the Library), you indicate your acceptance of this License to do so, +and all its terms and conditions for copying, distributing or modifying +the Library or works based on it.

+

10. Each time you redistribute the Library (or any +work based on the Library), the recipient automatically receives a +license from the original licensor to copy, distribute, link with or +modify the Library subject to these terms and conditions. You may not +impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance +by third parties to this License.

+

11. If, as a consequence of a court judgment or +allegation of patent infringement or for any other reason (not limited +to patent issues), conditions are imposed on you (whether by court +order, agreement or otherwise) that contradict the conditions of this +License, they do not excuse you from the conditions of this License. + If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, +then as a consequence you may not distribute the Library at all. For +example, if a patent license would not permit royalty-free +redistribution of the Library by all those who receive copies directly +or indirectly through you, then the only way you could satisfy both it +and this License would be to refrain entirely from distribution of the +Library.

+

If any portion of this section is held invalid or unenforceable +under any particular circumstance, the balance of the section is +intended to apply, and the section as a whole is intended to apply in +other circumstances.

+

It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is implemented +by public license practices. Many people have made generous +contributions to the wide range of software distributed through that +system in reliance on consistent application of that system; it is up +to the author/donor to decide if he or she is willing to distribute +software through any other system and a licensee cannot impose that +choice.

+

This section is intended to make thoroughly clear what is believed +to be a consequence of the rest of this License.

+

12. If the distribution and/or use of the Library +is restricted in certain countries either by patents or by copyrighted +interfaces, the original copyright holder who places the Library under +this License may add an explicit geographical distribution limitation +excluding those countries, so that distribution is permitted only in or +among countries not thus excluded. In such case, this License +incorporates the limitation as if written in the body of this License.

+

13. The Free Software Foundation may publish +revised and/or new versions of the Library General Public License from +time to time. Such new versions will be similar in spirit to the +present version, but may differ in detail to address new problems or +concerns.

+

Each version is given a distinguishing version number. If the +Library specifies a version number of this License which applies to it +and "any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation.

+

14. If you wish to incorporate parts of the Library +into other free programs whose distribution conditions are incompatible +with these, write to the author to ask for permission. For software +which is copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally.

+

NO WARRANTY

+

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, +THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT +WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU +ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

+

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW +OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY +WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE +LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL +OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES.

+

END OF TERMS AND CONDITIONS

+

B - Constants

+

This appendix lists all of the constants that are defined by the +CUPS API.

+

CUPS Constants

+

Version Number

+

The CUPS_VERSION constant is a floating-point number +representing the API version number. The current version number is +1.0100 which represents CUPS version 1.1.0.

+

Printer Capabilities

+

The CUPS_PRINTER constants represent capability bits +for printers and classes:

+
    +
  • CUPS_PRINTER_LOCAL - Is a local printer or class.
  • +
  • CUPS_PRINTER_REMOTE - Is a remote printer or class.
  • +
  • CUPS_PRINTER_CLASS - Is a class.
  • +
  • CUPS_PRINTER_BW - Printer prints in black and white.
  • +
  • CUPS_PRINTER_COLOR - Printer prints in color.
  • +
  • CUPS_PRINTER_DUPLEX - Printer can print double-sided.
  • +
  • CUPS_PRINTER_STAPLE - Printer can staple output.
  • +
  • CUPS_PRINTER_COPIES - Printer can produce multiple + copies on its own.
  • +
  • CUPS_PRINTER_COLLATE - Printer can collate copies.
  • +
  • CUPS_PRINTER_PUNCH - Printer can punch holes in +output.
  • +
  • CUPS_PRINTER_COVER - Printer can put covers on output.
  • +
  • CUPS_PRINTER_BIND - Printer can bind output.
  • +
  • CUPS_PRINTER_SORT - Printer can sort output.
  • +
  • CUPS_PRINTER_SMALL - Printer can print on media up to +9x14 inches.
  • +
  • CUPS_PRINTER_MEDIUM - Printer can print on media from +9x14 to 18x24 inches.
  • +
  • CUPS_PRINTER_LARGE - Printer can print on media + larger than 18x24 inches.
  • +
  • CUPS_PRINTER_VARIABLE - Printer can print on variable +or custom media sizes.
  • +
  • CUPS_PRINTER_IMPLICIT - Is an implicit class.
  • +
  • CUPS_PRINTER_OPTIONS - All of the printer capability + and option bits.
  • +
+

Encodings

+

CUPS defines the following character set encoding constants:

+
    +
  • CUPS_US_ASCII - US ASCII character set.
  • +
  • CUPS_UTF_8 - UTF-8 encoding of Unicode.
  • +
  • CUPS_ISO8859_1 - ISO-8859-1 character set.
  • +
  • CUPS_ISO8859_2 - ISO-8859-2 character set.
  • +
  • CUPS_ISO8859_3 - ISO-8859-3 character set.
  • +
  • CUPS_ISO8859_4 - ISO-8859-4 character set.
  • +
  • CUPS_ISO8859_5 - ISO-8859-5 character set.
  • +
  • CUPS_ISO8859_6 - ISO-8859-6 character set.
  • +
  • CUPS_ISO8859_7 - ISO-8859-7 character set.
  • +
  • CUPS_ISO8859_8 - ISO-8859-8 character set.
  • +
  • CUPS_ISO8859_9 - ISO-8859-9 character set.
  • +
  • CUPS_ISO8859_10 - ISO-8859-10 character set.
  • +
  • CUPS_ISO8859_13 - ISO-8859-13 character set.
  • +
  • CUPS_ISO8859_14 - ISO-8859-14 character set.
  • +
  • CUPS_ISO8859_15 - ISO-8859-15 character set.
  • +
  • CUPS_WINDOWS_874 - Windows code page 874.
  • +
  • CUPS_WINDOWS_1250 - Windows code page 1250.
  • +
  • CUPS_WINDOWS_1251 - Windows code page 1251.
  • +
  • CUPS_WINDOWS_1252 - Windows code page 1252.
  • +
  • CUPS_WINDOWS_1253 - Windows code page 1253.
  • +
  • CUPS_WINDOWS_1254 - Windows code page 1254.
  • +
  • CUPS_WINDOWS_1255 - Windows code page 1255.
  • +
  • CUPS_WINDOWS_1256 - Windows code page 1256.
  • +
  • CUPS_WINDOWS_1257 - Windows code page 1257.
  • +
  • CUPS_WINDOWS_1258 - Windows code page 1258.
  • +
+

HTTP Constants

+

Limits

+

The following constants define the limits for strings:

+
    +
  • HTTP_MAX_BUFFER - Size of socket buffer.
  • +
  • HTTP_MAX_HOST - Maximum length of hostname.
  • +
  • HTTP_MAX_URI - Maximum length of URI.
  • +
  • HTTP_MAX_VALUE - Maximum length of field values.
  • +
+

Status Codes

+

The following status codes can be returned by httpUpdate() +:

+
    +
  • HTTP_ERROR - A network error occurred
  • +
  • HTTP_CONTINUE - Continue response from HTTP proxy
  • +
  • HTTP_OK - OPTIONS/GET/HEAD/POST/TRACE command was +successful
  • +
  • HTTP_CREATED - PUT command was successful
  • +
  • HTTP_ACCEPTED - DELETE command was successful
  • +
  • HTTP_NOT_AUTHORITATIVE - Information isn't +authoritative
  • +
  • HTTP_NO_CONTENT - Successful command
  • +
  • HTTP_RESET_CONTENT - Content was reset/recreated
  • +
  • HTTP_PARTIAL_CONTENT - Only a partial file was +recieved/sent
  • +
  • HTTP_MULTIPLE_CHOICES - Multiple files match request
  • +
  • HTTP_MOVED_PERMANENTLY - Document has moved +permanently
  • +
  • HTTP_MOVED_TEMPORARILY - Document has moved +temporarily
  • +
  • HTTP_SEE_OTHER - See this other link...
  • +
  • HTTP_NOT_MODIFIED - File not modified
  • +
  • HTTP_USE_PROXY - Must use a proxy to access this URI
  • +
  • HTTP_BAD_REQUEST - Bad request
  • +
  • HTTP_UNAUTHORIZED - Unauthorized to access host
  • +
  • HTTP_PAYMENT_REQUIRED - Payment required
  • +
  • HTTP_FORBIDDEN - Forbidden to access this URI
  • +
  • HTTP_NOT_FOUND - URI was not found
  • +
  • HTTP_METHOD_NOT_ALLOWED - Method is not allowed
  • +
  • HTTP_NOT_ACCEPTABLE - Not Acceptable
  • +
  • HTTP_PROXY_AUTHENTICATION - Proxy Authentication is +Required
  • +
  • HTTP_REQUEST_TIMEOUT - Request timed out
  • +
  • HTTP_CONFLICT - Request is self-conflicting
  • +
  • HTTP_GONE - Server has gone away
  • +
  • HTTP_LENGTH_REQUIRED - A content length or encoding is +required
  • +
  • HTTP_PRECONDITION - Precondition failed
  • +
  • HTTP_REQUEST_TOO_LARGE - Request entity too large
  • +
  • HTTP_URI_TOO_LONG - URI too long
  • +
  • HTTP_UNSUPPORTED_MEDIATYPE - The requested media type +is unsupported
  • +
  • HTTP_SERVER_ERROR - Internal server error
  • +
  • HTTP_NOT_IMPLEMENTED - Feature not implemented
  • +
  • HTTP_BAD_GATEWAY - Bad gateway
  • +
  • HTTP_SERVICE_UNAVAILABLE - Service is unavailable
  • +
  • HTTP_GATEWAY_TIMEOUT - Gateway connection timed out
  • +
  • HTTP_NOT_SUPPORTED - HTTP version not supported
  • +
+

Fields

+

The following fields are indices for each of the standard HTTP +fields in HTTP 1/1:

+
    +
  • HTTP_FIELD_ACCEPT_LANGUAGE - Accept-Language
  • +
  • HTTP_FIELD_ACCEPT_RANGES - Accept-Ranges
  • +
  • HTTP_FIELD_AUTHORIZATION - Authorization
  • +
  • HTTP_FIELD_CONNECTION - Connection
  • +
  • HTTP_FIELD_CONTENT_ENCODING - Content-Encoding
  • +
  • HTTP_FIELD_CONTENT_LANGUAGE - Content-Language
  • +
  • HTTP_FIELD_CONTENT_LENGTH - Content-Length
  • +
  • HTTP_FIELD_CONTENT_LOCATION - Content-Location
  • +
  • HTTP_FIELD_CONTENT_MD5 - Content-MD5
  • +
  • HTTP_FIELD_CONTENT_RANGE - Content-Range
  • +
  • HTTP_FIELD_CONTENT_TYPE - Content-Type
  • +
  • HTTP_FIELD_CONTENT_VERSION - Content-Version
  • +
  • HTTP_FIELD_DATE - Date
  • +
  • HTTP_FIELD_HOST - Host
  • +
  • HTTP_FIELD_IF_MODIFIED_SINCE - If-Modified-Since
  • +
  • HTTP_FIELD_IF_UNMODIFIED_SINCE - If-Unmodified-Since
  • +
  • HTTP_FIELD_KEEP_ALIVE - Keep-Alive
  • +
  • HTTP_FIELD_LAST_MODIFIED - Last-Modified
  • +
  • HTTP_FIELD_LINK - Link
  • +
  • HTTP_FIELD_LOCATION - Location
  • +
  • HTTP_FIELD_RANGE - Range
  • +
  • HTTP_FIELD_REFERER - Referer
  • +
  • HTTP_FIELD_RETRY_AFTER - Retry-After
  • +
  • HTTP_FIELD_TRANSFER_ENCODING - Transfer-Encoding
  • +
  • HTTP_FIELD_UPGRADE - Upgrade
  • +
  • HTTP_FIELD_USER_AGENT - User-Agent
  • +
  • HTTP_FIELD_WWW_AUTHENTICATE - WWW-Authenticate
  • +
+

IPP Constants

+

Limits

+

The following constants define array limits for IPP data:

+
    +
  • IPP_MAX_NAME - Maximum length of an attribute name
  • +
  • IPP_MAX_VALUES - Maximum number of set-of values that +can be read in a request.
  • +
+

Tags

+
    +
  • IPP_TAG_ZERO - Wildcard tag value for searches; also + used to separate groups of attributes
  • +
  • IPP_TAG_OPERATION - Tag for values of type operation
  • +
  • IPP_TAG_JOB - Tag for values of type job
  • +
  • IPP_TAG_END - Tag for values of type end
  • +
  • IPP_TAG_PRINTER - Tag for values of type printer
  • +
  • IPP_TAG_UNSUPPORTED_GROUP - Tag for values of type +unsupported_group
  • +
  • IPP_TAG_UNSUPPORTED_VALUE - Tag for values of type +unsupported_value
  • +
  • IPP_TAG_DEFAULT - Tag for values of type default
  • +
  • IPP_TAG_UNKNOWN - Tag for values of type unknown
  • +
  • IPP_TAG_NOVALUE - Tag for values of type novalue
  • +
  • IPP_TAG_NOTSETTABLE - Tag for values of type +notsettable
  • +
  • IPP_TAG_DELETEATTR - Tag for values of type deleteattr
  • +
  • IPP_TAG_ANYVALUE - Tag for values of type anyvalue
  • +
  • IPP_TAG_INTEGER - Tag for values of type integer
  • +
  • IPP_TAG_BOOLEAN - Tag for values of type boolean
  • +
  • IPP_TAG_ENUM - Tag for values of type enum
  • +
  • IPP_TAG_STRING - Tag for values of type string
  • +
  • IPP_TAG_DATE - Tag for values of type date
  • +
  • IPP_TAG_RESOLUTION - Tag for values of type resolution
  • +
  • IPP_TAG_RANGE - Tag for values of type range
  • +
  • IPP_TAG_COLLECTION - Tag for values of type collection
  • +
  • IPP_TAG_TEXTLANG - Tag for values of type textlang
  • +
  • IPP_TAG_NAMELANG - Tag for values of type namelang
  • +
  • IPP_TAG_TEXT - Tag for values of type text
  • +
  • IPP_TAG_NAME - Tag for values of type name
  • +
  • IPP_TAG_KEYWORD - Tag for values of type keyword
  • +
  • IPP_TAG_URI - Tag for values of type uri
  • +
  • IPP_TAG_URISCHEME - Tag for values of type urischeme
  • +
  • IPP_TAG_CHARSET - Tag for values of type charset
  • +
  • IPP_TAG_LANGUAGE - Tag for values of type language
  • +
  • IPP_TAG_MIMETYPE - Tag for values of type mimetype
  • +
+

Resolution Units

+

The IPP_RES_PER_INCH and IPP_RES_PER_CM + constants specify dots per inch and dots per centimeter, respectively.

+

Finishings

+

The finishing values specify special finishing operations to be +performed on the job.

+
    +
  • IPP_FINISH_NONE - Do no finishing
  • +
  • IPP_FINISH_STAPLE - Staple the job
  • +
  • IPP_FINISH_PUNCH - Punch the job
  • +
  • IPP_FINISH_COVER - Cover the job
  • +
  • IPP_FINISH_BIND - Bind the job
  • +
+

Orientations

+

The orientation values specify the orientation of the job.

+
    +
  • IPP_PORTRAIT - No rotation
  • +
  • IPP_LANDSCAPE - 90 degrees counter-clockwise
  • +
  • IPP_REVERSE_LANDSCAPE - 90 degrees clockwise
  • +
  • IPP_REVERSE_PORTRAIT - 180 degrees
  • +
+

Qualities

+

The quality values specify the desired quality of the print.

+
    +
  • IPP_QUALITY_DRAFT - Draft quality
  • +
  • IPP_QUALITY_NORMAL - Normal quality
  • +
  • IPP_QUALITY_HIGH - High quality
  • +
+

Job States

+

The job state values are used to represent the current job state.

+
    +
  • IPP_JOB_PENDING - Job is pending
  • +
  • IPP_JOB_HELD - Job is held
  • +
  • IPP_JOB_PROCESSING - Job is processing
  • +
  • IPP_JOB_STOPPED - Job is stopped
  • +
  • IPP_JOB_CANCELLED - Job is cancelled
  • +
  • IPP_JOB_ABORTED - Job is aborted
  • +
  • IPP_JOB_COMPLETED - Job is completed
  • +
+

Printer States

+

The printer state values are used to represent the current printer +state.

+
    +
  • IPP_PRINTER_IDLE - Printer is idle
  • +
  • IPP_PRINTER_PROCESSING - Printer is processing
  • +
  • IPP_PRINTER_STOPPED - Printer is stopped
  • +
+

Operations

+

The operation values represent the available IPP operations.

+
    +
  • IPP_PRINT_JOB - Print a file
  • +
  • IPP_PRINT_URI - Print a URI
  • +
  • IPP_VALIDATE_JOB - Validate job attributes
  • +
  • IPP_CREATE_JOB - Create a new job
  • +
  • IPP_SEND_DOCUMENT - Send a document to a job
  • +
  • IPP_SEND_URI - Send a URI to a job
  • +
  • IPP_CANCEL_JOB - Cancel a job
  • +
  • IPP_GET_JOB_ATTRIBUTES - Get job attributes
  • +
  • IPP_GET_JOBS - Get a list of all jobs
  • +
  • IPP_GET_PRINTER_ATTRIBUTES - Get printer attributes
  • +
  • IPP_HOLD_JOB - Hold a pending job
  • +
  • IPP_RELEASE_JOB - Release a held job
  • +
  • IPP_RESTART_JOB - Restart a completed job
  • +
  • IPP_PAUSE_PRINTER - Pause a printer
  • +
  • IPP_RESUME_PRINTER - Restart a paused printer
  • +
  • IPP_PURGE_JOBS - Purge jobs from the queue
  • +
  • IPP_SET_PRINTER_ATTRIBUTES - Set printer attributes
  • +
  • IPP_SET_JOB_ATTRIBUTES - Set job attributes
  • +
  • IPP_GET_PRINTER_SUPPORTED_VALUES - Get printer +supported values
  • +
  • CUPS_GET_DEFAULT - Get the default destination
  • +
  • CUPS_GET_PRINTERS - Get a list of all printers
  • +
  • CUPS_ADD_PRINTER - Add or modify a printer
  • +
  • CUPS_DELETE_PRINTER - Delete a printer
  • +
  • CUPS_GET_CLASSES - Get a list of all classes
  • +
  • CUPS_ADD_CLASS - Add or modify a class
  • +
  • CUPS_DELETE_CLASS - Delete a class
  • +
  • CUPS_ACCEPT_JOBS - Accept jobs on a printer or class
  • +
  • CUPS_REJECT_JOBS - Reject jobs on a printer or class
  • +
  • CUPS_SET_DEFAULT - Set the default destination
  • +
  • CUPS_GET_DEVICES - Get a list of all devices
  • +
  • CUPS_GET_PPDS - Get a list of all PPDs
  • +
  • CUPS_MOVE_JOB - Move a job to a new destination
  • +
+

Status Codes

+

Status codes are returned by all IPP requests.

+
    +
  • IPP_OK - Request completed with no errors
  • +
  • IPP_OK_SUBST - Request completed but some attribute + values were substituted
  • +
  • IPP_OK_CONFLICT - Request completed but some +attributes conflicted
  • +
  • IPP_BAD_REQUEST - The request was bad
  • +
  • IPP_FORBIDDEN - You don't have access to the resource
  • +
  • IPP_NOT_AUTHENTICATED - You are not authenticated for + the resource
  • +
  • IPP_NOT_AUTHORIZED - You not authorized to access the +resource
  • +
  • IPP_NOT_POSSIBLE - The requested operation cannot be + completed
  • +
  • IPP_TIMEOUT - A timeout occurred
  • +
  • IPP_NOT_FOUND - The resource was not found
  • +
  • IPP_GONE - The resource has gone away
  • +
  • IPP_REQUEST_ENTITY - The request was too large
  • +
  • IPP_REQUEST_VALUE - The request contained a value + that was unknown to the server
  • +
  • IPP_DOCUMENT_FORMAT - The document format is not + supported by the server
  • +
  • IPP_ATTRIBUTES - Required attributes are missing
  • +
  • IPP_URI_SCHEME - The URI scheme is not supported
  • +
  • IPP_CHARSET - The charset is not supported
  • +
  • IPP_CONFLICT - One or more attributes conflict
  • +
  • IPP_COMPRESSION_NOT_SUPPORTED - The specified + compression is not supported
  • +
  • IPP_COMPRESSION_ERROR - The compressed data contained +an error
  • +
  • IPP_DOCUMENT_FORMAT_ERROR - The document data + contained an error in it
  • +
  • IPP_DOCUMENT_ACCESS_ERROR - The remote document could +not be accessed
  • +
  • IPP_INTERNAL_ERROR - The server encountered an + internal error
  • +
  • IPP_OPERATION_NOT_SUPPORTED - The requested operation + is not supported
  • +
  • IPP_SERVICE_UNAVAILABLE - The requested service is +unavailable
  • +
  • IPP_VERSION_NOT_SUPPORTED - The IPP request version +is not supported
  • +
  • IPP_DEVICE_ERROR - The output device encountered an +error
  • +
  • IPP_TEMPORARY_ERROR - A temporary error occurred
  • +
  • IPP_NOT_ACCEPTING - The destination is not accepting + jobs
  • +
  • IPP_PRINTER_BUSY - The destination is busy
  • +
  • IPP_ERROR_JOB_CANCELLED - The requested job has been + cancelled
  • +
  • IPP_MULTIPLE_JOBS_NOT_SUPPORTED - The server does not +support multiple jobs
  • +
+

PPD Constants

+

PPD Format Version

+

The PPD_VERSION constant defines a floating point +number representing the newest format version that is supported by +CUPS, currently 4.3.

+

PPD User-Interface Types

+

Each printer option has a type associated with it:

+
    +
  • PPD_UI_BOOLEAN - The user can turn this option on or +off
  • +
  • PPD_UI_PICKONE - The user can choose one option value + to use.
  • +
  • PPD_UI_PICKMANY - The user can choose zero or more + option values.
  • +
+

PPD Sections

+

Some options must be output before others, or in different sections +of the output document. The ppd_section_t enumeration +defines which section the option must be output in:

+
    +
  • PPD_ORDER_ANY - The option can be output in any of + the document, page, or prolog sections of the document
  • +
  • PPD_ORDER_DOCUMENT - The option must be output in the +DocumentSetup section of the document
  • +
  • PPD_ORDER_EXIT - The option must be output before the +document
  • +
  • PPD_ORDER_JCL - The option must be output in the job +control section of the document
  • +
  • PPD_ORDER_PAGE - The option must be output in the + PageSetup section of the document
  • +
  • PPD_ORDER_PROLOG - The option must be output in the + Prolog section of the document
  • +
+

PPD Colorspaces

+

Each printer has a default colorspace:

+
    +
  • PPD_CS_CMYK - The printer uses CMYK colors by default
  • +
  • PPD_CS_CMY - The printer uses CMY colors by default
  • +
  • PPD_CS_GRAY - The printer uses grayscale by default
  • +
  • PPD_CS_RGB - The printer uses RGB colors by default
  • +
  • PPD_CS_RGBK - The printer uses RGBK colors by default
  • +
  • PPD_CS_N - The printer uses a DeviceN colorspace by +default
  • +
+

Raster Constants

+

Raster Sync Words

+

The CUPS_RASTER_SYNC and CUPS_RASTER_REVSYNC + constants define the standard sync words at the beginning of each CUPS +raster file.

+

Raster Stream Modes

+

The CUPS_RASTER_READ and CUPS_RASTER_WRITE + constants are used with the +cupsRasterOpen() function to specify a stream for reading or +writing.

+

Raster Boolean Constants

+

The CUPS_FALSE and CUPS_TRUE constants +represent boolean values in the page header.

+

Raster Jog Values

+

The cups_jog_t enumeration defines constants for the +Jog page device dictionary variable:

+
    +
  • CUPS_JOG_NONE - Do no jogging
  • +
  • CUPS_JOG_FILE - Jog pages after each file
  • +
  • CUPS_JOG_JOB - Jog pages after each job
  • +
  • CUPS_JOG_SET - Jog pages after each set of jobs
  • +
+

Raster Orientation Values

+

The cups_orient_t enumeration defines constants for the +Orientation page device dictionary variable:

+
    +
  • CUPS_ORIENT_0 - Portrait orientation
  • +
  • CUPS_ORIENT_90 - Landscape orientation
  • +
  • CUPS_ORIENT_180 - Reverse-portrait orientation
  • +
  • CUPS_ORIENT_270 - Reverse-landscape orientation
  • +
+

Raster CutMedia Values

+

The cups_cut_t enumeration defines constants for the +CutMedia page device dictionary variable:

+
    +
  • CUPS_CUT_NONE - Do no jogging
  • +
  • CUPS_CUT_FILE - Cut pages after each file
  • +
  • CUPS_CUT_JOB - Cut pages after each job
  • +
  • CUPS_CUT_SET - Cut pages after each set of jobs
  • +
  • CUPS_CUT_PAGE - Cut each page
  • +
+

Raster AdvanceMedia Values

+

The cups_advance_t enumeration defines constants for +the AdvanceMedia page device dictionary variable:

+
    +
  • CUPS_ADVANCE_NONE - Do no jogging
  • +
  • CUPS_ADVANCE_FILE - Advance media after each file
  • +
  • CUPS_ADVANCE_JOB - Advance media after each job
  • +
  • CUPS_ADVANCE_SET - Advance media after each set of +jobs
  • +
  • CUPS_ADVANCE_PAGE - Advance media for each page
  • +
+

Raster LeadingEdge Values

+

The cups_edge_t enumeration defines constants for the +LeadingEdge page device dictionary variable:

+
    +
  • CUPS_EDGE_TOP - The top of the media is the leading + edge
  • +
  • CUPS_EDGE_RIGHT - The right of the media is the +leading edge
  • +
  • CUPS_EDGE_BOTTOM - The bottom of the media is the + leading edge
  • +
  • CUPS_EDGE_LEFT - The left of the media is the leading + edge
  • +
+

Raster Color Order Values

+

The cups_order_t enumeration defines the possible color +value orderings:

+
    +
  • CUPS_ORDER_CHUNKED - CMYK CMYK CMYK
  • +
  • CUPS_ORDER_BANDED - CCC MMM YYY KKK
  • +
  • CUPS_ORDER_PLANAR - CCC ... MMM ... YYY ... KKK ...
  • +
+

Raster Colorspace Values

+

The cups_cspace_t enumeration defines the possible +colorspaces:

+
    +
  • CUPS_CSPACE_W - White (luminance)
  • +
  • CUPS_CSPACE_RGB - Red, green, blue
  • +
  • CUPS_CSPACE_RGBA - Red, green, blue, alpha
  • +
  • CUPS_CSPACE_K - Black
  • +
  • CUPS_CSPACE_CMY - Cyan, magenta, yellow
  • +
  • CUPS_CSPACE_YMC - Yellow, magenta, cyan
  • +
  • CUPS_CSPACE_CMYK - Cyan, magenta, yellow, black
  • +
  • CUPS_CSPACE_YMCK - Yellow, magenta, cyan, black
  • +
  • CUPS_CSPACE_KCMY - Black, cyan, magenta, yellow
  • +
  • CUPS_CSPACE_KCMYcm - Black, cyan, magenta, yellow, + light cyan, light magenta
  • +
  • CUPS_CSPACE_GMCK - Metallic yellow (gold), metallic +magenta, metallic cyan, black
  • +
  • CUPS_CSPACE_GMCS - Metallic yellow (gold), metallic +magenta, metallic cyan, metallic grey (silver)
  • +
  • CUPS_CSPACE_WHITE - White pigment (black as white +pigment)
  • +
  • CUPS_CSPACE_GOLD - Gold foil (black as gold foil)
  • +
  • CUPS_CSPACE_SILVER - Silver foil (black as silver +foil)
  • +
+

C - Structures

+

This appendix describes all of the structures that are defined by +the CUPS API.

+

Raster Structures

+

Raster Page Header

+

The raster page header consists of the PostScript page device +dictionary for the page: +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MemberTypeDescription
MediaClasschar[64]The media class name
MediaColorchar[64]The media color name
MediaTypechar[64]The media type name
OutputTypechar[64]The output type name
AdvanceDistanceunsignedThe distance to +advance the media in points
AdvanceMediacups_adv_tWhen to advance the +media
Collatecups_bool_tWhether or not to produce +collated copies
CutMediacups_cut_tWhen to cut the media
Duplexcups_bool_tWhether or not to print on +both sides of the paper
HWResolutionunsigned[2]The resolution of the +page image in pixels per inch; the HWResolution[0] represents the +horizontal resolution and HWResolution[1] represents the vertical +resolution
ImagingBoundingBoxunsigned[4]The bounding box +for the page in points; the elements represent the left, bottom, +right, and top coordinates of the imaged area (if 0 then the whole +page is imaged)
InsertSheetcups_bool_tWhether or not to +insert a sheet before this page
Jogcups_jog_tWhen to jog copies of the page
LeadingEdgecups_edge_tThe leading edge of the +page
Marginsunsigned[2]The lower-lefthand margin +of the page in points
ManualFeedcups_bool_tWhether or not to +manually feed the page
MediaPositionunsignedThe input slot number to +use
MediaWeightunsignedThe weight of the output +media in grams/m2
MirrorPrintcups_bool_tWhether or not to +mirror the print
NegativePrintcups_bool_tWhether or not to +invert the print
NumCopiesunsignedThe number of copies to +produce
Orientationcups_orient_tThe orientation of +the page image
OutputFaceUpcups_bool_tWhether or not to +output the page face up
PageSizeunsigned[2]The width and height of +the page in points
Separationscups_bool_tWhether or not to +output separations
TraySwitchcups_bool_tWhether or not to +automatically switch trays for the requested media size/type
Tumblecups_bool_tWhether or not to rotate the +back side of the page
cupsWidthunsignedThe width of the page image +in pixels
cupsHeightunsignedThe height of the page +image in pixels
cupsMediaTypeunsignedThe device-specific +media type code
cupsBitsPerColorunsignedThe number of bits +per color
cupsBitsPerPixelunsignedThe number of bits +per pixel
cupsBytesPerLineunsignedThe number of bytes +per line of image data
cupsColorOrdercups_order_tThe order of color +values
cupsColorSpacecups_cspace_tThe type of color +values
cupsCompressionunsignedThe device-specific +compression code
cupsRowCountunsignedThe device-specific row +count
cupsRowFeedunsignedThe device-specific row +feed
cupsRowStepunsignedThe device-specific row +step
+
+

+

D - Functions

+

This appendix provides a reference for all of the CUPS API +functions. + +

+

cupsAddOption()

+

Usage

+
+int
+cupsAddOption(const char *name,
+              const char *value,
+              int num_options,
+	      cups_option_t **options);
+
+

Arguments

+
+ + + + + + + +
ArgumentDescription
nameThe name of the option.
valueThe value of the option.
num_optionsNumber of options currently in the array.
optionsPointer to the options array.
+
+

Returns

+

The new number of options.

+

Description

+

cupsAddOption() adds an option to the specified array.

+

Example

+
+#include <cups.h>
+
+...
+
+/* Declare the options array */
+int           num_options;
+cups_option_t *options;
+
+/* Initialize the options array */
+num_options = 0;
+options     = (cups_option_t *)0;
+
+/* Add options using cupsAddOption() */
+num_options = cupsAddOption("media", "letter", num_options, &options);
+num_options = cupsAddOption("resolution", "300dpi", num_options, &options);
+
+

See Also

+ cupsFreeOptions(), +cupsGetOption(), +cupsParseOptions() + + +

cupsCancelJob()

+

Usage

+
+int
+cupsCancelJob(const char *dest,
+              int job);
+
+

Arguments

+
+ + + + +
ArgumentDescription
destPrinter or class name
jobJob ID
+
+

Returns

+

1 on success, 0 on failure. On failure the error can be found by +calling cupsLastError().

+

Description

+

cupsCancelJob() cancels the specifies job.

+

Example

+
+#include <cups.h>
+
+cupsCancelJob("LaserJet", 1);
+
+

See Also

+

cupsLastError(), +cupsPrintFile() + +

+

cupsDoFileRequest()

+

Usage

+
+ipp_t *
+cupsDoFileRequest(http_t *http,
+                  ipp_t *request,
+                  const char *resource,
+		  const char *filename);
+
+

Arguments

+
+ + + + + + +
ArgumentDescription
httpHTTP connection to server.
requestIPP request data.
resourceHTTP resource name for POST.
filenameFile to send with POST request (NULL + pointer if none.)
+
+

Returns

+

IPP response data or NULL if the request fails. On +failure the error can be found by calling +cupsLastError().

+

Description

+

cupsDoFileRequest() does a HTTP POST request and +provides the IPP request and optionally the contents of a file to the +IPP server. It also handles resubmitting the request and performing +password authentication as needed.

+

Example

+
+#include <cups.h>
+
+http_t      *http;
+cups_lang_t *language;
+ipp_t       *request;
+ipp_t       *response;
+
+...
+
+/* Get the default language */
+language = cupsLangDefault();
+
+/* Create a new IPP request */
+request  = ippNew();
+
+request->request.op.operation_id = IPP_PRINT_FILE;
+request->request.op.request_id   = 1;
+
+/* Add required attributes */
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+             "attributes-charset", NULL, cupsLangEncoding(language));
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+             "attributes-natural-language", NULL,
+             language != NULL ? language->language : "C");
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+             NULL, "ipp://hostname/resource");
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+             NULL, cupsUser());
+
+/* Do the request... */
+response = cupsDoFileRequest(http, request, "/resource", "filename.txt");
+
+

See Also

+

cupsLangDefault(), +cupsLangEncoding(), +cupsUser(), httpConnect() +, ippAddString(), +ippNew() + +

+

cupsDoRequest()

+

Usage

+
+ipp_t *
+cupsDoRequest(http_t *http,
+              ipp_t *request,
+              const char *resource);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
httpHTTP connection to server.
requestIPP request data.
resourceHTTP resource name for POST.
+
+

Returns

+

IPP response data or NULL if the request fails. On +failure the error can be found by calling +cupsLastError().

+

Description

+

cupsDoRequest() does a HTTP POST request and provides +the IPP request to the IPP server. It also handles resubmitting the +request and performing password authentication as needed.

+

Example

+
+#include <cups.h>
+
+http_t      *http;
+cups_lang_t *language;
+ipp_t       *request;
+ipp_t       *response;
+
+...
+
+/* Get the default language */
+language = cupsLangDefault();
+
+/* Create a new IPP request */
+request  = ippNew();
+
+request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+request->request.op.request_id   = 1;
+
+/* Add required attributes */
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+             "attributes-charset", NULL, cupsLangEncoding(language));
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+             "attributes-natural-language", NULL,
+             language != NULL ? language->language : "C");
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+             NULL, "ipp://hostname/resource");
+
+/* Do the request... */
+response = cupsDoRequest(http, request, "/resource");
+
+

See Also

+

cupsLangDefault(), +cupsLangEncoding(), +cupsUser(), httpConnect() +, ippAddString(), +ippNew() + +

+

cupsFreeOptions()

+

Usage

+
+void
+cupsFreeOptions(int num_options,
+                cups_option_t *options);
+
+
+

Arguments

+
+ + + + +
ArgumentDescription
num_optionsNumber of options in array.
optionsPointer to options array.
+
+

Description

+

cupsFreeOptions() frees all memory associated with the +option array specified.

+

Example

+
+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+
+...
+
+cupsFreeOptions(num_options, options);
+
+

See Also

+

cupsAddOption(), +cupsGetOption(), cupsMarkOptions(), cupsParseOptions() + +

+

cupsGetClasses()

+

Usage

+
+int
+cupsGetClasses(char ***classes);
+
+

Arguments

+
+ + + +
ArgumentDescription
classesPointer to character pointer array.
+
+

Returns

+

The number of printer classes available.

+

Description

+

cupsGetClasses() gets a list of the available printer +classes. The returned array should be freed using the free() + when it is no longer needed.

+

Example

+
+#include <cups/cups.h>
+
+int  i;
+int  num_classes;
+char **classes;
+
+...
+
+num_classes = cupsGetClasses(
+
+...
+
+if (num_classes > 0)
+{
+  for (i = 0; i num_classes; i ++)
+    free(classes[i]);
+
+  free(classes);
+}
+
+

See Also

+

cupsGetDefault(), +cupsGetPrinters() + +

+

cupsGetDefault()

+

Usage

+
+const char *
+cupsGetDefault(void);
+
+

Returns

+

A pointer to the default destination.

+

Description

+

cupsGetDefault() gets the default destination printer +or class. The default destination is stored in a static string and will +be overwritten (usually with the same value) after each call.

+

Example

+
+#include <cups/cups.h>
+
+printf("The default destination is %s\n", cupsGetDefault());
+
+

See Also

+

cupsGetClasses(), +cupsGetPrinters() + +

+

cupsGetOption()

+

Usage

+
+const char *
+cupsGetOption(const char *name,
+              int num_options,
+              cups_option_t *options);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
nameThe name of the option.
num_optionsThe number of options in the array.
optionsThe options array.
+
+

Returns

+

A pointer to the option values or NULL if the option is +not defined.

+

Description

+

cupsGetOption() returns the first occurrence of the +named option. If the option is not included in the options array then a +NULL pointer is returned.

+
+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+const char    *media;
+
+...
+
+media = cupsGetOption("media", num_options, options);
+
+

See Also

+

cupsAddOption(), +cupsFreeOptions(), cupsMarkOptions() +, cupsParseOptions() + +

+

cupsGetPassword()

+

Usage

+
+const char *
+cupsGetPassword(const char *prompt);
+
+

Arguments

+
+ + + +
ArgumentDescription
promptThe prompt to display to the user.
+
+

Returns

+

A pointer to the password that was entered or NULL if +no password was entered.

+

Description

+

cupsGetPassword() displays the prompt string and asks +the user for a password. The password text is not echoed to the user.

+

Example

+
+#include <cups/cups.h>
+
+char *password;
+
+...
+
+password = cupsGetPassword("Please enter a password:");
+
+

See Also

+

cupsServer(), +cupsUser() + +

+

cupsGetPPD()

+

Usage

+
+const char *
+cupsGetPPD(const char *printer);
+
+

Arguments

+
+ + + +
ArgumentDescription
printerThe name of the printer.
+
+

Returns

+

The name of a temporary file containing the PPD file or NULL + if the printer cannot be located or does not have a PPD file.

+

Description

+

cupsGetPPD() gets a copy of the PPD file for the named +printer. The printer name can be of the form "printer" or +"printer@hostname".

+

You should remove (unlink) the PPD file after you are done using it. +The filename is stored in a static buffer and will be overwritten with +each call to cupsGetPPD().

+

Example

+
+#include <cups/cups.h>
+
+char *ppd;
+
+...
+
+ppd = cupsGetPPD("printer@hostname");
+
+...
+
+unlink(ppd);
+
+ + +

cupsGetPrinters()

+

Usage

+
+int
+cupsGetPrinters(char ***printers);
+
+

Arguments

+
+ + + +
ArgumentDescription
printersPointer to character pointer array.
+
+

Returns

+

The number of printer printers available.

+

Description

+

cupsGetPrinters() gets a list of the available +printers. The returned array should be freed using the free() + when it is no longer needed.

+

Example

+
+#include <cups/cups.h>
+
+int  i;
+int  num_printers;
+char **printers;
+
+...
+
+num_printers = cupsGetPrinters(
+
+...
+
+if (num_printers > 0)
+{
+  for (i = 0; i num_printers; i ++)
+    free(printers[i]);
+
+  free(printers);
+}
+
+

See Also

+

cupsGetClasses(), +cupsGetDefault() + +

+

cupsLangDefault()

+

Usage

+
+const char *
+cupsLangDefault(void);
+
+

Returns

+

A pointer to the default language structure.

+

Description

+

cupsLangDefault() returns a language structure for the +default language. The default language is defined by the LANG + environment variable. If the specified language cannot be located then +the POSIX (English) locale is used.

+

Call cupsLangFree() to free any memory associated with +the language structure when you are done.

+

Example

+
+#include <cups/language.h>
+
+cups_lang_t *language;
+...
+
+language = cupsLangDefault();
+
+...
+
+cupsLangFree(language);
+
+

See Also

+

cupsLangEncoding(), +cupsLangFlush(), cupsLangFree(), +cupsLangGet(), cupsLangString() + +

+

cupsLangEncoding()

+

Usage

+
+char *
+cupsLangEncoding(cups_lang_t *language);
+
+

Arguments

+
+ + + +
ArgumentDescription
languageThe language structure.
+
+

Returns

+

A pointer to the encoding string.

+

Description

+

cupsLangEncoding() returns the language encoding used +for the specified language, e.g. "iso-8859-1", "utf-8", etc.

+

Example

+
+#include <cups/language.h>
+
+cups_lang_t *language;
+char        *encoding;
+...
+
+language = cupsLangDefault();
+encoding = cupsLangEncoding(language);
+...
+
+cupsLangFree(language);
+
+

See Also

+

cupsLangDefault(), +cupsLangFlush(), cupsLangFree(), +cupsLangGet(), cupsLangString() + +

+

cupsLangFlush()

+

Usage

+
+void
+cupsLangFlush(void);
+
+

Description

+

cupsLangFlush() frees all language structures that have +been allocated.

+

Example

+
+#include <cups/language.h>
+
+...
+
+cupsLangFlush();
+
+

See Also

+

cupsLangDefault(), +cupsLangEncoding(), cupsLangFree(), +cupsLangGet(), cupsLangString() + +

+

cupsLangFree()

+

Usage

+
+void
+cupsLangFree(cups_lang_t *language);
+
+

Arguments

+
+ + + +
ArgumentDescription
languageThe language structure to free.
+
+

Description

+

cupsLangFree() frees the specified language structure.

+

Example

+
+#include <cups/language.h>
+
+cups_lang_t *language;
+...
+
+cupsLangFree(language);
+
+

See Also

+

cupsLangDefault(), +cupsLangEncoding(), cupsLangFlush(), +cupsLangGet(), cupsLangString() + +

+

cupsLangGet()

+

Usage

+
+cups_lang_t *
+cupsLangGet(const char *name);
+
+

Arguments

+
+ + + +
ArgumentDescription
nameThe name of the locale.
+
+

Returns

+

A pointer to a language structure.

+

Description

+

cupsLangGet() returns a language structure for the +specified locale. If the locale is not defined then the POSIX (English) +locale is substituted.

+

Example

+
+#include <cups/language.h>
+
+cups_lang_t *language;
+
+...
+
+language = cupsLangGet("fr");
+
+...
+
+cupsLangFree(language);
+
+

See Also

+

cupsLangDefault(), +cupsLangEncoding(), cupsLangFlush(), +cupsLangFree(), cupsLangString() + +

+

cupsLangString()

+

Usage

+
+char *
+cupsLangString(cups_lang_t *language,
+               int         message);
+
+

Arguments

+
+ + + + +
ArgumentDescription
languageThe language to query.
messageThe message number.
+
+

Returns

+

A pointer to the message string or NULL if the message +is not defined.

+

Description

+

cupsLangString() returns a pointer to the specified +message string in the specified language.

+

Example

+
+#include <cups/language.h>
+
+cups_lang_t *language;
+char        *s;
+...
+
+language = cupsLangGet("fr");
+
+s = cupsLangString(language, CUPS_MSG_YES);
+
+...
+
+cupsLangFree(language);
+
+

See Also

+

cupsLangDefault(), +cupsLangEncoding(), cupsLangFlush(), +cupsLangFree(), cupsLangGet() + +

+

cupsLastError()

+

Usage

+
+ipp_status_t
+cupsLastError(void);
+
+

Returns

+

An enumeration containing the last IPP error.

+

Description

+

cupsLastError() returns the last IPP error that +occurred. If no error occurred then it will return IPP_OK + or IPP_OK_CONFLICT.

+

Example

+
+#include <cups/cups.h>
+
+ipp_status_t status;
+
+...
+
+status = cupsLastError();
+
+

See Also

+

cupsCancelJob(), +cupsPrintFile() + +

+

cupsMarkOptions()

+

Usage

+
+int
+cupsMarkOptions(ppd_file_t *ppd,
+                int num_options,
+                cups_option_t *options);
+
+

Arguments

+
+ + + + + + +
ArgumentDescription
ppdThe PPD file to mark.
num_optionsThe number of options in the options array.
optionsA pointer to the options array.
+
+

Returns

+

The number of conflicts found.

+

Description

+

cupsMarkOptions() marks options in the PPD file. It +also handles mapping of IPP option names and values to PPD option +names.

+

Example

+
+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+ppd_file_t    *ppd;
+
+...
+
+cupsMarkOptions(ppd, num_options, options);
+
+

See Also

+

cupsAddOption(), +cupsFreeOptions(), cupsGetOption(), +cupsParseOptions() + +

+

cupsParseOptions()

+

Usage

+
+int
+cupsParseOptions(const char *arg,
+                 int num_options,
+                 cups_option_t **options);
+
+

Arguments

+
+ + + + + + +
ArgumentDescription
argThe string containing one or more options.
num_optionsThe number of options in the options array.
optionsA pointer to the options array pointer.
+
+

Returns

+

The new number of options in the array.

+

Description

+

cupsParseOptions() parses the specifies string for one +or more options of the form "name=value", "name", or "noname". It can +be called multiple times to combine the options from several strings.

+

Example

+
+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+
+...
+
+num_options = 0;
+options     = (cups_option_t *)0;
+num_options = cupsParseOptions(argv[5], num_options, &options);
+
+

See Also

+

cupsAddOption(), +cupsFreeOptions(), cupsGetOption(), +cupsMarkOptions() + +

+

cupsPrintFile()

+

Usage

+
+int
+cupsPrintFile(const char    *printer,
+              const char    *filename,
+              const char    *title,
+	      int           num_options,
+	      cups_option_t *options);
+
+

Arguments

+
+ + + + + + + + +
ArgumentDescription
printerThe printer or class to print to.
filenameThe file to print.
titleThe job title.
num_optionsThe number of options in the options array.
optionsA pointer to the options array.
+
+

Returns

+

The new job ID number or 0 on error.

+

Description

+

cupsPrintFile() sends a file to the specified printer +or class for printing. If the job cannot be printed the error code can +be found by calling cupsLastError().

+

Example

+
+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+int           jobid;
+
+...
+
+jobid = cupsPrintFile("printer@hostname", "filename.ps", "Job Title",
+                      num_options, options);
+
+

See Also

+

cupsCancelJob(), +cupsLastError(), cupsPrintFiles() + +

+

cupsPrintFiles()

+

Usage

+
+int
+cupsPrintFiles(const char    *printer,
+               int           num_files,
+               const char    **files,
+               const char    *title,
+	       int           num_options,
+	       cups_option_t *options);
+
+

Arguments

+
+ + + + + + + + + +
ArgumentDescription
printerThe printer or class to print to.
num_filesThe number of files to print.
filesThe files to print.
titleThe job title.
num_optionsThe number of options in the options array.
optionsA pointer to the options array.
+
+

Returns

+

The new job ID number or 0 on error.

+

Description

+

cupsPrintFiles() sends multiple files to the specified +printer or class for printing. If the job cannot be printed the error +code can be found by calling cupsLastError().

+

Example

+
+#include <cups/cups.h>
+
+int           num_files;
+const char    *files[100];
+int           num_options;
+cups_option_t *options;
+int           jobid;
+
+...
+
+jobid = cupsPrintFiles("printer@hostname", num_files, files,
+                       "Job Title", num_options, options);
+
+

See Also

+

cupsCancelJob(), +cupsLastError(), cupsPrintFile() + +

+

cupsRasterClose()

+

Usage

+
+void
+cupsRasterClose(cups_raster_t *ras);
+
+

Arguments

+
+ + + +
ArgumentDescription
rasThe raster stream to close.
+
+

Description

+

cupsRasterClose() closes the specified raster stream.

+

Example

+
+#include <cups/raster.h>
+
+cups_raster_t *ras;
+
+...
+
+cupsRasterClose(ras);
+
+

See Also

+

cupsRasterOpen(), +cupsRasterReadHeader(), +cupsRasterReadPixels(), +cupsRasterWriteHeader(), +cupsRasterWritePixels() + +

+

cupsRasterOpen()

+

Usage

+
+cups_raster_t *
+cupsRasterOpen(int fd,
+               cups_mode_t mode);
+
+

Arguments

+
+ + + + +
ArgumentDescription
fdThe file descriptor to use.
modeThe mode to use; CUPS_RASTER_READ or + CUPS_RASTER_WRITE.
+
+

Returns

+

A pointer to a raster stream or NULL if there was an +error.

+

Description

+

cupsRasterOpen() opens a raster stream for reading or +writing.

+

Example

+
+#include <cups/raster.h>
+
+cups_raster_t *ras;
+
+...
+
+ras = cupsRasterOpen(0, CUPS_RASTER_READ);
+
+

See Also

+

cupsRasterClose(), +cupsRasterReadHeader(), +cupsRasterReadPixels(), +cupsRasterWriteHeader(), +cupsRasterWritePixels() + +

+

cupsRasterReadHeader()

+

Usage

+
+unsigned
+cupsRasterReadHeader(cups_raster_t *ras,
+                     cups_page_header_t *header);
+
+

Arguments

+
+ + + + +
ArgumentDescription
rasThe raster stream to read from.
headerA pointer to a page header structure to read +into.
+
+

Returns

+

1 on success, 0 on EOF or error.

+

Description

+

cupsRasterReadHeader() reads a page header from the +specified raster stream.

+

Example

+
+#include <cups/raster.h>
+
+int                  line;
+cups_raster_t        *ras;
+cups_raster_header_t header;
+unsigned char        pixels[8192];
+...
+
+while (cupsRasterReadHeader(ras, &header))
+{
+  ...
+
+  for (line = 0; line < header.cupsHeight; line ++)
+  {
+    cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
+
+    ...
+  }
+}
+
+

See Also

+

cupsRasterClose(), +cupsRasterOpen(), +cupsRasterReadPixels(), +cupsRasterWriteHeader(), +cupsRasterWritePixels() + +

+

cupsRasterReadPixels()

+

Usage

+
+unsigned
+cupsRasterReadPixels(cups_raster_t *ras,
+                     unsigned char *pixels,
+		     unsigned length);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
rasThe raster stream to read from.
pixelsThe pointer to a pixel buffer.
lengthThe number of bytes of pixel data to read.
+
+

Returns

+

The number of bytes read or 0 on EOF or error.

+

Description

+

cupsRasterReadPixels() reads pixel data from the +specified raster stream.

+

Example

+
+#include <cups/raster.h>
+
+int                  line;
+cups_raster_t        *ras;
+cups_raster_header_t header;
+unsigned char        pixels[8192];
+...
+
+while (cupsRasterReadHeader(ras, &header))
+{
+  ...
+
+  for (line = 0; line < header.cupsHeight; line ++)
+  {
+    cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
+
+    ...
+  }
+}
+
+

See Also

+

cupsRasterClose(), +cupsRasterOpen(), +cupsRasterReadHeader(), +cupsRasterWriteHeader(), +cupsRasterWritePixels() + +

+

cupsRasterWriteHeader()

+

Usage

+
+unsigned
+cupsRasterWriteHeader(cups_raster_t *ras,
+                      cups_page_header_t *header);
+
+

Arguments

+
+ + + + +
ArgumentDescription
rasThe raster stream to write to.
headerA pointer to the page header to write.
+
+

Returns

+

1 on success, 0 on error.

+

Description

+

cupsRasterWriteHeader() writes the specified page +header to a raster stream.

+

Example

+
+#include <cups/raster.h>
+
+int                  line;
+cups_raster_t        *ras;
+cups_raster_header_t header;
+unsigned char        pixels[8192];
+...
+
+cupsRasterWriteHeader(ras, &header);
+
+for (line = 0; line < header.cupsHeight; line ++)
+{
+  ...
+
+  cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
+}
+
+

See Also

+

cupsRasterClose(), +cupsRasterOpen(), +cupsRasterReadHeader(), +cupsRasterReadPixels(), +cupsRasterWritePixels() + +

+

cupsRasterWritePixels()

+

Usage

+
+unsigned
+cupsRasterWritePixels(cups_raster_t *ras,
+                      unsigned char *pixels,
+		      unsigned length);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
rasThe raster stream to write to.
pixelsThe pixel data to write.
lengthThe number of bytes to write.
+
+

Returns

+

The number of bytes written.

+

Description

+

cupsRasterWritePixels() writes the specified pixel data +to a raster stream.

+

Example

+
+#include <cups/raster.h>
+
+int                  line;
+cups_raster_t        *ras;
+cups_raster_header_t header;
+unsigned char        pixels[8192];
+...
+
+cupsRasterWriteHeader(ras, &header);
+
+for (line = 0; line < header.cupsHeight; line ++)
+{
+  ...
+
+  cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
+}
+
+

See Also

+

cupsRasterClose(), +cupsRasterOpen(), +cupsRasterReadHeader(), +cupsRasterReadPixels(), +cupsRasterWriteHeader() + +

+

cupsServer()

+

Usage

+
+const char *
+cupsServer(void);
+
+

Returns

+

A pointer to the default server name.

+

Description

+

cupsServer() returns a pointer to the default server +name. The server name is stored in a static location and will be +overwritten with every call to cupsServer()

+

The default server is determined from the following locations:

+
    +
  1. The CUPS_SERVER environment variable,
  2. +
  3. The ServerName directive in the client.conf + file,
  4. +
  5. The default host, "localhost".
  6. +
+

Example

+
+#include <cups/cups.h>
+
+const char *server;
+
+server = cupsServer();
+
+

See Also

+

cupsGetPassword(), +cupsUser() + +

+

cupsTempFile()

+

Usage

+
+char *
+cupsTempFile(char *filename,
+             int length);
+
+

Arguments

+
+ + + + +
ArgumentDescription
filenameThe character string to hold the temporary +filename.
lengthThe size of the filename string in bytes.
+
+

Returns

+

A pointer to filename.

+

Description

+

cupsTempFile() generates a temporary filename for the +/var/tmp directory or the directory specified by the TMPDIR + environment variable.

+

Example

+
+#include <cups/cups.h>
+
+char filename[256];
+
+cupsTempFile(filename, sizeof(filename));
+
+ + +

cupsUser()

+

Usage

+
+const char *
+cupsUser(void);
+
+

Returns

+

A pointer to the current username or NULL if the user +ID is undefined.

+

Description

+

cupsUser() returns the name associated with the current +user ID as reported by the getuid() system call.

+

Example

+
+#include <cups/cups.h>
+
+const char *user;
+
+user = cupsUser();
+
+

See Also

+

cupsGetPassword(), +cupsServer() + +

+

httpBlocking()

+

Usage

+
+void httpBlocking(http_t *http, int blocking)
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
blocking0 if the connection should be non-blocking, 1 +if it should be blocking
+
+

Description

+

The httpBlocking() function sets the blocking mode for +the HTTP connection. By default HTTP connections will block (stop) the +client program until data is available or can be sent to the server.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+http = httpConnect("server", port);
+httpBlocking(http, 0);
+
+

See Also

+ httpCheck(), +httpConnect() + + +

httpCheck()

+

Usage

+
+int httpCheck(http_t *http);
+
+

Arguments

+
+ + + +
ArgumentDescription
httpThe HTTP connection
+
+

Returns

+

0 if there is no data pending, 1 otherwise.

+

Description

+

The httpCheck() function checks to see if there is any +data pending on an HTTP connection.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+if (httpCheck(http))
+{
+  ... do something ...
+}
+
+

See Also

+ httpBlocking(), +httpConnect(), httpGets() +, httpRead() + + +

httpClearFields()

+

Usage

+
+void httpClearFields(http_t *http)
+
+

Arguments

+
+ + + +
ArgumentDescription
httpThe HTTP connection
+
+

Description

+

The httpClearFields() function clears all HTTP request +fields for the HTTP connection.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpClearFields(http);
+
+

See Also

+ httpConnect(), +httpGetField(), +httpSetField() + + +

httpClose()

+

Usage

+
+void httpClose(http_t *http);
+
+

Arguments

+
+ + + +
ArgumentDescription
httpThe HTTP connection
+
+

Description

+

The httpClose() function closes an active HTTP +connection.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpClose(http);
+
+

See Also

+ httpConnect() + + +

httpConnect()

+

Usage

+
+http_t *httpConnect(const char *hostname, int port);
+
+

Arguments

+
+ + + + +
ArgumentDescription
hostnameThe name or IP address of the server to +connect to
portThe port number to use
+
+

Returns

+

A pointer to a HTTP connection structure or NULL if the connection +could not be made.

+

Description

+

The httpConnect() function opens a HTTP connection to +the specified server and port.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+http = httpConnect(cupsServer(), ippPort());
+
+

See Also

+ httpClose(), +httpGet(), httpGets(), httpPost(), +httpRead(), httpWrite() + + +

httpDecode64()

+

Usage

+
+char *httpDecode64(char *out, const char *in);
+
+

Arguments

+
+ + + + +
ArgumentDescription
outThe output string
inThe input string
+
+

Returns

+

A pointer to the decoded string.

+

Description

+

The httpDecode64() function decodes a base-64 encoded +string to the original string.

+

Example

+
+#include <cups/http.h>
+
+char encoded_string[255];
+char original_string[255];
+
+httpDecode64(original_string, encoded_string);
+
+

See Also

+ httpEncode64() + + +

httpDelete()

+

Usage

+
+int httpDelete(http_t *http, const char *uri);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to delete
+
+

Returns

+

0 on success, non-zero on failure.

+

Description

+

The httpDelete() function sends a HTTP DELETE request +to the server.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpDelete(http, "/some/uri");
+
+

See Also

+ httpConnect(), +httpSetField(), +httpUpdate() + + +

httpEncode64()

+

Usage

+
+char *httpEncode64(char *out, const char *in);
+
+

Arguments

+
+ + + + +
ArgumentDescription
outThe output string
inThe input string
+
+

Returns

+

A pointer to the encoded string.

+

Description

+

The httpEncode64() function decodes a base-64 encoded +string to the original string.

+

Example

+
+#include <cups/http.h>
+
+char encoded_string[255];
+char original_string[255];
+
+httpEncode64(encoded_string, original_string);
+
+

See Also

+ httpDecode64() + + +

httpError()

+

Usage

+
+int httpError(http_t *http);
+
+

Arguments

+
+ + + +
ArgumentDescription
httpThe HTTP connection
+
+

Returns

+

The last error that occurred or 0 if no error has occurred.

+

Description

+

The httpError() function returns the last error that +occurred on the HTTP connection.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+if (httpError(http))
+{
+  ... show an error message ...
+}
+
+

See Also

+ httpConnect() + + +

httpFlush()

+

Usage

+
+void httpFlush(http_t *http);
+
+

Arguments

+
+ + + +
ArgumentDescription
httpThe HTTP connection
+
+

Description

+

The httpFlush() function flushes any remaining data +left from a GET or POST operation.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpFlush(http);
+
+

See Also

+ httpConnect(), + + +

httpGet()

+

Usage

+
+int httpGet(http_t *http, const char *uri);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to get
+
+

Returns

+

0 on success, non-zero on failure.

+

Description

+

The httpGet() function sends a HTTP GET request to the +server.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpGet(http, "/some/uri");
+
+

See Also

+ httpConnect(), +httpSetField(), +httpUpdate() + + +

httpGets()

+

Usage

+
+char *httpGets(char *line, int length, http_t *http)
+
+

Arguments

+
+ + + + + +
ArgumentDescription
lineThe string to fill with a line from the HTTP +connection
lengthThe maximum length of the string
httpThe HTTP connection
+
+

Returns

+

A pointer to the string or NULL if no line could be retrieved.

+

Description

+

The httpGets() function is used to read a request line +from the HTTP connection. It is not normally used by a client program.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+char line[1024];
+
+if (httpGets(line, sizeof(line), http))
+{
+  ... process the line ...
+}
+
+

See Also

+ httpConnect(), +httpUpdate() + + +

httpGetDateString()

+

Usage

+
+const char *httpGetDateString(time_t time)
+
+

Arguments

+
+ + + +
ArgumentDescription
timeThe UNIX date/time value
+
+

Returns

+

A pointer to a static string containing the HTTP date/time string +for the specified UNIX time value.

+

Description

+

The httpGetDateString() function generates a date/time +string suitable for HTTP requests from a UNIX time value.

+

Example

+
+#include <cups/http.h>
+
+puts(httpGetDateString(time(NULL)));
+
+

See Also

+ httpGetDateTime() + + +

httpGetDateTime()

+

Usage

+
+time_t httpGetDateTime(const char *date)
+
+

Arguments

+
+ + + +
ArgumentDescription
dateThe HTTP date/time string
+
+

Returns

+

A UNIX time value.

+

Description

+

The httpGetDateTime() function converts a HTTP +date/time string to a UNIX time value.

+

Example

+
+#include <cups/http.h>
+
+printf("%d\n", httpGetDateTime("Fri, 30 June 2000 12:34:56 GMT"));
+
+

See Also

+ httpGetDateString() + + +

httpGetField()

+

Usage

+
+const char *httpGetField(http_t *http, http_field_t field);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
fieldThe HTTP field
+
+

Returns

+

A pointer to the field value string.

+

Description

+

The httpGetField() function returns the current value +for the specified HTTP field.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpGet(http, "/some/uri");
+while (httpUpdate(http) == HTTP_CONTINUE);
+
+puts(httpGetField(http, HTTP_FIELD_CONTENT_TYPE));
+
+

See Also

+ httpConnect(), +httpSetField() + + +

httpHead()

+

Usage

+
+int httpHead(http_t *http, const char *uri);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to head
+
+

Returns

+

0 on success, non-zero on failure.

+

Description

+

The httpHead() function sends a HTTP HEAD request to +the server.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpHead(http, "/some/uri");
+
+

See Also

+ httpConnect(), +httpSetField(), +httpUpdate() + + +

httpInitialize()

+

Usage

+
+void httpInitialize(void);
+
+

Description

+

The httpInitialize() function initializes the +networking code as needed by the underlying platform. It is called +automatically by the httpConnect() function.

+

Example

+
+#include <cups/http.h>
+
+httpInitialize();
+
+

See Also

+ httpConnect() + + +

httpOptions()

+

Usage

+
+int httpOptions(http_t *http, const char *uri);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to check for options
+
+

Returns

+

0 on success, non-zero on failure.

+

Description

+

The httpOptions() function sends a HTTP OPTIONS request +to the server.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpOptions(http, "/some/uri");
+
+

See Also

+ httpConnect(), +httpSetField(), +httpUpdate() + + +

httpPost()

+

Usage

+
+int httpPost(http_t *http, const char *uri);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to post to
+
+

Returns

+

0 on success, non-zero on failure.

+

Description

+

The httpPost() function sends a HTTP POST request to +the server.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpPost(http, "/some/uri");
+
+

See Also

+ httpConnect(), +httpSetField(), +httpUpdate() + + +

httpPrintf()

+

Usage

+
+int httpPrintf(http_t *http, const char *format, ...);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
formatA printf-style format string
+
+

Returns

+

The number of bytes written.

+

Description

+

The httpPrintf() function sends a formatted string to +the HTTP connection. It is normally only used by the CUPS API and +scheduler.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpPrintf(http, "GET / HTTP/1.1 \r\n");
+
+

See Also

+ httpConnect() + + +

httpPut()

+

Usage

+
+int httpPut(http_t *http, const char *uri);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to put
+
+

Returns

+

0 on success, non-zero on failure.

+

Description

+

The httpPut() function sends a HTTP PUT request to the +server.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpDelete(http, "/some/uri");
+
+

See Also

+ httpConnect(), +httpSetField(), +httpUpdate() + + +

httpRead()

+

Usage

+
+int httpRead(http_t *http, char *buffer, int length);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
httpThe HTTP connection
bufferThe buffer to read into
lengthThe number of bytes to read
+
+

Returns

+

The number of bytes read or -1 on error.

+

Description

+

The httpRead() function reads data from the HTTP +connection, possibly the result of a GET or POST request.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+char buffer[1024];
+int  bytes;
+
+httpGet(http, "/");
+while (httpUpdate(http) != HTTP_CONTINUE);
+while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
+{
+  buffer[bytes] = '\0';
+  fputs(buffer, stdout);
+}
+
+

See Also

+ httpConnect(), +httpWrite() + + +

httpReconnect()

+

Usage

+
+int httpReconnect(http_t *http);
+
+

Arguments

+
+ + + +
ArgumentDescription
httpThe HTTP connection
+
+

Returns

+

0 on success, non-zero on failure.

+

Description

+

The httpReconnect() function reconnects to the HTTP +server. This is usually done automatically if the HTTP functions detect +that the server connection has terminated.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpReconnect(http);
+
+

See Also

+ httpConnect() + + +

httpSeparate()

+

Usage

+
+void httpSeparate(const char *uri, char *method,
+                  char *username, char *host, int *port,
+                  char *resource);
+
+

Arguments

+
+ + + + + + + + +
ArgumentDescription
uriThe URI to separate
methodThe method (scheme) of the URI
usernameThe username (and password) portion of the +URI, if any
hostThe hostname portion of the URI, if any
portThe port number for the URI, either as specified +or as default for the method/scheme
resourceThe resource string, usually a filename on the +server
+
+

Description

+

The httpSeparate() function separates the specified URI +into its component parts. The method, username, hostname, and resource +strings should be at least HTTP_MAX_URI characters long to +avoid potential buffer overflow problems.

+

Example

+
+char uri[HTTP_MAX_URI];
+char method[HTTP_MAX_URI];
+char username[HTTP_MAX_URI];
+char host[HTTP_MAX_URI];
+char resource[HTTP_MAX_URI];
+int port;
+
+httpSeparate(uri, method, username, host, &port, resource);
+
+

See Also

+ httpConnect() + + +

httpSetField()

+

Usage

+
+void httpSetField(http_t *http, http_field_t field, const char *value);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
httpThe HTTP connection
fieldThe HTTP field
valueThe string value for the field
+
+

Description

+

The httpSetField() function sets the current value for +the specified HTTP field.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpSetField(http, HTTP_FIELD_AUTHORIZATION, "Basic dfdr34453454325"));
+httpGet(http, "/some/uri");
+while (httpUpdate(http) == HTTP_CONTINUE);
+
+

See Also

+ httpConnect(), +httpGetField() + + +

httpTrace()

+

Usage

+
+int httpTrace(http_t *http, const char *uri);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to trace
+
+

Returns

+

0 on success, non-zero on failure.

+

Description

+

The httpTrace() function sends a HTTP TRACE request to +the server.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+
+httpTrace(http, "/some/uri");
+
+

See Also

+ httpConnect(), +httpSetField(), +httpUpdate() + + +

httpUpdate()

+

Usage

+
+http_status_t httpUpdate(http_t *http);
+
+

Arguments

+
+ + + +
ArgumentDescription
httpThe HTTP connection
+
+

Returns

+

The HTTP status of the current request.

+

Description

+

The httpUpdate() function updates the current request +status. It is used after any DELETE, GET, HEAD, OPTIONS, POST, PUT, or +TRACE request to finalize the HTTP request and retrieve the request +status.

+

Since proxies and the current blocking mode can cause the request to +take longer, programs should continue calling httpUpdate() + until the return status is not the constant value HTTP_CONTINUE +.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+http_status_t status;
+
+httpGet(http, "/some/uri");
+while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+printf("Request status is %d\n", status);
+
+

See Also

+ httpConnect(), +httpDelete(), httpGet() +, httpHead(), +httpOptions(), httpPost() +, httpPut(), +httpTrace() + + +

httpWrite()

+

Usage

+
+int httpWrite(http_t *http, char *buffer, int length);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
httpThe HTTP connection
bufferThe buffer to read into
lengthThe number of bytes to read
+
+

Returns

+

The number of bytes read or -1 on error.

+

Description

+

The httpWrite() function reads data from the HTTP +connection, possibly the result of a GET or POST request.

+

Example

+
+#include <cups/http.h>
+
+http_t *http;
+FILE *fp;
+char buffer[1024];
+int  bytes;
+
+httpPost(http, "/");
+
+while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
+  httpWrite(http, buffer, bytes);
+
+while (httpUpdate(http) != HTTP_CONTINUE);
+
+while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
+{
+  buffer[bytes] = '\0';
+  fputs(buffer, stdout);
+}
+
+

See Also

+ httpConnect(), +httpRead() + + +

ippAddBoolean()

+

Usage

+
+ipp_attribute_t *ippAddBoolean(ipp_t *ipp, ipp_tag_t group,
+                               const char *name, char value);
+
+

Arguments

+
+ + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
valueThe boolean value
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddBoolean() function adds a single boolean +attribute value to the specified IPP request.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, "my-jobs", 1);
+
+

See Also

+ ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), ippAddRange() +, ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddBooleans()

+

Usage

+
+ipp_attribute_t *ippAddBooleans(ipp_t *ipp, ipp_tag_t group,
+                                const char *name, int num_values,
+                                const char *values);
+
+

Arguments

+
+ + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
num_valuesThe number of values
valuesThe boolean values
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddBooleans() function adds one or more boolean +attribute values to the specified IPP request. If the values + pointer is NULL then an array of num_values + false values is created.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+char values[10];
+
+ippAddBooleans(ipp, IPP_TAG_OPERATION, "some-attribute", 10, values);
+
+

See Also

+ ippAddBoolean(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), ippAddRange() +, ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddDate()

+

Usage

+
+ipp_attribute_t *ippAddDate(ipp_t *ipp, ipp_tag_t group,
+                            const char *name, ipp_uchar_t *value);
+
+

Arguments

+
+ + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
valueThe date value
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddDate() function adds a single date-time +attribute value to the specified IPP request.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddDate(ipp, IPP_TAG_OPERATION, "some-attribute", 
+           ippTimeToDate(time(NULL));
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddInteger(), +ippAddIntegers(), ippAddRange() +, ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings(), +ippTimeToDate() + + +

ippAddInteger()

+

Usage

+
+ipp_attribute_t *ippAddInteger(ipp_t *ipp, ipp_tag_t group,
+                               ipp_tag_t tag, const char *name,
+                               int value);
+
+

Arguments

+
+ + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
tagThe type of integer value (IPP_TAG_INTEGER or +IPP_TAG_ENUM)
nameThe name of attribute
valueThe integer value
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddInteger() function adds a single integer +attribute value to the specified IPP request.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddInteger(ipp, IPP_TAG_OPERATION, "limit", 100);
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddIntegers(), ippAddRange() +, ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddIntegers()

+

Usage

+
+ipp_attribute_t *ippAddIntegers(ipp_t *ipp, ipp_tag_t group,
+                                ipp_tag_t tag, const char *name,
+                                int num_values, const int *values);
+
+

Arguments

+
+ + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
tagThe type of integer value (IPP_TAG_INTEGER or +IPP_TAG_ENUM)
nameThe name of attribute
num_valuesThe number of values
valuesThe integer values
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddIntegers() function adds one or more integer +attribute values to the specified IPP request. If the values + pointer is NULL then an array of num_values + 0 values is created.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+int values[100];
+
+ippAddIntegers(ipp, IPP_TAG_OPERATION, "some-attribute", 100, values);
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddRange()

+

Usage

+
+ipp_attribute_t *ippAddRange(ipp_t *ipp, ipp_tag_t group,
+                             const char *name, int low,
+                             int high);
+
+

Arguments

+
+ + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
lowThe lower value
highThe higher value
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddRange() function adds a single range +attribute value to the specified IPP request.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddRange(ipp, IPP_TAG_OPERATION, "page-ranges", 1, 10);
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddRanges()

+

Usage

+
+ipp_attribute_t *ippAddRanges(ipp_t *ipp, ipp_tag_t group,
+                              const char *name, int num_values,
+                              const int *lows, const int *highs);
+
+

Arguments

+
+ + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
num_valuesThe number of range values
lowsThe lower values
highsThe higher values
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddRanges() function adds one or more range +attribute values to the specified IPP request. If the values + pointer is NULL then an array of num_values + 0,0 ranges is created.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+int lows[2];
+int highs[2];
+
+ippAddRanges(ipp, IPP_TAG_OPERATION, "page-ranges", 2, lows, highs);
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), +ippAddRange(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddResolution()

+

Usage

+
+ipp_attribute_t *ippAddResolution(ipp_t *ipp, ipp_tag_t group,
+                                  const char *name, int xres,
+                                  int yres, ipp_res_t units);
+
+

Arguments

+
+ + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
xresThe horizontal resolution
yresThe vertical resolution
unitsThe resolution units
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddResolution() function adds a single +resolution attribute value to the specified IPP request.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolution",
+              720, 720, IPP_RES_PER_INCH);
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddResolutions()

+

Usage

+
+ipp_attribute_t *ippAddResolutions(ipp_t *ipp, ipp_tag_t group,
+                                   const char *name, int num_values,
+                                   const int *xres, const int *yres,
+                                   const ipp_res_t *units);
+
+

Arguments

+
+ + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
num_valuesThe number of resolution values
xresThe horizontal resolutions
yresThe vertical resolutions
unitsThe resolution units
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddResolutions() function adds one or more +resolution attribute values to the specified IPP request. If the +values pointer is NULL then an array of +num_values 0,0 resolutions is created.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+int xres[5];
+int yres[5];
+ipp_res_t units[5];
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolutions-supported",
+              5, xres, yres, units);
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddSeparator()

+

Usage

+
+ipp_attribute_t *ippAddSeparator(ipp_t *ipp);
+
+

Arguments

+
+ + + +
ArgumentDescription
ippThe IPP request
+
+

Returns

+

A pointer to the new separator or NULL if the separator could not be +created.

+

Description

+

The ippAddSeparator() function adds a group separator +to the specified IPP request.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddSeparator(ipp);
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddString(), +ippAddStrings() + + +

ippAddString()

+

Usage

+
+ipp_attribute_t *ippAddString(ipp_t *ipp, ipp_tag_t group,
+                              ipp_tag_t tag, const char *name,
+                              const char *charset, const char *value);
+
+

Arguments

+
+ + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
tagThe type of string value
nameThe name of attribute
charsetThe character set for the string
valueThe string value
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddString() function adds a single string +attribute value to the specified IPP request. For IPP_TAG_NAMELANG + and IPP_TAG_TEXTLANG strings, the charset value is +provided with the string to identify the string encoding used. +Otherwise the charset value is ignored.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+             NULL, "abc123");
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddStrings() + + +

ippAddStrings()

+

Usage

+
+ipp_attribute_t *ippAddStrings(ipp_t *ipp, ipp_tag_t group,
+                               ipp_tag_t tag, const char *name,
+                               int num_values, const char *charset,
+                               const char **values);
+
+

Arguments

+
+ + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
tagThe type of string value
nameThe name of attribute
num_valuesThe number of strings
charsetThe character set for the strings
valuesThe string values
+
+

Returns

+

A pointer to the new attribute or NULL if the attribute could not be +created.

+

Description

+

The ippAddStrings() function adds one or more string +attribute values to the specified IPP request. For +IPP_TAG_NAMELANG and IPP_TAG_TEXTLANG strings, the +charset value is provided with the strings to identify the string +encoding used. Otherwise the charset value is ignored. If the +values pointer is NULL then an array of +num_values NULL strings is created.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+char *values[2] = { "one", "two" };
+
+ippAddStrings(ipp, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "attr-name",
+              2, NULL, values);
+
+

See Also

+ ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), ippAddInteger() +, ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString() + + +

ippDateToTime()

+

Usage

+
+time_t ippDateToTime(const ipp_uchar_t date[11]);
+
+

Arguments

+
+ + + +
ArgumentDescription
dateThe IPP date-time value
+
+

Returns

+

A UNIX time value.

+

Description

+

The ippDateToTime() function converts an IPP date-time +value to a UNIX time value.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_uchar_t date[11];
+
+printf("UNIX time is %d\n", ippDateToTime(date));
+
+

See Also

+ ippTimeToDate() + + +

ippDelete()

+

Usage

+
+void ippDelete(ipp_t *ipp);
+
+

Arguments

+
+ + + +
ArgumentDescription
ippThe IPP request or response
+
+

Description

+

The ippDelete() function deletes all memory used by an +IPP request or response.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippDelete(ipp);
+
+

See Also

+ ippNew() + + +

ippFindAttribute()

+

Usage

+
+
+

Arguments

+
+ + + +
ArgumentDescription
+
+

Returns

+

Description

+

Example

+
+
+

See Also

+ + +

ippLength()

+

Usage

+
+
+

Arguments

+
+ + + +
ArgumentDescription
+
+

Returns

+

Description

+

Example

+
+
+

See Also

+ + +

ippNew()

+

Usage

+
+ipp_t *ippNew(void);
+
+

Returns

+

A pointer to a new IPP request or response.

+

Description

+

The ippNew() function creates a new IPP request or +response.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ipp = ippNew();
+
+

See Also

+ ippDelete() + + +

ippPort()

+

Usage

+
+int ippPort(void);
+
+

Returns

+

The default TCP/IP port number for IPP requests.

+

Description

+

The ippPort() function returns the default IPP port +number for requests.

+

Example

+
+#include <cups/http.h>
+#include <cups/ipp.h>
+
+http_t *http;
+
+http = httpConnect(cupsServer(), ippPort());
+
+

See Also

+ cupsServer() + + +

ippRead()

+

Usage

+
+ipp_state_t ippRead(http_t *http, ipp_t *ipp);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
ippThe IPP request or response
+
+

Returns

+

The current read state.

+

Description

+

The ippRead() function reads IPP attributes from the +specified HTTP connection. Programs should continue calling +ippRead() until IPP_ERROR or IPP_DATA + is returned.

+

Example

+
+#include <cups/http.h>
+#include <cups/ipp.h>
+
+http_t *http;
+ipp_t *ipp;
+ipp_state_t status;
+
+ipp = ippNew();
+
+while ((status = ippRead(http, ipp)) != IPP_ERROR)
+  if (status == IPP_DATA)
+    break;
+
+if (status == IPP_DATA)
+{
+  ... read additional non-IPP data using httpRead() ...
+}
+
+

See Also

+ ippWrite() + + +

ippTimeToDate()

+

Usage

+
+ipp_uchar_t *ippTimeToDate(time_t time);
+
+

Arguments

+
+ + + +
ArgumentDescription
timeThe UNIX time value
+
+

Returns

+

A static pointer to an IPP date-time value.

+

Description

+

The ippTimeToDate() function converts a UNIX time to an +IPP date-time value.

+

Example

+
+#include <cups/ipp.h>
+
+ipp_uchar_t *date;
+
+date = ippTimeToDate(time(NULL));
+
+

See Also

+ ippDateToTime() + + +

ippWrite()

+

Usage

+
+ipp_state_t ippWrite(http_t *http, ipp_t *ipp);
+
+

Arguments

+
+ + + + +
ArgumentDescription
httpThe HTTP connection
ippThe IPP request or response
+
+

Returns

+

The current write state.

+

Description

+

The ippWrite() function writes IPP attributes to the +specified HTTP connection. Programs should continue calling +ippWrite() until IPP_ERROR or IPP_DATA + is returned.

+

Example

+
+#include <cups/http.h>
+#include <cups/ipp.h>
+
+http_t *http;
+ipp_t *ipp;
+ipp_state_t status;
+
+ipp = ippNew();
+... add attributes ...
+
+while ((status = ippWrite(http, ipp)) != IPP_ERROR)
+  if (status == IPP_DATA)
+    break;
+
+if (status == IPP_DATA)
+{
+  ... read additional non-IPP data using httpWrite() ...
+}
+
+

See Also

+ ippRead() + + +

ppdClose()

+

Usage

+
+void ppdClose(ppd_file_t *ppd);
+
+

Arguments

+
+ + + +
ArgumentDescription
ppdThe PPD file
+
+

Description

+

The ppdClose() function frees all memory associated +with the PPD file.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdClose(ppd);
+
+

See Also

+ ppdOpen(), +ppdOpenFd(), ppdOpenFile() + + + +

ppdConflicts()

+

Usage

+
+int ppdConflicts(ppd_file_t *ppd);
+
+

Arguments

+
+ + + +
ArgumentDescription
ppdThe PPD file
+
+

Returns

+

The number of option conflicts in the file.

+

Description

+

The ppdConflicts() function returns the number of +conflicts with the currently selected options.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("%d conflicts\n", ppdConflicts(ppd));
+
+

See Also

+ cupsMarkOptions(), +ppdIsMarked(), +ppdMarkDefaults(), +ppdMarkOption() + + +

ppdEmit()

+

Usage

+
+int ppdEmit(ppd_file_t *ppd, FILE *file, ppd_section_t section);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
ppdThe PPD file
fileThe file to write to
sectionThe option section to write
+
+

Returns

+

0 on success, -1 on error.

+

Description

+

The ppdEmit() function sends printer-specific option +commands to the specified file.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+
+

See Also

+ ppdEmitFd() + + +

ppdEmitFd()

+

Usage

+
+int ppdEmitFd(ppd_file_t *ppd, int fd, ppd_section_t section);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
ppdThe PPD file
fdThe file descriptor to write to
sectionThe option section to write
+
+

Returns

+

0 on success, -1 on error.

+

Description

+

The ppdEmitFd() function sends printer-specific option +commands to the specified file descriptor.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdEmitFd(ppd, 1, PPD_ORDER_PAGE);
+
+

See Also

+ ppdEmit() + + +

ppdFindChoice()

+

Usage

+
+ppd_choice_t *ppdFindChoice(ppd_option_t *option, const char *choice);
+
+

Arguments

+
+ + + + +
ArgumentDescription
optionA pointer to the option
choiceThe name of the choice
+
+

Returns

+

A pointer to the choice data or NULL if the choice does not exist.

+

Description

+

The ppdFindChoice() function returns a pointer to the +choice data for the specified option.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_option_t *option;
+ppd_choice_t *choice;
+
+option = ppdFindOption(ppd, "PageSize");
+choice = ppdFindChoice(option, "Letter");
+
+

See Also

+ ppdFindMarkedChoice(), ppdFindOption() + + +

ppdFindMarkedChoice()

+

Usage

+
+ppd_choice_t *ppdFindMarkedChoice(ppd_file_t *ppd, const char *keyword);
+
+

Arguments

+
+ + + + +
ArgumentDescription
ppdThe PPD file
keywordThe name of the option
+
+

Returns

+

A pointer to the choice data or NULL if the choice does not exist or +is not marked.

+

Description

+

The ppdFindMarkedChoice() function returns a pointer to +the marked choice data for the specified option.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_choice_t *choice;
+
+choice = ppdFindMarkedChoice(ppd, "PageSize");
+
+

See Also

+ ppdFindChoice(), +ppdFindOption() + + +

ppdFindOption()

+

Usage

+
+ppd_option_t *ppdFindOption(ppd_file_t *ppd, const char *keyword);
+
+

Arguments

+
+ + + + +
ArgumentDescription
ppdThe PPD file
keywordThe name of the option
+
+

Returns

+

A pointer to the option data or NULL if the option does not exist.

+

Description

+

The ppdFindOption() function returns a pointer to the +option data for the specified option.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_option_t *option;
+
+option = ppdFindOption(ppd, "PageSize");
+
+

See Also

+ ppdFindChoice(), +ppdFindMarkedChoice() + + +

ppdIsMarked()

+

Usage

+
+int ppdIsMarked(ppd_file_t *ppd, const char *keyword, char char *choice);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
ppdThe PPD file
keywordThe name of the option
choiceThe name of the option choice
+
+

Returns

+

1 if the choice is marked, 0 otherwise.

+

Description

+

The ppdIsMarked() function returns whether or not the +specified option choice is marked.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("Letter size %s selected.\n",
+       ppdIsMarked(ppd, "PageSize", "Letter") ? "is" : "is not");
+
+

See Also

+ cupsMarkOptions(), +ppdConflicts(), +ppdIsMarked(), +ppdMarkDefaults(), +ppdMarkOption() + + +

ppdMarkDefaults()

+

Usage

+
+void ppdMarkDefaults(ppd_file_t *ppd);
+
+

Arguments

+
+ + + +
ArgumentDescription
ppdThe PPD file
+
+

Description

+

The ppdMarkDefaults() function marks all of the default +choices in the PPD file.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdMarkDefaults(ppd);
+
+

See Also

+ cupsMarkOptions(), +ppdConflicts(), +ppdIsMarked(), +ppdMarkDefaults(), +ppdMarkOption() + + +

ppdMarkOption()

+

Usage

+
+int ppdMarkOption(ppd_file_t *ppd, const char *keyword, const char *choice);
+
+

Arguments

+
+ + + + + +
ArgumentDescription
ppdThe PPD file
keywordThe name of the option
choiceThe name of the choice
+
+

Returns

+

The number of conflicts in the PPD file.

+

Description

+

The ppdMarkOption() function marks the specified option +choice.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdMarkOption(ppd, "PageSize", "Letter");
+
+

See Also

+ cupsMarkOptions(), +ppdConflicts(), +ppdIsMarked(), +ppdMarkDefaults(), +ppdMarkOption() + + +

ppdOpen()

+

Usage

+
+ppd_file_t *ppdOpen(FILE *file);
+
+

Arguments

+
+ + + +
ArgumentDescription
fileThe file to read from
+
+

Returns

+

A pointer to a PPD file structure or NULL if the PPD file could not +be read.

+

Description

+

The ppdOpen() function reads a PPD file from the +specified file into memory.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+FILE *file;
+
+file = fopen("filename.ppd", "rb");
+ppd = ppdOpen(file);
+fclose(file);
+
+

See Also

+ ppdClose(), +ppdOpenFd(), ppdOpenFile() + + + +

ppdOpenFd()

+

Usage

+
+ppd_file_t *ppdOpenFd(int fd);
+
+

Arguments

+
+ + + +
ArgumentDescription
fdThe file descriptor to read from
+
+

Returns

+

A pointer to a PPD file structure or NULL if the PPD file could not +be read.

+

Description

+

The ppdOpenFd() function reads a PPD file from the +specified file descriptor into memory.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+int        fd;
+
+fd = open("filename.ppd", O_RDONLY);
+ppd = ppdOpenFd(fd);
+close(fd);
+
+

See Also

+ ppdClose(), +ppdOpen(), ppdOpenFile() + + +

ppdOpenFile()

+

Usage

+
+ppd_file_t *ppdOpenFile(const char *filename);
+
+

Arguments

+
+ + + +
ArgumentDescription
filenameThe name of the file to read from
+
+

Returns

+

A pointer to a PPD file structure or NULL if the PPD file could not +be read.

+

Description

+

The ppdOpenFile() function reads a PPD file from the +named file into memory.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppd = ppdOpenFile("filename.ppd");
+
+

See Also

+ ppdClose(), +ppdOpen(), ppdOpenFd() + + +

ppdPageLength()

+

Usage

+
+float ppdPageLength(ppd_file_t *ppd, const char *name);
+
+

Arguments

+
+ + + + +
ArgumentDescription
ppdThe PPD file
nameThe name of the page size
+
+

Returns

+

The length of the specified page size in points or 0 if the page +size does not exist.

+

Description

+

The ppdPageLength() function returns the page length of +the specified page size.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("Length = %.0f\n", ppdPageLength(ppd, "Letter"));
+
+

See Also

+ ppdPageLength(), +ppdPageSize(), +ppdPageWidth() + + +

ppdPageSize()

+

Usage

+
+ppd_size_t *ppdPageSize(ppd_file_t *ppd, const char *name);
+
+

Arguments

+
+ + + + +
ArgumentDescription
ppdThe PPD file
nameThe name of the page size
+
+

Returns

+

A pointer to the page size record of the specified page size in +points or NULL if the page size does not exist.

+

Description

+

The ppdPageSize() function returns the page size record +for the specified page size.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_size_t *size;
+
+size = ppdPageSize(ppd, "Letter");
+if (size != NULL)
+{
+  printf(" Width = %.0f\n", size->width);
+  printf("Length = %.0f\n", size->length);
+  printf("  Left = %.0f\n", size->left);
+  printf(" Right = %.0f\n", size->right);
+  printf("Bottom = %.0f\n", size->bottom);
+  printf("   Top = %.0f\n", size->top);
+}
+
+

See Also

+ ppdPageLength(), +ppdPageWidth() + + +

ppdPageWidth()

+

Usage

+
+float ppdPageWidth(ppd_file_t *ppd, const char *name);
+
+

Arguments

+
+ + + + +
ArgumentDescription
ppdThe PPD file
nameThe name of the page size
+
+

Returns

+

The width of the specified page size in points or 0 if the page size +does not exist.

+

Description

+

The ppdPageWidth() function returns the page width of +the specified page size.

+

Example

+
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("Width = %.0f\n", ppdPageWidth(ppd, "Letter"));
+
+

See Also

+ ppdPageLength(), +ppdPageSize() + diff --git a/doc/spm.pdf b/doc/spm.pdf new file mode 100644 index 0000000000..c96291df7c --- /dev/null +++ b/doc/spm.pdf @@ -0,0 +1,9570 @@ +%PDF-1.2 +%âãÏÓ +1 0 obj<>endobj +2 0 obj<>endobj +3 0 obj<>endobj +4 0 obj<>endobj +5 0 obj<>endobj +6 0 obj<>endobj +7 0 obj<>endobj +8 0 obj<>endobj +9 0 obj<>endobj +10 0 obj<>endobj +11 0 obj<>endobj +12 0 obj<>endobj +13 0 obj<>endobj +14 0 obj<>endobj +15 0 obj<>endobj +16 0 obj<>endobj +17 0 obj<>endobj +18 0 obj[15 0 R +17 0 R +]endobj +19 0 obj<>endobj +20 0 obj<>endobj +21 0 obj<>endobj +22 0 obj<>endobj +23 0 obj<>endobj +24 0 obj<>endobj +25 0 obj<>endobj +26 0 obj<>endobj +27 0 obj<>endobj +28 0 obj<>endobj +29 0 obj[19 0 R +20 0 R +21 0 R +22 0 R +23 0 R +24 0 R +25 0 R +26 0 R +28 0 R +]endobj +30 0 obj<>endobj +31 0 obj[30 0 R +]endobj +32 0 obj<>endobj +33 0 obj<>endobj +34 0 obj[32 0 R +33 0 R +]endobj +35 0 obj<>endobj +36 0 obj<>endobj +37 0 obj[36 0 R +]endobj +38 0 obj<>endobj +39 0 obj[38 0 R +]endobj +40 0 obj<>endobj +41 0 obj<>endobj +42 0 obj<>endobj +43 0 obj<>endobj +44 0 obj[41 0 R +43 0 R +]endobj +45 0 obj<>endobj +46 0 obj<>endobj +47 0 obj<>endobj +48 0 obj<>endobj +49 0 obj<>endobj +50 0 obj<>endobj +51 0 obj[46 0 R +48 0 R +50 0 R +]endobj +52 0 obj<>endobj +53 0 obj<>endobj +54 0 obj[53 0 R +]endobj +55 0 obj<>endobj +56 0 obj[55 0 R +]endobj +57 0 obj<>endobj +58 0 obj<>endobj +59 0 obj[58 0 R +]endobj +60 0 obj<>endobj +61 0 obj<>endobj +62 0 obj<>endobj +63 0 obj<>endobj +64 0 obj<>endobj +65 0 obj[61 0 R +62 0 R +63 0 R +64 0 R +]endobj +66 0 obj<>endobj +67 0 obj<>endobj +68 0 obj<>endobj +69 0 obj[66 0 R +67 0 R +68 0 R +]endobj +70 0 obj<>endobj +71 0 obj<>endobj +72 0 obj<>endobj +73 0 obj<>endobj +74 0 obj<>endobj +75 0 obj<>endobj +76 0 obj<>endobj +77 0 obj<>endobj +78 0 obj<>endobj +79 0 obj<>endobj +80 0 obj[70 0 R +72 0 R +74 0 R +76 0 R +77 0 R +78 0 R +79 0 R +]endobj +81 0 obj<>endobj +82 0 obj<>endobj +83 0 obj<>endobj +84 0 obj<>endobj +85 0 obj<>endobj +86 0 obj<>endobj +87 0 obj<>endobj +88 0 obj<>endobj +89 0 obj[81 0 R +82 0 R +83 0 R +84 0 R +85 0 R +86 0 R +87 0 R +88 0 R +]endobj +90 0 obj<>endobj +91 0 obj<>endobj +92 0 obj<>endobj +93 0 obj<>endobj +94 0 obj<>endobj +95 0 obj<>endobj +96 0 obj<>endobj +97 0 obj<>endobj +98 0 obj<>endobj +99 0 obj<>endobj +100 0 obj<>endobj +101 0 obj[90 0 R +92 0 R +94 0 R +96 0 R +97 0 R +98 0 R +99 0 R +100 0 R +]endobj +102 0 obj<>endobj +103 0 obj<>endobj +104 0 obj<>endobj +105 0 obj<>endobj +106 0 obj<>endobj +107 0 obj<>endobj +108 0 obj[102 0 R +103 0 R +104 0 R +105 0 R +106 0 R +107 0 R +]endobj +109 0 obj<>endobj +110 0 obj<>endobj +111 0 obj<>endobj +112 0 obj<>endobj +113 0 obj[109 0 R +110 0 R +111 0 R +112 0 R +]endobj +114 0 obj<>endobj +115 0 obj<>endobj +116 0 obj<>endobj +117 0 obj[114 0 R +115 0 R +116 0 R +]endobj +118 0 obj<>endobj +119 0 obj<>endobj +120 0 obj<>endobj +121 0 obj[118 0 R +119 0 R +120 0 R +]endobj +122 0 obj<>endobj +123 0 obj<>endobj +124 0 obj<>endobj +125 0 obj<>endobj +126 0 obj[122 0 R +123 0 R +124 0 R +125 0 R +]endobj +127 0 obj<>endobj +128 0 obj<>endobj +129 0 obj<>endobj +130 0 obj[127 0 R +129 0 R +]endobj +131 0 obj<>endobj +132 0 obj<>endobj +133 0 obj<>endobj +134 0 obj[131 0 R +132 0 R +133 0 R +]endobj +135 0 obj<>endobj +136 0 obj<>endobj +137 0 obj<>endobj +138 0 obj<>endobj +139 0 obj<>endobj +140 0 obj[135 0 R +136 0 R +137 0 R +138 0 R +139 0 R +]endobj +141 0 obj<>endobj +142 0 obj<>endobj +143 0 obj<>endobj +144 0 obj<>endobj +145 0 obj<>endobj +146 0 obj[141 0 R +142 0 R +143 0 R +144 0 R +145 0 R +]endobj +147 0 obj<>endobj +148 0 obj<>endobj +149 0 obj<>endobj +150 0 obj<>endobj +151 0 obj<>endobj +152 0 obj[147 0 R +148 0 R +149 0 R +150 0 R +151 0 R +]endobj +153 0 obj<>endobj +154 0 obj<>endobj +155 0 obj<>endobj +156 0 obj<>endobj +157 0 obj<>endobj +158 0 obj[153 0 R +154 0 R +155 0 R +156 0 R +157 0 R +]endobj +159 0 obj<>endobj +160 0 obj<>endobj +161 0 obj<>endobj +162 0 obj<>endobj +163 0 obj<>endobj +164 0 obj[159 0 R +160 0 R +161 0 R +162 0 R +163 0 R +]endobj +165 0 obj<>endobj +166 0 obj<>endobj +167 0 obj<>endobj +168 0 obj<>endobj +169 0 obj<>endobj +170 0 obj[165 0 R +166 0 R +167 0 R +168 0 R +169 0 R +]endobj +171 0 obj<>endobj +172 0 obj<>endobj +173 0 obj[171 0 R +172 0 R +]endobj +174 0 obj<>endobj +175 0 obj<>endobj +176 0 obj<>endobj +177 0 obj<>endobj +178 0 obj[174 0 R +175 0 R +176 0 R +177 0 R +]endobj +179 0 obj<>endobj +180 0 obj<>endobj +181 0 obj<>endobj +182 0 obj<>endobj +183 0 obj[179 0 R +180 0 R +181 0 R +182 0 R +]endobj +184 0 obj<>endobj +185 0 obj<>endobj +186 0 obj<>endobj +187 0 obj[184 0 R +185 0 R +186 0 R +]endobj +188 0 obj<>endobj +189 0 obj<>endobj +190 0 obj<>endobj +191 0 obj[188 0 R +189 0 R +190 0 R +]endobj +192 0 obj<>endobj +193 0 obj<>endobj +194 0 obj<>endobj +195 0 obj<>endobj +196 0 obj<>endobj +197 0 obj[192 0 R +193 0 R +194 0 R +195 0 R +196 0 R +]endobj +198 0 obj<>endobj +199 0 obj<>endobj +200 0 obj<>endobj +201 0 obj<>endobj +202 0 obj<>endobj +203 0 obj[198 0 R +199 0 R +200 0 R +201 0 R +202 0 R +]endobj +204 0 obj<>endobj +205 0 obj<>endobj +206 0 obj<>endobj +207 0 obj<>endobj +208 0 obj<>endobj +209 0 obj[204 0 R +205 0 R +206 0 R +207 0 R +208 0 R +]endobj +210 0 obj<>endobj +211 0 obj<>endobj +212 0 obj<>endobj +213 0 obj<>endobj +214 0 obj<>endobj +215 0 obj[210 0 R +211 0 R +212 0 R +213 0 R +214 0 R +]endobj +216 0 obj<>endobj +217 0 obj<>endobj +218 0 obj<>endobj +219 0 obj<>endobj +220 0 obj<>endobj +221 0 obj[216 0 R +217 0 R +218 0 R +219 0 R +220 0 R +]endobj +222 0 obj<>endobj +223 0 obj<>endobj +224 0 obj<>endobj +225 0 obj<>endobj +226 0 obj<>endobj +227 0 obj[222 0 R +223 0 R +224 0 R +225 0 R +226 0 R +]endobj +228 0 obj<>endobj +229 0 obj<>endobj +230 0 obj[228 0 R +229 0 R +]endobj +231 0 obj<>endobj +232 0 obj<>endobj +233 0 obj[231 0 R +232 0 R +]endobj +234 0 obj<>endobj +235 0 obj<>endobj +236 0 obj[234 0 R +235 0 R +]endobj +237 0 obj<>endobj +238 0 obj<>endobj +239 0 obj<>endobj +240 0 obj<>endobj +241 0 obj[237 0 R +238 0 R +239 0 R +240 0 R +]endobj +242 0 obj<>endobj +243 0 obj<>endobj +244 0 obj<>endobj +245 0 obj[242 0 R +243 0 R +244 0 R +]endobj +246 0 obj<>endobj +247 0 obj[246 0 R +]endobj +248 0 obj<>endobj +249 0 obj<>endobj +250 0 obj<>endobj +251 0 obj<>endobj +252 0 obj<>endobj +253 0 obj<>endobj +254 0 obj[248 0 R +249 0 R +250 0 R +251 0 R +252 0 R +253 0 R +]endobj +255 0 obj<>endobj +256 0 obj[255 0 R +]endobj +257 0 obj<>endobj +258 0 obj<>endobj +259 0 obj<>endobj +260 0 obj[257 0 R +258 0 R +259 0 R +]endobj +261 0 obj<>endobj +262 0 obj[261 0 R +]endobj +263 0 obj<>endobj +264 0 obj[263 0 R +]endobj +265 0 obj<>endobj +266 0 obj[265 0 R +]endobj +267 0 obj<>endobj +268 0 obj<>endobj +269 0 obj<>endobj +270 0 obj[267 0 R +268 0 R +269 0 R +]endobj +271 0 obj<>endobj +272 0 obj<>endobj +273 0 obj[271 0 R +272 0 R +]endobj +274 0 obj<>endobj +275 0 obj[274 0 R +]endobj +276 0 obj<>endobj +277 0 obj[276 0 R +]endobj +278 0 obj<>endobj +279 0 obj<>endobj +280 0 obj[278 0 R +279 0 R +]endobj +281 0 obj<>endobj +282 0 obj<>endobj +283 0 obj<>endobj +284 0 obj[281 0 R +282 0 R +283 0 R +]endobj +285 0 obj<>endobj +286 0 obj[285 0 R +]endobj +287 0 obj<>endobj +288 0 obj<>endobj +289 0 obj<>endobj +290 0 obj[287 0 R +288 0 R +289 0 R +]endobj +291 0 obj<>endobj +292 0 obj<>endobj +293 0 obj<>endobj +294 0 obj[291 0 R +292 0 R +293 0 R +]endobj +295 0 obj<>endobj +296 0 obj[295 0 R +]endobj +297 0 obj<>endobj +298 0 obj<>endobj +299 0 obj<>endobj +300 0 obj[297 0 R +298 0 R +299 0 R +]endobj +301 0 obj<>endobj +302 0 obj<>endobj +303 0 obj[301 0 R +302 0 R +]endobj +304 0 obj<>endobj +305 0 obj[304 0 R +]endobj +306 0 obj<>endobj +307 0 obj[306 0 R +]endobj +308 0 obj<>endobj +309 0 obj<>endobj +310 0 obj[308 0 R +309 0 R +]endobj +311 0 obj<>endobj +312 0 obj<>endobj +313 0 obj<>endobj +314 0 obj[311 0 R +312 0 R +313 0 R +]endobj +315 0 obj<>endobj +316 0 obj<>endobj +317 0 obj<>endobj +318 0 obj<>endobj +319 0 obj<>endobj +320 0 obj<>endobj +321 0 obj<>endobj +322 0 obj<>endobj +323 0 obj[315 0 R +316 0 R +317 0 R +318 0 R +319 0 R +320 0 R +321 0 R +322 0 R +]endobj +324 0 obj<>endobj +325 0 obj<>endobj +326 0 obj[324 0 R +325 0 R +]endobj +327 0 obj<>endobj +328 0 obj<>endobj +329 0 obj<>endobj +330 0 obj<>endobj +331 0 obj<>endobj +332 0 obj<>endobj +333 0 obj<>endobj +334 0 obj<>endobj +335 0 obj<>endobj +336 0 obj<>endobj +337 0 obj<>endobj +338 0 obj[327 0 R +328 0 R +329 0 R +330 0 R +331 0 R +332 0 R +333 0 R +334 0 R +335 0 R +336 0 R +337 0 R +]endobj +339 0 obj<>endobj +340 0 obj<>endobj +341 0 obj<>endobj +342 0 obj<>endobj +343 0 obj<>endobj +344 0 obj<>endobj +345 0 obj<>endobj +346 0 obj<>endobj +347 0 obj<>endobj +348 0 obj<>endobj +349 0 obj<>endobj +350 0 obj[339 0 R +340 0 R +341 0 R +342 0 R +343 0 R +344 0 R +345 0 R +346 0 R +347 0 R +348 0 R +349 0 R +]endobj +351 0 obj<>endobj +352 0 obj<>endobj +353 0 obj<>endobj +354 0 obj<>endobj +355 0 obj<>endobj +356 0 obj<>endobj +357 0 obj<>endobj +358 0 obj<>endobj +359 0 obj<>endobj +360 0 obj<>endobj +361 0 obj<>endobj +362 0 obj<>endobj +363 0 obj[351 0 R +352 0 R +353 0 R +354 0 R +355 0 R +356 0 R +357 0 R +358 0 R +359 0 R +360 0 R +361 0 R +362 0 R +]endobj +364 0 obj<>endobj +365 0 obj<>endobj +366 0 obj<>endobj +367 0 obj<>endobj +368 0 obj<>endobj +369 0 obj<>endobj +370 0 obj<>endobj +371 0 obj<>endobj +372 0 obj<>endobj +373 0 obj<>endobj +374 0 obj<>endobj +375 0 obj[364 0 R +365 0 R +366 0 R +367 0 R +368 0 R +369 0 R +370 0 R +371 0 R +372 0 R +373 0 R +374 0 R +]endobj +376 0 obj<>endobj +377 0 obj<>endobj +378 0 obj<>endobj +379 0 obj<>endobj +380 0 obj<>endobj +381 0 obj<>endobj +382 0 obj<>endobj +383 0 obj<>endobj +384 0 obj<>endobj +385 0 obj<>endobj +386 0 obj<>endobj +387 0 obj[376 0 R +377 0 R +378 0 R +379 0 R +380 0 R +381 0 R +382 0 R +383 0 R +384 0 R +385 0 R +386 0 R +]endobj +388 0 obj<>endobj +389 0 obj<>endobj +390 0 obj<>endobj +391 0 obj<>endobj +392 0 obj<>endobj +393 0 obj<>endobj +394 0 obj<>endobj +395 0 obj<>endobj +396 0 obj<>endobj +397 0 obj<>endobj +398 0 obj<>endobj +399 0 obj[388 0 R +389 0 R +390 0 R +391 0 R +392 0 R +393 0 R +394 0 R +395 0 R +396 0 R +397 0 R +398 0 R +]endobj +400 0 obj<>endobj +401 0 obj<>endobj +402 0 obj<>endobj +403 0 obj<>endobj +404 0 obj<>endobj +405 0 obj<>endobj +406 0 obj<>endobj +407 0 obj<>endobj +408 0 obj<>endobj +409 0 obj<>endobj +410 0 obj<>endobj +411 0 obj[400 0 R +401 0 R +402 0 R +403 0 R +404 0 R +405 0 R +406 0 R +407 0 R +408 0 R +409 0 R +410 0 R +]endobj +412 0 obj<>endobj +413 0 obj<>endobj +414 0 obj<>endobj +415 0 obj<>endobj +416 0 obj<>endobj +417 0 obj<>endobj +418 0 obj<>endobj +419 0 obj<>endobj +420 0 obj<>endobj +421 0 obj<>endobj +422 0 obj<>endobj +423 0 obj[412 0 R +413 0 R +414 0 R +415 0 R +416 0 R +417 0 R +418 0 R +419 0 R +420 0 R +421 0 R +422 0 R +]endobj +424 0 obj<>endobj +425 0 obj<>endobj +426 0 obj<>endobj +427 0 obj<>endobj +428 0 obj<>endobj +429 0 obj<>endobj +430 0 obj<>endobj +431 0 obj<>endobj +432 0 obj<>endobj +433 0 obj<>endobj +434 0 obj<>endobj +435 0 obj[424 0 R +425 0 R +426 0 R +427 0 R +428 0 R +429 0 R +430 0 R +431 0 R +432 0 R +433 0 R +434 0 R +]endobj +436 0 obj<>endobj +437 0 obj<>endobj +438 0 obj<>endobj +439 0 obj<>endobj +440 0 obj<>endobj +441 0 obj<>endobj +442 0 obj<>endobj +443 0 obj<>endobj +444 0 obj<>endobj +445 0 obj<>endobj +446 0 obj<>endobj +447 0 obj[436 0 R +437 0 R +438 0 R +439 0 R +440 0 R +441 0 R +442 0 R +443 0 R +444 0 R +445 0 R +446 0 R +]endobj +448 0 obj<>endobj +449 0 obj<>endobj +450 0 obj<>endobj +451 0 obj<>endobj +452 0 obj<>endobj +453 0 obj<>endobj +454 0 obj<>endobj +455 0 obj<>endobj +456 0 obj<>endobj +457 0 obj<>endobj +458 0 obj<>endobj +459 0 obj[448 0 R +449 0 R +450 0 R +451 0 R +452 0 R +453 0 R +454 0 R +455 0 R +456 0 R +457 0 R +458 0 R +]endobj +460 0 obj<>endobj +461 0 obj<>endobj +462 0 obj<>endobj +463 0 obj<>endobj +464 0 obj<>endobj +465 0 obj<>endobj +466 0 obj<>endobj +467 0 obj<>endobj +468 0 obj<>endobj +469 0 obj<>endobj +470 0 obj<>endobj +471 0 obj[460 0 R +461 0 R +462 0 R +463 0 R +464 0 R +465 0 R +466 0 R +467 0 R +468 0 R +469 0 R +470 0 R +]endobj +472 0 obj<>endobj +473 0 obj[472 0 R +]endobj +474 0 obj<>endobj +475 0 obj[474 0 R +]endobj +476 0 obj<>endobj +477 0 obj[476 0 R +]endobj +478 0 obj<>endobj +479 0 obj[478 0 R +]endobj +480 0 obj<>endobj +481 0 obj[480 0 R +]endobj +482 0 obj<>endobj +483 0 obj[482 0 R +]endobj +484 0 obj<>endobj +485 0 obj[484 0 R +]endobj +486 0 obj<>endobj +487 0 obj<>endobj +488 0 obj<>endobj +489 0 obj[486 0 R +487 0 R +488 0 R +]endobj +490 0 obj<>endobj +491 0 obj<>endobj +492 0 obj<>endobj +493 0 obj<>endobj +494 0 obj[490 0 R +491 0 R +492 0 R +493 0 R +]endobj +495 0 obj<>endobj +496 0 obj[495 0 R +]endobj +497 0 obj<>endobj +498 0 obj[497 0 R +]endobj +499 0 obj<>endobj +500 0 obj<>endobj +501 0 obj[499 0 R +500 0 R +]endobj +502 0 obj<>endobj +503 0 obj<>endobj +504 0 obj[502 0 R +503 0 R +]endobj +505 0 obj<>endobj +506 0 obj<>endobj +507 0 obj[505 0 R +506 0 R +]endobj +508 0 obj<>endobj +509 0 obj<>endobj +510 0 obj<>endobj +511 0 obj<>endobj +512 0 obj<>endobj +513 0 obj[508 0 R +509 0 R +510 0 R +511 0 R +512 0 R +]endobj +514 0 obj<>endobj +515 0 obj<>endobj +516 0 obj<>endobj +517 0 obj<>endobj +518 0 obj<>endobj +519 0 obj[514 0 R +515 0 R +516 0 R +517 0 R +518 0 R +]endobj +520 0 obj<>endobj +521 0 obj<>endobj +522 0 obj<>endobj +523 0 obj<>endobj +524 0 obj<>endobj +525 0 obj[520 0 R +521 0 R +522 0 R +523 0 R +524 0 R +]endobj +526 0 obj<>endobj +527 0 obj<>endobj +528 0 obj<>endobj +529 0 obj[526 0 R +527 0 R +528 0 R +]endobj +530 0 obj<>endobj +531 0 obj<>endobj +532 0 obj<>endobj +533 0 obj[530 0 R +531 0 R +532 0 R +]endobj +534 0 obj<>endobj +535 0 obj<>endobj +536 0 obj<>endobj +537 0 obj[534 0 R +535 0 R +536 0 R +]endobj +538 0 obj<>endobj +539 0 obj<>endobj +540 0 obj<>endobj +541 0 obj[538 0 R +539 0 R +540 0 R +]endobj +542 0 obj<>endobj +543 0 obj<>endobj +544 0 obj[542 0 R +543 0 R +]endobj +545 0 obj<>endobj +546 0 obj<>endobj +547 0 obj[545 0 R +546 0 R +]endobj +548 0 obj<>endobj +549 0 obj<>endobj +550 0 obj<>endobj +551 0 obj<>endobj +552 0 obj<>endobj +553 0 obj<>endobj +554 0 obj<>endobj +555 0 obj<>endobj +556 0 obj<>endobj +557 0 obj<>endobj +558 0 obj<>endobj +559 0 obj<>endobj +560 0 obj<>endobj +561 0 obj<>endobj +562 0 obj<>endobj +563 0 obj<>endobj +564 0 obj<>endobj +565 0 obj<>endobj +566 0 obj<>endobj +567 0 obj<>endobj +568 0 obj<>endobj +569 0 obj<>endobj +570 0 obj<>endobj +571 0 obj<>endobj +572 0 obj<>endobj +573 0 obj<>endobj +574 0 obj<>endobj +575 0 obj<>endobj +576 0 obj<>endobj +577 0 obj<>endobj +578 0 obj<>endobj +579 0 obj<>endobj +580 0 obj<>endobj +581 0 obj<>endobj +582 0 obj<>endobj +583 0 obj<>endobj +584 0 obj<>endobj +585 0 obj<>endobj +586 0 obj<>endobj +587 0 obj<>endobj +588 0 obj<>endobj +589 0 obj<>endobj +590 0 obj<>endobj +591 0 obj<>endobj +592 0 obj[548 0 R +549 0 R +550 0 R +551 0 R +552 0 R +553 0 R +554 0 R +555 0 R +556 0 R +557 0 R +558 0 R +559 0 R +560 0 R +561 0 R +562 0 R +563 0 R +564 0 R +565 0 R +566 0 R +567 0 R +568 0 R +569 0 R +570 0 R +571 0 R +572 0 R +573 0 R +574 0 R +575 0 R +576 0 R +577 0 R +578 0 R +579 0 R +580 0 R +581 0 R +582 0 R +583 0 R +584 0 R +585 0 R +586 0 R +587 0 R +588 0 R +589 0 R +590 0 R +591 0 R +]endobj +593 0 obj<>endobj +594 0 obj<>endobj +595 0 obj<>endobj +596 0 obj<>endobj +597 0 obj<>endobj +598 0 obj<>endobj +599 0 obj<>endobj +600 0 obj<>endobj +601 0 obj<>endobj +602 0 obj<>endobj +603 0 obj<>endobj +604 0 obj<>endobj +605 0 obj<>endobj +606 0 obj<>endobj +607 0 obj<>endobj +608 0 obj<>endobj +609 0 obj<>endobj +610 0 obj<>endobj +611 0 obj<>endobj +612 0 obj<>endobj +613 0 obj<>endobj +614 0 obj<>endobj +615 0 obj<>endobj +616 0 obj<>endobj +617 0 obj<>endobj +618 0 obj<>endobj +619 0 obj<>endobj +620 0 obj<>endobj +621 0 obj<>endobj +622 0 obj<>endobj +623 0 obj<>endobj +624 0 obj<>endobj +625 0 obj<>endobj +626 0 obj<>endobj +627 0 obj<>endobj +628 0 obj<>endobj +629 0 obj<>endobj +630 0 obj<>endobj +631 0 obj<>endobj +632 0 obj<>endobj +633 0 obj<>endobj +634 0 obj<>endobj +635 0 obj<>endobj +636 0 obj[593 0 R +594 0 R +595 0 R +596 0 R +597 0 R +598 0 R +599 0 R +600 0 R +601 0 R +602 0 R +603 0 R +604 0 R +605 0 R +606 0 R +607 0 R +608 0 R +609 0 R +610 0 R +611 0 R +612 0 R +613 0 R +614 0 R +615 0 R +616 0 R +617 0 R +618 0 R +619 0 R +620 0 R +621 0 R +622 0 R +623 0 R +624 0 R +625 0 R +626 0 R +627 0 R +628 0 R +629 0 R +630 0 R +631 0 R +632 0 R +633 0 R +634 0 R +635 0 R +]endobj +637 0 obj<>endobj +638 0 obj<>endobj +639 0 obj<>endobj +640 0 obj<>endobj +641 0 obj<>endobj +642 0 obj<>endobj +643 0 obj<>endobj +644 0 obj<>endobj +645 0 obj<>endobj +646 0 obj<>endobj +647 0 obj<>endobj +648 0 obj<>endobj +649 0 obj<>endobj +650 0 obj<>endobj +651 0 obj<>endobj +652 0 obj<>endobj +653 0 obj<>endobj +654 0 obj<>endobj +655 0 obj<>endobj +656 0 obj<>endobj +657 0 obj<>endobj +658 0 obj<>endobj +659 0 obj<>endobj +660 0 obj<>endobj +661 0 obj<>endobj +662 0 obj<>endobj +663 0 obj<>endobj +664 0 obj<>endobj +665 0 obj<>endobj +666 0 obj<>endobj +667 0 obj<>endobj +668 0 obj<>endobj +669 0 obj<>endobj +670 0 obj<>endobj +671 0 obj<>endobj +672 0 obj<>endobj +673 0 obj<>endobj +674 0 obj<>endobj +675 0 obj<>endobj +676 0 obj<>endobj +677 0 obj<>endobj +678 0 obj<>endobj +679 0 obj<>endobj +680 0 obj<>endobj +681 0 obj<>endobj +682 0 obj[637 0 R +638 0 R +639 0 R +640 0 R +641 0 R +642 0 R +643 0 R +644 0 R +645 0 R +646 0 R +647 0 R +648 0 R +649 0 R +650 0 R +651 0 R +652 0 R +653 0 R +654 0 R +655 0 R +656 0 R +657 0 R +658 0 R +659 0 R +660 0 R +661 0 R +662 0 R +663 0 R +664 0 R +665 0 R +666 0 R +667 0 R +668 0 R +669 0 R +670 0 R +671 0 R +672 0 R +673 0 R +674 0 R +675 0 R +676 0 R +677 0 R +678 0 R +679 0 R +680 0 R +681 0 R +]endobj +683 0 obj<>endobj +684 0 obj<>endobj +685 0 obj<>endobj +686 0 obj<>endobj +687 0 obj<>endobj +688 0 obj<>endobj +689 0 obj<>endobj +690 0 obj<>endobj +691 0 obj<>endobj +692 0 obj<>endobj +693 0 obj<>endobj +694 0 obj<>endobj +695 0 obj<>endobj +696 0 obj<>endobj +697 0 obj<>endobj +698 0 obj<>endobj +699 0 obj<>endobj +700 0 obj<>endobj +701 0 obj<>endobj +702 0 obj<>endobj +703 0 obj<>endobj +704 0 obj<>endobj +705 0 obj<>endobj +706 0 obj<>endobj +707 0 obj<>endobj +708 0 obj<>endobj +709 0 obj<>endobj +710 0 obj<>endobj +711 0 obj<>endobj +712 0 obj<>endobj +713 0 obj<>endobj +714 0 obj<>endobj +715 0 obj<>endobj +716 0 obj<>endobj +717 0 obj<>endobj +718 0 obj<>endobj +719 0 obj<>endobj +720 0 obj<>endobj +721 0 obj<>endobj +722 0 obj<>endobj +723 0 obj<>endobj +724 0 obj<>endobj +725 0 obj<>endobj +726 0 obj<>endobj +727 0 obj<>endobj +728 0 obj<>endobj +729 0 obj<>endobj +730 0 obj[683 0 R +684 0 R +685 0 R +686 0 R +687 0 R +688 0 R +689 0 R +690 0 R +691 0 R +692 0 R +693 0 R +694 0 R +695 0 R +696 0 R +697 0 R +698 0 R +699 0 R +700 0 R +701 0 R +702 0 R +703 0 R +704 0 R +705 0 R +706 0 R +707 0 R +708 0 R +709 0 R +710 0 R +711 0 R +712 0 R +713 0 R +714 0 R +715 0 R +716 0 R +717 0 R +718 0 R +719 0 R +720 0 R +721 0 R +722 0 R +723 0 R +724 0 R +725 0 R +726 0 R +727 0 R +728 0 R +729 0 R +]endobj +731 0 obj<>endobj +732 0 obj<>endobj +733 0 obj<>endobj +734 0 obj<>endobj +735 0 obj<>endobj +736 0 obj<>endobj +737 0 obj<>endobj +738 0 obj<>endobj +739 0 obj<>endobj +740 0 obj<>endobj +741 0 obj<>endobj +742 0 obj<>endobj +743 0 obj<>endobj +744 0 obj<>endobj +745 0 obj<>endobj +746 0 obj<>endobj +747 0 obj<>endobj +748 0 obj<>endobj +749 0 obj<>endobj +750 0 obj<>endobj +751 0 obj<>endobj +752 0 obj<>endobj +753 0 obj<>endobj +754 0 obj<>endobj +755 0 obj<>endobj +756 0 obj<>endobj +757 0 obj<>endobj +758 0 obj<>endobj +759 0 obj<>endobj +760 0 obj<>endobj +761 0 obj<>endobj +762 0 obj<>endobj +763 0 obj<>endobj +764 0 obj<>endobj +765 0 obj<>endobj +766 0 obj<>endobj +767 0 obj<>endobj +768 0 obj<>endobj +769 0 obj<>endobj +770 0 obj<>endobj +771 0 obj<>endobj +772 0 obj<>endobj +773 0 obj<>endobj +774 0 obj<>endobj +775 0 obj<>endobj +776 0 obj<>endobj +777 0 obj<>endobj +778 0 obj[731 0 R +732 0 R +733 0 R +734 0 R +735 0 R +736 0 R +737 0 R +738 0 R +739 0 R +740 0 R +741 0 R +742 0 R +743 0 R +744 0 R +745 0 R +746 0 R +747 0 R +748 0 R +749 0 R +750 0 R +751 0 R +752 0 R +753 0 R +754 0 R +755 0 R +756 0 R +757 0 R +758 0 R +759 0 R +760 0 R +761 0 R +762 0 R +763 0 R +764 0 R +765 0 R +766 0 R +767 0 R +768 0 R +769 0 R +770 0 R +771 0 R +772 0 R +773 0 R +774 0 R +775 0 R +776 0 R +777 0 R +]endobj +779 0 obj<>endobj +780 0 obj<>endobj +781 0 obj<>endobj +782 0 obj<>endobj +783 0 obj<>endobj +784 0 obj<>endobj +785 0 obj<>endobj +786 0 obj<>endobj +787 0 obj<>endobj +788 0 obj<>endobj +789 0 obj<>endobj +790 0 obj<>endobj +791 0 obj<>endobj +792 0 obj<>endobj +793 0 obj<>endobj +794 0 obj<>endobj +795 0 obj<>endobj +796 0 obj<>endobj +797 0 obj<>endobj +798 0 obj<>endobj +799 0 obj<>endobj +800 0 obj<>endobj +801 0 obj<>endobj +802 0 obj<>endobj +803 0 obj<>endobj +804 0 obj<>endobj +805 0 obj<>endobj +806 0 obj<>endobj +807 0 obj<>endobj +808 0 obj<>endobj +809 0 obj<>endobj +810 0 obj<>endobj +811 0 obj<>endobj +812 0 obj<>endobj +813 0 obj<>endobj +814 0 obj<>endobj +815 0 obj<>endobj +816 0 obj<>endobj +817 0 obj<>endobj +818 0 obj<>endobj +819 0 obj<>endobj +820 0 obj<>endobj +821 0 obj<>endobj +822 0 obj<>endobj +823 0 obj<>endobj +824 0 obj<>endobj +825 0 obj<>endobj +826 0 obj[779 0 R +780 0 R +781 0 R +782 0 R +783 0 R +784 0 R +785 0 R +786 0 R +787 0 R +788 0 R +789 0 R +790 0 R +791 0 R +792 0 R +793 0 R +794 0 R +795 0 R +796 0 R +797 0 R +798 0 R +799 0 R +800 0 R +801 0 R +802 0 R +803 0 R +804 0 R +805 0 R +806 0 R +807 0 R +808 0 R +809 0 R +810 0 R +811 0 R +812 0 R +813 0 R +814 0 R +815 0 R +816 0 R +817 0 R +818 0 R +819 0 R +820 0 R +821 0 R +822 0 R +823 0 R +824 0 R +825 0 R +]endobj +827 0 obj<>endobj +828 0 obj<>endobj +829 0 obj<>endobj +830 0 obj<>endobj +831 0 obj<>endobj +832 0 obj<>endobj +833 0 obj<>endobj +834 0 obj<>endobj +835 0 obj<>endobj +836 0 obj<>endobj +837 0 obj<>endobj +838 0 obj<>endobj +839 0 obj<>endobj +840 0 obj<>endobj +841 0 obj<>endobj +842 0 obj<>endobj +843 0 obj<>endobj +844 0 obj<>endobj +845 0 obj<>endobj +846 0 obj<>endobj +847 0 obj<>endobj +848 0 obj<>endobj +849 0 obj<>endobj +850 0 obj<>endobj +851 0 obj<>endobj +852 0 obj<>endobj +853 0 obj<>endobj +854 0 obj<>endobj +855 0 obj<>endobj +856 0 obj<>endobj +857 0 obj<>endobj +858 0 obj<>endobj +859 0 obj<>endobj +860 0 obj<>endobj +861 0 obj<>endobj +862 0 obj<>endobj +863 0 obj<>endobj +864 0 obj<>endobj +865 0 obj<>endobj +866 0 obj<>endobj +867 0 obj<>endobj +868 0 obj<>endobj +869 0 obj<>endobj +870 0 obj<>endobj +871 0 obj<>endobj +872 0 obj<>endobj +873 0 obj<>endobj +874 0 obj[827 0 R +828 0 R +829 0 R +830 0 R +831 0 R +832 0 R +833 0 R +834 0 R +835 0 R +836 0 R +837 0 R +838 0 R +839 0 R +840 0 R +841 0 R +842 0 R +843 0 R +844 0 R +845 0 R +846 0 R +847 0 R +848 0 R +849 0 R +850 0 R +851 0 R +852 0 R +853 0 R +854 0 R +855 0 R +856 0 R +857 0 R +858 0 R +859 0 R +860 0 R +861 0 R +862 0 R +863 0 R +864 0 R +865 0 R +866 0 R +867 0 R +868 0 R +869 0 R +870 0 R +871 0 R +872 0 R +873 0 R +]endobj +875 0 obj<>endobj +876 0 obj<>endobj +877 0 obj<>endobj +878 0 obj<>endobj +879 0 obj<>endobj +880 0 obj<>endobj +881 0 obj<>endobj +882 0 obj<>endobj +883 0 obj<>endobj +884 0 obj<>endobj +885 0 obj<>endobj +886 0 obj<>endobj +887 0 obj<>endobj +888 0 obj<>endobj +889 0 obj<>endobj +890 0 obj<>endobj +891 0 obj<>endobj +892 0 obj<>endobj +893 0 obj<>endobj +894 0 obj<>endobj +895 0 obj<>endobj +896 0 obj<>endobj +897 0 obj<>endobj +898 0 obj<>endobj +899 0 obj<>endobj +900 0 obj<>endobj +901 0 obj<>endobj +902 0 obj<>endobj +903 0 obj<>endobj +904 0 obj<>endobj +905 0 obj<>endobj +906 0 obj<>endobj +907 0 obj<>endobj +908 0 obj<>endobj +909 0 obj<>endobj +910 0 obj<>endobj +911 0 obj<>endobj +912 0 obj<>endobj +913 0 obj<>endobj +914 0 obj<>endobj +915 0 obj<>endobj +916 0 obj<>endobj +917 0 obj<>endobj +918 0 obj<>endobj +919 0 obj<>endobj +920 0 obj<>endobj +921 0 obj<>endobj +922 0 obj[875 0 R +876 0 R +877 0 R +878 0 R +879 0 R +880 0 R +881 0 R +882 0 R +883 0 R +884 0 R +885 0 R +886 0 R +887 0 R +888 0 R +889 0 R +890 0 R +891 0 R +892 0 R +893 0 R +894 0 R +895 0 R +896 0 R +897 0 R +898 0 R +899 0 R +900 0 R +901 0 R +902 0 R +903 0 R +904 0 R +905 0 R +906 0 R +907 0 R +908 0 R +909 0 R +910 0 R +911 0 R +912 0 R +913 0 R +914 0 R +915 0 R +916 0 R +917 0 R +918 0 R +919 0 R +920 0 R +921 0 R +]endobj +923 0 obj<>endobj +924 0 obj<>endobj +925 0 obj<>endobj +926 0 obj<>endobj +927 0 obj<>endobj +928 0 obj<>endobj +929 0 obj<>endobj +930 0 obj<>endobj +931 0 obj<>endobj +932 0 obj<>endobj +933 0 obj<>endobj +934 0 obj<>endobj +935 0 obj<>endobj +936 0 obj<>endobj +937 0 obj<>endobj +938 0 obj<>endobj +939 0 obj<>endobj +940 0 obj<>endobj +941 0 obj<>endobj +942 0 obj<>endobj +943 0 obj<>endobj +944 0 obj<>endobj +945 0 obj<>endobj +946 0 obj<>endobj +947 0 obj<>endobj +948 0 obj<>endobj +949 0 obj<>endobj +950 0 obj<>endobj +951 0 obj<>endobj +952 0 obj<>endobj +953 0 obj<>endobj +954 0 obj<>endobj +955 0 obj<>endobj +956 0 obj<>endobj +957 0 obj<>endobj +958 0 obj<>endobj +959 0 obj<>endobj +960 0 obj<>endobj +961 0 obj<>endobj +962 0 obj<>endobj +963 0 obj<>endobj +964 0 obj<>endobj +965 0 obj<>endobj +966 0 obj<>endobj +967 0 obj<>endobj +968 0 obj<>endobj +969 0 obj<>endobj +970 0 obj[923 0 R +924 0 R +925 0 R +926 0 R +927 0 R +928 0 R +929 0 R +930 0 R +931 0 R +932 0 R +933 0 R +934 0 R +935 0 R +936 0 R +937 0 R +938 0 R +939 0 R +940 0 R +941 0 R +942 0 R +943 0 R +944 0 R +945 0 R +946 0 R +947 0 R +948 0 R +949 0 R +950 0 R +951 0 R +952 0 R +953 0 R +954 0 R +955 0 R +956 0 R +957 0 R +958 0 R +959 0 R +960 0 R +961 0 R +962 0 R +963 0 R +964 0 R +965 0 R +966 0 R +967 0 R +968 0 R +969 0 R +]endobj +971 0 obj<>endobj +972 0 obj<>endobj +973 0 obj<>endobj +974 0 obj<>endobj +975 0 obj<>endobj +976 0 obj<>endobj +977 0 obj<>endobj +978 0 obj<>endobj +979 0 obj<>endobj +980 0 obj<>endobj +981 0 obj<>endobj +982 0 obj<>endobj +983 0 obj<>endobj +984 0 obj<>endobj +985 0 obj<>endobj +986 0 obj<>endobj +987 0 obj<>endobj +988 0 obj<>endobj +989 0 obj<>endobj +990 0 obj<>endobj +991 0 obj<>endobj +992 0 obj<>endobj +993 0 obj<>endobj +994 0 obj<>endobj +995 0 obj<>endobj +996 0 obj<>endobj +997 0 obj<>endobj +998 0 obj<>endobj +999 0 obj<>endobj +1000 0 obj<>endobj +1001 0 obj<>endobj +1002 0 obj<>endobj +1003 0 obj<>endobj +1004 0 obj<>endobj +1005 0 obj<>endobj +1006 0 obj<>endobj +1007 0 obj<>endobj +1008 0 obj<>endobj +1009 0 obj<>endobj +1010 0 obj<>endobj +1011 0 obj<>endobj +1012 0 obj<>endobj +1013 0 obj<>endobj +1014 0 obj<>endobj +1015 0 obj<>endobj +1016 0 obj<>endobj +1017 0 obj<>endobj +1018 0 obj[971 0 R +972 0 R +973 0 R +974 0 R +975 0 R +976 0 R +977 0 R +978 0 R +979 0 R +980 0 R +981 0 R +982 0 R +983 0 R +984 0 R +985 0 R +986 0 R +987 0 R +988 0 R +989 0 R +990 0 R +991 0 R +992 0 R +993 0 R +994 0 R +995 0 R +996 0 R +997 0 R +998 0 R +999 0 R +1000 0 R +1001 0 R +1002 0 R +1003 0 R +1004 0 R +1005 0 R +1006 0 R +1007 0 R +1008 0 R +1009 0 R +1010 0 R +1011 0 R +1012 0 R +1013 0 R +1014 0 R +1015 0 R +1016 0 R +1017 0 R +]endobj +1019 0 obj<>endobj +1020 0 obj<>endobj +1021 0 obj<>endobj +1022 0 obj<>endobj +1023 0 obj<>endobj +1024 0 obj<>endobj +1025 0 obj<>endobj +1026 0 obj<>endobj +1027 0 obj<>endobj +1028 0 obj<>endobj +1029 0 obj<>endobj +1030 0 obj<>endobj +1031 0 obj<>endobj +1032 0 obj<>endobj +1033 0 obj<>endobj +1034 0 obj<>endobj +1035 0 obj<>endobj +1036 0 obj<>endobj +1037 0 obj<>endobj +1038 0 obj<>endobj +1039 0 obj<>endobj +1040 0 obj<>endobj +1041 0 obj<>endobj +1042 0 obj<>endobj +1043 0 obj<>endobj +1044 0 obj<>endobj +1045 0 obj<>endobj +1046 0 obj<>endobj +1047 0 obj<>endobj +1048 0 obj<>endobj +1049 0 obj<>endobj +1050 0 obj<>endobj +1051 0 obj<>endobj +1052 0 obj<>endobj +1053 0 obj<>endobj +1054 0 obj<>endobj +1055 0 obj<>endobj +1056 0 obj<>endobj +1057 0 obj<>endobj +1058 0 obj<>endobj +1059 0 obj<>endobj +1060 0 obj<>endobj +1061 0 obj<>endobj +1062 0 obj<>endobj +1063 0 obj<>endobj +1064 0 obj<>endobj +1065 0 obj<>endobj +1066 0 obj[1019 0 R +1020 0 R +1021 0 R +1022 0 R +1023 0 R +1024 0 R +1025 0 R +1026 0 R +1027 0 R +1028 0 R +1029 0 R +1030 0 R +1031 0 R +1032 0 R +1033 0 R +1034 0 R +1035 0 R +1036 0 R +1037 0 R +1038 0 R +1039 0 R +1040 0 R +1041 0 R +1042 0 R +1043 0 R +1044 0 R +1045 0 R +1046 0 R +1047 0 R +1048 0 R +1049 0 R +1050 0 R +1051 0 R +1052 0 R +1053 0 R +1054 0 R +1055 0 R +1056 0 R +1057 0 R +1058 0 R +1059 0 R +1060 0 R +1061 0 R +1062 0 R +1063 0 R +1064 0 R +1065 0 R +]endobj +1067 0 obj<>endobj +1068 0 obj<>endobj +1069 0 obj<>endobj +1070 0 obj<>endobj +1071 0 obj<>endobj +1072 0 obj<>endobj +1073 0 obj<>endobj +1074 0 obj<>endobj +1075 0 obj<>endobj +1076 0 obj<>endobj +1077 0 obj<>endobj +1078 0 obj<>endobj +1079 0 obj<>endobj +1080 0 obj<>endobj +1081 0 obj<>endobj +1082 0 obj<>endobj +1083 0 obj<>endobj +1084 0 obj<>endobj +1085 0 obj<>endobj +1086 0 obj<>endobj +1087 0 obj<>endobj +1088 0 obj<>endobj +1089 0 obj<>endobj +1090 0 obj<>endobj +1091 0 obj<>endobj +1092 0 obj<>endobj +1093 0 obj<>endobj +1094 0 obj<>endobj +1095 0 obj<>endobj +1096 0 obj<>endobj +1097 0 obj<>endobj +1098 0 obj<>endobj +1099 0 obj<>endobj +1100 0 obj<>endobj +1101 0 obj<>endobj +1102 0 obj<>endobj +1103 0 obj<>endobj +1104 0 obj<>endobj +1105 0 obj<>endobj +1106 0 obj<>endobj +1107 0 obj<>endobj +1108 0 obj<>endobj +1109 0 obj<>endobj +1110 0 obj<>endobj +1111 0 obj<>endobj +1112 0 obj<>endobj +1113 0 obj<>endobj +1114 0 obj[1067 0 R +1068 0 R +1069 0 R +1070 0 R +1071 0 R +1072 0 R +1073 0 R +1074 0 R +1075 0 R +1076 0 R +1077 0 R +1078 0 R +1079 0 R +1080 0 R +1081 0 R +1082 0 R +1083 0 R +1084 0 R +1085 0 R +1086 0 R +1087 0 R +1088 0 R +1089 0 R +1090 0 R +1091 0 R +1092 0 R +1093 0 R +1094 0 R +1095 0 R +1096 0 R +1097 0 R +1098 0 R +1099 0 R +1100 0 R +1101 0 R +1102 0 R +1103 0 R +1104 0 R +1105 0 R +1106 0 R +1107 0 R +1108 0 R +1109 0 R +1110 0 R +1111 0 R +1112 0 R +1113 0 R +]endobj +1115 0 obj<>endobj +1116 0 obj<>endobj +1117 0 obj<>endobj +1118 0 obj<>endobj +1119 0 obj<>endobj +1120 0 obj<>endobj +1121 0 obj<>endobj +1122 0 obj<>endobj +1123 0 obj<>endobj +1124 0 obj<>endobj +1125 0 obj<>endobj +1126 0 obj<>endobj +1127 0 obj<>endobj +1128 0 obj<>endobj +1129 0 obj<>endobj +1130 0 obj<>endobj +1131 0 obj<>endobj +1132 0 obj<>endobj +1133 0 obj<>endobj +1134 0 obj<>endobj +1135 0 obj<>endobj +1136 0 obj<>endobj +1137 0 obj<>endobj +1138 0 obj<>endobj +1139 0 obj<>endobj +1140 0 obj<>endobj +1141 0 obj<>endobj +1142 0 obj<>endobj +1143 0 obj<>endobj +1144 0 obj<>endobj +1145 0 obj<>endobj +1146 0 obj<>endobj +1147 0 obj<>endobj +1148 0 obj<>endobj +1149 0 obj<>endobj +1150 0 obj<>endobj +1151 0 obj<>endobj +1152 0 obj<>endobj +1153 0 obj<>endobj +1154 0 obj<>endobj +1155 0 obj<>endobj +1156 0 obj<>endobj +1157 0 obj<>endobj +1158 0 obj<>endobj +1159 0 obj<>endobj +1160 0 obj<>endobj +1161 0 obj<>endobj +1162 0 obj[1115 0 R +1116 0 R +1117 0 R +1118 0 R +1119 0 R +1120 0 R +1121 0 R +1122 0 R +1123 0 R +1124 0 R +1125 0 R +1126 0 R +1127 0 R +1128 0 R +1129 0 R +1130 0 R +1131 0 R +1132 0 R +1133 0 R +1134 0 R +1135 0 R +1136 0 R +1137 0 R +1138 0 R +1139 0 R +1140 0 R +1141 0 R +1142 0 R +1143 0 R +1144 0 R +1145 0 R +1146 0 R +1147 0 R +1148 0 R +1149 0 R +1150 0 R +1151 0 R +1152 0 R +1153 0 R +1154 0 R +1155 0 R +1156 0 R +1157 0 R +1158 0 R +1159 0 R +1160 0 R +1161 0 R +]endobj +1163 0 obj<>endobj +1164 0 obj<>endobj +1165 0 obj<>endobj +1166 0 obj<>endobj +1167 0 obj<>endobj +1168 0 obj<>endobj +1169 0 obj<>endobj +1170 0 obj<>endobj +1171 0 obj<>endobj +1172 0 obj<>endobj +1173 0 obj<>endobj +1174 0 obj<>endobj +1175 0 obj<>endobj +1176 0 obj<>endobj +1177 0 obj<>endobj +1178 0 obj<>endobj +1179 0 obj<>endobj +1180 0 obj<>endobj +1181 0 obj<>endobj +1182 0 obj<>endobj +1183 0 obj<>endobj +1184 0 obj<>endobj +1185 0 obj<>endobj +1186 0 obj<>endobj +1187 0 obj<>endobj +1188 0 obj<>endobj +1189 0 obj<>endobj +1190 0 obj<>endobj +1191 0 obj<>endobj +1192 0 obj<>endobj +1193 0 obj<>endobj +1194 0 obj<>endobj +1195 0 obj<>endobj +1196 0 obj<>endobj +1197 0 obj<>endobj +1198 0 obj<>endobj +1199 0 obj<>endobj +1200 0 obj<>endobj +1201 0 obj<>endobj +1202 0 obj<>endobj +1203 0 obj<>endobj +1204 0 obj<>endobj +1205 0 obj<>endobj +1206 0 obj<>endobj +1207 0 obj<>endobj +1208 0 obj<>endobj +1209 0 obj<>endobj +1210 0 obj[1163 0 R +1164 0 R +1165 0 R +1166 0 R +1167 0 R +1168 0 R +1169 0 R +1170 0 R +1171 0 R +1172 0 R +1173 0 R +1174 0 R +1175 0 R +1176 0 R +1177 0 R +1178 0 R +1179 0 R +1180 0 R +1181 0 R +1182 0 R +1183 0 R +1184 0 R +1185 0 R +1186 0 R +1187 0 R +1188 0 R +1189 0 R +1190 0 R +1191 0 R +1192 0 R +1193 0 R +1194 0 R +1195 0 R +1196 0 R +1197 0 R +1198 0 R +1199 0 R +1200 0 R +1201 0 R +1202 0 R +1203 0 R +1204 0 R +1205 0 R +1206 0 R +1207 0 R +1208 0 R +1209 0 R +]endobj +1211 0 obj<>endobj +1212 0 obj<>endobj +1213 0 obj<>endobj +1214 0 obj<>endobj +1215 0 obj<>endobj +1216 0 obj<>endobj +1217 0 obj<>endobj +1218 0 obj<>endobj +1219 0 obj<>endobj +1220 0 obj<>endobj +1221 0 obj<>endobj +1222 0 obj<>endobj +1223 0 obj<>endobj +1224 0 obj<>endobj +1225 0 obj<>endobj +1226 0 obj<>endobj +1227 0 obj<>endobj +1228 0 obj<>endobj +1229 0 obj<>endobj +1230 0 obj<>endobj +1231 0 obj<>endobj +1232 0 obj<>endobj +1233 0 obj<>endobj +1234 0 obj<>endobj +1235 0 obj<>endobj +1236 0 obj<>endobj +1237 0 obj<>endobj +1238 0 obj<>endobj +1239 0 obj<>endobj +1240 0 obj<>endobj +1241 0 obj<>endobj +1242 0 obj<>endobj +1243 0 obj<>endobj +1244 0 obj<>endobj +1245 0 obj<>endobj +1246 0 obj<>endobj +1247 0 obj<>endobj +1248 0 obj<>endobj +1249 0 obj<>endobj +1250 0 obj<>endobj +1251 0 obj<>endobj +1252 0 obj<>endobj +1253 0 obj<>endobj +1254 0 obj<>endobj +1255 0 obj<>endobj +1256 0 obj<>endobj +1257 0 obj<>endobj +1258 0 obj[1211 0 R +1212 0 R +1213 0 R +1214 0 R +1215 0 R +1216 0 R +1217 0 R +1218 0 R +1219 0 R +1220 0 R +1221 0 R +1222 0 R +1223 0 R +1224 0 R +1225 0 R +1226 0 R +1227 0 R +1228 0 R +1229 0 R +1230 0 R +1231 0 R +1232 0 R +1233 0 R +1234 0 R +1235 0 R +1236 0 R +1237 0 R +1238 0 R +1239 0 R +1240 0 R +1241 0 R +1242 0 R +1243 0 R +1244 0 R +1245 0 R +1246 0 R +1247 0 R +1248 0 R +1249 0 R +1250 0 R +1251 0 R +1252 0 R +1253 0 R +1254 0 R +1255 0 R +1256 0 R +1257 0 R +]endobj +1259 0 obj<>endobj +1260 0 obj<>endobj +1261 0 obj<>endobj +1262 0 obj<>endobj +1263 0 obj<>endobj +1264 0 obj<>endobj +1265 0 obj<>endobj +1266 0 obj<>endobj +1267 0 obj<>endobj +1268 0 obj<>endobj +1269 0 obj<>endobj +1270 0 obj<>endobj +1271 0 obj<>endobj +1272 0 obj<>endobj +1273 0 obj<>endobj +1274 0 obj<>endobj +1275 0 obj<>endobj +1276 0 obj<>endobj +1277 0 obj<>endobj +1278 0 obj<>endobj +1279 0 obj<>endobj +1280 0 obj<>endobj +1281 0 obj<>endobj +1282 0 obj<>endobj +1283 0 obj<>endobj +1284 0 obj<>endobj +1285 0 obj<>endobj +1286 0 obj<>endobj +1287 0 obj<>endobj +1288 0 obj<>endobj +1289 0 obj<>endobj +1290 0 obj<>endobj +1291 0 obj<>endobj +1292 0 obj<>endobj +1293 0 obj<>endobj +1294 0 obj<>endobj +1295 0 obj<>endobj +1296 0 obj<>endobj +1297 0 obj<>endobj +1298 0 obj<>endobj +1299 0 obj<>endobj +1300 0 obj<>endobj +1301 0 obj<>endobj +1302 0 obj<>endobj +1303 0 obj<>endobj +1304 0 obj<>endobj +1305 0 obj<>endobj +1306 0 obj[1259 0 R +1260 0 R +1261 0 R +1262 0 R +1263 0 R +1264 0 R +1265 0 R +1266 0 R +1267 0 R +1268 0 R +1269 0 R +1270 0 R +1271 0 R +1272 0 R +1273 0 R +1274 0 R +1275 0 R +1276 0 R +1277 0 R +1278 0 R +1279 0 R +1280 0 R +1281 0 R +1282 0 R +1283 0 R +1284 0 R +1285 0 R +1286 0 R +1287 0 R +1288 0 R +1289 0 R +1290 0 R +1291 0 R +1292 0 R +1293 0 R +1294 0 R +1295 0 R +1296 0 R +1297 0 R +1298 0 R +1299 0 R +1300 0 R +1301 0 R +1302 0 R +1303 0 R +1304 0 R +1305 0 R +]endobj +1307 0 obj<>endobj +1308 0 obj<>endobj +1309 0 obj<>endobj +1310 0 obj<>endobj +1311 0 obj<>endobj +1312 0 obj<>endobj +1313 0 obj<>endobj +1314 0 obj<>endobj +1315 0 obj<>endobj +1316 0 obj<>endobj +1317 0 obj<>endobj +1318 0 obj<>endobj +1319 0 obj<>endobj +1320 0 obj<>endobj +1321 0 obj<>endobj +1322 0 obj<>endobj +1323 0 obj<>endobj +1324 0 obj<>endobj +1325 0 obj<>endobj +1326 0 obj<>endobj +1327 0 obj<>endobj +1328 0 obj[1307 0 R +1308 0 R +1309 0 R +1310 0 R +1311 0 R +1312 0 R +1313 0 R +1314 0 R +1315 0 R +1316 0 R +1317 0 R +1318 0 R +1319 0 R +1320 0 R +1321 0 R +1322 0 R +1323 0 R +1324 0 R +1325 0 R +1326 0 R +1327 0 R +]endobj +1329 0 obj<>endobj +1330 0 obj<>endobj +1331 0 obj<>endobj +1332 0 obj<>endobj +1333 0 obj<>endobj +1334 0 obj<>endobj +1335 0 obj<>endobj +1336 0 obj<>endobj +1337 0 obj<>endobj +1338 0 obj<>endobj +1339 0 obj<>endobj +1340 0 obj<>endobj +1341 0 obj<>endobj +1342 0 obj<>endobj +1343 0 obj<>endobj +1344 0 obj<>endobj +1345 0 obj<>endobj +1346 0 obj<>endobj +1347 0 obj<>endobj +1348 0 obj<>endobj +1349 0 obj<>endobj +1350 0 obj<>endobj +1351 0 obj<>endobj +1352 0 obj<>endobj +1353 0 obj<>endobj +1354 0 obj<>endobj +1355 0 obj<>endobj +1356 0 obj<>endobj +1357 0 obj<>endobj +1358 0 obj<>endobj +1359 0 obj<>endobj +1360 0 obj<>endobj +1361 0 obj<>endobj +1362 0 obj<>endobj +1363 0 obj<>endobj +1364 0 obj<>endobj +1365 0 obj<>endobj +1366 0 obj<>endobj +1367 0 obj<>endobj +1368 0 obj<>endobj +1369 0 obj<>endobj +1370 0 obj<>endobj +1371 0 obj<>endobj +1372 0 obj<>endobj +1373 0 obj<>endobj +1374 0 obj<>endobj +1375 0 obj<>endobj +1376 0 obj<>endobj +1377 0 obj<>endobj +1378 0 obj<>endobj +1379 0 obj<>endobj +1380 0 obj<>endobj +1381 0 obj<>endobj +1382 0 obj<>endobj +1383 0 obj<>endobj +1384 0 obj<>endobj +1385 0 obj<>endobj +1386 0 obj<>endobj +1387 0 obj<>endobj +1388 0 obj<>endobj +1389 0 obj<>endobj +1390 0 obj<>endobj +1391 0 obj<>endobj +1392 0 obj<>endobj +1393 0 obj<>endobj +1394 0 obj<>endobj +1395 0 obj<>endobj +1396 0 obj<>endobj +1397 0 obj<>endobj +1398 0 obj<>endobj +1399 0 obj<>endobj +1400 0 obj<>endobj +1401 0 obj<>endobj +1402 0 obj<>endobj +1403 0 obj<>endobj +1404 0 obj<>endobj +1405 0 obj<>endobj +1406 0 obj<>endobj +1407 0 obj<>endobj +1408 0 obj<>endobj +1409 0 obj<>endobj +1410 0 obj<>endobj +1411 0 obj<>endobj +1412 0 obj<>endobj +1413 0 obj<>endobj +1414 0 obj<>endobj +1415 0 obj<>endobj +1416 0 obj<>endobj +1417 0 obj<>endobj +1418 0 obj<>endobj +1419 0 obj<>endobj +1420 0 obj<>endobj +1421 0 obj<>endobj +1422 0 obj<>endobj +1423 0 obj<>endobj +1424 0 obj<>endobj +1425 0 obj<>endobj +1426 0 obj<>endobj +1427 0 obj<>endobj +1428 0 obj<>endobj +1429 0 obj<>endobj +1430 0 obj<>endobj +1431 0 obj<>endobj +1432 0 obj<>endobj +1433 0 obj<>endobj +1434 0 obj<>endobj +1435 0 obj<>endobj +1436 0 obj<>endobj +1437 0 obj<>endobj +1438 0 obj<>endobj +1439 0 obj<>endobj +1440 0 obj<>endobj +1441 0 obj<>endobj +1442 0 obj<>endobj +1443 0 obj<>endobj +1444 0 obj<>endobj +1445 0 obj<>endobj +1446 0 obj<>endobj +1447 0 obj<>endobj +1448 0 obj<>endobj +1449 0 obj<>endobj +1450 0 obj<>endobj +1451 0 obj<>endobj +1452 0 obj<>endobj +1453 0 obj<>endobj +1454 0 obj<>endobj +1455 0 obj<>endobj +1456 0 obj<>endobj +1457 0 obj<>endobj +1458 0 obj<>endobj +1459 0 obj<>endobj +1460 0 obj<>endobj +1461 0 obj<>endobj +1462 0 obj<>endobj +1463 0 obj<>endobj +1464 0 obj<>endobj +1465 0 obj<>endobj +1466 0 obj<>endobj +1467 0 obj<>endobj +1468 0 obj<>endobj +1469 0 obj<>endobj +1470 0 obj<>endobj +1471 0 obj<>endobj +1472 0 obj<>endobj +1473 0 obj<>endobj +1474 0 obj<>endobj +1475 0 obj<>endobj +1476 0 obj<>endobj +1477 0 obj<>endobj +1478 0 obj<>endobj +1479 0 obj<>endobj +1480 0 obj<>endobj +1481 0 obj<>endobj +1482 0 obj<>endobj +1483 0 obj<>endobj +1484 0 obj<>endobj +1485 0 obj<>endobj +1486 0 obj<>endobj +1487 0 obj<>endobj +1488 0 obj<>endobj +1489 0 obj<>endobj +1490 0 obj<>endobj +1491 0 obj<>endobj +1492 0 obj<>endobj +1493 0 obj<>endobj +1494 0 obj<>endobj +1495 0 obj<>endobj +1496 0 obj<>endobj +1497 0 obj<>endobj +1498 0 obj<>endobj +1499 0 obj<>endobj +1500 0 obj<>endobj +1501 0 obj<>endobj +1502 0 obj<>endobj +1503 0 obj<>endobj +1504 0 obj<>endobj +1505 0 obj<>endobj +1506 0 obj<>endobj +1507 0 obj<>endobj +1508 0 obj<>endobj +1509 0 obj<>endobj +1510 0 obj<>endobj +1511 0 obj<>endobj +1512 0 obj<>endobj +1513 0 obj<>endobj +1514 0 obj<>endobj +1515 0 obj<>endobj +1516 0 obj<>endobj +1517 0 obj<>endobj +1518 0 obj<>endobj +1519 0 obj<>endobj +1520 0 obj<>endobj +1521 0 obj<>endobj +1522 0 obj<>endobj +1523 0 obj<>endobj +1524 0 obj<>endobj +1525 0 obj<>endobj +1526 0 obj<>endobj +1527 0 obj<>endobj +1528 0 obj<>endobj +1529 0 obj<>endobj +1530 0 obj<>endobj +1531 0 obj<>endobj +1532 0 obj<>endobj +1533 0 obj<>endobj +1534 0 obj<>endobj +1535 0 obj<>endobj +1536 0 obj<>endobj +1537 0 obj<>endobj +1538 0 obj<>endobj +1539 0 obj<>endobj +1540 0 obj<>endobj +1541 0 obj<>endobj +1542 0 obj<>endobj +1543 0 obj<>endobj +1544 0 obj<>endobj +1545 0 obj<>endobj +1546 0 obj<>endobj +1547 0 obj<>endobj +1548 0 obj<>endobj +1549 0 obj<>endobj +1550 0 obj<>endobj +1551 0 obj<>endobj +1552 0 obj<>endobj +1553 0 obj<>endobj +1554 0 obj<>endobj +1555 0 obj<>endobj +1556 0 obj<>endobj +1557 0 obj<>endobj +1558 0 obj<>endobj +1559 0 obj<>endobj +1560 0 obj<>endobj +1561 0 obj<>endobj +1562 0 obj<>endobj +1563 0 obj<>endobj +1564 0 obj<>endobj +1565 0 obj<>endobj +1566 0 obj<>endobj +1567 0 obj<>endobj +1568 0 obj<>endobj +1569 0 obj<>endobj +1570 0 obj<>endobj +1571 0 obj<>endobj +1572 0 obj<>endobj +1573 0 obj<>endobj +1574 0 obj<>endobj +1575 0 obj<>endobj +1576 0 obj<>endobj +1577 0 obj<>endobj +1578 0 obj<>endobj +1579 0 obj<>endobj +1580 0 obj<>endobj +1581 0 obj<>endobj +1582 0 obj<>endobj +1583 0 obj<>endobj +1584 0 obj<>endobj +1585 0 obj<>endobj +1586 0 obj<>endobj +1587 0 obj<>endobj +1588 0 obj<>endobj +1589 0 obj<>endobj +1590 0 obj<>endobj +1591 0 obj<>endobj +1592 0 obj<>endobj +1593 0 obj<>endobj +1594 0 obj<>endobj +1595 0 obj<>endobj +1596 0 obj<>endobj +1597 0 obj<>endobj +1598 0 obj<>endobj +1599 0 obj<>endobj +1600 0 obj<>endobj +1601 0 obj<>endobj +1602 0 obj<>endobj +1603 0 obj<>endobj +1604 0 obj<>endobj +1605 0 obj<>endobj +1606 0 obj<>endobj +1607 0 obj<>endobj +1608 0 obj<>endobj +1609 0 obj<>endobj +1610 0 obj<>endobj +1611 0 obj<>endobj +1612 0 obj<>endobj +1613 0 obj<>endobj +1614 0 obj<>endobj +1615 0 obj<>endobj +1616 0 obj<>endobj +1617 0 obj<>endobj +1618 0 obj<>endobj +1619 0 obj<>endobj +1620 0 obj<>endobj +1621 0 obj<>endobj +1622 0 obj<>endobj +1623 0 obj<>endobj +1624 0 obj<>endobj +1625 0 obj<>endobj +1626 0 obj<>endobj +1627 0 obj<>endobj +1628 0 obj<>endobj +1629 0 obj<>endobj +1630 0 obj<>endobj +1631 0 obj<>endobj +1632 0 obj<>endobj +1633 0 obj<>endobj +1634 0 obj<>endobj +1635 0 obj<>endobj +1636 0 obj<>endobj +1637 0 obj<>endobj +1638 0 obj<>endobj +1639 0 obj<>endobj +1640 0 obj<>endobj +1641 0 obj<>endobj +1642 0 obj<>endobj +1643 0 obj<>endobj +1644 0 obj<>endobj +1645 0 obj<>endobj +1646 0 obj<>endobj +1647 0 obj<>endobj +1648 0 obj<>endobj +1649 0 obj<>endobj +1650 0 obj<>endobj +1651 0 obj<>endobj +1652 0 obj<>endobj +1653 0 obj<>endobj +1654 0 obj<>endobj +1655 0 obj<>endobj +1656 0 obj<>endobj +1657 0 obj<>endobj +1658 0 obj<>endobj +1659 0 obj<>endobj +1660 0 obj<>endobj +1661 0 obj<>endobj +1662 0 obj<>endobj +1663 0 obj<>endobj +1664 0 obj<>endobj +1665 0 obj<>endobj +1666 0 obj<>endobj +1667 0 obj<>endobj +1668 0 obj<>endobj +1669 0 obj<>endobj +1670 0 obj<>endobj +1671 0 obj<>endobj +1672 0 obj<>endobj +1673 0 obj<>endobj +1674 0 obj<>endobj +1675 0 obj<>endobj +1676 0 obj<>endobj +1677 0 obj<>endobj +1678 0 obj<>endobj +1679 0 obj<>endobj +1680 0 obj<>endobj +1681 0 obj<>endobj +1682 0 obj<>endobj +1683 0 obj<>endobj +1684 0 obj<>endobj +1685 0 obj<>endobj +1686 0 obj<>endobj +1687 0 obj<>endobj +1688 0 obj<>endobj +1689 0 obj<>endobj +1690 0 obj<>endobj +1691 0 obj<>endobj +1692 0 obj<>endobj +1693 0 obj<>endobj +1694 0 obj<>endobj +1695 0 obj<>endobj +1696 0 obj<>endobj +1697 0 obj<>endobj +1698 0 obj<>endobj +1699 0 obj<>endobj +1700 0 obj<>endobj +1701 0 obj<>endobj +1702 0 obj<>endobj +1703 0 obj<>endobj +1704 0 obj<>endobj +1705 0 obj<>endobj +1706 0 obj<>endobj +1707 0 obj<>endobj +1708 0 obj<>endobj +1709 0 obj<>endobj +1710 0 obj<>endobj +1711 0 obj<>endobj +1712 0 obj<>endobj +1713 0 obj<>endobj +1714 0 obj<>endobj +1715 0 obj<>endobj +1716 0 obj<>endobj +1717 0 obj<>endobj +1718 0 obj<>endobj +1719 0 obj<>endobj +1720 0 obj<>endobj +1721 0 obj<>endobj +1722 0 obj<>endobj +1723 0 obj<>endobj +1724 0 obj<>endobj +1725 0 obj<>endobj +1726 0 obj<>endobj +1727 0 obj<>endobj +1728 0 obj<>endobj +1729 0 obj<>endobj +1730 0 obj<>endobj +1731 0 obj<>endobj +1732 0 obj<>endobj +1733 0 obj<>endobj +1734 0 obj<>endobj +1735 0 obj<>endobj +1736 0 obj<>endobj +1737 0 obj<>endobj +1738 0 obj<>endobj +1739 0 obj<>endobj +1740 0 obj<>endobj +1741 0 obj<>endobj +1742 0 obj<>endobj +1743 0 obj<>endobj +1744 0 obj<>endobj +1745 0 obj<>endobj +1746 0 obj<>endobj +1747 0 obj<>endobj +1748 0 obj<>endobj +1749 0 obj<>endobj +1750 0 obj<>endobj +1751 0 obj<>endobj +1752 0 obj<>endobj +1753 0 obj<>endobj +1754 0 obj<>endobj +1755 0 obj<>endobj +1756 0 obj<>endobj +1757 0 obj<>endobj +1758 0 obj<>endobj +1759 0 obj<>endobj +1760 0 obj<>endobj +1761 0 obj<>endobj +1762 0 obj<>endobj +1763 0 obj<>endobj +1764 0 obj<>endobj +1765 0 obj<>endobj +1766 0 obj<>endobj +1767 0 obj<>endobj +1768 0 obj<>endobj +1769 0 obj<>endobj +1770 0 obj<>endobj +1771 0 obj<>endobj +1772 0 obj<>endobj +1773 0 obj<>endobj +1774 0 obj<>endobj +1775 0 obj<>endobj +1776 0 obj<>endobj +1777 0 obj<>endobj +1778 0 obj<>endobj +1779 0 obj<>endobj +1780 0 obj<>endobj +1781 0 obj<>endobj +1782 0 obj<>endobj +1783 0 obj<>endobj +1784 0 obj<>endobj +1785 0 obj<>endobj +1786 0 obj<>endobj +1787 0 obj<>endobj +1788 0 obj<>endobj +1789 0 obj<>endobj +1790 0 obj<>endobj +1791 0 obj<>endobj +1792 0 obj<>endobj +1793 0 obj<>endobj +1794 0 obj<>endobj +1795 0 obj<>endobj +1796 0 obj<>endobj +1797 0 obj<>endobj +1798 0 obj<>endobj +1799 0 obj<>endobj +1800 0 obj<>endobj +1801 0 obj<>endobj +1802 0 obj<>endobj +1803 0 obj<>endobj +1804 0 obj<>endobj +1805 0 obj<>endobj +1806 0 obj<>endobj +1807 0 obj<>endobj +1808 0 obj<>endobj +1809 0 obj<>endobj +1810 0 obj<>endobj +1811 0 obj<>endobj +1812 0 obj<>endobj +1813 0 obj<>endobj +1814 0 obj<>endobj +1815 0 obj<>endobj +1816 0 obj<>endobj +1817 0 obj<>endobj +1818 0 obj<>endobj +1819 0 obj<>endobj +1820 0 obj<>endobj +1821 0 obj<>endobj +1822 0 obj<>endobj +1823 0 obj<>endobj +1824 0 obj<>endobj +1825 0 obj<>endobj +1826 0 obj<>endobj +1827 0 obj<>endobj +1828 0 obj<>endobj +1829 0 obj<>endobj +1830 0 obj<>endobj +1831 0 obj<>endobj +1832 0 obj<>endobj +1833 0 obj<>endobj +1834 0 obj<>endobj +1835 0 obj<>endobj +1836 0 obj<>endobj +1837 0 obj<>endobj +1838 0 obj<>endobj +1839 0 obj<>endobj +1840 0 obj<>endobj +1841 0 obj<>endobj +1842 0 obj<>endobj +1843 0 obj<>endobj +1844 0 obj<>endobj +1845 0 obj<>endobj +1846 0 obj<>endobj +1847 0 obj<>endobj +1848 0 obj<>endobj +1849 0 obj<>endobj +1850 0 obj<>endobj +1851 0 obj<>endobj +1852 0 obj<>endobj +1853 0 obj<>endobj +1854 0 obj<>endobj +1855 0 obj<>endobj +1856 0 obj<>endobj +1857 0 obj<>endobj +1858 0 obj<>endobj +1859 0 obj<>endobj +1860 0 obj<>endobj +1861 0 obj<>endobj +1862 0 obj<>endobj +1863 0 obj<>endobj +1864 0 obj<>endobj +1865 0 obj<>endobj +1866 0 obj<>endobj +1867 0 obj<>endobj +1868 0 obj<>endobj +1869 0 obj<>endobj +1870 0 obj<>endobj +1871 0 obj<>endobj +1872 0 obj<>endobj +1873 0 obj<>endobj +1874 0 obj<>endobj +1875 0 obj<>endobj +1876 0 obj<>endobj +1877 0 obj<>endobj +1878 0 obj<>endobj +1879 0 obj<>endobj +1880 0 obj<>endobj +1881 0 obj<>endobj +1882 0 obj<>endobj +1883 0 obj<>endobj +1884 0 obj<>endobj +1885 0 obj<>endobj +1886 0 obj<>endobj +1887 0 obj<>endobj +1888 0 obj<>endobj +1889 0 obj<>endobj +1890 0 obj<>endobj +1891 0 obj<>endobj +1892 0 obj<>endobj +1893 0 obj<>endobj +1894 0 obj<>endobj +1895 0 obj<>endobj +1896 0 obj<>endobj +1897 0 obj<>endobj +1898 0 obj<>endobj +1899 0 obj<>endobj +1900 0 obj<>endobj +1901 0 obj<>endobj +1902 0 obj<>endobj +1903 0 obj<>endobj +1904 0 obj<>endobj +1905 0 obj<>endobj +1906 0 obj<>endobj +1907 0 obj<>endobj +1908 0 obj<>endobj +1909 0 obj<>endobj +1910 0 obj<>endobj +1911 0 obj<>endobj +1912 0 obj<>endobj +1913 0 obj<>endobj +1914 0 obj<>endobj +1915 0 obj<>endobj +1916 0 obj<>endobj +1917 0 obj<>endobj +1918 0 obj<>endobj +1919 0 obj<>endobj +1920 0 obj<>endobj +1921 0 obj<>endobj +1922 0 obj<>endobj +1923 0 obj<>endobj +1924 0 obj<>endobj +1925 0 obj<>endobj +1926 0 obj<>endobj +1927 0 obj<>endobj +1928 0 obj<>endobj +1929 0 obj<>endobj +1930 0 obj<>endobj +1931 0 obj<>endobj +1932 0 obj<>endobj +1933 0 obj<>endobj +1934 0 obj<>endobj +1935 0 obj<>endobj +1936 0 obj<>endobj +1937 0 obj<>endobj +1938 0 obj<>endobj +1939 0 obj<>endobj +1940 0 obj<>endobj +1941 0 obj<>endobj +1942 0 obj<>endobj +1943 0 obj<>endobj +1944 0 obj<>endobj +1945 0 obj<>endobj +1946 0 obj<>endobj +1947 0 obj<>endobj +1948 0 obj<>endobj +1949 0 obj<>endobj +1950 0 obj<>endobj +1951 0 obj<>endobj +1952 0 obj<>endobj +1953 0 obj<>endobj +1954 0 obj<>endobj +1955 0 obj<>endobj +1956 0 obj<>endobj +1957 0 obj<>endobj +1958 0 obj<>endobj +1959 0 obj<>endobj +1960 0 obj<>endobj +1961 0 obj<>endobj +1962 0 obj<>endobj +1963 0 obj<>endobj +1964 0 obj<>endobj +1965 0 obj<>endobj +1966 0 obj<>endobj +1967 0 obj<>endobj +1968 0 obj<>endobj +1969 0 obj<>endobj +1970 0 obj<>endobj +1971 0 obj<>endobj +1972 0 obj<>endobj +1973 0 obj<>endobj +1974 0 obj<>endobj +1975 0 obj<>endobj +1976 0 obj<>endobj +1977 0 obj<>endobj +1978 0 obj<>endobj +1979 0 obj<>endobj +1980 0 obj<>endobj +1981 0 obj<>endobj +1982 0 obj<>endobj +1983 0 obj<>endobj +1984 0 obj<>endobj +1985 0 obj<>endobj +1986 0 obj<>endobj +1987 0 obj<>endobj +1988 0 obj<>endobj +1989 0 obj<>endobj +1990 0 obj<>endobj +1991 0 obj<>endobj +1992 0 obj<>endobj +1993 0 obj<>endobj +1994 0 obj<>endobj +1995 0 obj<>endobj +1996 0 obj<>endobj +1997 0 obj<>endobj +1998 0 obj<>endobj +1999 0 obj<>endobj +2000 0 obj<>endobj +2001 0 obj<>endobj +2002 0 obj<>endobj +2003 0 obj<>endobj +2004 0 obj<>endobj +2005 0 obj<>endobj +2006 0 obj<>endobj +2007 0 obj<>endobj +2008 0 obj<>endobj +2009 0 obj<>endobj +2010 0 obj<>endobj +2011 0 obj<>endobj +2012 0 obj<>endobj +2013 0 obj<>endobj +2014 0 obj<>endobj +2015 0 obj<>endobj +2016 0 obj<>endobj +2017 0 obj<>endobj +2018 0 obj<>endobj +2019 0 obj<>endobj +2020 0 obj<>endobj +2021 0 obj<>endobj +2022 0 obj<>endobj +2023 0 obj<>endobj +2024 0 obj<>endobj +2025 0 obj<>endobj +2026 0 obj<>endobj +2027 0 obj<>endobj +2028 0 obj<>endobj +2029 0 obj<>endobj +2030 0 obj<>endobj +2031 0 obj<>endobj +2032 0 obj<>endobj +2033 0 obj<>endobj +2034 0 obj<>endobj +2035 0 obj<>endobj +2036 0 obj<>endobj +2037 0 obj<>endobj +2038 0 obj<>endobj +2039 0 obj<>endobj +2040 0 obj<>endobj +2041 0 obj<>endobj +2042 0 obj<>endobj +2043 0 obj<>endobj +2044 0 obj<>endobj +2045 0 obj<>endobj +2046 0 obj<>endobj +2047 0 obj<>endobj +2048 0 obj<>endobj +2049 0 obj<>endobj +2050 0 obj<>endobj +2051 0 obj<>endobj +2052 0 obj<>endobj +2053 0 obj<>endobj +2054 0 obj<>endobj +2055 0 obj<>endobj +2056 0 obj<>endobj +2057 0 obj<>endobj +2058 0 obj<>endobj +2059 0 obj<>endobj +2060 0 obj<>endobj +2061 0 obj<>endobj +2062 0 obj<>endobj +2063 0 obj<>endobj +2064 0 obj<>endobj +2065 0 obj<>endobj +2066 0 obj<>endobj +2067 0 obj<>endobj +2068 0 obj<>endobj +2069 0 obj<>endobj +2070 0 obj<>endobj +2071 0 obj<>endobj +2072 0 obj<>endobj +2073 0 obj<>endobj +2074 0 obj<>endobj +2075 0 obj<>endobj +2076 0 obj<>endobj +2077 0 obj<>endobj +2078 0 obj<>endobj +2079 0 obj<>endobj +2080 0 obj<>endobj +2081 0 obj<>endobj +2082 0 obj<>endobj +2083 0 obj<>endobj +2084 0 obj<>endobj +2085 0 obj<>endobj +2086 0 obj<>endobj +2087 0 obj<>endobj +2088 0 obj<>endobj +2089 0 obj<>endobj +2090 0 obj<>endobj +2091 0 obj<>endobj +2092 0 obj<>endobj +2093 0 obj<>endobj +2094 0 obj<>endobj +2095 0 obj<>endobj +2096 0 obj<>endobj +2097 0 obj<>endobj +2098 0 obj<>>>>>endobj +2099 0 obj<>stream +xÚìÏsë8rÇIŠºÌ‰öŒî´üt§çyšÝ­ÚJñÙfvçÖ$ÁÊ!•S*Ç6•üÿ±~X"H€èn$è5¦jêÙE|ˆÆ·@ƒúÇOßòýÛßò?=å¿ýžÿçÿô,~*ÅOÿÈÛÿù×?þøÛï¿ÿºÏÿü—_Ÿò§§§·kýñõ¥ù÷¯|­ÿöœþº?•ßNå÷SùË©¼œÊ¿žÊ¿üÇ×?òÿýŸÿû¯¯ÿ–ÿíÛ׿ç‡oß¾>ÃKþ=ÿãõ§öcøä²+âõi»Ý>ÜËÛ?¶ß_—Î%^¶wY¤*w÷¯ËäOj¤Üöû¸ē‰é½Ü?–KáÂC]о/ëå!"—x[ÎõœE¼r˜ë‰KåÒ!˜¾rÛg޹^òȾü\ÆÕÊÏ3s=GžJRÎÉõ-òVâÃl\ŽuЄõV¾ÌÂ%²( + ‚B¹ü29×$X,0X –€Åƒ %ƒ/° ¬(ÚMÄåÝoÙ9h6×ÄXo`å\ûhò’LÀõ#𡬼sÕÑ,åÏ\M6A!|…gi,A +Ú Ñ ê£s5Ѭåà‹+›— 9Ä`™ãÅ`ž‹,öD.1?V{àÊàŠRç\uD98æY\‰c®}HÙ8媣`Jé++D91WT蚐°ŒÒË TÔ  LÔ‹Š4ðZåªBÃ2t,OãQ ÔxŒsÆq‰±FãzX¢Æ#F,Ï%£FL×]w÷Ûí—×cy>|ðÛa0IwÅ÷_†ƒüxÂ[‡ÿîŠG’þÅ˃ŸßÝuoœ*=[ í,¸ö~ºªÛk[ça=xì.Bú±àæØ\ìPƒ–.Î$[q¹¸¡==·aMJ&³»XéԜ.K™\¬@ž› É貘ÇUùÑv‡]¶cqeSÙà՛eN¤ܯjؤ½s’  ®|²¡ÅϼJé\Í Xd°˜ÎEùØÍÉÜZ9ƹfÂ"‚­¨\Õ FÈ1ŒȕυEÛи'’ –Y¹0p7ñú¥uZj+Cg‘¼c,Òé« …«rÎX•½ÅÍÁ‘jÄ¥{.B J<—°ÒlKÃ7D=Ì:¸ÎåÛÁÉ %i=•œkˆàBf½ .Ú`Ø`¹Š¹2O”,Á W­Ç’ó ìÍПR4q‡ãÚa…„–¤8®´&1Š«žÙ#3ì€á«aÚz/8 [c¸²0Dƒ¢õ ‚«æfóuXiæ*B J‡íÌ\Y OjOjäªÃê.d‡%F®"°îBú°ÒĕÖ]È'½1p5Á¸dZ“RW\wá¢ÄÄÀ•6ºÐRVŽr‰» 7æw£\u€Ý…[FJG¹*OŠ…²¢d”+ (2$*ÇVå'ÆB ÃRåÓ©¹Z’ Wå“s! q5ÂÀÚÛ=W¢È£­ÔrAˆ"v@;-W¨jàLi­ã¡ªnè¯t\5-4”=Ùí§ž±¿ÿ.Ï´’T¹Æúù=¾aÀ +¢6(®–KH·Kh%ºÖRÕÓbQ®•–ër›®Îa‡Àà ¯Çé¹ £^ >ÜÌіœáµCrí´\MçùÖ 1£$UsÑys¥Z®³í%·NH)}¢æÊ‰Îkœ+ÑsÝ´BPf=ègŒàp‡åz7.×MÛk¼b”¾Tq5ÔÊÀµÑrÝD° ¬•T؇ô¹WŠçZ鹊÷G”Q&ß V<זByW¤çª/ŸÕPÌ1PRWF4C#×NËu¾×úü+ü’QØV +.A5C#WªçڟòáªÕr[¬àª©fhäŠõ\盽§5Rì•K,×êZ[Éu6Ž;êÊ12BªWNZ,×:{—'%WG¤(³ÔgO@• ž«x j®Š5K5†ˆëWC6Ãq®ZÂp ÖbI…Ó5 ÊFÒâ¹Ä»Y¨¹®&EZ,ip-â\9%pžê¹*֚Nè(; +\n£á¬5;c+\ŒôÅq®æ" +®K‰kvª‰@“¤¥pµ¥×qgéB™ÐdcMãº(½Ž«àôWòD@“ë¢ô:®Œ3¾êÙwCÅuQz WÍÛÃÈ0’ ¤h#!r]”^ÃUðûMÏ%s Æð2r•^Õñ6g +ÌÃ’lì¨\g¥Ws5Ì]Œ +㘁´¶ÑR¹ÎJ¯æ½ØER2WÁ^f®“Ò«¹rfæŽÀ8f DQ)ëd݅~^¹e¢IàkSYŽ­\§Öç*®³Ý Fȑ#š ”(ªT?º²k ±ÌukDŸ+?krN7Ä="àVÌµë>š>h¸Þ;а›‚]†Yw¹k6+IlºŠšô¸ Wuáiè†X!dr¸Ñ˜ÄjøCýsȵèÝJ´§•¸rŽlH[âã‹:\…’K\[°'¢@Ø¢C­I¤€]Ÿ«VrU×Ê=öEèà£ÃDïû¯´ùÖṌŸêsí¯#èùVž«áxåÛ-â;^WÈ\OÌɱonn0¾d=äª\ÝT”‚lˆ{ó€¼0ÚT¹WWojò$ ð\{–l lbÕ¹.¶*qeÝKž„‰×ñÒáÊY²Ñ˜×Ó{Šyq—KΈÚ{ÈhzªX¯üPy8Å:F—« »òúh9ÔNþnï5ùÒ*¹Ä€+“,¯ñª è¨Wo'ÍéŧñýGH©\SßËy°†ÇeŽæãvQ°2Ÿ,’+çEQÁse¼(*t.a#‡s5–r*W͍çª>š^¸ +vt6מ͕4™¿peM/\œ¥ùp‰'óg®úÃÉ<–k2ߝÎ-‡͋ó·•Ü:\[æ»uîªßFwÒ²ßmµwpœOm›.Ò,²Î-ï\·u›þà,•\×FÍÕI¿\¹r¶ûRãkT§×ćk¥äjÔûËÛ}©4fÜkbÄኔ\¹z߁¿h£¶W]nj¯‰;×NÁU UPn9Ár­4áËNŕr¸RW6|ŒŽ¹Î«Ëë51áp%C®wшﲫÝÊ-§h®š+Vqõó¡¸g¯r~ô'/ÙÅlp\ëQ®Ó¿^òHjÁZv,¥Šk£tEr<Џ¨ëdÞ7ÛnlÌ\—᯻?"éx@·‰+×à¢Zr—Ûj{‡àꤥÈ]|Ëíé71âp .’7.y<€ +£®[‘"K~­lâŽÃÕ¿(—óM +-áðì8—Ðpz®”ÃÕ¿¨7RNf™*Œj1\·Ùÿj®˜ÃÕ»¨ðTà¹b\Šã|f.ÅEußÁnßÊ#`ÂÃĞk¨Šã|f.ÝÀT5_ŽÜp ×^­óŠã|®áE…ÒÁ&ŒJ[=Ì®9·r‡Çù\Ër¥#Bq­Q\µÚ՚8JqœÁ5¼HËU;â*”ñÆË- é5qxœÁ5¼(S:"×Ã%¢"ÎSÇù0\ƒ‹´\?Œê´áò;ô¼RqœÃ5¸¨[ývGסµœm”MçÃp .Òr?ŒjÕ£YU4ñ"Ú4®þE\-š+Uý6.5MìçCqõ/Òr¹ê^,ÕMìçCqõ/Òríùáa«68Íòþ ‰ýã|(®þEY/Mõʕ;ãŠK W'T•šØ;·ãê]ÄçJ\ñ®óۋ_¾,{lÔMìçÃqõ.Ê;Š-qen¸:ù‡Ýxã¼ì‘ª›Ø;·ãê]4ˆ£*,WÚâæ)­Š«ó~(EO¢Må’/Ú÷#¢âÂùåªÇ¸äã|H.ÅÀn÷X®µW£‹ç¯AeNä’/ªúC%;s Ï\BsŠCqœÉ%_T÷$[DX®W;Ê.é"Ñ Í« ¸—|Q&°üÂeÎ=Üy䒎óa¹ä‹ +E2þW=/WÁá’.ªn»Ê·EÞÙ¹j—t‘è¶²¾Æ6ÓJ\‚Ã%_”ßö¿ž#W铫{œÍ%_T ö+Càª8\òE½H0?qÙL—Q\Ù8WÃá’/’gÆé>®Îq>ès¥”ºór=ŸÞa?bšK©;3×Cÿøšü²¡ÎæuÕ»ꝪHqPJÛ:k®|¾!çéw·§†u\y1Ô׏áŒF~™WsÛìø9QeäÚÉÔ—Pì(É/4¬®KüuòÈȵ™‚ TSë¼;Àz齺 ®u+ M?\™j« ºã “Òdúu\©l)^¸š÷§»nÝî«ko»õʺ ®Dºµ®êºQ(¾unڑÀ[v…².Ÿ«öÉUtv¬÷7ïÒqY·äsM]Õ2¿ú®òöNå“+ª›v^Ȭ©K㊯ۧoƒ8ñƕu—áòžÒߌ§©KãJ®£0qÙÄóҟá¦×VËIÚªº$®Õõq¼=™t®êöÓ5ä$mU]WÚ}tk;.CúáõÏÍÝ[ÙtĪ윑Ò×%qÏ]ÓÆ+W¢ûѧ“T<¶ÔçÊ/ƒô8„wÞ¸2]:ÎeO¹éÀd#©;x®ýåóŽŸ|ðÆuŽš¸1‘†‘¶.‰«¸ÈÐÑÒKo\—½Îûƒ:À:eR¼Ë¹¶.‰ nÙ¯qëë¢Z{þ⇬ã‹õu•\ÃÄÎEu¯G÷叫“Òkmñîm®¾X_—ÂU_ `ü`;®±}½n=é½ÄÕ0‹V[—ÂÕ\~<ºeK®±}ØByŽCš—ƺ.]_ˆ¾ç²Ú_ÚÌÒ|Õ¢¯Kàj/Žùô[\½,Ú¸ôdЍKá:;æ“[öÉÕyіL¡ú’9]] +×Ù1×'ï“ëý ì —J•l:ZÇuvÌõ©¾—1ïë9Sš\ùPÔuñ~ùäËãÿc—‹|¶—‡á¤¦ÒLrTu \ÕÉOnÙ?×­µ«^(u@Õ%póÉ-OÁõ. +‰vЌÕ%póÉ-[raß-Z‹ÁX]—x÷b멸n‰×f®^]×Ù1ŸEr”Ë&ûø*™ìе\cu)\o&˜4·õS/\²{ãb§®.…ëM2âúì-¹JÜú¡k¬.…ëØÓUt}Q7®D²­x”KW—Âçð±‰ËæÜM.ý9Õù±º®ê|²&±çڍO¿6ÝyÈJË5V—ÂUߜº7®ªÛŸûÞmz«Kájn³Q.›sˆçkãï·M­–k¬®!ž—Þ¶%ä]A ®qö¶ ©Ÿ,ŽÕ¥puÞ ë«™«õ¹F꒸r—Õ¹ìf¤jŸk¤.ƒ«´çZãÒmú¡ÿ VÑ×%qƒßxàjô +3àj¸ëQ2\ŸÊ(—Õû7䵘_ÚQ.}]—îý¬n¹:}l \Úº$®úêÓǹ¬²Þè!Ón”ØÔµ*–ïí¹Ê×ëMóU|–ïY +¶X¾ë“kz.ó떗ÉUüÓr•‹ä2/pÉe3aþ䚞Ëjb¹h®õ"¹Ä?-WºH.ólõA¹’ere0ðµü>ŽO®¸ö0ðÅ}Ïn‘\ðA¹ª Z~¯Ù\Åô²×å÷ÐÍULMÞá¾70¸@ªrÃ\ e’ºÒò{9ç*Š+[\Àa +%°ß{ZÀ‘›ì ù=Å¡­´e&=@~¯thG„â‚¥Âèo‘ßoXÀQã¸÷}ô•±mç˜Á8lc®Á9æ½Qæ#/Á9°Üè–ã‚s`™±Åš3‡}€²×ÀXcV@éK`3Ëڬހò9°ÊÜX@=€ÀXa6.@l`3°½9êT˜ËÍ"8á Kèmœ£ Jè„m®gƒú¡€S˜ „A:àª%ô¢©€ìڐ„>G˜ ‡bH}fv_ï\bAB/0Ò -Vè׋‘Ã]‡+_Ž V˜Ȑ+ A,0 +-V裥ÈaÜ媗#ˆ(Â-ôDˆ *âƒ-ôéBäpÝåB} Â(»‚-ôÇ¥€VÏP„#C̾:\ÕB")£œ· Å }ºÙHd.„Ð'‹TæB,Ýċu+_†pd8üƒ"âȇxà B8j¤—Â!Gl#´A `1Û¨«>BðÌØå +h)‚¸xí\Åú,(ÖCéÑg­¡% ÇÜ ýŽhIÂ1ó3?ú•‚+~€áï€d¼s°=z @KŽy>r’s˜y€Õø©bå™a÷H*:sˆH؇–(30Ê&ÐúyÖ9eˆιÈQDs‘ƒ²Ôā9£Ò7”AОQéI+Ò@½t>¥Ï)Mª’ζÚ&HšÔ¡9›!"li¥åڇkˆ´åhél¨vc! »ô™ ±¢g83âžö¼nų¢ †®@žâÌcˆñqCË`3Ĉ9qx@Ë`iˆf(Í4€ó`¦Ÿ¬Tԇ -g€M>kΩj-k€MœdY“½´¬6± +ÈcX]>±rz‹€5D'VFÔ +œéöÔ1GNÀY™8樼A:©ÔgB©œÇ Üϙ.H,8ޏÃtºc wàÊêd†kÍÁ…Tú‰:,c=càÔ4Æ €?R§é°ŒÖÛNÓaә_‚& :C¢Åqí±`»0ºk…äªé0‘qƒph­ ±÷UKó„ªY.´v†èuâ,øV­!zÕzìÓÝ ¹ð†èQ:j ›ÖÖãrfWŠØ ¬OKüñÍPË%¢¹-±±’.h­ ѓ&æV>¬­'BõÊXZ?Þ¹±´°öõ^†˜È,e \<1÷3–½í#×½{&ܸ¥rU¤s©ÍJÉ\"š LdöܹK0‘;¸)82‡i\o\´;¼•Ÿ'–‘P¬.t¬Â^¿¹1p1_uFÃÒÇàd}¡ãNSbé¥ +\EiW°/)áøf08Ô&[õ cœFwžÿf<[l2êR6W›qÀúßtŽ*OôÛø\‹+Š¿S;‹añcq€‰‹ÙaQt_zî¬ñ¹‘‘«ˆ¸ÿ¥ó/9k·6\"â—{”56¼OßYqYtØqœ=šÌñ…Ie˜>˜¹l:ìŒöªÿ짌ý¹K.ê4Li¯ƒ~/ÛÌæqµ¶\Mä¦ÜÝo·Û/¯oåe»}È,?mcÍå¢ÃœSþ#†KȵqÀe'‰³tŽ+¼Û9á +®ÃÌK_8.±´îBrvm¦(ˆ=$W›…ÄupÇU/«»Ð\¬•O_ºäj‚áÚ´.¹‚ÑzÜöžKdKÑxw gÑ q!Øý^ +—XŒÒ¸°DôÖ!‰kvKÄgиš…X!•kæø—°MäšÕ)¹/T®9½3eû‰Ê5c`OJš#sÍ6Ähi/t®™†1±ŒÁ5Ï#îí2¸fbÔ,%=pÍ`sM®ôT9×ÄÚÁÈdr‰<\)´ášRY©Ã\®éÀx™dl.FÚÏ$ŽËšk¢Éóā×þ9椰áòoŠü,M+.ß`ɧv\~UÑ&Yؒ˧ƒ¶Ê¶åòf—ŒoÍEΡö41qÏåcÚb™®î†Ë½,ڟ›pÂÕ +·¶øhß"7\o¶è®Ë’CW+Âé,—\ŽºìþІÆÕŠ'küâª-.¹ø©ÕªGw-qËe‘^Hݞ“‹Kæ–ʇìþ‹ë6øà"æÅÇ[ï¹ðÃõV^qÙññýw/·÷Æuê5ƒAÞm_}ÝÛ'ש۞¶wê~z|õy_ß\çŽ;žpØ>ÜËývûøúêý–“pÍPàÿÿÿârõä +äÿÿUÌA‚0…á=§˜¥&¶vJƒt©w$õԀ˜4Ü^Ç™ÝäÿÞÁDۓ)À4H®SÅS0õ +Ž—¢‚jhƏõ +?´Þö½órûœl·6V€Hã”'À0æ’4aV9Cþ;J + +d™ ób½ž®cø‡*^, ¯ÙßÛÛ¨õŽI!Äö]%=”.8ÿv5ÑÌDçè úñèendstream +endobj +2100 0 obj +6279 +endobj +2101 0 obj<>>>endobj +2102 0 obj<>stream +xÚ+ä2T0BCc3JÎår +ár á +äHÉHendstream +endobj +2103 0 obj +31 +endobj +2104 0 obj<>>>/Annots 18 0 R>>endobj +2105 0 obj<>stream +xÚuTMoÛ0 ½çW=µÀâÙ®›¤Çuíº ýðætØ!Åf­²åJr‚ì׏”Ü´Í:0"‘"ß{|ÒÓ ˜~ ŒS8AY.fƒ_Î!a¶„,É¢1ŒÆ˜UǹÁ¥(ñdö›22HΆ”ái–F)gÍÖ҂ÕK·¡5zeD]£±P‹¦Š·6²Âw’d³Ù,µ©…“ºúnðY×5-¸y Ãä44ˍl+vÖa óã£Ïyq4?ŸÔ’‹$ÿèsHÆ š*œ¦QÆúƒ÷4‰[λš â(&Yø“ðçÇ5d£$š@JßԐM@X)(‚hϒÄH)@ÕÌ a­6N,Sî+±Cã™2½yz6.„Å +t‹Føë!Ú¦Ö± +7¨(§‚ż*o!›_ »û/!Z@šMH¢“Fgý‚Ù¼Ãþ%¡†I²?Úsçåy¯çóPs£«®tö-¶ø8ÍÂÔÚ!ébh*aª]¬VÝÞB)/l°©4Y‰²¡³4áÞH|`6O?àŸþÌšGT¸ƒ’,EC%$Ï94lmõÒQ`ã‹S#ë}8å¼ìmG$.µbãMóœ}'B. ‘>bÅɞü֋€ÿ©ÃŽ:Œ²oÆ{Ö&k\ +dóSƒ›ü’äTÚ¿EkÅ +áBéò‘ÃÅí…?øÚŸÚ¶ m‚:?Ñc$"ø†îR,•h{Ø„&%”ÕÍmײUÉ][éÖ`FI‹eה<¡¤Ûõҋª²@¢lµy  ÜÂè­eÎ &×Ö¥‘m/šƒn—h}Xžyà®ÁÞÚÇ-û¦GG°„R_õ*­k* wéÝY2Wšw©ºp!ËÎ:]Ë?ÔiÓ?z ×wp½&؁*;c°qj×ÃÒ˳΢³x~rÀ Țgµ”tõLsrˆp^ûŽ‹½¢ÔèføJ¯^OrI!ê–WF2No¬¯¹—÷*/îïº>Ÿó=zºUèJÙ Ö£ñµÃÛ8Ù¿^Ã$É^½øÙ$ŽÎ)H»Iÿ¦|ü;ÅîBendstream +endobj +2106 0 obj +805 +endobj +2107 0 obj<>>>/Annots 29 0 R>>endobj +2108 0 obj<>stream +xÚµ—ISã8€ïüŠw„CËKìLŸÂ6ÕU ÐL÷…‹ÚV‚†xiIfé_?O’ˆ49@A%%çÓò>-~úyD Ä?ñDÿÕÑéâh|9’Áb‰¿Lr‹òø¼)ºŠÕ +þ~d⑳§“ÅÈ%@ˆåFQL4¹¸çd³TOT0hE³´ª˜PѺ£kÀŸ±¢5ÿÅJàµj@Ý3X6ëuóÄëHV(ÞÔòÛEÑwåA„½L‚D÷rM2ÐÀÅâ( BŒAýqû'FàÈ#ýYA’`E[XÃü Ú*Hãwh¨`Jp8>Ú* ø=ñâ.üdLþô·XÅ +¶“뚙¶C`7ÝjŸó©Xõjâ¶­„›VÏ£,ÈaDt”z&Ö<›‚ÏsO[Ú*Èâ€xi@oaÄ^Ü%ô¼MzF?¹öƒK¸|Ïþ½™Ãìæë‡ÛM§S\½][ðØh#ÏG;®âðÚÐÉÑÝ?ÀVÚ³!F[ß7Ëò’¯ž +/,×GÄ Ì|ÂzÚúðÐ0óР—W„Û؇»òiúŠ_pšgöXLÁæ`ÎüљfѦàÝÓÖ£‡v€A´‡vüqYbãMq§´x`uù Æ&¡}#M‚¬/ì1¶ÐXŠ›ÇG;Ëñ ôÑ ¥ïà.|kÃþÓ?ÌÐï|H +®xÁjÉ`¶Œé¬âãM£Áܚ&}a¯i²¡Qdè¥À˜NúIf_§(ã 3Ekõ «,ŽíÄf +¾Ø{چæ¡cׇÿ–> ö8±¯€3½”è +Õ ö ÁG¡=ýÍ2ßëi»ƒ<´˜àC‡> øˆØãùƒ¿ìj›ßî‹}ȽGXs„'š©yÝ(ªkéuóˆ;fhàÍü¼é$æÔ˜°ÓºùR+ú Ŷ.è}ØI“cþ9ùªã% àâ™VíšISs. b˜¬×+ûë˜ÊfôÛ©aÏíšòÛûÁ0ïs÷´‰tº¤Çg‚éûÐ A™9Ž]Ëa²¼ÕóµÃaD™>u6.Ö-îµ3ûðî˜Ü¼ö½òLçj5­0†f‰>*¼“”ò‹½p!w[­¬. ÓÇÛ ,ûID{;5»§­~ïrÙ_j´”¬oï?;|KWl¸ò@ÝU?˜lt¾‰`þø‘ŠFƝcyÓ2.ºVŽKªèX1©Z­ô)ÁDŒ™©-¹Àq4âÅ +vgÁ#Ií"»e?;쾞ëHûdc„3ýV_f‚ç÷è²Sm§úÖɞ ×-ŒJhûf‰CÔc‚‹ëÅÅíÞ®8ÂxÃÄ5Šúkìå ȖŸ=° kþÀ^÷ëH|£íc³Mp‡Ì®®àlv37£Þ+ÞLÐÎH®ÍDJ»¹(ö¬LSO˜b(tÐIÜP;“¨Á–áÎ-áî8¸;¼óºäUÌ´Rb$Õï ¨ÑSlǝ6 Iu^”Æv®ìõdóþ½q.åmåˆ$S|!Œ²È„égq>lηîÿx ÿsô?Ö¥endstream +endobj +2109 0 obj +1177 +endobj +2110 0 obj<>>>>>endobj +2111 0 obj<>stream +xڍ’ÁN„0†ï<Å5¤Ð¥¬·ÕèÌÆÕÅ(K*ÐØ7¾½-`¤Æ] š™ùþ?ÿ̛‡ 4AœÀ¾õ®3ïòn ˆ@VšJ’"Ȋ³UžKöΩæ¢SçًéÁ€ÐØãG$HlWV3(Eӈï* ó ’A¯Xº–¢¯jÑkóË´´ëis5B“ j¼øQ`K}Í]A[CqÙÚ=oDþ¡™º!…†áéÒü9ns·aãpº ɟÄõ ⚻DŒR׿WÚ¾Y‚c–ºfžXÉ$ëö?õù)õ›çív¢Ô›ñªhyǕ–T ©`3¤{Üߪú=a6UÏ »FiÖÃ`€« œÁuñ¬ØÿÄYWøæ,äL¶Wözމ§‡AŒÐ¨®üVŠJÒ¶uMø/͐‰9üõ¦qKj±}ßfÞ£÷ Ôôâhendstream +endobj +2112 0 obj +341 +endobj +2113 0 obj<>>>>>endobj +2114 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS04±Ô3T072PIÑPp VÎO+)O,JU(ÊO/JÌÍM-*VðMÌ+MÌÑ Éâ҅hхê1‰™è™(€ùŽIIE©e™‰%™ùyÅ 9×®@.óä#Âendstream +endobj +2115 0 obj +122 +endobj +2116 0 obj<>>>>>endobj +2117 0 obj<>stream +xڝUÁrÓ0½ç+öØÎ¤¦IKҁ4LRàЋb¯cQY2’œ¿ç­ì¤Áía:“iâÝ÷Þ¾}’&t‰¿ ͧt5£¼½]^}¸¥é%­J|β+šÍohUœMè‚^ۨ톖û¹¦»-û­æÝùê'Ú®i2‘¶‹®ïâêzšM¥uUé@y¥šÈžﶺà@ʒëûɕT¹Ŋ靫kgéþ˧ÏøvÎ?†¬c»¥É\Ø.A4Í®;~jYx·6\ÿ- ÅÓy6“âÎӞ•ԕÌú’3ÑPš—PΨR£6-IiF÷ÖèG¦Ï:÷.¸2>L_Ïè»¶…Û…ô?è>«œî–ãn6°N€!jrÕ9¢²…òž}©r–¾ÐM¯­pâ§R~k›Æù^cª½s›äbp¦ÚYøÞzÏ6š=©­ÒFaœ±” ˜ß²dè²ÅÁîoO>t°4Ï ¿v!â)o•xփMgÇE~ÞÜk&£-UÓÃYäߑœ5û‡swìeîuŸ‰¸WM¥óðp>Nßw:VC]͔;õ[wvì)GÚ֐­ +èwG%ŠÊÖòÊnXBxäàR›äu­"¼ýèvŒ¸Ž“«ã±Ê‡¼[å5ì$1)íÙ5ìՉ „^àS¡Ë’e3CŸÐ +±Òoe䬯5'‹¦Âk( rI…‚˜ðåy†JáX‚Âs͈‡ÒykbF«JEøW¯±¨Îà¤ÇèZG.†C#jubËÛá<èD‹øÓYp°E"'90ûütólÇ]XÌ“QۜÆ[ ”Óš‡¹{w¿XÊP¸^ôF¤‘EµU‘ÿãœgtg%HéF®©ÖYÐç9zAj?{8MÝ_̖¹â€ä /¦ÄM£vEk”—dJÉÓ%ð>'¤†g$Èq—™ç'e,ô„g±9M~·~£c4é2²°´Ä3Äd©-¸“é‡[}@¾v}tŽ7Šñx×M‹ñ$Œ;pÜ¥N5Ñ¹J÷®q³jàš-—âI:kzHlñR‰œWÖ·Ùw3@9^Bñð +¹yz+ÌçÙ?½å®o.³[4 ôµ|¿}ý üjºendstream +endobj +2118 0 obj +836 +endobj +2119 0 obj<>>>>>endobj +2120 0 obj<>stream +xÚ}WMoÛ8¼çW<ô”¶»““¦Ý¦H°ÞÚÅ^z¡)Êf-‰*IÅëþúGв-ÄE$²È÷13oHÿº˜Ð~&ô~Æ¿²º¸_^¼ûü&7´,ðfv;¡e~¹Ü(Z*¹©MiÖû·ËŸXtM“I\4žÞd3^öñû|AÚÑJ8•SۘšDMªRv­ë5=Ö^ÙZyr^Ô¹°9IQ–Xé¾9·ºö¼|n7Ҕ=Îç´ˆ«TÍɑrò>›rJU­¬ˆ±ÚSn~«Ú‘)¨áÊ"{Þÿï”}ÁŸJÔm!¤o­².,@Á®mc} ó¬¥5ΞþÕunvnrzuu•uŸMgÙ5ÆæªÐµBÌCMׯÆB¸1t²SeÉQ؄—ôÓ¬ÜIѦñÚ §RoU*×bPŒÓ¿Õˆ¬r¦lyé(lw†3úMFO¼(Ãq¤%ÕäFW †VŠZ~U&dO(Ö0V'¼x3HÝÕèhÓÖ¹U¹ã}~cZ‡ •.Øgô½=Ä´Ç5lÌN!W,F”¨¼#¥Tnˆ¾4µ·¦DŸ-BP)}«ZÚ}Ÿ+±e`µ!U+7T«Ðn#V¥Š() xI¢ 1ԙ)s¦ü¾F=$TнÄÛMÃÝ3z_ö²ã¥úÏÓҊÚqc½°éÇå›/Ëåü͏·´Ûh”ˆ8¼ DéàN­:ÝâqXÒ1;-7Øö W&¼¡­v ÙV@ªÃIn”ܲD}ëH×ÐIÞpåâ ¼40ØAæ ZÅ¥j›v€JY +甋T)·Žqë¸—•EyÊ! ¾M¼è<̏4US*¯Xï&ل’rQ{çUÅ4ùö{€&Gô ×ÊùXCÐ3Ie½.X'jÐÇ©„†nÈ*¡Pèç&ª‘:ýð§Å‘Þh§1d$ñ"t$¦k*Zö™AVf3 5æÎ³è§Ó¿ŸF\¾ófûI@0&,rå9\.à\mUiÏ®vb?xÓù® }ÖE¿i§ù.3ú< s”k2º¤ ¶Ö¿ZEu[­”ڒ6zÇéÂÀrÈC¯k6|ÃRã%²-……u:¬îÚº6¸P/Æ®vª`ñ¢’3uÎH-¸çö–^€›-û'EnjU3fÒ4:‰ Õ~ž’Qã>{ЗJúÄvï˜ÛÚìj.i€¿|-zâÀþˆ\X±;4R6„B[燠ô’LÓ­ë°8Ä9ßëg]rµg{íÞG×aA¸h¢iÊ4S(+mðŒ=yØ¡;•)2­'Ø£¤ +>³²xˆþqh™qj,è†P SìòؗwÎSubKRZ˜*­Ì!YšC¹. +CæèÝ@!Öë`&Ž@äs?£¿ùŒsççÐùš+ê„tf@™  +·u¶ÃTëÉ Ÿ¢©+Nїùø¯§wÓô8øœþå̞¢ðœ½†i—˜ šçÒêÆÇ‹RŸ†¾ ǝ?†Opž±5¢>hßÃy–ªÐ%˜â™¡cõy‚†•ö•hR„xK9èÁÆ­g5|/äb8/â´ §‹£B¡h—‡XpF°Ä8ó=jÌ öAaÝÀuҋ2υi‹;Kï*å?á7\¿`ìÓ¸ë@êZ”‘Áï‹{ +îû‹n;c·8óE¼¸Íç£Æ_•Ð:QwM³0Hí¼žpy³‡€BUÐ*ø|š?0Ÿý-£»<׬d­}ñÁݏN¾AâT¬–@û@·ë­™ ^<ß§€ˆ Ë6?rq´Ü„£bq÷|G|=‡ñ©ŽøÛŽ×ÉõÜf·"ÒAá˜ø¸–uº¶¢ªX—Ïø JÞ=Ž›Æ7Ó+Þ3ãÏ®¯n3þjôêWŸOˋ.þ°\žendstream +endobj +2121 0 obj +1452 +endobj +2122 0 obj<>>>>>endobj +2123 0 obj<>stream +xڅUێÛ6}÷WLóÒ-`k}ƒ½ûl.(Š6q±ú̕F+v)RåP«êï;CJŠ­4ü ‹—9gΙý³ØÀš8naw€¼^<œ·÷°ÙÀ¹äÃÝÎÅ̓Ê_ÐÊ#(CZ‚ƒúZ[„PñÖ«ÒF=äõW#eðÙåCÛª¼‚§ +4£R: +Œ¦®üåü÷b «Í.Û +îtj›Æù@KP|[ٴ嫵 +ÚYW!† dp®äÝ×QäÖ(Ïoh&Ì> 1ðîËé1˜+ NŸ?ÁcèMKðΦzX¯¡ñÚrÚ0Î*i1!QØ,cjø¯ªæ#Áo?ÞÃæ˜”]í¶Ù^`NC°÷^¿¢§tî««í1;\ž+Ò9N?1ϝ¥$8¶µc—Jm‚£s]ê\ª‘y–®j››¶`})rwç& €’ͯØ aub •/àwEèÃMyô"ÿ‡0“„÷«FÛ%l÷éy©h4t9ìŸ*'²á2ø«Ò&á$CáÀºÏhÑ«Àù7A×ʀkCӆHZÜ/tY¢G;±c• +4´œ!óÙ^b6Þ½ê¹Xˆµ‹w´}ŽX³ä!¢U®ƒÞµs±t^ó +¿yppF¢r•wž«ƒ¯~‹[ó6§+Î|¿Z>aèœa.?*”„˜EÄÇA0.gm¨§Àp±™ÛइxÙô@¯ÐéPãó~8:Ý· >u×¼_R¯‰œ¡´¼Tä€6:yUˆ‘#ÏÎÍ4ò¢‹\_,°Ô8gXqJ®2܌—¾pŒÄ¹Z¾ˆP«^Vy +¡Á<Ȩ‰ŒñŸz°ªFˆSȳµaê&&ž¿‘ý·‰Ç›lÀÜ’±âD*† sŒ¹ÑÜZ:ç 6XqíÛͺJó\3rg„#4’>¾ì£[æ7zí‘LIˆ »l¦Äåì»ò£nMÐÒê)âQ5T¶LÃ1dSõ$1Ú=2¹šhK ÷cSð8ûs`9M/±¹xˆ–fª 4vU˜«© +¢š;d:º1¤¿œ.¦4Cÿ&A)°«dQê‰ãûԏ‰¯Ü¢¢|É_‘– i­AŠJÂP\—¡fÐ#â3yü”Œ¾ŒÞìï³ ìvÇìN§üèÊЉó'ªk¹ÿ‡²­Šµ½J—VÇíú;_ŠýÝ:»‡¸{”÷纋ÿâpTendstream +endobj +2124 0 obj +923 +endobj +2125 0 obj<>>>>>endobj +2126 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS04±Ô3T072PIÑPp VÎO+)O,JU(ÊO/JÌÍM-*VðMÌ+MÌÑ Éâ҅hх걉™šé™+€ùE™y%©E +.E™e@ Y×®@.>é$hendstream +endobj +2127 0 obj +123 +endobj +2128 0 obj<>>>>>endobj +2129 0 obj<>stream +xÚuTÛnÛ0 }ÏWÙK +$jìd¹ìtC;ŠlsÞ + ŠÄ4jeɕìùû‘¾ô’¶1Û2Åsxx¨û^cº˜§0™Ê{ß³ÞéÅÒ1d[˜$sñfódzÂ²õê/œ­.O²[ +B’p訉M¦©H9<ۙj'‹hŒ*˜ F(3…5J–Æ;XdžcˆpéhÃV*„ëAŸ`ú×'¢ZB2g¨1¡¤bڀ<ñ_fd8¼äEÁé\Ì^Û&Šà Q û·Ê[‹ª¦ä·`:&¢F ¥‡X…e]Gभ?GÞÒUÇ9™4ZD¿-÷2 È{´–ïú¸O>‰‡°5–ÓCjÐÁ<Ô ÒiØHu‡NGт¤³F‹µ³æë¼cÉi™Êð™ä$RW;5§-_Cå4pØÏ«u'#üD‡Š[UâFË +]DqTZÝæ¥ãŠd _’ªˆï;ØørÇèT–¼ÆeùÝ(ú*Pç‹Æ¯Jl}ÒB½ Q +ÓÚì ‰mœ²•nbsŒ[s ¾¨ªˆ§ü'vß^g;”¬ u?uû–õẌҴ¡ô¡Ëþ*óNç !ŽVnýÆhø +¿â._ +>?´=ï¡ÏÈNæ(ŠÈ¯¥)-ö‡]Æ¢KxóçªüŸ/Z?µ×'Ÿg– ©ù¬ã›úŒ,<Fù¼ j¡MLÎÄwwÆÝðŒ¼Õ”VÁ䵂JÁÈw-ïî‚kl8¿ÊÎÿ¼ËûLkÃȧm•µ™PC“›Ëlx"î+ÈëÉgš‰q&J¾ 4x´±Ä¼ÞϬoO§f®|\_{F-ž;‹¦Õo›ÓÅX,)ˆ>/ùý<ëýîýúi±endstream +endobj +2130 0 obj +670 +endobj +2131 0 obj<>>>>>endobj +2132 0 obj<>stream +xÚ­VQo9~çWÌmû@$ز„&¡¹œDI{‡šDiCt÷©2^/ëÖØ[ÛÄ¿¯Ç^–°K°Þ™ùf¾™ÏÞ_­zîÀá~è¢õqÚz÷yɦ™»stâþ¤ísfµ\ÎÁæ Æ·×70ºžÀŸi¢WÀ%ü}u £Ò*ªdv0ýႠIBnÿƒ  ©L€ P¨¢D®ðy©‰åJ‚UJ@iX +³,ˆ\A¡Õ\“…‰a”¦>…L ¡–˜à’ç+Uê€L6ÈÉaÜGì5‹]® =hÎèOJoW%6UaÌFv†j^Ø©CrÔuûƒØS5ÿóiüåûÅäã]Û(ú“ÙNõƒN˜T/>ASžeÆBô¶”dÁ"øã ¢É·ÉÑ)f$æP½\à›³¨+BPx‹×QÖ Ãqg4W])ë8Fë@îŠ2,ˆf K)ñ6æ7Ãgüî ±´]·4¢3g6WÆÎV$Mõ+×îâ¿BáåeU÷“øh·jZ¦“[[Œ•”N0ÁÜëé礋ƒrèòZséuÃô=§ÌìM€˜î›M§ˆ{žºÁ7jÁ`F §n­ +iª~´IQNýì:™äĂdNZnü½½ƒ‰ë<kôa牤¢L|F³G„òÊÎkk-^"¨ ûiܝRҐ…ÓþZ>!RûOdî~Åù_Û(íÇ¥öf ºÇ}]Ч¼?Ü¢œøjþ§˜šîšf»T +@^k¶€~×n¤wËÃÌ<ú.n–9§y‡{"ަ¨G¸Ú¾P"©Gz æ5ŽãÆ +ÎÀ5ãéé“¦Þ Î`«œ»vRꇔ|®[I¶£4l°’çØYnÅ®Q¯W·w§Û\†^×¢i4aƒ·áÞX-䯟hQÍkèÓà:M1f#«B³á·KzDÆwú¼ًð€ŒgW€­í‹ç1D#ênþ«t +犖 &mTwø(Ì¢jfK-ឈ’…cº”ü—û?9Y.fŽ”õ‘YC M=àØí¢KâÜ$0­•~|k©õxY +Ë ñô&c˜;‹ÓÒ«ù”äÌþ-夺NÃ8q:‡!¯ ÿ•Ù% ×áácÁ´K"K"лœºÇýú$=\ìÞÇï¡÷²'¦OÓÖ×ÖofáÊQendstream +endobj +2133 0 obj +878 +endobj +2134 0 obj<>>>>>endobj +2135 0 obj<>stream +xÚµUïoÓ0ýÞ¿â4$ÔNmš”ª[ ! åE“—8«QjÿØTñÏsggiš¶›"“¦Ê>¿{w÷žý«“@Œ àÙÒeçõ¬3¼ˆa +³œV&Çø+ë>2-\ÆáEêJ3¤ÑâUoö³Ã`”D +Š¢¨µ"¤…êû©®DvRí'qtÜڗny™‹‚›vLª¤±.˜†Cð=‰ãí¨íÜ>!¼âúYc¦ :<ïH¶ä} ðáÅ(TڭӇåªÝvØÎ+lAq>}ûðaÞ; !cHŠ`##ÏêÃY*‡’#ä50 TbÆj¿bàVØÜ% +(ݍJæÝyo3 2Y)ça+LH•ÃÏ»- V±5À¼Lfw}ˆqM®T˜šk`Z³Õ6èÀ\ià,]BvÁ¬gyː˜UPR=õè&јRžþmývÁAs봄V8‚Zá¤ø…¿ß{2㳒$£1…dLÄa8œ1™ò¢ q¼WW­Â(f¶ƒe8Œçv°„ÜÉÔ +%!õQÄé9ž­i=ߐ˜WÏ8Ðú#îu ±Ì:ó°£B\e©F‰-+¡X6-²å6Oe3æ>Óìèò:ɺ±•{LÉS‘ nü¨3n¬Ì7ÅMŠp{ÚË8Êy)$÷†ëT7®ŽqAJ8C:9lRhX¤QΚM-@B"ç\#z'¦ÏµZâàKÍo„¦>Rê€B¾ïˆÙu&eEmqgºu¸oQMÚq"÷%cSÐåŒKSnLîŠbUI¾ÀÐ,ZHñn$Í=“ÀµVz¿eßrkI”ýô†‰‚]á•ã{µñÏ +¼ù#݌¸ç(ó™áŠ×ÚºæÇ[T +ý`5£²bԇ4ÐéeâÓ@í1þ–lÝŒ5,°ÏQ³Ù¹#š¯19gû5F0¿siáp#b?p V]ë~>õË÷Yÿ =M£¡ŒUšS¿°Ã;ÆUÑÛq;¸ŒjZJm4ë÷ۋ®ò#º^ú•sÃTZóð/⼋ +er5ïõI«ÂÞÙ±™+l“x˜qsS•´´‡[¿T „ý·«’ãÁªDØü†‡øÁy£…´0lÍõw?®Ú•` L¦£P-œ}ûü¾ªÜÞ2M–Rך-—䪏L:VÐéA2žâ¡ÁÑ(Þ󀎏ƘÍï&þÚx3ë|éüɒ +åendstream +endobj +2136 0 obj +914 +endobj +2137 0 obj<>>>>>endobj +2138 0 obj<>stream +xÚåWMoÛF½ëW ”‹,H”( ²¥-Ú¤ +8‰ƒ(‡Œ97].YîRªùïÙÙ%e’¦>.=E6 z9óöÍ×ûߎcóåÃõŒ¾ƒ¸óDz3ºÃ–k:™Ýš§°D,ƒÃ§/YŒƒâ—Q2.5fd¦Ð{菮–ß:cúcïÖÁÔ?}.•f2À…ƒ¹O& Ñ+s ۢ͊àJSdl˸`+%¿koBW/X׀IIòOž•bÀ×<¨’ƒ\q¹±è.žqOB}ú±}ì=^Õ£íÁ:—¼.ÝÊNN¦Þ”ؼâ2yˆð† FôË~-(O|ÏæÊó¼ÆIµ¼T\"«JTêýóñžžgïvvð Ԃïº'.ÄÕ¯t¯;€†MYÚv‡ˆ¶ +êñêt5Šò|÷s%”Ψ„\Ù*¦mîÁßE3¤tÄ`ËDŽÔJ |šà&¾N`ƒº:–Õ:¤pæªÞBºžŒcÄs…ÙÐ\À%†uiñàX_FU¡À Î¶z¯13]º¡km…”{2*ºž»dþ”.¡Pç.T+¦ÁŽë¨T:%²¾!Û߅ lW!Üò$/üñ?§•›t*‘IA#Üq3VR RBÚbµƒ™ÆÖ»ÄˆÑ&QjEÙ2oê•ÌÐ Øï¸À6 haPóQ§tCy`ZEµ#½$βÔòFÍJe' Ò¤Ø6œBö FÆöÇʼnT¦ _ÃÄîÏbmVOÖÆæå©æZààÌöt+«²¨GP!¨4UÏž8ª:Á¾;;˰%ª¬/9Ö¥Wiь<йi(¡dAt(9íTÓ>VÜÊö¢^²kÕ®_fô1¤'cì&­Ñ\E½ýúðňIfa¡|žV”Ó6ÝS܎±†ÛÓ´GæA.eÃr;tFéÚn%ÕLÚËidT¡5'g»ØŽÇ3lÞ_™d!ËÇìÝõߒÛúÿ'ücඨ†oêåÃl>uŒ\S~IÖzGmý%›ŒÅ1Õû“9ä=ô§sã4¼™ŒÉǟÐáõíÌ£!Nm­?—Ïh†¢Pendstream +endobj +2139 0 obj +965 +endobj +2140 0 obj<>>>>>endobj +2141 0 obj<>stream +xÚíVmkÛ0þž_qt0ܑ8±ò²®…®4£ÐmI¿ŠbˍŠ#u’œýúÝù%±]§Ð}Ú` G¾{îE÷<Òϖ=üz0ôálÁºõyÞêNz0†yD+ƒáÈõa:Oj)B€ ’g3ÕBډˆùÂYïBnlçR²5oÃI„‹ôx‚ÏVØNçO­t¼ž;" hþìq’õƒz¶BIÓÞ/æ ‹ÓsëNúày”`3ìø‚¯„E<°bÃã$†°+¹30ZÒ°bž5ß•0BÚýžÅ¨fGöC²ÎßBÀ$°Ø(XrŒla¹ƒJ4¦£5[c~„I9g@½È¡ž_…a†³p§Õ@D‰ èÝDZؿŽßÏ2~'d'!‡OÖ¥wu™ïï¹i]×­­`y¥M*mÎym[ 0÷`áCÍêx€$W¯[¼¢Ï|»¿»{+d­w'Y‡ü¬CÍj¥gMnÕfÃâä¥QePßW'´TÀÿdþÞdŽÉ ú¢g¬&²ŠLcȂTã 7m`2lâr)Ích© DJã?fsÀý”2Bß°`…ŠÇ`՛õBs›h™çηԥ%ÊVwȅ +†©&mÕ^GI*ɱØÎ³ì€0Ԃ¬®·ZØ\#¡Ík*|Qþ%Ã6„ +$ +.3&AÏ´\ª‰b¾V“i*ÊïÕR²bÍ)_ì‘æ&‰-‰Vûk½¦f6DhÎÞE=B ¦9Ö"yIÃó(ÿž$×j^8Õ)TœŽ…Æð%?o´VúØ¡x!Cvi®ï§3¸šÞâYˆõ‘sq¤™ý°âéÉ ±zhΌ’–¤¯Ò#vIÜI}x¾æÃTÝÕ҈P­wÌØ4Õ¦¡"7ÌDj?KYÛàå6¹¼¦LÈ áv:-J›H}°©à-^d¸ °R¼ðÐ}{š-‘«6 {ˆFŠB!lžø…—#d‘a¼P)“˖q=)Ú ¼X.-£#Â¥[ן ;å‰zƒÁhœß Óa™©Èn‰vÓìö´æÚÀW&“wÇëÑ©3D¾¿~aëûˆ›Zyg´p3oýhýÈßI[endstream +endobj +2142 0 obj +867 +endobj +2143 0 obj<>>>>>endobj +2144 0 obj<>stream +xڝUmoÚ0þί8±K«’ÊhY×iÚÖN•º ú ©r§¸JìÌv ý÷»³ +P5 9ßËsϽøo+.~8З­¯“ÖñU†0ÉH28=‹{0I£8Ž&­.tzI< ‰Tõ½LÏ7¶¨f0¼.\\@wzPŸ'ÝøŒÎÊÊÙiÄ«Ò^£ÍØ©‚à†Yç…Óhz@ïøjÉ)¡ì ÌΉ9}‡±0sɅ J}HR"0§Ì·ÛѤây• + Y¥¸“ZYpGC L¥P0%Ë*gNÀH[7æF–FË ߅õ4ÄÌÚ·==€LæèÑ͘fTV¤M¢'Å…t3TP֎R#çÂXÄ„kIÜ î“þ%ã3 ¬È5U $ë}°9“9»ÇƒL0W—FÏe*R¸Ö9ª³EFk•å’;eÚÌg€O8m)¸Ì$]r¦‘ˆbàL½wVe.ž@WËè@¨¹Èu)lJë‹Óox†\®åpE,m©Îª¥TºµJô‰zá¸,ÓxöyÝ:‚™`)’éIÂ2"ñރ'®©ïÇÆ_Óڝ^?{W7ìá{¬çÛg2“v- ¾²Üꦥ<÷;ñÓÏþâþÎQ ™OŒh¤ÊÑk¨óN'¯± +ô†nh¦6Á4”8†b^·Û² )( +0Û¦“QÈsfßÎó +{—¶¬uÀgÌÀ!ŧ°›+§‘ìæÖXzKDkè¢ör›l­ô+â^<¼Ðeý®¢6hH­ yCÍê Ò¹…Æýbqc¡–·dØL%N1šÒê c·1œíÚï—`؎—û´YïW‚‚9˫УPê‡,ÃÍcîŽÚ°qŽØPi¨1ÆÂHç„¿¿-%Îò=­ó³ro‹Åp½!H5v›Òē´înTà×íÍÍfšÄ1Ý7©‹t÷(Ýh–®Òۇ÷ÃïR(2Ú;=m\ˆÊ¶ë~rèbÉ14î{ÚÀXˆ[À<ÿÇnÚ;2¨vGïâsÝâg5Æk”Àà샿zýu8֙[Н52úÁ°¢ ;é'SËɶ“ô‡hÒ9íuÉ&铰Ÿ ±ÔÝm÷îå¤õ§õVzŒendstream +endobj +2145 0 obj +865 +endobj +2146 0 obj<>>>>>endobj +2147 0 obj<>stream +xÚ¥X]OÛH}çW\u_B®í8‰Óî®Ô¦€vZ–¤•¢‰=&®ì×Ðì¯ß{gÆNbÀ1BH‘3¾_çÜ337ü +>5Z®)ÖZžÖBhè×-†Ü3†*mÚM:`± áˆ*]¡nPËØ*Nâr¬Dñ¯ª’'åZY2#q‰DI”(°(±zcU”±»¶lŠø?^»#ù…„šIêd¶Þ1öR–ßQM¨ýÂ$¦|ô=ÅDi•ªï)û¥ž)tãÑJkü-øˆýV‚ǝoeH§(eŽ5ψʴA³½Ý Ýf›Îj6c^<î‰1êѕ‚‘£mc´tÍþÖL;)ëސ€½)Ú ÑFËry‡¯á öŒd’ÈÚ±¸¹°úÂl¥‘qñ‡–Ð} ýJِ…cPù¶’ô&S5:¸ç\½ôY!Ìêsãlqd[6^ ÍÇÍx¾5wŒ_1•Áœ)ºceó'ŒÑÔkŸÒt»ÞÐÕ¡§ØZ›kKƒÙT‚§ö ‚*g%_båx¬¨öëº"lÈ>—~ÖÁ¯¨²LæxF×a`'L|ϦêúÂWÖ}áëЇá»´P÷D"óeÈï〿 ¼ò„­g^u^öÆ«¬ûâÕ¡âu|o‘±Ghi÷Åò)ÈØ×úŽX•”°ñžN„ål¾œ]}ÿ礵e·¯Nj³‹›ßŸ1»¹øÔ˜áósѾtSíŒÝFZ#‚ÜIµ¶V»Œ5Õ&´¢zkýÕÞ´¦Z”8,¥H6/“V}à©OAbQÉ +OQš3ê``µýÕ¦­{ªÍ„>¬¶¡­¼–<­u'­Žî¿0›w† Ý+õI4œ<ÁÝX'>>>>>endobj +2150 0 obj<>stream +xÚ¥˜Koã6Çïþƒœ²E¬•¬‡-,zi6É¥Ýuk÷À %ÊæV¯’T²î§ï”äG‹NÀv˜ÿŒf~Iÿ;òÀÅüHý&Åè·åèó=Žx°Ì t)D³–éõ$_Ñ2ý´ü1º[Ž\ÇEÃþå¯fJ;935^ìL€SX¼"õÂØñ-µn‹#Ãüî'ï„ï¹8²Ì?ì;ðg8²Tqàä™)‹BÁIËI™Š„ÔTM›ç¹N„³ã¬”jäó}ÐÎô,Àgêýޙ@Å-%‘¬*o`»8øšÒ §T òŠÀ<т«Vë,’7®ãSÜ«_©Û B°ÁÒMª”•›ɖpøå-Ë-¥ ‰¤ASÈ‚ÄáªV\@HŽN‡`®ØÃÐj[Æõ0Œ‰ÛWÄfõD¹ÀèmY´ eސ } †8¤áÂØóÑí¯ïÊMÎÄöî9ξS™8Ÿ¨¹3µt|þ³²k aØ~Q¥4_•M±¦Ü>÷¯œá:‹š&,c h/`¼8ɇ—4 £¶M>´k¡?E¦Q™l_Ìùù¾9W6TE¡6Uêê]u‹›„4$Ï ð=•-­¶E`\#ð¼vþ±b3Üþbþmzææ@$öÈu#)d¼*4ùüëIÇÌXNo€e@ʁeÄû1Ü$Ú²I¶®›d0MÔºÀKRÐ÷0R¶ßÐÖИ(ꗐ­¶c\ƒÁˆnž%Kþy'—ohz˺ñƒ 6W£¶Åc\ãñ‚¶Ãð*mù:scùèpœP†ãzýÞcG«má׃pü™Ul+.?P> e¦†NÈB®!?Šû=ŒÉ¨-1µ®‡1á­#—[^5›mÝHû ú›ÞŠ¡Ê Æ“™€ÿ(X‰|òÝ~í oMFm¹5µ®·&ߟê¬%'·RöŸýÆÔ_l–¼Yîðš—U¥„½x¼VÃÁdè|îûîÇS£¶Å`\cð¦¦Ã>ÎÈ:§+)\x>M]ã*Ð9Þəä=ï‚ã©QÛ&ïyoOã6&³öxö½½záA p Ôâ8W\ݓÈH»Õ-º”¡hrÉ꼿ÀÝÀó–áÉMÕ…¬8^ñX Æaþº®Ó•ѯN¸^ë(^‘'ۊ%ô¥> XïNzQßě2ÑÁ9­ KçŽ`¤í5£D7øŽ „¨F$ÆþÌ$æ…å åù• µìLŒNËRÂú´u¶Çüý:Ú_L/í#PVòÍ(Ñ5Rɰ—)_®hI9ɯÔ0Ww?qÑ_<ݧ´Æc6ÞÀ¡*îå§àÒ ¹¨`Kžpº›õX{_àöïù’†ãe]æ;ÈYÁpy(‡ø ;æ^®Nõž¹ÖªÈ¸INáà¿á¤(Thx+ÀŠûÉäÎ1¨ã—•z[•YÎyI-w÷,ý}• +1i¨)3«dMå3EÂ)Ë2ªÒë*߁þ™ÇÕ\(‡9©ºnmÎV¶YR&¼ÝÑ×%rKä>L]T5ŠxKgÖºô‚Øñ ò]³¹›9ZT™|VáÎ[À” }Ý ú[б1O'¦ÙEjПúN¼ßÈ{ ‹.â¶ñý9úc׃Jendstream +endobj +2151 0 obj +1345 +endobj +2152 0 obj<>>>>>endobj +2153 0 obj<>stream +xڝWmOãFþί]¿”ìKÒôEâ®H•ŠJKªª‚Zìu²={×·»>àªþ÷Îì®ãÄqà {gž}v晙åÓA 'øÃ4·H˃³ÅÁñù â9®LN§°È—lÉáJ|áæpñŒ×£dÉå{ÈEÁ ˜Š§"V r°+ì3»+8Tˆ„&LfnµZ=‘²J¦—Bâ‚1*Ìò î…]‘QÁbÅ ÷®Ä÷ŽßF íÍ4¾·J£½à)žŠƒªÊnÉéÖns ‹®S[ë@…PZ¢DÜ:`².oÍn cÛkWòòŽk³í±q""MÑ|‚t«R&¡Pêc]Ãàj+Òº`ÚÅÙÅjÁž¸PZÿ™]Ý n; ŸâFŽ¿r¹ì÷ì Fp" õ¸@^ËÔ +%ÍwßŒP“£dìöiQg¾OëÊ#`´ú1!‰£ ÙDQÔyÓŽðïy£œ“è´Yöâ€#úî®ç…bÜçžõÄzáâ1–‘K +À°|ÂøÄÞYn…cðææ°ËÀÑڀ ù|5ž?F‹×¤ùe€mnG.‡îä‹]¶[ +r Â8ÕJVbY·rVéÄuŸ§¶ÀšJ ·RBZ3'ªiüÅþæ_BÅu§{ ®VïåR%-£že>Ã@ƗoiH*WºdD}¿ÂícÅ3žtÒÔñ~ í¾@ÏǝŒýÛy܍¼që<›;áhxÁSl­?Á@ºÂÞáb~=Ž?ÌÉó‚g‚mƾÏÏ×A8¿ßÑ ‘ú\éÖiés߬ ¡w÷º{¡nÝîÞ?·P¡’¬kçë<<‹r§¬Ue`qæ^…£Åre›`üA¯‚±ªšCs¨…ª^ò´u9Û­Ëwµ¡C~Ő?ãFd܋ÝXÔ7Óµi Æú!Ì ¹ Á¨’{Ú4ùL]UJ[øÌ´pÇPRÏ EŠà—|ïjtl|ï„ôÞuëŽïÞÖek¯8zÁÃ`°|É5¨¨Q«ë²ÙߐÃ'qò0%X‚×§Ñ·@óý‘† 7υ’˝ú q’Œ=Âu<}ÖßÕ踭Ñ!]`3§<üæZpO…N}}â˜qÁ3ùHùÔ#/–,4p3Äk#^Îû•G;½ç9Cm˜§®jؙÜF&ói‡í ×XÜdÖô„WÜòŽÏO…ácüÏ$ñ÷)x÷çå\©ÜÞS–/µZjV–TkLÖ¬ ïQ<ž¡Óhšœ47ârŽ\઩)2Oǘ:gOéÅϋƒßþ›ûÎendstream +endobj +2154 0 obj +1097 +endobj +2155 0 obj<>>>>>endobj +2156 0 obj<>stream +xÚ¥–ßoÚ0Çßù+NÝ ­ Š(ì×ÃÚUÚC5¦²7$dœKãÎq2Û¡â¿ßÙI ¤PJg~(Øw绯?¶ùÛ +¡O¯.GîÍÓÖ·Y«wۇ Ìb×3ÓSÔ‚à|öØêCw#דçÑ".èùScx¯ÃÓn0f…´fî:æçÞ¯w;„0t3viÊîÀÛÏTÀ™”`„Ò¬_™ÕÁ~æVdjޞŸï†iC\(îÆÀf’%‰•ˆ +&!ó^æc³®µ;C7õ¡¸,"„ϼÈM& ’¯o)pŸ"a?»a¡,Tg*–‚[s\µ)|FÑô³geƒ²ˆ¶b)î”Õ>{a³b²hYˆ¦üÛi¶Š35͞ʹµ3V õ`€'YfäL[Á Étµ2> ŽÐhr¤¥\¡\àrÑh ­Àa_×Z_—2£)4}Tf·r×È,F°\{¨ Jô”lT•\ÿžÞ“&ƒ\gD ʓ¬P T·xřö|QIàX­Ø"ÜöaëpZ”& »G˜‚Siøf0Ý׉dR;'5U¤U–¦i¸S\°Ú ÷NÜÝT[ÞMü³Ü:µÚ'Òû"ð+LJ‡ ! %1²¹“rª³ÍÒµ;¦è¢tÞÝp8!§îÕ ï|±ë¼»? ¯Ò÷}ÖúÕúì¿sàendstream +endobj +2157 0 obj +693 +endobj +2158 0 obj<>>>>>endobj +2159 0 obj<>stream +xÚ=ÍNÃ0„ï~Š9¶ qˆò#ąnHE5·^Lj·n;ؼ>^J+ˇÍ·3ûÅ8Šô8š5†‰= vÿZ ƒÐ¤ÔM›—ûÕà¬Íž0Ïûþ:îViÚ­×â”À +œ™%4+kÅQÁ«¸x‹o9. +& &Í.Ó§òp×ÕÆàæhœ wp>õ2š¬^A¦oÝÍòK\ûÇ«.ç©kÞR"úÍ[§ãqï^N“òoÒ.r$8»0YSÄôG5œ©€NÁ·ãÈX5UZûgâ /‚½³_Xs\Êendstream +endobj +2160 0 obj +224 +endobj +2161 0 obj<>>>>>endobj +2162 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS04±Ô3T072PIÑPp VÎO+)O,JU(ÊO/JÌÍM-*VðMÌ+MÌÑ Éâ҅hхê12 [€,r3R“³3óÒÒò‹œóóÒr2“KŠAJ\C¸¹&Ï&’endstream +endobj +2163 0 obj +130 +endobj +2164 0 obj<>>>/Annots 31 0 R>>endobj +2165 0 obj<>stream +xÚu”QoÚ0Çßù'žZi¤I ^וªÕº’j/}1΅¸‹íÌv@ìÓïÎ@XÑ’eìóÝÿ~ùÛ¿¤ôË`šÃø¤|-7‹9ä)Œ³YrwÓåÕFðÓ© Ìª èüuñAÑÈ2ŽíÃGãIžä|¢¨•Y‹–b¡D/Z¡‡Ún!XØR.•jª¬ƒû·—e²Ï<‡lʙSJš'Îù}ƒn£pû¹4äSªM‹S:Â!´Î®ÐB-Hk(C€ÊY Ö PEm)ìùéù®%$NjÄ É±]è< –VkkX•ÍÆû^yQ˜rÔ(ÊI@³Q΍&€2t¼÷DÓØ-ëA͵V–Ž• <Ēf´Ü::éí¢°ÕYéˆîÄlrD2ß3[¢ìöî­ñªD'‚¢ÙöìŒušÔîÀu†Õ Z1#*¸!Y嚄÷¼ån@‹Âéåä¿å€¼àÐÛΆ.¨Fý‰ëg͌úoçkÛ5% ä )%éL£4ù†Xiۙà h¤/¸‹ÔKåo õeo>¶GяÎví%5Tb%º&DOr;•Zw‡vˆˆ?ù,zÃÁ°i‡1óš3Ã0šhxYJºµNx¶íE%}ÔÞ 2äéP0 e"ÿR9”Yø¥ªm­vqkX<¿|{z~òåF8%V 9œšåâÅ MRzxÈxx}ä?p›'3Ð0ç[ç ,ù­8‹vk¸Y¤½þÛqŸI”¹ nòýêý:~óþdڟ>>>>>endobj +2168 0 obj<>stream +xÚ­WÛNä8}ç+,ž‰dèÀv«}€™f„Ä0½\4ÃjåN*Ý%vÆvºé¿ß*ÛéKHЀV áøÔqÕ©Sί½;Ÿ;ÒoZî]>ì}¼:cƒöãÊð²ƒ{™3öŒá30Ì*fçÀ è?qË  ü–(і\þô8¹g&CV YªŠRkXÙÀ¶Á2–ˌ댁ÖJ³\À¦+·„ÏtÌÓÀf7×À4|‘ÀЃã8¡à²FzlÊ d¬®”ôaÖt<ñ£@üàFÍn`ÅîyX&4’ ˆCdŸ4'´« +˜ÊNL–r-…Ä HŸK&¤°‚¬Ò‹gf$<³ß;÷Ó19Å3¬ƒ<%ÃQ›éçñåã—ó6ψqŒ=­g ™]Ø­ìta^ß^}ë‚$ú¹Ò%·BI<Ä{°¿_ÜÝ^ßv3^r-IYïÁßÝ}»ë&í5ôÐÉŗq'ӊêËÓTÕÒ¶G»5»ÎÒ¨¶¤ ϖe ++•eS˜ ɖÂΑçÊ­ã»|ªæ KR²¸EqÓ®-ö¢¶TŸc©%q#È 7„IU%%4E뼕aûYˆv2¶9?·V‹im±1­Ým;ÄC ¿Â(Ƴ¬¯=oà\qþ-Ô¬¦–Ƈ!=ŒÜSƒØml+JÎ|)&´áb½¡Ç«&ݰÞajãsçÉx½@YÎAb'1+¾Z­7ùôd17]ÎæÜ´³3wù,ϛ’œ+ôá(9 ôIŒ6’u9uZ­"Gt÷,‘Û6l|É/×EÞ ´sž (2'6ܖÖZ“=¹<û÷ɘµK ·làL¸ ßGªA7¤} ­\`8™ß>>>>>endobj +2171 0 obj<>stream +xÚµWmoÛ6þž_qȗ9EäDJ`'í:ÀKœÆ@×x¶Úa›‡€‘N67‰TIʉ»î¿ïHJ‰ã—-00,ñx/Ïsoþ¼Â1}BèFpҁ¤Øû>Þ;º:‡ðâŒN:gô#m]ÈrïP b†KqÿNR§†^*ˆºV*ž!ø£N}ÔJdÉQ?—oSÓª@a@—˜ðŒ$ÀÐ]Qw¨@fு‘P*™V ڗV„‹²2ñÛ00u.凰虬ò¤ÈÖ ¹ž´#ë˜3Øèå^ي¯V«`nõ–kÐUYæÓ6Ø`­)À‡K‹Šu×ÌHˆ)´.T6.fš V¼JqÎ ¸H±Dú" C©Í8Q¼4 +cC´î¹¡À 0± E\ZŠ£(˜H5dJ.–úä Ãá¥hrpš ŽÎWL/ÙñŽÖX7A—ÚÈr7ŠM¡.¥Ðü.§¥õ„2cú˜må)‚è¼íR¨/æ\Iá€üÄg¤AoI¤þÕ¢ñLa‚|N¬1zó€)h46pIá¼QèñN˜€;„J“ôÝÂá㕽ö“Ú`tFpQÇ{8‰:ÝU.®{£q?^"pô'3¦Xb}´.-[K(GÈ- Ëǎcå¹K”l´~ó!îˆo㟇ýÍ.Hŧ\°R™ø$5‹‰ø*™Ó°Ïl¾&Ž›£’X׎õýÝÜø8ß^öâÞå`´Ù\z–+ )3ÌÅ«w·4î>õG£››ø…Æ)2>­|þ«—ýOƒ‹þíÇÑ` Ⱦ}½Â£Ø µ¿ï}x·%&¦›âÿ‘:Ã^|½Ù*>`R9¤JffôXJeȾë^M¡ìfkx¹ÙTVå94mµiáëj7c£Ŗ<Ü`>WXífb4Þ^ô.®·Ô\ÁxQÀ +Y ׊ +,$5,dTtuת‡1»“éñÍUüSoÔÿ÷ð\æk™™{7‡¶ì©ÌsšGûöä(l‡»yüËöjËÁð¿H±[0Ç/á)©”²OP©ÇéѵҁïÏ'‘ïϗ\kL Swïz¼{ÁÕRÂ>›$íN³”4¢57“ÖŠ£³ršo˜w“;¹ç<¥ê°SØcn¼ÀeŽö|ªXQ)hp½lÏ·¢% ()%¼dô·aì¦7Üô‹îÚ©\3,¤¾Ðg´<ä¸:¼išÀ½âá¦z¤[mþqÑØ>ó‚”±œi8ÛÊUÃTƕ¦Æô6=ìÊSsÆÝ6ˆBW +=Ú.w$åNbžmŽn3 +r.ðqsó+YI» =¼nÈ?·Öië ¢Sï.­…“ÝIà[èÀׯà~ÝÉAƒåqûÌJþ¹ò òzÒÚ·ƒkôšŒ‚ßå]À] ~ÎMþ¸ƒ6Àþj!üm2û4µMŠJMÞ¬©Wh*%Ƚpýô¯çx.$—û½ÌBçÆˆ]%å̇Ž;K¹B–>ñ« ÁÇTZ¯Ú´CؤÁt;lWƒ÷}x••_Qè+ïèÕj¯`Á=RúͺOôÖÕóÇ÷»É×$?QÚ^WyC2êžk»õPMX¹ ﵡ¸ÚíõG+~>Ñþö-tÖ¸¶ÜÂ[¯öᬆ:¤Ú +¡s:9ׯuG†¡ï …ýðËíÝ <=§+A7:Þò¿ê´{JvÝitb_ôã½÷þ÷¦endstream +endobj +2172 0 obj +1266 +endobj +2173 0 obj<>>>/Annots 34 0 R>>endobj +2174 0 obj<>stream +xڝVmoâFþߘCB„›·„DùpI“S¥kC§~(Õi±×/­½Ëí®CO§ûïÙ5„˜p흉L<;/ÏÌ<3æS+„?!Œ¦ô•­›eëì>€,’L/ð¿¸Ë Í{Ë¿Zxaà_èKãÎúM ôa©>ƒ‘ 7\€É8lT. $yÁ}ß?Ö?«EÃП:QžÀª»ê&¸†„ܬºL¥OLÿ@[­Û«Þª××ðë‡÷ïW½#G(ñÚp¥¤ZuÛw—P ¶.øæ3Dðý_½âBqS)ÈÂ×ο6$öùnÙ +ü«M·nï`Ný LÆ#%ŒGT?°p½CR3<ãú{oT2¦aÍ>åÀã~›\ + x€ª2âZó*‹Ôš[˜/1©¨ý.d7ª6zΔæÎv¢÷Ò(Øípv‰ødÂø“ÝK˜Íöu¶ßCª!eO Þqã ý?DI%"›À%éòÛŽý1y¥B>_¢*?Öl¶—Â×g ôOi¡Ì@”1EîúO¬¸jPûx\ú0wM‚H–%VÑ+rÁ÷DlUnv­—…L_¢£ÚÙÓ忤 ö [Ô8nº¸ \0€†óz<1¿Úò 3íuÁ¢¿7…4íÁaE÷Ü´³ûæäìêŒÅDÕk®¾'l’›zŸ›9£Ûð»‚âÔmóØd?uÎÅïdŽq×’™U™ÛhhÙ·´“+Çß³=Ë` îmb¸²ÌØu2cOÜ­„ýì¬î Òµ\Ò0—Ú,"•o®2¶k”´A¾1ƒ¬Ì¦2°f´;¤Ýâ;ø#·Žž·Ð¢BjtÚXNH! ‚ó˜Ç«ÞÀ2ÙmPc½ e<® +®|—ã Âs7÷ÞhèfôêƒEõ²Ôªsת{›"á`†Ò+ܘæuRe…Cšâ¾T Ǫâè&R•vI:hoc‰ô'U%ǔFU¢GF%n¥xB ×ù‘øð³¨ýè)×Pr&\yÖ<ͅ (2΢̕ÊB²g°ÍMvzauÞÌžEæa¤£:Y šžùÏ%iH–†ÚRÈ-WAÎÈo$vZd)Ú-Üá´&%Um×6Ðþ¶ÀÊ㬬?£y¶Ø—´*ÖèÞ}5êjà†ìxß§Šk#w¡.êtCddˆ?Þ¦Ž—pûa¾€…L̖òÇ×Lª6Kð +ÈÚ Ç34ò·Ù Ç$'89}ø’ÿ­õ/Uòñ"endstream +endobj +2175 0 obj +1042 +endobj +2176 0 obj<>>>>>endobj +2177 0 obj<>stream +xÚuËNÃ0E÷ùŠÙT©±úÚjwТ†0®ó@‰ÆUý{ÆMHEr¬™s=ÇþL$düIX(˜ÍÁtÉc‘Üm3XAQÆÊ|É»ãM¨ý©×•½->¸ƒ”±/jwª-Xþû¬65”Mk¡ñŽtãÖcüçt¡ò4ñɤ@Í8F"!³t9Ö÷<5¬Á Ý»EÂf³Ûþ+VÔ6Xè:ë(€n[º˜î} ƒÁ¦§(J>>>>>endobj +2180 0 obj<>stream +xÚ-‹A‚0÷ÿo© ° â£;cMë"±K¯¯UóÞj&ó$†øŒ±®Ò[K¦Õ¡3t.·9cSè뻋TP®/ã;Hïo¬íüŒ£yDs_ꑲ_’ý›¢J°"¯ñÒÍAµþ6œb˜bH~¯éLo®•%{endstream +endobj +2181 0 obj +126 +endobj +2182 0 obj<>>>/Annots 37 0 R>>endobj +2183 0 obj<>stream +xڅTKoÛ0 ¾çWð¶H\Ûñâ中ݰӲÖÃ. +U–c ¶¥Jr‚ö׏”œÄI; ?H~’zž$ã/<…Åx;ù\L®¿®!¡¨ ]¬£–ù +ŠršÁ~éd·…‘nŒÜ c¯Š?˜•A’PÖ<¤ÍY¥”YÔÒ¯™¦”RZÞ[+,ÔjNÁk +` ‡š¥¯9ƒ}-y ˜ÉÀjÁ%k ’ Eh£¶†µàj怫݅/¿6÷D$†y²À†Y_‘9X\a"iÌG0†¨\µ-ëJÄèÊfÄs/(¡RæD* + +אä¤!i”ÄßI±?·ÒŸ¸§ÅÇÐ,Bn’ôjQ‚÷õIlega/]M{ፐœL`慜ê¹ëqd9k4ÀsNÁla¤Úð<ւ•øçΓâcÒIø³äˆva?vÏ1bI¦sÕ(c5ãbO[ª±þå ZQJšêWq¸w/ïkfÊ=CFXÕô¤næÏ«h`] ˆé2Lé§*,„xã-޾‡£#­ê›f>Fé;ÌÐøÆÒøH×2,è…èh¹ßÛ)*,;8ß/Õ;Ý»‘üaÇV§ÕYåýŽô,ÏpDbŠLóa¬~Nþ°]óendstream +endobj +2184 0 obj +734 +endobj +2185 0 obj<>>>>>endobj +2186 0 obj<>stream +xÚ­XÛNãH}ç+ZóÄH‰×vœÛìS˜‹ Œ7dv„„4êØÜ»¾m» “¿Ÿªjہ@‚‡¬@N°Oש:ué6ÿ8̆‡õø$'ÓåÉÇÌñØr O#øžúüN°Ideªez÷~ù <æ8Õu‡„R2ÕB±PÉ{¡ +–”…fOÃX0Ç,G+¼±b±e$%xZ0‰YPˆ4dïüɧóïàaQÀ*xž!‰ÎéY.Œs2¡T¦ØZѾD†íöL¦,á醼E‡Y¾¹}Dº²Ërãºe"ÛÆßuÇ)0Ëb0<ç)XM`aK ž2™ä1­A&©€M%)v/99alڕÍÓ Ì ¢õU†¡=¥@|”cv±³vÛúÎ4$yTÁɪ¼2• é0ÍrX‡ÞЁõ¤Cυ¿ê`ÀÄzL:°Ña‹Lô}·Žý³w‘>*xcâ Ñ÷0Am£'pÛè ¼7z(ŒAÿ\„’×µ¼#Áƒ’Z´ÓÀ ¯n‘‹@ÂÎÛ~ˆ{"ö^…â!ì5j-Û +Aà}B¸£¡ÕÌÜÂjVï o×âªLV´;a=¸'™æOæt˜Ûa^‡Fֈf`P*˜¥¶°jfŠð°Xî¯-Å2à–bð^±úHùT,«ü¨ÞyA+jÐ +÷óžûŠž[Òb¸­Þ+†ënÇçt'8PãöÒÿK 4IjÄ`ôÑöu§xÉà•ÉâÚãösՀÛÊBà}²8C{ÛPÔI_U(Ú¶“Hˤ‘¤×£M6ÂÃohD1Gº{—Û³™¸ÕöÔ;Ü 6foÝÁp÷h‰‡•_g狳Ïß®.ÎÏv˜]6›ß\l/OìÖæ§“«³­Ïfl>Ÿ³››vqñfóþåäj²xfo ¡]3HgYQâ'Òâ'Pãçárrzúœ†ØËɀ)‡ÁTNlÊi‹nÊ ØOÊéßfªr²ÛS}sYúé­kêØš]û“ÙùïÏü=§àõ5.™r8-ß¾ÿý$WæŸ¦Ï "ìÀ<"í°ôÄ1Ö'¯›‡M+Î#þf–‹çӘÿ¾Ù tå mµáào¯©æ¶qœ=¼™âf>{NqC6‘ÀyL-ÃÀ×~˜•[?èMkTeÒñ̤Ie^¯³µ~ÀsŸ¯2ØË“ߖçôyíš%Ýj;›žÝƒQnïù7”Â_'¿cgMÔendstream +endobj +2187 0 obj +1477 +endobj +2188 0 obj<>>>>>endobj +2189 0 obj<>stream +xÚµXmOã8þίí'@4´i›¶Üj%h ‹–Š)·BÇie·õâÄ9Û¡×ûõ7v’¾¤ÀfNH%Ï<óÌxÆêß{ ¨ã_:.4=¢½³ÉÞñyL¦ÐèuxÝ6LÂý{×ëÀÁä;®×óõýþíØÿÖ÷ǧýá·»QÿK¶Ü*–¡w”s±8‚ˆÌh¬ÉKÁ'Ác†.œÕ¡Öh:nW_ú£»]WgÆfá`åoi ¼ÉUUtf`§»¶¾Ì£çl6×98{ηlóªmmþµ‹gQM8gA8ÜïÏïvÉEr¥Õê͋Iúi†þÿÊpõu&é )Ɵ¨¼?x 鯟/'Ã]Ö_çLSHØ,B&èʊDí^lßFåâúj°ËäՂ©`|ƒ̊—e?QëþåÕÛ]‡¾UuÇe&öNükÃÉ^Ý©cƒY}Ü\€ÛrZÐvëø‰¯ Ñé8H +þ3ØF½W¼a8ÚÚÉßn»áuö¯°Ž¶¶ò·oy..þíhk«a‚­Þõ Ózó‡™ ÒDõE”Hª±I!¶~7ᢤ$¬-$Ö¶y¿QU,Öt–ÕA»ç4 +ü€>±€ÖTB65vmô2¡ø"¤¯WI«ÛÅ»mühºøýU½3°eð*ØJ’Ý^k ]ÒBL«äF,ú"õûª!±ïÆ,<žþH‡v­TÕÁ‚«ê`Á/êÐô6T8§4|¦hµ’®±]U ®ª¿¨A½élªàkš¼¿ + +­VQ¡Ù3Gµ¢ +¸¢ +øГ—3?c:"‰‚Ós X¿\H•€‚˜Âî¥ HB$Аž“/™LC‚ƒÄnb$‰UÄ´Æ"Ðqe %Ai$„’™ Äb0¦7<ÿfö¬–²V‰ˆ{à畄DŠ0 X<³¸@HI Š&DmZ2…Œ/96Ü×·¶,”ì‚,•“MÉöß|ÈZÑLz™Rè£pùy\÷¯``nVÜäv2e'kd b!ÊbÅ6ââè-ÍîL-æIifß`¨1šÑʈŽIƒ ó©‘e•Ë:eÿ)ŒH‹Rü9ìÚÆ®¬˜‘PðmÍôr”ψœHSæR9`b N 7àˆh£í†3ËS„Ì´œcl˒W†…jDLkùµ…†T=~§ÚI’°|_A¢%0'ŠÊçÑë<¶Š”ô²<çHC=“´bÝÐTp²Ä%Bj‚=«ËFwÓ"ú\§<½(×ubêOAH§,Ʊ¶·¢72—c +ü@²D¯Sƒ§KªînQuen­Ù+qqr¶Ý¡‹S3žY€i´U· ÆrĘXð4¤;wIs,G8ÖyIå£2ò2NRís¡ã™óÙ¿´ +î†Îò[Ë5ÚoÈyC•à©ÞÝ"KCÌóoVǹXÄX”ÅùV˜ðÈ0Kœ­û“Â]ϘÂZ³½Ý^'4¾½„Ã"¬ã óxc<^Ç«˜_ʯeHå€âΐÆÁò»;œÆKŸê4Y[*ïÐ)I¹.–OàŠb—•eX±ž/ßúùÓ |øø±„>^¡ÿô.tzî_eÄ%6I”æìLüqÊyiýÓ',D ™ÐNÁe>Ã,Y/Pœž1ćÁãónñs¦Çl×˒›Õ¯/¦zafÍXŠ™$QdވÄiÖòk–µŽ[¯Ò½[Ò²P·—Ïêß÷þ‹®±­endstream +endobj +2190 0 obj +1326 +endobj +2191 0 obj<>>>/Annots 39 0 R>>endobj +2192 0 obj<>stream +xÚÅVßsâ6~ç¯ØÉK sÛI&3ùÙæ¡s”$ӇãæFØt±%Ÿ$ÃÑ^ÿ÷îZ‚!éKK‘´»ß~»ß*ßøø@·Oß8kÜ<7:> áyF+ý¾%ÍΈÍù“øƒÃ§~BàûƒÏ§Ï_>´ß”G36r~s£¾ƒ,Ò´¶u†Ûý$|)b~RÛoÝˤ¾´zu®£s8¹¼¬GÝë {0ˆÂÿ×mª y<‡-B:Ñyˆ ˆ¸62×ûtöyÁÁmú›ÍæÇœË—Ç}‹&¼òõJéLÎc1܀ESÉW r+”ô€\̈́6$Ë8wÂíÂJØ0 ÌX®…y…I³59!a¦•´ f ¬W%Òõ +ܾÇÂ,M×0SiªV<é˜”™zì G&\Y“mÍY¦)‡%׆P`”7˜Èi2ì{…¼Ç£ëê€ã WqÆÖiY°%Çx Ÿ±"µ°diÁ?lIJ0Ö¶ ZcùÎY¸ÕpÇ=~‡û¬,^TP§›È8šk)î‘E{±ÊòËPrUgŠ0e1kÅ)cŸb-rKÐ(1ÏäÔ`y¤ ‡Däè[¡,9:f3 ¹VK´Hb‘¨´4’ŸWÌU¢o‡‘#à˜·ŠÛ +î@aG%uTJÃT«W.1«•$œ†çL3ˁ™÷Ë»Qå1YH~&$¹AÓìß%ø¿M˜wçG¼PhV‰Ë®ö…Θ5oË nZ{ð ö"ªìpê_â‘ÆƒÑèՎ­C:©,ðï1Çö{½Z[Ä ,BŒ,Ԛ1ƒµ*ôÑ^ck¥°Hx2¶Æ‘ÅËL±ç_Kþ¡ÈK빔‡D”2ÉnèŠ2F­PÕÇå,ƒ;fÙ>=töŒN^›jî­)3KI—@s-$Ù&Z `ªHQŠÓ×Îo‚~i8fH ÑRJy7X°u½nøž÷$=zŒ†Ðz„QÏëCÝ òÎ6¿Rx¢[Ôǟ}¯¬á†«vY +lù2(•ÒX\fزBâÀp¾¬Ä~8=‡7¹qÔÐE2iNN÷Mü­ÉN³BÆå¼Rh‚5«80‹”Q;Õ $‹ð¾tpvŸYrÏN ¨ÁnÊ.Á\[Z·ü/.ü -|» »qTv.º¡ ÝiÕ|B n<~-íp +¼¢ô¼È¸´Æó¼ƒÓ•Ã0pÂþž4Ñ"†KèÏP¾_Áن۝íŸu_‡XÌï4¥åOÖÝ^îJКǨº"›bš(å-À XiªÀ™ÍµÆ2n ‹#~é>ÑÜZz‡»õ¤°(ØTfÒ<¹?ŽÏ75·*Søª¦mA·'‚±Â¦„0§:ܽfàIâód"OpØ‘MN/‚:0H^p¸û—kÁ¦ l­úÃhƒîöeôOjfW4AFZÍ5Ë2œ8ð+“8ÒȺD¤²öYè“M×§Åî òºàÿä@ÁþÖø »6åendstream +endobj +2193 0 obj +1131 +endobj +2194 0 obj<>>>>>endobj +2195 0 obj<>stream +xڍSMoÚ@½ó+F9T`ã5D©”¢ÒB 9Tq„¶ö;2¶»»$¥Uÿ{wÖ$´ÆM Ãx>Þ¼÷æk‹£¿ †.ô®ZóVïځc˜Ç G¶ ó¨Ý;ìÌ[X̱G€C˜”˜ƒJJ¾DJ _Ù¶½—ØÛF\f(’Æ´¹X†pvàS+øQo¦ hÇœA¡‡šê§ûÁC& ÿjòñösÐ :ÔÎb{ýö;”(D!‚öÁØ÷'þ ÜåüK†  +3— +Ä©ŽYptNzÈ ± Ú¬ù­@µ9üåýÏZ¤þ3‰{E†ç´Æ§ÆªÃẔ¾A=1ÅQ.靈…>›ý…?>¿Úé]{ÀIli-×t™ä!¦XCŸА€‘QwKE¥¯Éx\K9ÒûB¯É#@&• xA)Ò\AªNªa;;Y®g{4ŒÀ.ªÆ‹D7ÐՏ:UÔjﳩg­s™. q˜pñ’qÅïGìØ}¨Söœ°A{Gš¯‡ßڅw2Ö? ª]ižª”géw¬n‚8д5ąг7Z´j†M0n0]&ê6ð^K¬GGÿiå?—˜¦ß´w¶KÝß§\lÊ)ŠÛ4ÇfÛÒ.µŠ[Ý3I:¿µP£™]vSW›•¢QJ­Ï2c :Ì +‰ Ö#kUGõ¶±*..©‹¡a·ç뿜¦óz£-VÆú6o0¨2Í Á¬ˆÕ3SQ,_­PHøÀó5ϨÚbÞ±.²†®C5¤Bš/¡ÂWZÊò†žfÇdôÆóÖ§Ö/ž†ˆ³endstream +endobj +2196 0 obj +622 +endobj +2197 0 obj<>>>>>endobj +2198 0 obj<>stream +xÚ-‹K‚@÷}Š·ÔH3Dqëog‚Р#Ñ8‡1^_GÍ{«JՃÙg ³Œ¿8Ú-%˜!¸X§ŒUžAÚ¶çªA3vá¥Þ¢òcïÕ9ë'uxê}.7J~IòoL¡)‹Ôà j«íuèQë¬ÇNƒFc/t¢7òm%—endstream +endobj +2199 0 obj +127 +endobj +2200 0 obj<>>>>>endobj +2201 0 obj<>stream +xÚ}TMo1½ó+æØJa`’c5U¥Hiªž×°Óxííí¿ï›ý€B›ˆ‹ϛ÷1û:™Ñ>3ZÎiqMºšÜ­&—·4¿¢Õ†æ7y6§ëå ­ŠŸhJ¿'v[ºSúŸ"~\ýFyN³™”Oûúé"Ÿã WV%GÒ¥ª“ T˜¨¯M¤Òï)yÚ£™!Eë¾m| ûŸßŸ³C{Ò¾ªÇZ¡°à`t²-í9•TvèI¹B¦¸¢élÑ£*k0Px7ÔцmwàQ •5Q)×RjkC~TçÅÞQ +ÊÅZ〜õtoi¶º€\̳\ Ÿ±c³?Õóev-FhE±6š•=ŽSªtBõ”áH<£UiÚ®C +uEËÛR4)x³1ý”ÒΝI2 ]ˆô³^tr”j‡a|eÀ¯¡`^€Uèdó‘ËmOöÙèÖµtï]äÂ%RÅÿpÿ‡yh)!ŒGï´—Y¢?H¢¥ªjb¢5X*ܳÔÎsAµOLªâ8Á޽íÑ3úvN¶%֍U€RÕqè´>fnÏÖ +”Z[#H•r\ãJ—·ø"ÈV˜kyÙ<Æè}pص<‡G…Ú7V¢V©­¤=¶1™ŠõÁළ¾G$8}dgèsØ61oélċ^ۘpM…1ð~¸{1ïíPҋ']àœ?Š[#JY†X +µSlE¦3ªƒ4N–¬Fí°ì<Ž#Éá°ù‰°¦þõfxO€º¥¯Æ {ƒù#¿:$ü@0–ðÝ¢WM\Ãbík†Hà#:ut“w°ŠA³ûé–Ʀ®-cpy”çÔõà…?=I,öM×z Ø0…ŠÂö铿›:ÊW£C%¶BYœXð¢âwùpsò6Éß{çË<»A!J 9ø²šü˜üô]ï?endstream +endobj +2202 0 obj +718 +endobj +2203 0 obj<>>>>>endobj +2204 0 obj<>stream +xڕW]oI|÷¯hñdK€$:l‡è,% +°”K§aw€ »3›™Yùõ©žÙåccNwŠ ÌtWWWW¯¿Ÿõ©‡}ººæŸ$?{˜ž]~R¿OÓ9¾¹¾½¡iz®e"vK‰És¡SGÆR*¼ o¨°&-I~))/3¯ŠLâ`¡¤ë^L¿!àõ‡1`gp×rȱXHºOSj¯ô"žÛ'î B⑬¤Ni®2/­£…ÔҊ,ÛRjHÏ/G»HmZš\KËx¶ä–¦ÌRžåJ«¼Ìw€9\È$'GÊþUwÀICÀœ Æë…J‘,¹ -B"ru„”6K©ø¤¹ŒßI'µ'£#cLiÙ¥é'”kdœÉD”.2ˆWKNf2ñˆß²bÓBHj#BÙdpÐÔLJg.¼BR†`œS³Lž¦ô#ÉJ§Ö¡(õßùw±p/²7<3‰È(Y ++Ò²følE©\+D«I7…ŒÄÏK€Jr—<7i“ý—óˆ¥Wa9ÿüÏèëãÇc€ç/ $1Ha…—´Q~YÑÈb±¤rÎÓÐBFá¸AÊib¾Ho!Ü|ÜgÍjNâ™75¤¼t¾’,¢ñÐhL7Ç1ê=#µ4øHÁÛì?ÒݔÏ!ùmn/¤\l+Àµe… eʚ%ú^ÊïL-0¿§ªXnâÔœ1ב©)O> RGC¡!z?SéU¦¼ú´ØÁªªjU, å2)‹Ð9 ™Ìœ¼Bâ™ô 騨‹wr9æãóxÒqeQd +Þñù6bc ØÒU³þÓ+º©Zz5ˆ…¼WÎq{P>‡žH«PôØXO•þ_QC÷:pÀ\ÅóŸ¯K…?¬w”!ò\h}°Òg—&Ё*v1 €ý2t$™]Y¤¥dM˜©ióå].&KfYl‰ÈهÁé&ˆÉ ËiÙO"NNþ>+XI C:5 +ÁéÖʔv /–i{ß­¹B&\p4oƹ°"oˆ»Öa¥Þ.Ýë8Æ^¸ˆ˜í;pP:ÏaôÙõØðxJ”‹Úk¡2÷ÛÙHªúàxâöŠä;îÄ¥àìºÉ¹HS¨Û¡ÄE™ƒêªØZ‹¯Ø>½œ«.†ý[YA¬¾$^Ýn÷å¢9Z{YC­ÁͶp³ª&öPì±ì(!Ol¨íèכ•* í»msPLŠã 4ÃI7¨­AÒ<󸁲ž¾<}}¹h‡½„œÎ`zá"BŒb˜)³_¡aü%„?+®V†. È¦Í|®fƺ:*o¬òÒíV9¾wK;œª,×y DI$­Å÷LT—F|*Üa>~]ÉßìF¹·õNºcÖð¨Ô #¼ +N|yË _z¿ôþœ‰2ý£ß3èõ¨õ¬WÚlt‹Z‡îÒow£ïŒe®,ô²1€ÜŠñ[Aë»Æ^×]¬ök’‰æ&?G>¬˜=Ss¸i Ÿdo¨nn–Šqà ³°8Ò°]±XƪŸÌÿo"ˆû% ï\„ÉeO¦¤´©ÐMèÊ,4nǔs“efÂÉeÍiR!Ü"ò®ë/ƒëj”Ò▵¨ƒf§ +æ:xäð9âµQí1F!øIRfÄðC¦ð$Q54<ܲ|Ú%fX\xoV ÖíÓh4êô·Ã0œñ¦{»ÇñŽß·™¾É§‡Ëǧ“ߊ‡ç{“˜¬.ú¶Êßǁ>þºxƒÃ8¥31sÏ~Cã¸)r~ˆû$4́owúÃ;\êÜ z|çjÈ{WÑ;ñÅhzö÷Ù/Ï=ãendstream +endobj +2205 0 obj +1431 +endobj +2206 0 obj<>>>>>endobj +2207 0 obj<>stream +xڍVmOãFþίåSP‡\x»´*訮„BÐõ$KÕÆ_œ]ßîš\Ôö¿wf×&Á$WćØËÌ<óò̳þ¶BþB8êÃáâÅÞùdïàja“”þ3<>‚IÒþ5µ¨ÁÎ|Êb„8Æ@fÜÙþä+9 +§veòpwíÿQGkw “ä@^±0-ƒ:ùé9X»ºïý2e2 +Ãwý^¯À„M+ ŠF¿ÂrÈtÃàω™™*ó¦¥Aú]9cz¦lÌ1¶²PÚp¥4xXw`: ¦À8K3ôÀ ñ=[”‹.;€Á”GZƒótÝ£ˆmIHO"/–YΏzSÁ¹*él^ž³ö)H•ïw¡3I½*üþ00þ„þE# Ú–T¦%£GB£OY%˜ƒ MËÄ:+lF`Ï]#8@ëAÎ¥ZÊV(¤qmÞÄn”î£SGKïMµµ¨™á³Óy…VOYBïÔÆ9º”¼»)㭏·ðÍü7´-,ò\-M“[cœ»Q©]ºBÄ3¥ GQ¥Ë©²†DgOô³PdŒÂdù*€seg?hÑ¢4M‚³Pƹâ‰eÒp1‰*¹¼o¥²hÏñ~cºý?¢q’›Êp÷žr·Ôú—;Áö~à HÅ,*4õQ•&_u¸D–xŽ21PQ]QØz Ó,§†ÓRá÷8/ Õë +ë¸Â4ZâõXÁ(p)m–s6 +_iœâId9ΓccK¨b· #•éö¾C‰ªSéÇ|ðwã K!jGí4‘«ê:iK´ 5›‘.`ZU@µd~NÊÝÜs'šëq¹½r[õ(2ÀuÚØ¥:¸ë'ã'hIÎiûH M<"Ÿ”–1žUßÅÝÈCLùrZ‹0|UÓõsî4Ÿæ“’\ÅJk‡¹[š>ëÌòVÔyü@›nn=wYÆ3¡éZc}­ô¾¨4Ø©.¸J–3¢Ï²BK6Ð֗䊮†kåÞìfEB€N •Ÿîte½î­H +hÆiJùL1e©÷ä#<’1ruykUºóg@•y:¹wå[ÛDgñu@3AÂ:Ū‹r·¤ÕD•Þóg&ë[Ené}F¾^&{‡k+¬î€çTíý–˜[ìfLz¸Õà-HõâöÃ`¸‘fåº=‰mê²[[ 3ÝӛåÄ/8íP–©F1?Û)ëL«îwGU¥¯}|µðÓ ‹ƒ«ãŠú!‘ „áIßS.nïá¾þô¸ÕêQ‹Å‚¿I~’>ñØ»NÈ©{ÔïýÏõ?8PÎêð\NöþØûXšuendstream +endobj +2208 0 obj +1227 +endobj +2209 0 obj<>>>>>endobj +2210 0 obj<>stream +xÚmQÁRÛ0½ç+Þ1Ì`×vLÀW¸µÐÁ:ÃE‘×XT–\IN†Cÿ½»‰¤íØéí{»ûž~­Jü•Ølå×ãê¶]}y(РíÙÞð©[ÿ¾h߯Q–Rȸ’U[©´A¤¢÷‰o'j±P×÷ßÛöǹ~ +é&ÂuÔÁ;D?&«7#’‡¶¤”[Ø}ð#¦@{ãçx>§@VnòJV2^'ûº~½ø{¨VÖæ'°AY/²ªÉk‘=gâ`Ü^¦s¥®…òè4áÃÏԞÉ¥£ã)>õÆÒ%¥98–˜þXôD`—q֚bìgk?ÀŽJa™„Îtp>åhŽä`¬¯êÒAVùd.rØÝl)H@1ùéÓï~·Œ $Ù*t¯|ÌïR’‹öbñ\$OÇÁsÓ#&/Vÿ?¿³4r;"íC Íæ–`o–ÌʺÉK”WQáîåéϾOÅ«=ÿÔ8RˆøªÜ¬¬h³“$»® +Ñl¶ÖÕUÞ øßûÜ·«ï«?øÔÔÅendstream +endobj +2211 0 obj +402 +endobj +2212 0 obj<>>>/Annots 44 0 R>>endobj +2213 0 obj<>stream +xڍTÑnÚ0}ç+®xj5qÒ§±–1$Z„ÒJ} ‰O!Îlgˆ¿ßµ +¥£š'çž{îñq~7Øø!8àúìߢFç{Ž ÑHеðƒDéMÚ0çkµ…1Kh.)ô7‚ÒÍÕmôË’@¶‰ZÚ®×C,¾ç»Ïañ4z©`¹bùæ©èî—„h®0°zÐv˯ˆŠƒ`›­†AÛ±mVÄòP«› +ž–‰’šÈéZžÖSéð<âèfÓÉ,‚çÑ` 3˜GœØÓpÝ(¨ñ?&ãñër2yhÁcö:î?= Òwý¶KPÞbÞ×Eݞå¢D;aÍ3ǁîà ±\¿k…¾íjÜ jØ +6¢/³!8ØËÇÕVïÀµµÞj•Á\ïéð+Iƒ]̲;Ð|db7IYÈ6Ë×ü«þgq±ù¤±Î:ŽcÙ¦q€üÕêØ¸.±ô$M‰«…,—Ë«2¶JwÎ~¿·Îu|d4™ñªÌò¶V6ŽrUm#ãùûDØ:m)|’¬SUÏdÙ÷×ß󓪴àí¦y¿˜ÎßUzù¼°ùvÛ&¡üKi +ežR +õ Ÿ0¤9qÓr•±äø*n8®_ç û§c¤ƒ8OM혭D,W8´àqUтg*$šŽ}Hð _k Ë*¸„5Ï2¾Ç»Ìœ»nÍÎü¶ŽÏN‘ŽŽƒèVEƐJq3 ö úÓö0J[ñ$VhË  ©ÐY®R&h¢¸8 «j%/EB/Ô¤L*ÁV¥Vc¼8‘uJ):,O²2¥Š¹¦ÕÀ&ê0™‹›­z!3\qqvƒ7aÍ2œ£b¾è¿b¹vý\†¼æÊ?LO©ÉÀù¤çl˜3„Ž«¬8BŒ¹FþÂ~˒-|Ø©U,uÄ +tÆ´ßr©d"X¡ kumãBE™®×]ðÁà ‚ð4†¶Ue»W2O¿yÿëÍïBm vƒã çgã/Eôοendstream +endobj +2214 0 obj +772 +endobj +2215 0 obj<>>>/Annots 51 0 R>>endobj +2216 0 obj<>stream +xڝW]SãF|çWLñt©Yò·y:u)¸3„KU^ÖÒÚÞ i}»+ç×§g%ùCà»\ꮙÙ陞žÖòõ$¢ÿ"êøœ\>œ´¯{Eô0Ão£!=$﮵!·ÐVR®ÍD¦R% ­•[àsI7Ÿéæþ¶åRË¡SaU,ÒtCø¢×–6º §Ïzøq…Ñ:ë ‚ýÕ © ¨‹x÷ˆ\œ÷—Çû Y=ska$ ‡Z(^3—Áaʐ΢.²Éw¥¬3jZ8I+i¦Â©Œb½TҒžy¤-ˆÊñsabI `ªra64Ó&û1À‰LÓïB!- Êd¢ͤl1¢åƒ¶X.µq>`ÿÄÿnºN¼4*wÒPbг$ò„f*uü³[€ßÂnI§Tçs¶¦#Ö Ø±” |+¡R1M%cƒÑ®’"OdY5Ôá >ƒÌ¶Ó~b·@žZ3eÕýºêDƒ)H®ÑL)¨JO”è²’gÉrÈçL.¸LЍ®0xF”o„[D5yI€¨FÊÙ÷èKjª”νÄuáöûèOg…u P¯T"ëßúæÊåºfµU×ÔªŠRœÖW„BÈõh[¾P4Yò졦²FKè€VÎ{Ëß1±D æ*\)pÇõCµ¦>ÔÈT¼0/øð4Uùó™Ó§ø”¹ÀVI±ÂÐk–åJ¦zÉ–¨º¨eRïg£¡‹ûíÔðޔEkDšzÜ^smÔë¼&æ° O)*0û¸•òÇõ*åwÆU“z̄y¶‡Šáod„ÝФ޹{£“"v–@uõY™”íè,ƒ?}ü‚@¬ +“1ÙX'³–ﵜ’×Uªç: Pl›#ÍEV¶écX¦%8ƒ<”pG˜ ‹&QFƐïúÎmÄÏ`8 éšõ Ǜú•ˆZyÅø[´L¥°¬ß}æL÷Ú(ç°#Ki2e-N¿a칯Cyý"¹CÅ t¦n%ÒBVÇen§â‰À䱔¥v|ã¯ê… JWªÓ‚?Z¨ùâìk!Rå6d’“ذ(h£æ .=.’Ë’Ù«}f?Áý hD +_d#±düñj©kÏÜe)}ñæLkçó†V2OtíŌ\äl²Œ‚ýõãÜ©ÞÊì¬gk7¥T3¨Ùnw+OôŽ1ÄêîO²iÄ·•óûϧØ×Kª°äí\2.¼/‹…^CÜS½zӎ¾±aµ×!%.­ÓFàcsZ½ *ãq¸†üS٘/W7‰Z:êý°ÑU¬gƒG÷»h¤E” ˆéH‘±~KTR™€ƒ—Ÿ!Wï5¯ìQ_?¤Ì_…ö_ˆw¾Œ_u.›)®¼;wlRLVÓmS3ù²“êÇ<1½~n±*7ðwtbé³iѤP0Û(5Â'»!fB¦ð¼ ÷Æa—'°?48§Ÿ£ õƒÞ¸ŒGƒ¨t-^š!ùðp!î¡ü%â/Ÿoh0ºõCÜ&2¬p7WO)Mø’ +Ö¢~„gÞÏ;Ü?ÎýÝ¡‘ÈÌé+ö½0<ƒ ÖÙaTXE\KX›§ËdæôÒnÏÅ®y³Þ¾ ÇÇáîBößõ±=Ójpô}\I#Ÿé2 OZçÓÂ̏ó7 +"FÁ€étÝ?ìØvðÈäeß"/aÀüýLk\ðlÍߛˆÃnR„B3ê„ ú‡ +ñ5娡_9òÓÓÓÑ +Î-ÏÛíõzìUÑ~ýí·gÙ¾UÖˆƒ°lµô»}#Ÿ‘e|ß½9^/þ‚õÆ8t6ì„|¦ë7¢‡¿Rº¾¾b€‰ßOþ-Esendstream +endobj +2217 0 obj +1380 +endobj +2218 0 obj<>>>/Annots 54 0 R>>endobj +2219 0 obj<>stream +xÚ]QËnƒ0¼ósl16Aà lO¦j+"¶]D*Ýuî‹#íÞÍDȀ¦ˆ8yô†&ОzK¦'¸Ö×;Öۗ’Bࢸ¼>Q‚VW™ˆÑS9ë[‡‚úǰ„‰œC¡ÅðÃûq†ó<‹š"r³ -—%n|yãg×T­§ ¤ k¬Qý ÷b5Gåð¬‡Iw¬·á6i$ÿý­8E†åv›_÷} ~È`´endstream +endobj +2220 0 obj +314 +endobj +2221 0 obj<>>>>>endobj +2222 0 obj<>stream +xڅWMsÛ6½ûWì-ñ ͈²b[íÉÎØ™tœÔ­åv2ã DB"jPPŠþ}ߤDQv3¶f,Ø·ûöí‡ÿ=Éh„ŸŒÎ/ø7¯Onf']Òl7W͊÷Ÿ¿=ÑçÛo·^ßÓÃÓÍý—O„Ïí·ÇÛÓÙ?¸0¡,‹ÎÆ—é_ùKZ§Œ¦qB¿5ZR6fñðˆ¦ÝÙI:᳟ÌjkÕ²ô8u5MÂYº³RÒ£Yø°’îL£ áa1¡/:OÙ,d£ôŠ-|„IY¯*I•ÈeBò’ÎÏG ÝçùÚ×k³,;ËÎG—ôôxÝÚgÑãÛµ´[W•£•´µò^ä åp„.¨PÎ[5o`gçp§ø£J:2 ò%ÌT*—ÚI*LÞÔRû„p™òRè¥ÒKRž±´ñ$ªÊld‘F†¦{:?ŽØìƒ•¢žWò˜í‹Èଔ˜£…±T#hr{ü)¤SK#òâ7bK[ÓXZ€êÂÔüƕá<‚ ^‚ ŸÒÍho…óIðy:f`à ©¥=4søA÷màOi/uq—°ßåÏqùÝ« çì jÁ5¸Ä.ì" ß €T¸ï¨qÐbJ3ÎÈ~ŠÕªâıafÎ,^‰ó-E¾s=¦uTè-ܱ´²fiEM›Ò0NãKc謡/>Ù¸¨„”žß?šzs4òòAܹ(Áó|K]VîÕÜ +»}3;Úy)Šôùt€úÝ4” hÙRt4d¬Æ%xbº"ìDøw)5mŒ•/\!‹ ¿bW­\Hk9jXm%„*XY8–ÒïzÝcǾöuÝ…ðì2•b%Ò[¯Ž÷{à,’ÑjÑ.£˜¸ž‡z”v ¿H-ÒF¹òù4ÙC[™Kµf£ÍªKLìRúPýíMÔ¾ö®ò™¶àûuÀÆ mByŒMjÒr£é²õk”egüE›Í¥0Œà)qÜΠ[ñ2÷Q¡M»K-{¤[ɔæ,J‘@Ú\\ ÜS™u©C¿iñ¢%ށëŽð«aÑN¦åöaCã.å`áÅU¨\Z/ÀN¬ðRÍU¥¼j[#»Ðÿš^)ü½„q½½Z›B-¸6†ŒÝáŒü!x%ÿ‡ƒÐò’D—$PZÊPìøæU &41ZH + :ÓR­_Ó´¦`XƒQn{{²+!¥ï¡A­àÆ6Tu²ÓmO«‘…ŒÓú5äµóЕ.ԝ°0K¹Cˆ(>ü¥:-uùšâP]¾$¿"¼\¹_P ÙóiÍqs8Ìëýùý'Ìݦ•]o"oJö™ÌaUóÑJ.Ñ{ÂàÂÓnI?“Àø&mBÒuå@+gS +Îy˜mœ À#ÚXY¡t•Õi9dIv;JÃ5á<®¹]þÂD£ ¬YºÛ];lu)}YÍДŠÃÄa*1¤¬\œo+á^ñNÕ9‹1û¶ I›uø¹éÄ;s»ÿ0¾A"•Uµ‚cŒÐ#ýÝñÉj›ô~e_}‰M û œÀFÄü{ È@RKފ_s‚Žy"„î¶6ªžÜÒmˆîÈ坴xA@‡è!T¥ µVEÃ’™aDÄÝú—ðP}j<ÌÙrgf€Š§ºÒcI@Wå^…±ø “Ý¤Z¼R^Ia{©‰À¡èç»ý³ˆBo…ú®UÏ)cÄé÷·D؂æOpZÚ5’0— xˆ}ŸÁ¸4g¯:»’Š:Îã²´0¼e·;öU»Dg“išÑÅä"ºDŸž÷«ÖCd­f­}¼óí³xéìr¶óɈžgýüŸ¥ÛÙÉ'ÿ‰Òendstream +endobj +2223 0 obj +1442 +endobj +2224 0 obj<>>>>>endobj +2225 0 obj<>stream +xڅXÛnÛ8}ÏW ò²)àºqšMoO½¤]mšm\,È -Ñ·é’R\ýýžR²,;»(Z¤5—33góódFçø3£ôüвêäÝâäÙÇW4›Ñb…7W/_Ð"?ûtó>]ß\{û™n¿¿û<Oø{}swýdñÏÉ9==Ÿ^ðÁÅõ·/wôöæ½ÿzóa¾˜½¹£_¿á¿·Ïo>MèÃünñmþî;¿’ƒ_¾~˜œ¿ËØÚ³—ÉýÅïôôâjzɆϧÄ/Ï… ôÙdÚMj³)T;R¶¥wk¯*rž\]hO[çж0YA™³µ26"ëj|O›Re:§eK8‹÷›Ö›uQ³¸ï3*\™ÃTP­±k25Uª¥¥¦Ü„Ú›eSÃFcù›©µ¯¹þƒ8?i«½*é¶Y–&ëžÒ'Ooc´§“„K]ºí„¼^iß§ä0ȏ3›àMŽ|N%Í¥ +ˆÄY £³M•VÈYÿŒ|Ýî,²daTmt„.æÕCC¥Ú¾†U“‘È +‚ˆgÀ Ò X¹T´q¾6(™zÒ÷ ý®cvxD•ËÍÊdŠÏNõÞÔù”ŠA7V°‰•.•]7j­§#o÷gh¯U+TfÒÎ±YÙä°Å]ƒMeêôÚö¥Óa,§Óû't­P2ÖSÃÔ8É<÷:pAT ÓÖ5§]`]?¿Í³©¹{]*޲5œìº‹Cá2# å5w1޵®‡wsñ†#oùÔ(,¤LŽxë@¾R+ª¬æbøÆ”FÙ’A8`MÇG`lÈVÞU£OF^»(-[2+ñÎÝ¢mü!Ô¦Æut¬‘éþÌ 7ÿX ¶PëRk;rW)dDޤsÿdJºÃ;¶±o0Ìb:°×-?ºÎR½§L ]ýf‰þv0WN Ùñ®¥ñR +½þ 5pÏ˜{1}¤3ÍóǓa¸ô혐*›¦š0<n^Ʉ¿e,7&k\Ê Ò»7<Ù0 …‚³ÔJ8Qbž:(]7ú‰4S†Y©L‘ÑVy Uݾ¡Zox*¹TYJ®ñ³cJcÞ¨÷HÜæ#¯r/–A[ø„&§#bÍ ñã8=€Ícî¨}”ÑU’fGÉÉëx^K‡NÚ|;žÙ¾Ö…òkî×få"óoŠ6`>Ënš„j¯çŒAÄÙi“•X4`¸IlˆÃ£°º”¹ÖµÎ:^Ò¿]GßÅa^ŒúSø£# þx[v»`ÄÒuÑöWÅtv“:nÏýÁ)ÙhûŸöÚ±uz—²Ÿ ·¹›U‡í§c+ƏšÍx{͖.~Ÿ^ Œ 1køU5ø†‰ÂÁʔQpd¨ˆ0'uxítS)µÊ»í;;Gz—Ñ\G©9&°k÷øÙ®°½<8¤Lƒ×û` `ÓìOï1ϹRÞàçòõN!ñ³0.«HÎL÷]»° EíVÆ)íGY‚*9TŒT7A¼ÀËr<ý…ñ¹Øãæ|LZuZ*ⳇi–2«ýÒuòÉ¢‹áB«œ7PU)&PÔïe&Ëm¡-ïIØҘ†Ã:Êi”Þ³2é6§´ùÀ2‰ ›"ƒQçsÈÏüÖ +p b^qž Êƒ3nzk]f¬¸ï¢†‘©Ücr:Êݽú­Óšó:îøÇ˜çþ ‘è2`Ȓî, —6†0Š­ŒÈò•©»׊‡´+K_é½1MzC—e·ËÙ0nËX=½}„á•àõ¯L ×¾&³OyP$º\EE¸«â•å/ +¨ošX)ëf¹öqIÓK«Ÿayԗžë80¹)MŽûYÏî A)}ZÉÚã»PKiuö=/îwã7¥9Òd …×j‰y ‘XÓ`¡nñ‹éÈ¡>Ɖä÷’ƒRÁYØnEÀ™±¾So|8h 8w)»cØH@W¨ÉƒÌXÚî•6úc)œµìÊ. R“áQ";W/ŒÂšÒ;´À#_cª|,È읨.^>>>>>endobj +2228 0 obj<>stream +xڝXMsÛ6½ûWì­Î ­X²ë$í)É8ifÒLZ+‡Îø‘ ‡€´¢ß·H‘âL;ùp‘»oß¾ý@¾-é¿–tuÿóæìÍúìù»kZ.i]òÑÍË´.ÎwÆ~u´Nd4u•¤ÏÖl­hÏÖg—t±ºY\ó“4‰¢P2:£FZIb»µr+ø„LIB¼n‰Mþ}Ò*íTWÍîύ §"z\^-V¶“FîŸñ GS÷ô¾ÉuƊ->X*”ë¬ÚôX# Õ7Té(«ôÖóhO¹ìu0ø—›ÖÛï*åè£Ê¥vÒs"Gj®Ägçÿ˜ž±'¼µÅ‰<YÐ<>ÕeÑóÌ=ôâT vó€-8:vľÄò»ÌûNljI¥±Í|'mã|´ç µ"±1’ZkUç]%:Ú»¨S@ƒ– =¥©k³¿ñ«_7‡ïD$áuž›¦zˆÙæ³Zvük¥k.8È+¥å…•¢ð18ÓÛ\ú`3ÚU*¯¨é]磾Û£»œ°[ü‡°½r¢*r˜6°ªÞSÏy(MªgÊn' v¥a9¯„ÞÊߑ‡lTÁˆè‡ ÕVuä2)¥ÍèQÔÊ;#0_Ká:@·RÒ^ +ë2ê m°²HÏÔ +Ûí³ðJ*€²P¾6ÔËJšÓiÁ" ƒ‰¶Ú;•‹Q¶Ò²L˜ûHõ´Z2@2•ðp”)/ò ’$©³"”§S•øùÿ‰£Ÿ¤j&ŸüIµ*Í$…Îƅae.‘‚„ã€|÷àLò‡IÏh8–ì„—zÀš{ЍUÃôQ_¾ 0ŽI €h·¹õ¼³17þ9U2ȄÇ2ƒmcã9ê&”¶OëQvbT+Þ  *äo?wýÆÅ~µ ‰ZÜ?ó„cȌr]ÍJ;è84ÀF +¤: ”ðgC6›A[þ!~¾_}Ë0…*¡æ $@u zwT·€?‰d‡&4…üƒøÐñS8‡Ç¾ÆøPL›î„Ò(ѶîݑKt}ç RÅ:÷*,—˜,•ö““JKáí8a¬j;DŒ`؁5µ‡ªj1&>;`ñÇÖÑ.èˆè‘S½b4¶Ò«G~ÏeÊ< uZŸZò_•Jçu_Èã(ђü EóRŠÄßw².½ú¹I(éRªÓ%©œ×( M#Èiù»Fàçf*¡Ã•GeB-­iÁB:µÕ¬ªj[C_>ú`C~ë& ˜;R8›÷‡{”7†/z¤ÊI\¥q%¶2‚âxK3ý¶š -æŒ{2 ŠY”u=(}HÔ&4Íé:6(dBÛñúu¬_ÁU‹qé{~º~S‡å-›-ˆóµ,Ô׌üŽ^äÏËaIòS+¼³µ^sýcÌ70â—˝rrõ˜'°Àî£QEvT|܄ѓDÏó¯‹S©b}„¹oÕ¶âžíãØ†Üì*C•ÀôÆQ1´Š;–ÌfA5<pœo)K1Zw€ék—óÍdó´IeÁYÙ Ûò*û:4ÅZ OD0¼òëDƒÞ,W‚ rãJh»X¤-Îsàò;\hܼ» W|±ñ…U;™JÙâra-‡ç×GgbºŸH1¾AAm[T«_üelA–`RÄ%Á¤ìXS©bÑ:j±‹¯î‰P½QŒW쇿ÀqL³ûR¸%îæ·hü‰{Yæq(,@ù¨Æ‡³–Þ¤üúd …S2çÉËü„}žOr^¬)¥Ÿ-GÍñó¢0—Ð=¿ì&>‘ñ#QÝDQÝ +ž"ª‘q|ò^÷3†ø#ŠM¡®t—Êi^×±&yˆ-clÙåˆbªã7Æ:ÍÞHÇEzÅéCw ›­“')_д½*LHî'eoý”GÄÓ(Úõ¦û%ñ‰©ˆ•Ö ÷Ì¡eùjk,V¥ƒÏC5ójíTÜUIò’žsš}µígÏŠñÔU~xðEÌø‡2.O`À¡È(_>@ÀôÐۆ'lØ'ÿ ÒBø¼:蒇±*£4L$K¸ Àçï^Æÿ”Y®®KºyuÅ8èí—Ïwt7Ühbâppô§Ð½¨òëWxåâÅêÒÏÁ^-¯É|ÿé ½¿ýtû÷ëôù˛ÞþÜ~º»åÇn×gý #1endstream +endobj +2229 0 obj +1741 +endobj +2230 0 obj<>>>>>endobj +2231 0 obj<>stream +xڅWÛnÛF}÷W ò”²l%®/ȓlÓ¶P[R%º®¿¬È¥´ ÉewI«úûžÙ%%‘rRA"rîsæÌ🣝âπ.¾Ò·sв£ëðèäîŒ +~t~yAaüùís®KJU¦JS©©¥ÌKRÖVÒ¾}éQ¤óX•J疄‘¤²B[ˆêœ6º¢·Ïë•,WÒÐbÑʔ¤M,MÄÒH™±-m¾„Òñà[ÿ+;Õ¬°VV¾}¡r%JöQ«¨Äo¹ïR'x¢,=ªHæVöøý†bM¶ü7ª¬tq$FgݮӶ¥>§‰œmÅʖF-ªR’Õ$,׊RÙdCVeUZŠ\êʦÖ2¤©Z +d•#cg½ã³öE"ñwC.q*¤)Uî*³3â2ËÙ±à¬ü§’yä“ËĆ:1B¸ãkjô҈ŒPN‘¦}ºÓY‘¢j*ÙºµiÔZWiìì" ôŸŒÞˆ´Ü'h¹õ†ð|~æ­‡Kh6»ÒPޤzçfJZč%*‡T¾ýU®Œ®–+N±Îž¨s¼Z W掿ÈEÜtejÂæâîw¶Nl!¹…F&F¨œ8ܲÊ©QL¿öùõ¼Æ>î\¡ÍN¾,RàßøïJ›ÊßEªbΰBkm")©¬±áL˜ˆªTŠ”‰ªÌR‘‡t'хHùUڞ3•£‡±UQHȧ¿rBàûCyÃÁ°[Û½ìA˜TØSQ怃ZÀº[Õ u¿£ò¥¬ÓgôY®P=Fó$lȨå + +• ­a;LҖäJ¬ ¡}Sl­j½ïíPV<À\.Ã^¼ðY²H¾t¯¹:K‹q…$7V'嚙¯»±¥Ìz(´B \h4¦;ÔóPTíh;k…ðʕ¥'DÞqWH e‘ÉD,i)s‰Ù°žkŸŽ’8¬µ‚ˆ\Xzw»-f׎39Ãó <ÌrG9Ðg~`˜¨HìàFñJßyܐkU4¡ˆ +CoNbûNÅ2âà@7˜†€]9L®Ušºè6ëÖy4±ï³Ù±hSRÙ·_He­4d»X;ã»?!™øÁ–´ ³¥Óºæ +@rzÉw/ viót Ã8ÕI'’ÖâáwÇØÃۈ.ûÄϘjØD gÈù„9ÅÊOq@ìÌ`iJæŠ0LLu`I xWªf3ï ß¡ýïhµØ¸tvJi¤ö<ã…ÊEJ[!µ0¥1Ï)K¶ÂÚíÂ-c}uê!bއXOŒ4`j)Y¹À,ÁS+w™x,bÛ§UìG—;¾Í³ÇÛÁ´¥z°ýš+ÝñR!˜9Ó°¸«™'9Œžw'c +yÍ4 {©©<Ò ƒòÚx|/z¦bm8€œ}sÑ:ÞtOœ>+W5>BhÜ1%͛Q¹Cر·Ï7‚#».Þßh5xr¹¦wiìtÏ ƒbOOuѤç¯*•¹UÊÿöiΕhYäqæyÀ•¤x¹!7[($ڐDœ2±Ô=Bƒ>E¬’D:õXÈ©[Yq eë‚»±P3bLàž,ª@ ºÚOÈWjï€äT¨¨‘È«l!;÷1l ÐXÂhÑ_v½ JG×õyò‰¹,HLcïSÏ-IGùnΊ†o¦zÝl(¨,E¶¸w"×SÞPu°6͚l9n@â×TمTÇÕ`EŠu=-¾Z›jչݛ[ĬÝU܅@c,kþ'Ð=ì×sÞÿm„ÁéŽTÙíšç$ہu™= ÕR~í¸õ_øç–ùζÉÙMóºcÒÖ·’G4 ßsƒ/Û[ÓáÛþ@Í¿À­uuæÃ}» ·÷ÅIwÅ_W§ãûgbßiÍ;8“<æÖmŽ¢,|r2·¶O| +ñÒwmk˜sïÚV®5-µH­?ÀÀ潁·¿°@‘•{‹¯ˆ.)H£Þà»tüåÕ¾Êxüa—éí]gW‚O÷ÒÈzynU–žûҍÎÉÝUýU|ŒÏâ-€ÆzÎfÃqøê¥šoçÁU gƒg×ÁÍðyPøÐt6¹Ÿ Ÿh4§ÇÑM0ž·t7 šÜÑÍÃpvôXn°DÇQPw“Ù¾E¨MÜïà¯0‡4 fO£0„ùëWN§ð6¼~ èqøÒ‡ÌM0 ;õ|yÆ4aç/#D;‡¬=ÓËlŽÆ÷ÎúÍdú:Ý?„ô0y¼ fsŽoOŠSì~gá(˜sˆŽnÛø4œ#ÅOô2 +&Ïá6Q.ÄpüJ¿Æ·½Ž½`ÄNýt̹rð;zBjÁmÞ<>ß"Î]ÃÞx¢Â(ĉ+j#ë›vÙ4 Öt~õ=ÐÍót¾›zò3pç•H=Ÿœ]Aåøâë)ë܏Ÿé>³á#MŸ¯Q覵,|vqÖ¿$'xöáÑGÿçØ,endstream +endobj +2232 0 obj +1876 +endobj +2233 0 obj<>>>>>endobj +2234 0 obj<>stream +xÚmTÛnÛ0 }ÏWð±’´N³^i™Ž‰É’«K‚} ¶vÀ°®X¶a¿?RIÖ4À¶$òêǨ‚KùUpu­ÿOÏ£:.Ú9T¤']º¾½ôùl…! KL| =ÓÉ'Öl9­]-'G1Bë ›l1ÀÃà#MÏÓ×Ñ%Lª«éLSG@‚Ǐ€’]½Ïøu  €=:CšX·‡à{àx‚¸âÔÁÚç)ÄÎgÛ¼9-Ï%AC-™ÄKëAÉsOåœñ1I†H´á…a ‘Â’ »Å È„«ñ!(¦w…᤺ž~x¨fSÐå3và<ÐR(CvV• +tŸ…~µpËkK`q¥¸¸${¢‰„®'É«HoñW,¢[KÃ:ð¢KÐyÛP ÙðÂ.”~¬aÕyèq ½o¸-_øpBY +â˜×9Ñ¥AҍžS’²°ö*b-år©ZêTEÛwx ö¸ 8ÆæFX”²ä( CȰ¾È>7"ڝ¬.Š>ê´ÿ‡ã(žÏé`ŽI£Ù¬)uéÚ‘°‡³×„³t) '¡¹ßúX,ß`BE.Ϛôt 'BSs(¹ÉS©Dã¥Ô˜cBv»f«P²•:ÍnRt¬tlZd›½7âq#¤*/ÐÅòG]ޝˆçãb5àV2›nï‰LÉxlŽN\“a³ä(•æMð^M¿ÇÛw 8þ¢½Û_¹/&³ëé\ÑEœ‚ –‰e”¥£ ëœÄ]Ôí>ªšßM+˜U7Ó[“ÑëåéןÍö†í˗íæùùqûúÍ÷ߛo»)+A“›Ù¥ÆÌçºxUÍ¡|.\>øKnŸZK:jH ¥Ç(îG5§E–endstream +endobj +2235 0 obj +671 +endobj +2236 0 obj<>>>>>endobj +2237 0 obj<>stream +xڍWQSÛF~çWì[’á C ´OÀ@†Ii0ÍdJÎÒÙ¾ ݹw'»þ÷ývO’ i˜ÁÖÝî·»ßî~úg/§üät2¦Ãc*ê½óÉÞÛ«SÊOh2Óã÷9MÊ×>ÝÓÍõùç³Ï_éÃå§ËÏg7t{~s}¯/.?Ý]¾™|ÃÅ#Êótq|2:æ«jŒ³4Îè·ÆjÊOOótø€N»³G£#>{á–oæ‹H¯/ÞÈYºòZӝ›Åµòš®\cKa1£k[ŒØ,ä£÷láLêzYiº­T¡iŸî5dtîBä{ψÆyžïç‡'Ýߝ Ì\®´ß8 5–Ú×&F]RtT!)[RiBôfÚÀ6ÎN¨æ‡F‡)7£¸€™ÊÚM¥+šZۘ.S±PvnìœLd_ÖERUåÖºì"ç)MØ +~ãBÓÌøÉëJ«`«6ÇâKÃÕÔ+¿¡·7#¢k¶<E¶©§Úã꘦ºP €ÁÜé@k½ÅqgÓùÒØÎèß©€§;ÕŒ·^«zZéçd8Nž:ID ™óT£$ºâò_©ƒ™Û”í¨ñåZmhãO30¡t5? 9BHýˆÎ7(^…˜uŽÆì˜C`ÐV{UÑm3ºé°°5c£¶eòVT’oJPreð¡/|Ÿ³-{2±qÓÕ÷Å`2RËe" +ZWÃçR>6mr“ùI[ ðo›¬Ç›IȰ¨ì†Pø–fìh½p jâÂù'…)5ŸM´ÑW×P¡lûYBæ´¼öö¥sÃ4|YhKk F=2+%{[xëD¯gÚ{î(øo˖I_-=ò3¢ßQΰ`€i—»…T‘# …Z¥²îdg2¤ð ,¦[Ë?Oà 1äö+à"3Oko²­k¯ mVl´ñ»*¹I%Ísež´7Ác|ܹÊgZòûw¸ËƸ^ˆ H1°IKV¯S4Kïæ^Õá×ÄŒÎø£uëÞKéØC`?(Ésj;¶uS›ÉìRK«w’î5§´`B†ä I›š’ÉÈSš³®­L‰Ö_²Ä10eÃ#?ŽÇÅôÜò^j˜îŒh’,<ñ‰a*ôìí£B&pb‰‡fj*M;ÐB›ø—ˆðÂXj§uÆ`ۛµ+Ílí3HØÎè/¸ìGnè‰áõBKâ\ÑHRdèÐLÊøk0…ç¦å2˜e`ÇÆ!%yLm• +R͹ `&õ¹Ø´ +.m¤©³ž¶;TMc±gñˆ®g/”«2ö˜[Ö¥-õ$Ê>Yñ*ç iqÓoL±™©ÒP|$|oQ2¨clYv§/yU³ˆÌ"^9©©zÝæþ€?ÀSd׏è ßõˆÃ=ÞӃ{¤E €Ò_øÏtí2ä¸w%¡í/v»Ób\@¹FD½ ¿` å[E/¿ž†¨¯Ç8àf®m—m—ÒôzaŠ…°)ÈÑJÏ1jEEÑ­ŒÊv™ oEñwÜ£;«XÄüÕ +nzο +}°,ò@L™|Ý éºVJ­;}×p÷‡÷¡'AZÎÖ ãRž%Á¦Øi v8™µ»EÇs‰Æ`ŽM7²ˆÙ¡®BRKXºíBe ðÝæCmé¹ëz¾Êj•cÒiz o\Öӛ7y6AëxW6E'ûœ•†ž5À¬âþáÒízh÷ý+`^6QäÂ32^ñÉJH´y²6’’…^„æè6®B„F‘dµ;hɏy&Ѳeš¯œ)IÉÝæ%ºdî5eyöáxº…%\cKƒiш* bðíýtiÿd|ðóïÃG'Gxݒ Gïø‹ËÉÞ{ÿáí*¢endstream +endobj +2238 0 obj +1635 +endobj +2239 0 obj<>>>>>endobj +2240 0 obj<>stream +xڍW]oÛ¸}ϯøå¶€ë6m‘nwŸ’4éHÓÜÄE±@_h‰²x+‘Z’Š×÷×ß3C}زw‘<Èə9sæÌðϳszƒ¿szwÁÿY}vµ:{}ûžÎÏiUàËÅ/h•¿È´ÊXÊu0«¢Î©2k¯¼ÑaA«Òüδ šðøgk¢¦Ü…öÚF*¼«)–šœÏU~GÎêßh­)´^StäµÊÉD‚‰¢­ª9)›¿\ýçì ½:·xË.äÎþ+’ +¡­±¥Tx¶»X»á]¼7ˆ ð]~y`²óoÑûöbñž]a ¬gi«©TÏØLA7Ê#JjÚ5ö ±ÎSp8>Y…3°µ£uÕz±š›Í¢IǶ¡UUµ›DT«Ÿ ĭ֖j¼v l¨<ç'£¨ñnãU͈P0uSípœDtgìO~—mM,ñ39¸›OLòW×FÊJe7b¢ÔÃZލI€Aâ=°w°”½ÁreUå6® ’ÄÖÚäLMeâ4ÞÞE°i€©|º× úÝmõ³ösvBQÔE &–*½Á“ø4ïü°?ÁAý—Îڨ֕ÐNQæêµ±zJ­ó?á2ØëÍ3Œ"Ç®èØaÎ>ì€7ŸµÕ+î:*D&æ¸Ú¬œëJgª %xÇÜððyó=dÿŸ=¦ÞȺÜäd]$Ë8 êصƒƒ+âV¡ÊB‰­v3ã’cµ `¯k´Ïäoc®¥À¿k@k³ªÍužè¾Õ ¯ŸØÄšÜp`j³)# N$ÛLö¨ý©!ï­õ:Do²¤/‰ÚÀÏ:ûªðZ÷T ´um(uã9™ì-¼F ¶ {+ñ¥ËV&N„INQÅ6ôÔÁƯ:èêyº»D–¿K•”QÔVÀrpë#Ë{¸Ÿ û8òrðdNÛÒT¼J#ÚgFgç 8¼*G$Šk€à3™“§ PNÐcðûá²¶‚1`©óó"÷INQ¥?^|ït’ÉX»J·­ÊJ£%\ŒabÜ£†}:â4%TΈ ±­Û8Jp:*ïêëÄ^v\e¢E›Ê©OÝÄp—­Å—Äb_õ=ÕÆÓր w Q¨ŠöuQsû©‡ê!ÈIf¸rí *²W \¼™kvR,Þ Z?^(Òß«aáªÊmô v”ULe…š±ò î‡×·Ùlì%Šf,y´V:»/Ý31Ù¯À˜p°d!@ÁéZ³ß–[?Àwù‘mT˜êhÑDTyÅþƒ‘„m2û6_|êU{Û¦¸Þ³vˆ‹©½7.ÃbÏx=ŽaY³@ACàËz÷ô¬fpºM[̔°¡AF±³Š8öúöã0©¿yüòD—÷Ÿèúëý§åjùõþ‰n¿>âçÃËûÏsú´|Z=.¯¾ñ'Yøåë§åíòú’_¤s?Ÿû¦3ÙOb/zåIÞ_n@H!§tR-%yh”û$"+Ç$*®ZBM¥²-&§gɞ`PºŠ+p;KµWoþ‹˜"ì©]šE¨a×zd7–´6×iJUÑ·ÂÓúyT¶)Ô/T WPq9‹{0Ì~¼\Ð ´¢ÐҐçÐGf>”cœMyuI³¡j­lp~ØX<{GmAÙ¼¹ŠâƒIéô„)»»¾ýK×·Ïß\œÓÅÇw¼Ž®¿=<ÑS/¸éèšù‹²eyï«´åՇ·oxÏû ~ùöâÝâ#ɋÏ÷ßènyõxùø}¾¹¿y¼¼£‡oWwËk¼¾¾¹ºá 7«³Ÿýi…endstream +endobj +2241 0 obj +1883 +endobj +2242 0 obj<>>>>>endobj +2243 0 obj<>stream +xڕWMoÛ8½çWÌmSÀñÆI6éÇ©éf‹Ý"Û¸‡¹Ðms#‰*IÙÑ¿ß7CJ–eØ"@Kâ̛7o>øódFçø›ÑÍ]^SVžÜÎO~ÿë†f3š/ñæúí ÍóÓÙôÍü_¼¸J/Né‡m¨T-e¶nIU9åÆgMдÑn¡‚)ù¥Ñžì’ÂZÓ³pʵ¿ybtz‰3Áâ—ñ #ӕ&åÙØ¹Zx]Á'œpÜ;G#ºU DXÚ-lµ¢­ ë!ûÓääâzzÅNú<®•[±­¥Ö´´NÎÔë֛LÄ!±}ðˆÁXŽn'‚¦MVb"ÀK X¶K¸> +œÉw y‚j} Š$¹{̯ª±´¹Y¶C$Å!¿`RkëR\X7ž”1À­uÏ´P"Ã7‡JÆ"Ç*Á7™€ìȳc1ÛT¹Ž,íJÁ÷˜è˜‘Z؍ÞI|ä¶¼*¼E=訷¡çrªr#ÞÞóɋ?¦×;òԔøáéž#2D'ˆÊưàu±¤KÁÛe@ò4휝­-’5IŸÏTÖÒ ½w‰gBËA^]…¾8|7 |WÈ"…|`¼²ä{À‚¦%ÛÕG<1Îί™½r»¶…î´!,ç‚#–"ÊYѕíªïba—S­ @%R`Šûè¨0ÂÙ_žðÝ/Yù*3… -Eæ¨S®t/XhÙTQ2R4A-b0 E¥@|S×_°8Ç*~•ÉyY9UÆ,€éOp&dñ“ãä†é¥mºUSrk噪íZW{gÈø‘rMµ±Ï:çB÷m—R=³ÞVÖæ8ÌK/Q…ceÓ‚jÒq¢7ì6vîn’¹ÚX‰Cº„¬É>^ ×Q­tåcYã7ðð£M†ÇHqµõã¾àt© j½Ôª‚°—M1n»O§ƒ~Q<'ÃL"DÕœ f¥´’Ÿ —¢³nלÎyÌRŒÃ ¡Ùê¢8ËõE—Ã|®kUèd? qJh ˜uõØ`EP9d÷³õ4ÊPpãiµ³r֋î€p–hQ*¢-*€ZãÜPÅ{2Ø$Á#§H7¥Çö½ÇÓÈ~Ìî1>§Oo¤(/m.­4EÍ2÷¦M³zÔ;%ÒL¦„26Ì/^KȉÄ4‚@^<áôµ¢•`ùqh’Ãy•F $¿`Pʃ¥EÑÊÊgn”YþØk•û#»ó©tJt÷ ¤}0Q¤twM*úc…KS›€|F;¤€•ׇ¶íêy0üسd:r}ۄ×N“WåÀLu¥—¸Æƒ²6þجÞQw8¸{?iöïFA¯Äj6•èÑJ㽀ãµ%vÈ4:P)ú%èê`xGùÄZN#Ù²{pÃãՔp³icÈN¯”Ë1 і·'$hÜX氂>)ý€ƾ°“öån|G¨4ÞcI6\w%|êÓ—ã3ávëL€¾Ëpã»ãÞ§˜…Éб‰q½h—™4wãR-í­ +ÎÆeyœ)Ô>n‚­(ù¦St—ìC-¿¶ìÞ£·æq5š 9ƒµZ1·GUÅJÀLß1AìÔôtÊ[?:!:fäé ?P´±†hÔ´Ö©•»GE¼ñôŽ.nKšhe 9B…Ç^ªéØrt·¾|u·Fo–¥#v€ýÚ`̹©˜‹Ï_¿Óg]a„ôÀ®¬¿‘`$­òƒ› +[!_!ÍÕà^³K)Í-7#60Ùmªš_¸uM°ÜÆ×ø>íTÇ õ6ᯗ99Ù rßç:‘¯Ò[ êÎðF5rݛûve'¨kÁ2\°xføZg|/’€“ñƒÍ,ÂÆÜåS[ܓ1éÏØöゆ%; +.]ÕâHñ=ßI:o“tfWï¦3º~wÉöéÓ÷‡GzìnqÙ,y“ý[U*âV,GÎn.Îù ûåþöÛÇo?èóÝ×»o¿ÐÃ÷Û/÷ŸðøÓÝ×Ç;>tus5}Kràê†ÜÍOþ9ù„©òendstream +endobj +2244 0 obj +1679 +endobj +2245 0 obj<>>>>>endobj +2246 0 obj<>stream +xڍX]oÛ6}ϯ ö²pÜ8IÝv{J‹´ µYãb(š¢m¶é’T<ýûKR²Då Yy¿Î9÷Ò¿fì?3v6§_Q¼_¼úxÎf3¶XáÉüí¶(¿h!™ß(ÇĆëµd¸ªxÿšq¶V÷R3a¶Í„)Oϔµò^Z§–¥d+c±–ûô†3ø$™±…ÒÜ6ìÓçoì“ÔÒò’ÝÔËR‰£Åƒv<;›ž’ñk%¤v’ñí¶TÒ1o/Kæê¥“¿j©ÃÆô€ë‚Òª{îáÛû3¹¹²¦Úû0MNçÓs2° ÀÌÖ+£ÉùÚÉU]²ÝA5¦f;å6d”–²-·ž™UAl®¯ÕÒR4J“{lkÍÚòd{jãÏâ*ã’àÍ«oºœw~§Gm9Ùw¸Sñ&ºÂUÎ[µ¬½xqwˆœÃ cCPøÐË õˆ¤$×G¥ÞpyÎÿ%î?“çp§‚!«Ðb“Œl žy¥zî÷¶{ʍD¹h{{Bu&hîspËô`(C²S†ÀRMhœpyµm^ESQA‰‘j¥‡:©ÕÞ)Ü §zl°‡!"†þ +2è,!¬ß£{öÔD6èIS) *h+LµÎõ¶þa¯9Y)ÑPòÝí!”šw-8T&”Îh,×u…¤B ¨JPhTÓMXÁ=ˆl-| ĕ¼!Ö:G¹7ô}tÍLhÖäÉÜ?ViBQkÚâÝ¡G©è¦ ’E SúÉÚoˆ9¡÷Pæˆm©ÌýhœÒÈ@-в@5¹æ¶ 2/°x—jgÈoRaGpšÂ­Ë=%Z†“â„*ôû궬GÌD¤wІJOI³ùh>½;Êjö…œÅpˆ—Á'“ª!ښ4Ãe£[ßë«‚¨]>ÄÀEvÞ%K H6ä%Fð‡Bœt€}B/®›,¶ãRa@ø² y¤ÏãÝy>îÎIõ…Œc¸‡„n> “Ø>w!„ÔLÛ^ú’vóDӀE EMGRŽ}òé“ñ Þ&9 ›màx^C±1ŠÆ·ál¼¯ìÁ„ÊAÖúóH°Ð‚$ޤÒþC;ˆH^ÅبWé5ÈçËÐoä²^¯éSŸ¾±Q¯ ‡š«é¼GnWØ +j ¤ ˆ‰Ù<p}W»È:€¸8=CKbœ>†¯< Q@UŒî©ÞÚ9éjI=öÞôß»ê¹WÔ!‘8ˆ<³úbn\ØÉªõ¦ Ù%@’9¥EY§i)¯+U>¯L`¤¬€ Çv}é~@ā éè©i´Ö¶ y8º ð£ç\aÐDZ%rá$¯×î2wúz:ߗ˜OÝ<¼èNg]’Fg4öòSYž²1;ÉýÐÒGûì‚nú¦²ce‡–Ν»Ãçz/9ÛÝýIÇ>˜@û“ú€ýϝ[G9yJ ú]޽ +§ËÞQ*|y’˜B0ˆ:ú6éè †glþ³ßnnÙm{6½‰§…cs]ó’ÖÏÎßaÉñ›Ó“ðÃۀ‰ùÙô 7è˙ë«÷_/¾~gŸ.?_~½¸f7ßÞ__}Àí—Ÿo/iÁåâàŸƒÿ>û.Sendstream +endobj +2247 0 obj +1704 +endobj +2248 0 obj<>>>>>endobj +2249 0 obj<>stream +xÚ¥WMoÛ8½çW zÙpÔ$Íæcoi‘v d‹n“.P J¢m¶é’R\ÿû}3%Y¶÷²(Ð֒8oæ½þ<:§3ü9§ë zsEE}ôöéèõûK:?§§9?ºº¹¦§ò¸P–jWšù†š¥¦“{å7¤lÉ¿-y]ûƒG+ïʶФâ÷F—¤é¢mT^i*œm”±Æ.ÄNúääéûѝž¿É.Ø[g>£ç㏠™@­-µsìN5r¶ ÚÓzé¨X*»ÐA²}m›@nN¥žÃScœ 47¾0výÄéÚTYאՅAySm(G"7óºpõÊðØP«Ue +ÅÖù%‚ÙJhì<{>aW§Àôôâ*»dgyFüìø®`£ÊFX×Îÿ µi–@oíMƒTÈ\û½¨Ê”4wž~¥U`¼Ö´Ñʇǰ0/1ˆ êüb7ì9¥Y«F{£ª@a¥‹,pyló  IçJ͐´{ѳèö lžgÊv`# +½ÒÖ±¨&Lp-Mh¼É[¶E ÎBEÑAñ}ʆ{Lе*5囈»R—‰/ÜjCsïjÄZê`9–´ªT䀠 nSXúgk*šejIÊËùP?=Êâ#Û)oÙåô eÆ=»TTåµ*7ÜTe+eö“F3 ç7®ÅQD•ÎŽ=>.±x‰chàqÚ{.©qr&‘yÆÃki±:aÿJÀï°ÆäyEu‹ê- +Ã\ªF‰" ~•i¦ü‚0,¼ªø¥Ëè^£\$=)…àlšŒþtkýÂ`ØbIT…/ ½â>‰á×ú‚;²Ô‡Ú.Ù³P|6çJ„Æ"{UøãcÏÇ ˆ-kç±çƲ2^Ï'‘µÝÎÆlûŽO™ãΊ.=w*‚„~hou5̂#ga§CށSD6¡Ñ¨ˆ…Ö™b9…É·ìo-ämJ<É©w ,ƒ®æÜì¢8¦«ç`+ëΧNôÖjƒž[­´M= ŒºV©Ù(ë­W¥)šh š¨màvbøŠ(¾ÈÉ x(öÊÝ0n•ôQŒ–K7‰^”8UCmÉäœ êU,¥ãS4, µVpδÁôbs,Ò¹‹uªÓìÚ?z  -1£ô[tÈ8´ˆ ÷úýu76G^w¯ÒD=¦o8ɰŠrt( ‹TÁœéáPž'¨Ð/W=è¶FSêÓ|sÊÿJˆxbUopÚ +)iÓXŒ=®¤ÂÇ:obµbEc—)SH× ¾ïÌÍvYÿb˜î½½R(Ÿ>¬ö{3f÷‰‡âߙ=òåÚ îh™šjÙKªé:åmÖü? þ`k¿g#õT{çö„4ÃG’ÇÅÁô˜ÂÉÊæàìPæ=q­D’s½%^²:‰+ ”:¤puGN™tÙÁå/@ ӝùŽA?ôj·›yg¡5[[–#úº§§§Ó«G„뤁'q_\#uYİX•qH§"ðë¿­ÖÃ>áèÖL¼9ÈÒȈ¢‰Ûï }ŸW‰²ó23#rŒ7N*ž^Hº g©ý&íšj5Ð.£;”]¡qkØÚ¹ÛUþGX;\yq¦#‡lªm–ì¸,ÀÜ;†×*æ +æ¶Y,›@ûâíÇ5žIÉ+ºì-iיøEøLBfgqö3)wP¿¦‹Mdd|š:aSjåxM Qªºp&Î1ÆÐ^¬ óv¹Ÿ*£lñ’~»·YX°9ª~B…x¯\5…NzXæø o¬¼…—<—ÅDWÈ{ï84UWÎ7„îÒ]Ð×o°`GöX}f63Cԃ•O%IðBù¥ÉM'A¥Ödæçjr{2£^ƒ‹H&bpœÒ8¾´ø¥Ÿe=Ý엉Ý9ý|2,! |ëÚ3†ÃeŒ20jÀ„˜ƒ‹ŽÞD¢4ò¬eº3Êæ¶â˜gï41Ÿ!¹ ܂ïJ|°¯ ùÓÆºW¼ð™:ö ºjYƒF#˜â–_°ïú3yþendstream +endobj +2250 0 obj +1766 +endobj +2251 0 obj<>>>>>endobj +2252 0 obj<>stream +xڅWÛRÛH}ç+ºò”T9&†„$•'\Kl¯,–¥*/cilÏ®¤Qf$ýýžž‘|‘ [P–fúrúôéöϓ}ÀψÎ/ø7ÎN.£“Ó›Ï4Q´Â›‹/Ÿ)JގFÃwÑ?xó±yó–&« K‚b[ù³’y,I¯ÜƒÊ”ôO•¬3™—¤ ‰4•kQ*ó‰B”ü\å+£òµl­ø`^“.7Ґ‘Ââø·¹.Ùõz?:žq0©ÊT)*õΔµ•´?Þ 8˜D±#Df$©¬ÐGa©Ö¬m7ҙ_ÖM˜Ú$Ò “µ‘»H\[eåwTnD×?|”F$*.ñVºDråFYºW±(~_S¢ IüWVº8VFgÿsw€ùl×·ÈÙV¢liÔ²*%YÍeÛUMVeUZŠ\êʦ5Û@FËTùXªrd|ä °'ÐҔ*ßF\fy¿þœ\&jêÄȩޫ¥¦&Q2†t å/‘)pR̛¦˜©ªã|««4qvêOF×"-ë÷+lÙykHvèņK<h»Ñ8KõÌðJZDŠ%°Ò¦ãUå»wåÆèj½á›ìمÎñj+ÌÌ(ÄØÖa 4 2¸GhûT–’‹fäÊ•wܸ…eG”ߤ6l.ž] ?òEp†ëXh³? Ï)ðgü»‘ð­òg‘ª„¹^¡Ðè¼XŠe*n8&â*†beâ*³ Tì)MK‘ò‡.?|hÎTŽŠ&¾UEQ¤õ AcÊQ5ó—.àIÃÊÃ(l/oÖǶ]T†Û¾—>Œ¢ UÃS÷ÉKP“1ÓÏî€ +£¹j2j½))N…ÊÜëR¿ ҖäPU¸¡}loš{ߎCÙpÏ2 œøA¼ðYò‘|í^3kÓXäÌöŽs«Wå–Åîˆ'¶¶¥Ì€¬BŒ,7 ÀE?š9n{ nœ2°ôÝa!5Ž#J4I&’®ËµÌ%ºÁ’“ÂÆ¥!Žq«t¤`\u?<.oÓL¬®m¨¨48¯„›#¹“ÜèËóBÅbOð‰oÜnȵ*ÚPD…¦7§‰Î]Ù(‘1¹áÞ5d7Žv[•¦r}¬¬>òŽÿ6ö½`6 8m!…¸x©ö#ȇo4ÞvÉuZô° 2ñ/ßÕÎ%Ú!N%:rËÆpr ¼ä³? =éÍb†À01›NèdҎ?Ú÷CÙè셱ï¬q ‰Ÿ²”XÙU^ÄÈþ f¥dÙ¡ %ø¯®˜9_©Ú|Ѐ˺×aEíÚЙ)¥Y °Õ«‘Æ •‹”v‡zÂBÆZ_¤|ò(ª& -‘ðìJñ/fxµ–zmD~‚§£ôÝ>âùˆŸV‰ï^®ú.ÍÏiǁ£«ˆÀ³Ò-)Nﺪ +=Î4,î!ó:‡öóîd‚e!oÄFøµã 5•Çúb€®‡á ^¨zak8€¼ïÛi½NêÞrò:cÎ{Œ‰`䆇ô¢U‚d’øw§Ev¦<+^Ö:årKÏÒØýv´¯à- ê0w2ö2­›-KenÐòß!-£#ÃÜúÜ;ؚ;pÓ +€´R€À¼–47„Ò¹°µZIÓ-‘`xê&X’à²u!ì°~~ KÑyoŠÑ5~˜kì(¨‘£ 8U$¦V{"¯²¥4ö%[ll‘[1ODçèïe ™N^¥ófyyÃJ—‚>¦µ÷fà&¨®‹VW:Mõ¶_¸‚ŒÙÆ~Ñíö—oÿVÈۀµigè‘ã–+~ˆ•¿aV–DË®oî#V½îfƒÝN ñÖÖ¯ +íh¯ùŸ:.|½‡>¾¤ºƖÛÄí-»–v‹Z¯? ‘ºNn?û ^¨ÅÖÉґeê-À±Î ̊·Ã-jÅnXbX3äñ˜u”·ÿº/rNÕ¬u…àM·ì’CE÷Àu¡z¥²߯ûF[á™äη~B/eáSå ¹†¯3|[â-ÁÕ·´^²¯o¹Õ´Ö"µ~aæ¹e¼CKjY¹·üµ³F=#¤géñ×±ßmqÜ-~Ìôn´Á‹ª{id3hwWÖ^ ÓúuNMgô8Ãñ4zêˆÎèSm—ÁÕøaPtÐýä2‡O4Yàß«`º®é& šÝÐÕÝ8¼ |. øÄº™…ÌáÎ̙þŽ‚iDó ü>‰"ؾ|¢ñ|WãË{?qæ*˜GôxL»ÅbϏ„ºˆÆ|{2¥ÇpM¦·ÎúÕlþNnï"º›Ý_á‚ÆÓëÓYHî"ÍÇa4 £ópö×äú8û7ãò{C“ènöí³ +ãéý1™^(˜8³Áßó0X0P=&ߑZ€£“éÕýÃ5âÐ%ìMg|\ŠfQjζ¾(¼ùR}iJ5úøu8¢‹¯çl›®æ‹}'Ì}Ëg*Þé+‘òÝ÷þÊûÏgøÎ§üðìâ|ø•܃ÛéÃ.éÛ`„ã{š?\¢mùùBüyòc‹Àendstream +endobj +2253 0 obj +1899 +endobj +2254 0 obj<>>>>>endobj +2255 0 obj<>stream +xÚeTÁn1½ósl$ YB!9z½³ì¨^{3¶AH¹ 6©T5J[õ÷;³l݈Èã÷æÍ›g~N +¸‘OëÜ®àóˤL“ëz EéY*«»5¤/ZdÛŸLIŽÒŒ¯ ¦ä1F¨ƒÎp"›aè2w!âRƒ€>#0ÅO`"¤p•¾Mn`VÜÎʬw²9³vÈBØoBÝS8*Ùð(ŽRûç›]uYw¶Öhmqª0Qs‹=ʆ˜´ƒqŠ99(ÁHŠ„aÄrzKJލhòo9]zv9Èã…™R–’¤&ƒõ^¸]5 ye’~8ù.Q±Œ^Œt³6³I}oEˆÔ˜c2äO»kƚY4W§g#÷û7Tr™ßå^†â½6èóÞëˆ4†:í ããÕ´ÏP-:l3dB{\Æ¡‘•–(×Lµ¥(JOmÇÏHæ¡ÁÍ0ð û"~ÿ>þbMÏ&‰ý«–}V¤O&ž0w¦XÞÏ XÜŠ›;qîõù÷ßÃñ ºãë×ãáååéø ÚÏ?‡ïŠ ³õâF1ŸÏ> ¡’ÿŸRž’[”)h¹^Îï |,ôÓäaò¯F?endstream +endobj +2256 0 obj +659 +endobj +2257 0 obj<>>>>>endobj +2258 0 obj<>stream +xÚ-Ë»‚0…á½OqF@Ze¤M%$Ø`/ƒc£`bDbÕøú‚šs¦?ùî„"G‘fӏ=á–,¶P +ہ.ó˜bÍØÓ Â5fèžoZ4a8ß÷mx`ço/Û ‰~$ú››"ËÒ8Ç7”Ê¡®¸.ô¥TR5ÇëJŒYHeä¤%{ò‚'õendstream +endobj +2259 0 obj +141 +endobj +2260 0 obj<>>>>>endobj +2261 0 obj<>stream +xÚ­•K““@…÷ùw9.@^“‡»±L&Èèª)h:¦µÓtã8ÿÞÛ3c&ZXYÁ=¹ß¹§|¹ààυ‰þÈa´ÈF/ßÌÀs ہíÁx2…¬¼Z€¡JçB«ÙTàºFe™åžíe¶g +òª¢¢d?€3¥ñ‘s;Ð{ +¤o‚O¹†¼¦PÒ´„â¾U„Û$…y²´;Ì Ü‰Á8ÈðìÀ ZÅ#7( z™cì†ÖŠI«æPÐúÔ4ʼIg—BWrŽ¥¶ýíM´I—ëÕé¿®~Ù3$ì¸Ì5Ÿ­J2|'ZÔ´ª©¢ÂTډpø~4Óil0\ÒÔ5Ê ý¸~à©Ò€\ÛqîöŒìº«.©^îÚ(³Ÿ„áͺ̒b»0¯ò‚q¦UÿI²Y®²hs.õ` HO¹‡‚ae'k¨:˜›(ð\)ª^uÍȱ™7Å,oÜYþä'Ϲ×á<~lǂ¥Y.IÎ{& ¾%Ú§¼ßR¿ÛDïÖYt†VӃÔôâÂxž¦ghC{/>>>>>>endobj +2264 0 obj<>stream +xÚ­ØÍrÚ0à;O±ÇöµlðOo„@ãÛIa„‘A­mQ[$iŸ¾+ I™×Á8$ù[i´b•_-¾¦z‡IëÊo}…@øèvGÓ¶À_}ø®›|ô`³vhþ0fÞb6woýá|1˜Þ çE‡î±´a–ñT² BšÂv'!,ËA¤ v¿èCޤmb ZE¼ro¯ËÁ%OWõo:÷˝\d²gҏÿ³‚ê³Z¼„­8…ݤç‰t§á†å5ôÉðÚ &ïâ£L$…ŽQûIo Œqþeø®(bš­±En°©¡ îús·5®ÇÍ8]Æ 6ìr‰«R„–ó?µâp'³±;pÏì>7Œ€'ۘ‡³*¦yh:óÝé­÷ÚéÇ1ˆ—ÓÝO}K—<æò7†€éµ•\¨T“ÇÀãÛûó£­;® +b˜†bÅÓu~ª`˜úþ„QÁŠEùÁ5 ÷ÍÉÞ¢ï \÷õ¬ö-§ðëø£…}æùþ¨m¿Ì8H9þÁ. \ojÛ=gAÎloÚVmmR{"GE/QôÆ£D1Sº%J·1¥W¢ôSÌÅlL±J«1Å.QìÆ§DqSˆV––ZsNYʐær†”% i.kHYڐúysµãôÞ[ØÖ™ ÝcÙ(sP'2léšv«½§UQT¿z ©ÈzŒ^‘Ñë1FEƨÇt+25·@¯"ӫǘ³cUd¬zŒ]‘±_jOëŸÚÓЋðÆ÷g08–‹§e*FdhSuó„Ë·êSÿ´$=>ìP²î+Öx?{á±$3Uë¾»2U‘.&ýo‹«`4:w¡öðN¡*Æ\„?±^eï[ägãfꝹ[LèOv Ä,]ˍ²6"—)M؅L0w«(ØíBà®?†Uˆˆ³x…÷µx÷|/³ˆ®u0náÁþ:â‰H>Ҍá½O¬3š$êšîh¬Fã/žÓ!жtM)N’®ÑÃݤ½ºò ýÖ×Ö_aµendstream +endobj +2265 0 obj +812 +endobj +2266 0 obj<>>>>>endobj +2267 0 obj<>stream +xÚ­X]s›8}ϯÐÛ¦¶c7ÍǾ,;Ìb  ÒÍNg< +[[,¹B$Íþú½’™4r§Q;y èpuÏ=ç^¾MÑ üMÑù ½?CÅîèŠM—hzŠH+gðOyœiªÛù²dÍ;ò/ÜrЦÓþ–ÑìÜÜB¶ U²®åÔôæTPîRL·J°Ý=¢~““a“ã­Öû|_RÍ>~÷áøÏþº®g〞»7û<;;ÿ~·kB’5NÓ8ýn'4BL?Hõ1¥¤B²(Z¥Xù¢š¾˜øqD‚(ǯ1|)4­‰¸ÙKÑÀÁ(¹Cæ)´WòÛãÛÁâ¿^ÃÄ â(›,1™\co>IâŒLHêù~·£¢D´AM[¬iª¶v2ÅÁó×àIN~ˆçû8±¢ÌqˆÉï‹&ŠÉÚËÉuœÄ#Á%w¨¤ÚQÍ¥@¼hD[½•Š¡ù=sÁ옂#ò,{Žå)Ä·ïŸâ “Æ‹Lèî耎LO+ƒJsÀJ¼”^x-õ#¢hO•æ´F¯Ù€\pvÏÊIïòvÜU’ ñÚ¿Žg¯Wm­ùÐ dƒ ÅP¿¶¬qÁ‹oð|àtåEgxka¦,ڝ9Ø-„·“Ú3 Ž€ßêGWH‚WIœzi𓐚íöRQÅ] 3Œ×1¹Æ•ÌCzË$õ–)Tsñe<»Ü*ž‹ÀVÝ C!5SòŠ»02Ïð:Iã¿om”h4jA|i/ºHKD»zëCËÓàíxWÞ*îcŽ3 û¯héι<”éÛQåb¡ÿL֟ÙJ¨Ä»]­»@‚Ôªîô±cš‰†;¹ã"N¯‚ùG–´KuÇ˒‰ß’C±EœG¶CKƒN} Å*Ùº¨ë +CNæ½q„aüÉvX+™)Á-: jZ —ë0:'ô®B‹3E°¹§µ×ô®v0¢®L:ûƒÜ¾gšKæ»Rñ€l^<!J™0”Ëš+疲Iû’Ašï€Ü²ÕN½Ø" ül!4¬®F…UÍ èÏ6o‡Yƶ‰¥º‘4ª¼‘ôæ:¨qˆ£%¹þAMzÐ#ô^^3±Ñ[Ý+Ða›~›7¿P«IŠáçÁ!F0.yDŽŠ‚fÿ + âxzéΔá6j-QMÕÆéP÷=P-íªÐm.](GYž€GC» +â0Ø$I´Ì=›–ô>9 +©Ø´ÔEB^ऀc:”Pž>‹8` ]ß?ö†¶¯3bW P÷ûvÿ™‘ýÚŰ6Œ/ÑÙE—}äçI†2Yé“sh6Šîv@1´¢¢¥Ý,>šž^ާht>;±}3:=?_ néÃó&Gþåû(endstream +endobj +2268 0 obj +1257 +endobj +2269 0 obj<>>>>>endobj +2270 0 obj<>stream +xÚ­—]“¢8†ïûWäröWlGۙ«´Fe…н½µUT„ˆÌ`â„0=ýï7àÇÖÔ %aK«Tr8ÏÉ{’—øíÎ}õ2Áý¨zÇ»»G|÷û<¦ ð z0zœ|øg0ƒßð5Ü?XbìEs Ù³hê:98BÎԝYÎâ9œ5(îSAmíÃ@Õ¯ž¾Nƒã„…*¦Ê#u³¿¼¼D0ÄK•Þš6ú¤Š0`)· +’ÅgϜs\EõÉŸô†Íò¼Êµ I˜,ΑÃcM÷ýÞ¨Š²³]vþWò >þà-žçüM5ħd ¡›ŒQ@„ ï ¯3¨8*dB$ùô³‡º£C]M*¨£ü+ràªaÚ+ò#ە;×GÀ7€0@¤Ùº”0²k×ÑíÚ! +.óX¹[SQñ +* õñä%-€Ü bUÚAI2UŽúöM ÊÞÏR›2˜&IZ4Š3¾V,†‹èoä» +"˓˜ˆH’Ê«QP"â-->’”U\]Þ¡Ö H/÷E­äIÆ¢µ„UU®‡ü 橦Z×rM±¤: ¾§¢½©žx¸7“¾ðµ9³›”%Z Ï·œF§½ÀًŒµ5ß+t‚Ðó\«ÆÂwCïfjɊr¿çBÒ$ª—Lg~½å´øõ†æ0´ñÍTån¤Ì¥æ\Ÿ÷Åi1éíÇm§&ãú:.ÆðÑnÓÊ7%Yçº}³Fc¿Eër*iåiZDè¼¶“”°w}M+X´ð€ÊRMxt]ÁÛ×åšóœ’ãº|8ƛƒ~oF“ၦ¡€€oäx‚«ÃÕn§þ ª'(+I^Ým˜ÃIÏÆxЯîù8ª.ÍQo ú§„ïþ¼û–°:endstream +endobj +2271 0 obj +955 +endobj +2272 0 obj<>>>>>endobj +2273 0 obj<>stream +xÚ¥V]s¢0}÷WÜÇîÌâŠuýx¤ˆÊ¬…¸»Ù'…¨´@líúï7Qik‹.àø r“sî¹÷䆧† +-ñQ¡×†ë.øqã5¾|PU@Kh÷›mèö{€‚«?ín¾ nÂW¦ã,6^Ö|¶uò(€ð +–”Á3Ž2’]ßn$‹÷‹sš(êµ`ú‹‡\Ó—æI9 “U-¦¡†ŒÒ<椋kxötŽLÛ*ÍÅHJ£Œ‡4©Ç¨YãòÂNVõ”éötj蕔ù4Šˆ_[2~£©VÁœüå®éK›•Ø“ÚlR[%]µ5UÒS‹å‡q÷Ëv‡¥‰Éö…² ×Ü5Kód,¬Ëáé£BéSê¯IÍúéÍõŒòvðט¥¤ž#¤ÃçZ…!žáš3cfÎ tç”g‹Ã˜Èû P;rƒ²»³”ö Ù‘ŒîëÀ„yòô]¤ÖÞ]nhMŠòzáî´ôÉǼpœÛ¢º}š¤'<…tCüp¹…€Š? Lüõ0"÷¾«›O.ÕöU^9(ŸI´mko½é…I˜®ÅýwNñ2_”—6Ol÷£w ¨H +Ë2¦À)Ü™¤èIL¥åìÞ7èDwŸÑ©ÞLËô& ˶ +Z?¤Ð·4*ëî!͙À{o"’§_ݙØC'“]½[·îgl> Û\ˆ}cZƒø&>q´l +[îMqÆdômÙG›ñay²/p’c»ÈÕ̂áhQ`tOR¹Xb +=]+LƒdňäÓ,ÇSñ#ê?¾„iõè¢ÓžQ–ïbžÓÕRû¯w<ð蒿`FÀatÅp– '@îVÔΠ©‚Òk·N]‘^GîÂß{ò·¥×§endstream +endobj +2274 0 obj +790 +endobj +2275 0 obj<>>>>>endobj +2276 0 obj<>stream +xÚ­WMoâ0½ó+æØ=ÀÚR8âRª²‰ÓÓJÈ$¦MeâÔNZí¿_;ZáÃT ðø½¿ù0ï ÚêeÁuW¿£ec€¿ïû`Ý^¨•nO=ÄW|ANr*á7ep–µ2hvî´~¥ð¦Œ¤6‚ +* +…¤1äÍ•4Í!W¦Q!„~Þli­p£ +·Ókut·U²ÿítï`eЮ ®Æž7{œfš8ãÉhÛ­+h‚v9‘Ñ4Nҗmxå¶u­Ž`? ש~¥,6BõüéÁA§¨”¦~xêy¨Þu™ó,£fÞíɹîôˆ¤eÌßL}|Ì¹ÈM}Ÿ>y.:„ñeÆè]Í*û«|ôD’æT¯ˆ¬2<³*¶¶U†ç'ù³±ã¢Ý`×þ«€“˜Ñ³Ïr~(“¿q\Ík¦ÚŒþF³•Õ5ÊM3*Hžðôj|m´Vl[%òAF挂òðËX𠥓³&4 °HL%š…þ¸w³xì³íŽ£ý?–Ä:Óu['y.’y±)3X†>ªå +ª¤ôSóœ ¨1s¦Ãð Mð.~ æ…ByT,KŹúf̳W€ŠB­™£¯ÚpÍ• Øx„ðªcì!FÁ.Áˆæ—J\ÑԀ`‰Ì/€0¦©ÌÖÝãX,ë~{A<S×Ù¯ÆgZíêb¤‰\d5áSF‰Ô¡o$†ø¶}\‡¯ÆÐšl†£‰g‡*„J’=]‰e•&1¨Š®Çÿ +##åô5%òB„jr×+ÄKÙý$,_–ãâ½ 5è§¥oð3éœPõÁÏTýf¤‡žW^õôP •¦,²¬¼øU3ù,êaè%·ƒîíÐÅû©´X1]‚åêSæIZÎu3¦*ʓú[£AL¶ãÔg¼ÇÀ,yœ,þVVÉâ }i®'r¨î +—0èºv “,bDJjx^%ÏñÓ*9ŒÏª†dsRßÐ{ÕºÕi·úÐí·[];È?õOðA–K•&ðD҂0½»iÝô[4ï:m½ç¶§¼¹¾…öîŸv„ÿ8"endstream +endobj +2277 0 obj +829 +endobj +2278 0 obj<>>>>>endobj +2279 0 obj<>stream +xÚ­˜]sê6†ïó+ö®§3…B!¹4F$>ìãfÒé #ŒNm‰#ÉaÒ_ߕ I€`'“‹$Èò³»ÚwµËϋ\âO zm¸êBœ]ôË߇1´Z.¡}ÝlC÷ºáâÛßín~ qùr»ü͎¼`fÙ6ñÂÙw·”˝Ý24ÀŠc¶Öð(æ + +k™pÍ$ qJ•*·ì€—Ðh]!óÏ'߉}Œç³G-/ ál@†V4 +ßó¦A¯,Ø’æ©ÆßJ'œêDðê¤Û‚4ulrÀ³[$QH¥A,¦)²ž’˜©zÏœÁçjÆî”˜zO‹'†< Ðÿàló>h7Ðê˜ "í›fÇàMu®À‹×›Ú½½GbóPÉ@2KÎ0.üq<?û™#R5_;¶…uKØ!ßpóÌýóPÖ/Dl¶N™FÚ&Ñ+à˜”BV ` ™Q?ÏAÍs JdU­e‚ÿ1x¢)>†Pù£«ñãE3lw29vMKÌIðešÄuè}k€bÿ‘CqWlwް¡ +æ´:`èú}g0 “÷¯¿9,ÿEʚ„Å2¦”ÉX]p•ÈeÌ*'n8³¢ðŽLBǶB28 6yË*1G×ILMt—X¾„îúÎ_ÇÐ;¬É¿È4ݺþY²çÓ‘“G‰H±f²(Sn̙³—«L1q£ùcN2&0cEçRÖx·ñjèF“Á1—ÊhéiYŠœW§Üºò`…€Á1M7ô¹2`+±™IÊðþc¥i! ¥òÕ&M­Qt:LÙÐ41u›–Õ –üœÿÃņïĨ˜|b²²-׎Æè²)cëHYˆ8ÏPF{â“ò U¾^ ©ËKå6Xaè;ý($ÁáêšHãÿK-5u!K”JøCeVä;³À¾#ã#ÇuPñŠaõ~ëee–}gùØ5Å+*Ó_@9z3¹(,–™¯¢¤±ç,_î¤}yžë,߯Cµfq²LðìLÝB•*S;Àß+ˆï»þ‘øn™ˆ_PM÷•ÄËvä³Z9Eÿ_1Gؐ`$t} ̰§,,zϐXäé¶Iy™Õ¾3 ‰?±F§ÈeÆifŽÒíbüà4­{×#¾ž™y‡nÑOç]@|3’Ì¢‰5µœ‘uÆn"£‰açœ>Ñ$¥ó´ú}1%þ¹šÛkëákWÎb§Žû‡u®·“ØÛ“¯wà!££–Œ‹ ËÐ#*Ÿ·šúTSŽïÎäöˆ _f³]@i1Óã%TŒÙ•¡ž_ˆi֏‚û³˜ó\UïjŠà™tf[›ŒFkÆÌ¤¦•š3V4Ÿ1KÓAG£ÐñFÅüœu_”uc!Ø«„…,Ou‚}ï^˜q0îí ÆWírVÅ!§b®4åZ½¡Ñà«Ëfw÷Ô°ld¦¥DŽ ÑÆ¨7Žáޝß:oÁæ;¬õئÀ2´HµÀò<Ïæè dæb2 ®˜¶ g£×msµ“mÑè%…{Ñ~Õs™ï~ƒ"é¹NŸ¡Ó¼ÚÎò×[³Z›f º7rw±±ÔÓDyR>>>/Annots 56 0 R>>endobj +2282 0 obj<>stream +xÚ­W]oÚJ}çWÌc*_÷фÚæöFŠ„{ ®`×Ý]Ñ_ßYP 8$Y6ÌÌ9sfvwü³f‰ š-ý Öµ;¿öϗX×àGøOëo«ɤSIE}À (øÛ„ÊOþ4¿ËÊÍ덶6wH°„DÄÚx¢bÎ`I$PèDJÄDÑ6±ZB¬þÍE Æ­ÑÀX-#j´Ú˜…&4›fwãñƒÓÒ¸‚:øK +)†€0P©ÀË2–%ýEbQt‹ü­&"ŸÇœ ìûñÈy3Xr.)"ÑôY¥×6Æ¥ÀÃîè±òo*¸ÎrÍÅ!Y€—E®jwŒ]©=hûSåõøº )aJs|NU’ê»(TK*ägM fÆQDe +dÅNJì¼B¤küßЩf¿§M’„³"ÀL«@F$Ë3¤Q̨„Í2ÆF,\r¼\ˆ#Ò1»¨ÇnÏqg'+R`éšìCaÛ2ý2ïϐÍäJ_ñžP:zÛ¸ý«Ã¾ç!ïúÝyÞ½±=:#ÿ,ùgBe´{¸GUšìôÍszÆöýLÿobYôài™ÌªÈ_í‡ äùÁçp¦°’G⼗ϤÛw. 4Áæz©Vï¦ãŽÆýK4ùËlÎìO6z ™à1TéʏÜHºRX™Òù¢Eo{3{øxÿrÒ%"nÆ´Yóm‰ÿf©sÀjx×w»Uð‚le@Vôpnÿ®Z}Lvè¾ÞUoT@þŠ:ÚkÏg°¸"Ú{+¢ÙÈ;Õ%RDZñ´P„)y¸|cÓ4Z{†Þ–ð‹ðÔâÑìŽR±§T®ëù¸ê½Ç‘}œaá9×ùï%¯ ¤\œØÙ.  ‰AjžÍˆ*–=Éçt3³…Þ?¨^ðDže¯¨ñLŠr)¥P‚’5 yH/Ãuº½7ŠñÝøÎi)ˆÈ†¹b6.Òvüši˜8«ë‹¥/n_?@G‹±˼Ág+ðôd.°?Su®s ƒ4‘¹ㄲ§«§O™È;_sçû—j”²b â ÄÑûWæRâÉ xfe°±ÂÛW qÇùŠâ tÔĕ«ñ¥ûà9Uëà»Ó3ú š*õ°:/HåcsyvéI –˜"EZ·EëºcXøÊÔȵÍÛÑã‘Úèšâ™‡;æ‡T CÂR²ÒÞõÜ©Þn˜Ú§eê›77FÌ×Þ¼°)¾Õþæhïrendstream +endobj +2283 0 obj +953 +endobj +2284 0 obj<>>>>>endobj +2285 0 obj<>stream +xÚµ—M³š0†÷þг´ ­p­`w~ ÕQ±Ê½«Î0â ±!Øé¿oÂG«×x«(㏐÷9'yæÌø³¦@‹¿ÐTx逳¯õ­ÚçQ”6X_éèüƒ[_¡˜a +Sâà +²vü¹6(Jö\CÕÄsÖC¶ÔʗêNrˆíñmv¾§8Jö˜"\ìŽÁ!QÌPÄbðÆãó€|Ì9 ±ÑßpD4@›͒9–Ç<î ßz‹QËE¸Üç¼Uا½>ìt“z}•UÊí%õû*ê!Ç ¤Üós¦pé.ëg¹ü‚ —ëVJzÌw–5þ^ɨ6†cöÌå屉v9ˆ[•d§Äé—0+ Dk÷_WÊ\MÆß,9•þ–UÅ훖eÎåà aŒì«"όѕ†CìÝÚ¯žoUÔV³ /zF5ñØ/D1,)ñ)ÚsÁb˜£(A¡ØÝPÚݦ Mm]ýßÔÖÚMÒõŽ"~0¬Ú÷Ú°NÆendstream +endobj +2286 0 obj +641 +endobj +2287 0 obj<>>>>>endobj +2288 0 obj<>stream +xÚ­–Qo¢@Çßýó¨‰r‚ê½)r¶¡¨´ ‰‰ÙâŠÜ-àÖøíoѪp±E£qםÿovgý[¡‰/Z2;~e`U¾ýìØk‰¹‹“EÕ qB#PBF0‰8!lCãšõ÷·A÷ûR‡ï·Vö¦ffª:›u<¹ë<9÷ª 6>Hâ…,èÒ h J¬Ã8öÞ'¿s$¤^àÆ?ö2N&#u ù²F<“äÎeÊóԜOŒ¡j̕‡ç±¦/i€¢ÛÚÇÇ9'¶r]~Ð Õt]Û¶AÓJËOŸúã¾Q,/BŠà#ÇðQ|Ü;ŠÛÈÖr%Ž×Ä¡å*줾eKœ:—,¬bNûŠ:ͧåuå%fU¶ñ½€Õ¾žùLÞ òƒ.êàF”uxäݢ޿._ÂÖ+Rš¢åFœ?¥ñ§Rð0îÆë— ©ÃŽ2nK#l]É#ìTóâ ó–ShŸ<¯Ã- ÃÓhŸ<έ(­°8i½€{Ո£ÿk°:0Ï]%™q?϶”ŽcT˜]&„1ÏÉÀØܐ-f5 é`9Æv\¹G0ó®á¿bOØqåŽÐ= §{ìF—M®q¾ëZ}x´ÔÿµÒµçúƜfH ÛSà ýu4y*¸7G˜X†;Eº‡ÅpæãӋZp“ši +sÈøcùíf^¢ÔzÐêɂÌÁÀ)`†ËdK" +Ó(t#âãƒN‚ aÜ»!¶{‚ˆ•‘šÜG–øbë{oºæÕ¿]ªUùUù˰ îendstream +endobj +2289 0 obj +609 +endobj +2290 0 obj<>>>>>endobj +2291 0 obj<>stream +xÚ¥–ÉnÛ0@ïþŠ9¶‡¨"µ÷–:ÝAÝØEEЫEV¢‚äï;Ên“X Â€$“ËãP#þž1ñÇ ã¥PîfïV³7 +à!¬6ÅEAšå°ª^Íá –¦J3t²½ú…` ŒYð̑xã·ðj[÷ ´–mUßA%û²«×‹šÔÌVBè ÿ +¢“nêVV°¾'dþm±„óÅçÀVËìh!ă؎s%z#»'óB2ޓaþC.č„ORT²{¨€(ÏÜÔ%tÖÞ ¥jûº7ý~ú ՛%Ziã°JÞÖ%ÞêÒÔªÝ=lTG¤­~ëKÆÁ’$(p¼ÜI\ÊÝÚM§ˆqùBšÅ½–¶„%|_tA«¨m÷¶æýj!†ïp¹ú<Æ.9c؆…>³qe—G`Æ3 š£Ó/Ë +„Þ²Žö”uðY§˜U£ºSmÁŒ¹¿ Ѿ‚O +&EÒßÐ`Á$ÂWÔ[h_A‚'ã17|ŒÌI†Ššx+FtõU$ÚW‘àIEÎ\Ž9¯nE[Ê LaöþÈsÀÜvƒ‰÷©g56£@¸>(©¹×-hU·¦AŸ%'$$Gûê<©Žß£QŸvò㺿FµkóÐþûV¶G­ŸwÅYù§#‚=M‰Í#úD«¦F\+Õ1D©lRƺêNUº–®£ +t-_ˆn–žŸö4&vÊ8\ršf2ªå`¦¢Zڗ×/¢IvBz"ØÓØ)¿8v¹ébЍ¼ûŸâû ª…µ2[èk<‹í0Zhwì˜vòòÁžîÄ=Gä‡YxüØg1†ž*Óhœþ×Ù[« endstream +endobj +2292 0 obj +710 +endobj +2293 0 obj<>>>>>endobj +2294 0 obj<>stream +xÚ¥™ÛnÛ8†ïó¼lÆÑù€½KÐlwÑl¼µ‹\´E¡H´­®$ª7}úe+v$™LÀ­ÍŸc}3ä¯óóÌ&üØÄ äoZž].Ï.®=bÛd¹"N0óHùd™½ùp÷‰6¬hEΪ·Ëg¶åÂà¹íÎ9ÜVM¾®höÅù&Gƒhæ“ÝØrC ßO&lE|R'kJò_+Rç¿hѐšrx—nþÈê¿âé|±¾AÈ¢ÒJ4oÃxþ›U")ž~YReSaìga(yzDx¿<³f$kÿòéOâx2?¾¯*ž? `"Y ˆm'œ…Ó3)Žƒ™Û‰ 8 %R…W$ú ’˜WëKÖVþû«/uPo¸8÷ÝLøÏ/²büI} 2,‡Ü`A-h)3u”Ò} +QTЕx¡„`å;ÂóõÞBˆ`5IãðU‰ M·ŽbáŠÈHÂiB¾¾ÉW@¢ +#o7¬Ø]X£ÖNöõí‰òXÁ,Ò/ªu˃â±òø± £²¼ÂÕ¤‰ÜHï3u©Ç¼>?^â–ÁiDŽàzòB´qQ­‹‹âQ\·sž›„ƒó4cvóä^У²-åçÒ#6ÒJŒpxOØyÎ zÞêÓ£Z—Å£ôv¨Ø«6)®)Í^¾«KŒQ<’„Ñ­ºmí MƒÕºÜ(ãöâPÚ ÍòdΚü°8¨ýóÂçUÝ +Ò@^µå=äÐ6'h½Ø6°.¥Ö¤UâQÚ0Rօ´wTÞÆ´Y·(ß­jÖ +‰^Ê@ru¯yR6¥œ&{­H¶Zv M˜œîœÈGèXœRëæ#t†-î¨!ôüX™ÝMÎ9ãs{õ[ƒ¨µ¿‹4ï»–§Ôºø(]ž¥,ïºNDþ@_‰W²ÑÔÆv=¯Sj]lb;6B·åދµw@·Åat7q`®9ËÚôԆ·={Sj]T¢Z¶²·[žC+› ˜֗áðÐ]œõŸ?äLS»±o`sJ­I­ÄcÔnä(›»E“ºNRú¹~ù²î¬n¾‚x¤­OÀ‡§)µ.<ŠGáW9Ù®u‘ÿ¦&Ì6ÏÄŸk6noÒø~h`gJ­KŽâQrÏSv¶ uÂqÉ6¯®zskۍ ìL©u±Q<ŠmGªàKž<.¶¹H7ԁÚ!Ϲ“q<.€®ÁxD@èf÷ýìAùgK½žjXsâ±>åV﮼IOçËڻäXåËêÝ¡Wïòåĝ;,ÁÎ úòÂø"ÅýqŸ¤ÿxfð ãD&¡ÔšëE‰Ç֋v!Qïä†×oÑ&κN &ΠԺÈÁ”38~ç ùƒYÛ;d„FО‰/(µ.´7å ŽëÝ_v[R‹:£yJϛš¦ù*O»­-w5ô>Ù©¥íDíŽRë"£xÙöU»#¡/sÑÌ)¿bã/hñîa:ݦ»ÀVlÐé(µ.0ŠÇ€¥&8žËEùàz`؎-óRjM`%ÃÞ¼.•ÄóоXNGâÈOÔÆÎ‘œÀm#Sj]|âûQod¸²oyFùpKÃ}¶{ˆùä!)ZzÂÃlß1ð0¥ÖåEñ(¯Ð.ê$¼c§ÂEÏ2£…žAß¾”Z—Å£´ðQÔó–òÉqÔ±k§} Û¶¡£Ów1¥ÖåFñ(·eõ.ö‰m¯X[‰Cs¶ØöÔñCì8Š5Yco¿"»·/ 8i5]uÆ9CßÀªP¬É‰Ú1ÎÀé} +8‚Ö¯âlºS'199 ΃aƒº¸ŽºDۋg6 $ WŸç ²`+±M@:çL–”7D®KŒs5弛xòCÏvɹ"çd!x›Š–ïíêß³ÿW¹œendstream +endobj +2295 0 obj +1562 +endobj +2296 0 obj<>>>/Annots 59 0 R>>endobj +2297 0 obj<>stream +xÚ}ÍnÂ0„ï~Š9ÒCŒ;q8Ú Þh1€»åC«>~×j TE•¥]yüw´&!èH˜*GÕ±¹e– .HEÆò²„Ê4O‘Ã:(s¹µXßâÍ/~&¹þŸ¿":è"ö ?ÿ)¼bZΐ +XWÀ֓$(ßúêÔ ýñÎâìԐ2:“/k¢tJÜv×±G××ÍÆ0¼7µ#Áy\_9ø!`Û¶>>>/Annots 65 0 R>>endobj +2300 0 obj<>stream +xڕVmOÛ0þÞ_qbÒÔVÔØi^Řį@û°ÑÑò­Ê·dÊKç$cì×ïl§%ISªêÜã»Çwϝû{À€âƒ©-ÿƒdði18»ö€9°X¡Åv,ÂaPnòË0¼ÝQ–.‡ËÑhñKãL›L)±%ò>÷×\[)x•Ѱ¤)J iÀ5£Äípdi^@ðè §~ÂO[ph0W›–£ó½ƒžÜ~)ÖeÂÓ"×v “v×#V"ÌcÄÁÝøúŠçˆ”iù²PB±(»»0]D[Ì%X*Ã#Ý#ó0s\,…F–‡;_ЪºfE΢Ò+Uµ‘éVĔ{ElñÈA¾†l~×9 ¯“4=óٗ¤FwTÔL×ÒµQÕí`§Þ¿žãaØÞôú =Û֒¯©ªEò{™üäB2¬ì(,!Pñ3êQÑö…🏱¶)1û³V胬M­È­›ñ,Ã>AÊEVKjޏ¥É0Xo– +ݩϗæ2™¢zNjR¤UkmÕ+[ÏÙé”?Éæn&›tôª>{«çä¨j9=0ð¶Á‡à‡!¦%­bmó•ox­"Ö2ÖÉàË_?ÙÄå»( â2äðAÒ «Ye0-8BHëÍÙ®xû˜Ä½²Áø¬5ëä(|yjò=ß«0«ŠFå0aRX 8TVN-b]³^¬A¢™>jc–*&MI zã:ƒæÁ¾¦Qùqô¯×Ùj§  ç-óÖ$Ÿ X[ƒ~9¢ P»°e¥kؓÇ1"­ ' #ÿäNb^`¿á·úÝï›No·‚çY\ʅô=¥4ÜDG|w\fsÎá2γWÕ`Ëû%Á~#\-Š¡Þ_¶·Õĵàü¶¢R5Xg0ÆœU8ƒÙÛÅ^8º ·mSÆ ”ªy +Míí“S¬nxÑlúNN†¡kNSe´7§êoá4óEÞNUW·Ú4±Ô®m©Ÿnðù~6‡y¶*žäx˜‰l-ü$á"‡o~Zú±ô6a¦GLCݶ-_šÔÄ_/ôà8ÄÌüü8N¤endstream +endobj +2301 0 obj +807 +endobj +2302 0 obj<>>>/Annots 69 0 R>>endobj +2303 0 obj<>stream +xڍT]oÚ0}çW\u/0ÑÌ7äS›&u-Vm+ô­/&H•8ÌNÔíßïÚIÃ%‘¢\ßã{Žï‡½¡ “’|ðe1øp†°X“'ˆ«aRíô5—‰ÈîŠåãðq4Z<Õ8¯Æ]N˜䃿Q{čÓõ+•¥qÌ‰zÂ&…Ô%$[®àýJèr܁ë‡ÂÁm}<ãÆ~¥6U.d©k¿ˆÆ»Á¶ÓòÐ‰JweZHã™.Ìa”©ösÿ¼ˆÐþ$¦scˆŽ ÓG ˜÷€]rÆ ÚÅÈñþC۔{:Ÿ™¨nPgÓdÁJ³VÚLÑÁ…‚BA’q­Aò\¼!Òe†ð\‘Ý#²–ÆBZ'”úŽ2ª!|»yC +³"ΕbѽùÚWÛ ­ž{QVJêzl"NÐÈ÷¼ÀaƒÇâÖʺ5 ˜^hb"t•$Bë1-“µæiV)áÀÏöÊ­¡”©—°°.*¹‚å_²³,•°üZ’Ú€‘šÑNÂw®Ë© ó2`´Ø/‡NO×וé4ïžÅ`ÂãÜÆ6ç §¶'Ó;‘¤ëTh3mÇY§x¾ËŽŒþ»T&YµðÉP;ÛÏÍd»X÷yGÐ¥B¨;Q^Œø\¸Êtq´æd€ë‡Ä‘2ß̞µšŠŸªˆÙíÅÔ¦—™çø-£Ë&­uÀxXÑ8ÞSŽÏë{ܦ™8Õ1ÑþfAð¬Ë׳9̋uùÌ©…gªØ(žçBiøÁeÅ3î½ØÜ•¡Ë޶ ÝÎÖ„Mf~ þH>‘Bendstream +endobj +2304 0 obj +608 +endobj +2305 0 obj<>>>/Annots 80 0 R>>endobj +2306 0 obj<>stream +xڕW]oâ:}ï¯é¾ÐªMãQï®Ômi©·åBú†„\b Wù`gÙý÷wÆNB¡$e[DcÏØsÎÌñ8ýqÆÀÆ_]>‹äì[pvýàëC°D‹7`„E±Éﳇ(ñ£¹šufççÁÆ×5¾W]ÛòÈû5ç+a¬6ø¥Ñé‘)Úlæ +.Ȉs̶ Û¯•Òžô÷òÀ>ü”ÛJ³úsÿE–æ +k.iQžr!þlÕÁ¦<³ó›yp|Z+WE"R•{#{ß¶ÜCò`>³ú¸§ïE¾ÑFEYJ–apf[6Ö©þš<‚;@ïX˜aZÈ|Ë)`zė¹Ó8;~ßòßyëz»%¶žM›ÚºR”xоƒõ=ƔƒT,¨ r! +iµ£týfôD”ÆùJÍôLqÊJïÇP 䊆«ï£^OÅ¥qyž‘~%¦#™«L@²e&aü2 >ÃèQðS1jçFŒn­ˆ¦’î>F:}¦¤iÛH­5¼:Ÿ³Nu T:ϯOOfªRO6Y”*!!ZBš¥Â2=¢…Ëå©ì´óQýîΞË4ʼnP…Ló}|t2û;ä<ÎB °'ÐCZj-ê”,y缤ú©@8dRân žÂU¹Àl¾ýÆqGéêC:XIÐí;(î|¿Ćၿ\Á)¹vwmô‰çjHª}N½¶¦dé]F$=è}¼2‹-wÂ.ea&rà Àžž8æe#³ŸQˆ”·÷‡—Œ™ŽiûMæª7w±î;Cak…l‰»/KéV۔] F¸Sœg°Æýb ƒ5/ޒH)¬Ä^%5!ñL&dÚð<ßf2<Ê \“ªhÁuûã9¤B„"lNâðO6qÃUøW”.â"ð7eÒZm‡Ã\üN ëÐ׃FqwÝÃçê¸ +ÊûM_°7í¡mJ@=bem¡m·¬²šÇ<]5#¸ s/ í˜O¤púõ ó»&ûú¥ •|ýÆpsp÷›÷‰ÚÇ´ŠÊÉa¦×[–u0s}Bii…bɋXAÅ.®bԖ/ÐÈ^§œ!oé³5@3jä_®@¦#¤«{ƒ¦¹'t4¹+½ú=;)¸xÆR±Ý;¢èT†Oéø=­&f;tûöÚÔdü=£'¬É³Øþ!…ÕÕ×òÁÊ6øRáy"Zd5OFÏÁüaô4¼9Nkoƒò‘–]vóQ·a¨SIWJFo…ÂdÒÖ|ØZ螋Áõs‹Î»¬–9F›bs¿É̬¢q©Ù·ó—ñprŒ^žwSwßo'ÓapiÚÕ ìáÌõ-†ÿ”Š‚»×ñ¦ÙRm9Þxc™­$O!sø‡§uÌ¢«¾£_-¼MvÝê]£ñêÀÄü{ö?îq7endstream +endobj +2307 0 obj +1075 +endobj +2308 0 obj<>>>/Annots 89 0 R>>endobj +2309 0 obj<>stream +xÚ­TÛn›@}÷WLyÂ,»€ ¤J+šØV$Çq}yCЍ½¾TX”~~gÍÅQ£Ö–³Ìì9söì˜|ÌF`šŒØ¸K(À¢qË(‚¹}S’në’ƒU~ÌÆa¼Ä«d½·è\BË5P#LÊÃ-ºA÷«Ìҋ}t|öåNûãÑ_¯çØB¼ Ԕ?ç<ÜO§O ôô8ÌüÅýãä¼4ö'£¥?h'PÐEòmªÄ¡ÈÓ0Ò+.•>>>/Annots 101 0 R>>endobj +2312 0 obj<>stream +xڕWmoâ8þÞ_1ÚûÒV%óBˆ¸[‰m9©×r~«„ÜÄМòÂ:Îvïßßø%¡P\‹JìÛÏó̌'ýqAÀÆ_n_~âüâ[tqûg$€h…–þ€@”\Æõ¦º/çìGÍ*ñrùruý£ý<í×sm«/=Ÿ+ºfÚjChŒŽ/Méf³p-8Glkp`ë7!”—ü¾Ùs…³×+ûÆeQ ˆß(— ª²æ1{¹~bá„r툯뜢Òv‘ö0°ü}éABb¸§ïYót#Ò²–qta[6*Üþ™OÀ ·ï 'ñ| O-8ƒÅgz¨«öv<Wn½U¨<ηå®Ä×ì¥z +š:@AûE3©CÁb D ã?·N µCDp6Rå}©Âç…}%&h{§³ $TÐȼж¼³‘iïNdA€V…LgÇ!õ4g°*9̞Ñ)”ÁÃÎF©¼Fz›¦ž§ Î™¨ya’´É™ÄÁVÌjƒ™Ï”š€x›ÂÔ¾—Ï»Ë/!]xcmV4Í* ž +õT#ieœãn1-àU +Q ¼þ‹ã,K‹õ'=ˆ¡ˆðlS4‡0l™f¸çÏ×°E*]Ýí}ñ@+1–š«hONµ¶¥d(sì½rýxžQ±ãâÛʕ”¬ +*?d6´ÂQÔdÃ˟i‚R³ÙÅ×L™"„).ɪ²¹Æ\Œ½,dÜ&à 0’õkž +úîÄGÃ8&c.MZUï%O€ÖèUˆ4¦ªÚic KºÅÿ¢ù&븻K‹8«¿KE¬·¯GƒìøÂÏÁudÉ©Ag¥÷ÀUwÿáxš ]õ…áñý>žšƒªz—ƒc‡{¦ð%¯eF‹u7‚ki®±¿àúXÉ98A;8À5w¢êgGÉ·Ín¸×ìt+l}tÑ7NÑû[–µ7s{ &T:%lEëL@îo÷Îh-@'{%9 lUáÄWŸuò7+ÈÇÚ.Ö÷Mwu_*r=µú#;Ψ`X{ß)¸OtÃi:î@¥Á»ªoF'踦¢0,ìý²0Àz_̓Unðøªãeš `$¶œŒ£ål>}ŒÆóå(ŠæÓoÏÑx1<Ìrg3ó(·’ìÉðsVŒ’D)—r†7‰<}­ÞBZÅÎÄ\•÷}WÏGÒ>ðÚ¬ÇÓx„nTzihÜ(æÑh²|šç£húô¸ºû>š/ÆÑÑ÷À/[.=ù2X1ñåd¼éÎ…ñ ¯Û–køÝ?Ú¶Ìw7§ÇE\&ÇH6öreÞL{z£60¥:O“‡Ñãäy4Ÿ-JAñ•‚f½K£Žn +ÓõˆZÿ5h\p÷<[À¢\‰wŠï3^®9ÍsÆ+ø‹5ͽ¨8ê}*°å¤gK‚vg£Åxü}ñ“H:ãendstream +endobj +2313 0 obj +1085 +endobj +2314 0 obj<>>>/Annots 108 0 R>>endobj +2315 0 obj<>stream +xڕ“Ûn£0†ïyŠY®’ + æLWÝU6I«Hٔr©BÄ!YqªõõkÖ­’¥ YØæÿüÏøE ³ƒk€é@’K"I»×Á‡hÏ6}ìFðñÉâ"mã”À;Xm–Kø-–Ô_bó䩼ÿGÿ$T#‡g:VÕd· z,Ò툒—–ԍ‹ xŽ&ϏÁ|=‰«÷¥Íz¡€\±BՖe¥Ï‰uä]Ðq"Ïtn5íPÖMçD£¤.[šOˆ´˜•Ðô4!¸ÑÎ4X‚ª,jw´U=+×§àíèÐ4•â$ò…–vï¶N~ªFçgHL²ºäÛóHґΪÀ̇õŸ€í¸È€0öÃi–AÈ+töM× 㓈íx,”ÉpÒ%+Ȍìã6c¬Ûñ—Š»Èš†é û+M]hZ½&Æ º +tî @ +´y‘”»®Ø Ëøà‡©{bvÛÿ£|mS:ÈdbS8Ę|™×3±#|‹ˆ÷Ø´, +’ˆ"¥)Íe[lÌÁ7ÕO®ë+Û¾¼Âù.ò…¶uÞ_Ÿ«]¡g³¯4ˆ1­Èë7^j; ;]b˜n‚Âr߼Ɣ@@˔ÆyNh 㢍3žLŖ0¨®¡Ÿ_]˵ØÍì–]ÜÛð$½*KGendstream +endobj +2316 0 obj +507 +endobj +2317 0 obj<>>>/Annots 113 0 R>>endobj +2318 0 obj<>stream +xڍ”ÛŽÚ0†ïyŠ‘zÕblç„EU‰¶»{µ--ìÒ*M ¤Í:¡Û}ûŽcsh’² (R<<ŸgæÏ¯Š?ޝÿQ6ø°Lî°VŒøS«xö坒ò˾Jм\×£Ñê‡QºF9v(ñµö± ·ÒD)äžý.’XGpQ2íÜ9É+ÈÙSanzh\ú}«}ªà­}k=šµù„Ùa®¶‡LæUi0¦Œº$@Pq©Ñ&¨^þ$ËH%u +¹] (¡XÀÓíÛ=¸ST{|ŠÉ˜O‰LJ²CÌ© Ôª9ÿ¨ëN¸–ΣzWæ™#\Ô§&¬óԄŸÙw© Ø€C’C¨TøB^!F¿?q­î ®9]á›Qèf\Øc„¬ŠdBWPâö&4êʞgÂõŒ´«'×Ô]npÕÇ aƒa#âDÀqøÙk³ÄC¨~6¦¸ƒ{Žö¸Åpœ+•?bXÖ^‹P•M7µwœÜMm/ÇB _í7>>.–°,6ÕsˆÆ^¨b«Â,“ª„‡0?„©Þm̐–Á8àõg'àzÑ—^±4ãëà/f¬Î@endstream +endobj +2319 0 obj +619 +endobj +2320 0 obj<>>>/Annots 117 0 R>>endobj +2321 0 obj<>stream +xڍTËnÛ0¼û+èÅIF”õ°6@^Í©€;§¦(™’YèáRRÓ¢è¿wW¤lE¶›Ú€r‡³³³\~qpðÏ!ta@œ®£³ð F‚)‡År7ëêNÖי¨*Y=ŽŽß Ð3ÀӉÂ>T"•&ê@dƒ®O!UÔÀ5wØto¼Žc»qt¾“Ǎèà¥N›\ueâ>pNñ((Î#ÎB<‹Û7²ŠµZת,(r»9ÌA 6Ÿû;ð¦ˆö}‡y˜Õe˜;b.h ó=`â,Úõ<¹E·^zV"u"Ž +7¶êÚ­ºY‰I u 䄈i±¶›Bkñ‹½¢zÂ1ù«nÑ{Uo ÷Vð½¬]X»»š¨!E+ E“?¡Ì2µ6Šm‘ ~•‰§L²=Ý4~ úBwgâÐ촌!•5æ‚LU5©¨QÓ&óP’¬Û¢äÒx Õªl²%˜´v[ôÕ0ŒÛÉD;NÆØ`§Gïa؜W«_p\€cìiú=X$¥Æs +3:ç ÚFôYhïäd‡ðgšdqŸÕû´ô$ 0[@GóçÀ[4—.³ªÜMn§ ÀJ“C1nًÑìÀa@ïŽEO9 ò?Ð=@܏˜ßƒ_íˆÑ)ô§—;®©ÝöïF&¢ÉjºÌo»žÎÌàl&n𘴌SËÈ=ª.àö‘ƒë‡ÙæeR? |ZfºLµÈs$ƒ¢hDF|§æÐiè:‡ÇÜ =ìA 'ÖçO£¿Q9Çîendstream +endobj +2322 0 obj +663 +endobj +2323 0 obj<>>>/Annots 121 0 R>>endobj +2324 0 obj<>stream +xÚ}’_o›0Åßó)®:M"Sãb ´iRÿ­O“²†¾ñ⁓x26³M²}ûù†ÐEM¨@Fp~>¾÷r~O(„þ¢§xWÍ䮘Ü|ˁfP¬½’.(uPu­}âY']”Óiñ«“œÅ!I}±lÃ{5„ü(Fóƒ‹VÖAµe>!á’Å¥vZÔåôóÙ)QŽô3wQ¶W tP3To¡ÕB9nÀip[uïêŸÖ ŜЊ\p& î~à¶2¢EhèâÿØ0†BØpgÇN†ÖôÅi•dÖ(FHaÁ:mx B&“«°ÎC•¼Ý˜ªa/¤„ŸôŽ›½ÎqeÐَIù׫n{¨É²†ÃŽÉŽ—S`k,…³j •ÇÆÇòø‡5­ù±„ªdWsø‚³¹Á…l¿ ŽhŒCßë2¸z§Ý¶,ÕÕ5œx< +ÎáVZòc1 Iè# Ååù _ ž§~m Ë =¾HX]€³Ô÷;Ð Jòwé :ÏÉü¿;+Ælà4¯ñü4O÷n±Ù×,û¬Ø!dÿýÂW¿Åя&‡ÞÒ=áþe¹‚•^»=3–Fo koߙò‰@·Y¿e–E!îÉü˜„±ï)ºŸñÉ?Ã{0endstream +endobj +2325 0 obj +481 +endobj +2326 0 obj<>>>/Annots 126 0 R>>endobj +2327 0 obj<>stream +xڍ•Ûn›@†ïý£öƉ’ ‹”¶RzHT)iÒØ¹‹mñÚ¡5.Ъoßك Æ8†HvÌü;ó1'~(xøGû0 !ÉFg£³Ë(‡Ù-aDa6'õKy%«Û—*-òÇñãÑÑì§Õ1«;x$ÔʇR,¥µz;£'E^V< ÇZꑨÇ[™‹Lžtä°u¥yy=ætùºXGrʧ +ŽÝ™Ç£ó'òc}úB-ëLæUiíPªíq€Î;­ 1%OãíϲLTjük˗ÙÈ#f{óq,BuàGèŒ2Ÿ ÷˜ø $L{ÄÚ·ïÔ>ㄶԦlÌÁžöJûü:Í0h³g ú6 ¨ð›rӋ±Äƒ1ºÓÀ±8´íÒª[cýJS: ÖÚ ¥Ä¿¼,öÌkÕ{y9G+Ríg]Bã:ä`4£î­xÓ®Œ¾{YÕ*wͺîÝÌÜt*¼8-˜ÒªhþˆU-K(¬'×{¸¾Þö5†´Ý3–Ìå"ÍåœôL‘M\gš¸=;¦ ¬ì³™è‹Tá†(’¤VJæÉ¦“uWÏ×ý _ûPÓµ“¡·Zsµæä¼gwîn´U³Rñ:Æ,¥â¼’Ò¹cdð:µycî¿9ÙZ»pp—N¥„‹UYì uýŽ?ðÍ£GøÅݏ•m÷Ž^-¡Ýâ4ro Íz1Ÿo÷Qo¸È̟‹GC]==ó&Ήi‹](p©¤¼uùx †1‰7 ~n2°—Á¸ê× ?¤­TLpÕðCÈ:âN¨²›Œ]g—‘«%ö,¾m&nqÀ§‡»)L‹EõWàâ»SÅR‰,“ª„‘×b¥ÝRãv<å¾·w•0ÎpŒ.ßGÿVQ‡endstream +endobj +2328 0 obj +738 +endobj +2329 0 obj<>>>/Annots 130 0 R>>endobj +2330 0 obj<>stream +xڍTMs›0½ûW줧SˈMۙ´MrI;nŒo¾h°lÓ¢’¨ÓßÛ1¸íØÃûØ÷öí®~Ž(8ø£àÍÌ?-F“Ñô>B²ÁÈ,¢¬Çi]©®çL©½ëÕxu}|·Hß"'žCf»TlËmԁ¸ ºA“F”JCºc^¨C¢A†Sl%EQéÕõMÔÍÇ·r[¼ÔÊÆ ÔÄã€x烠1%!~¯?s•ʬҙ(Mä.9ÄAK—§ð#DC|䥳ÇÄÉa1¦±ƒA‹vñKz‚n¼õ[qˆÀ¬^ˆ8Ôa+lÄ5¸dÇÁ@ XgªÊÙos«1P+.É?4{©ÿ[sƒÔ|4€ÛŒbADâö!·³x†—[8?×s­¯Fê‚Ë_\v]䚙s #£ôHÝcsZ¶`fv¤£yÓ o_SÿTGö~¢é}ԝR.éG¡=áÓr¾€…Øè=ÜK±•¬(¸Tð…•5ËMº õcÜÒIè6çD83/½Øœ9Î_&=ø6ú‹ã•Âendstream +endobj +2331 0 obj +609 +endobj +2332 0 obj<>>>>>endobj +2333 0 obj<>stream +xڍTMoÛ0 ½çWÝ%PÕ²;A·aÝz醬urQm9ÖfKž$·ë¿eËiê¦Ý HÄGò=>‚¿'üPHBˆbÈêÉÇtròe4´ÀH¼¤æÓ¬mÌ9·ëõÙfº™Íҟ=hރŽ£€Ävmؖ÷ÑV>.º +J YÉ4¼v Ѐ,ÇÅ÷aÒr½™>i®\â½mk.­éã  ÔÅi“ùã tEI‚éø|ÆM¦Ec…’.ò9$ÀQì¾.Ïa¾Dôb`1G¨®HšÃÕpHCytÆ$ØCw3{vˆÀªQ‚8äá5v캻´ä YÍA`ñ·G‘P(vüoªú ՇA/‚Žå%·­–~̃gC2fËÀòºQšé{(DÅ µLH!·4¹W†EéËM¿]_\<î0ñH?dLJeá†C¥2fyîÊäŠÀça«"Ԃ¬JvˑÎАءނÑ*<0Ú <´ý·Ül”©æ~ðk§²@~֏'ßÙ鞦nr(Ì©òé˜UÔyø‘S<üy_*c]þñð0î5ýP-˜RµUŽ¶Ö +'±™¶²ò×fö˜!+‰{Ä3\€\I­qn Ûót¨Ž£0`¬Ò¨CHÔk,³"ƒ›¶(úýÝcËdw¢ª:M·\ßia-—øfKà,+Q0F­ïÀ‹“~ÞÂÏXÝTÏ\žWBfU›sx㪟¸/R¾FûËå/N“ŸŽ„Ñ ‚à-ì3}ꇿY/Öñ~¸z»·NØ|E(,¤¿ðéz}Wª°wÎ¥µV[Íêšk_™lY岏û¤ã$ /í<™c¹.˜$þ”|Ÿü«#endstream +endobj +2334 0 obj +650 +endobj +2335 0 obj<>>>/Annots 134 0 R>>endobj +2336 0 obj<>stream +xڍTÛnÛ0 }ÏWØKÚ®ªä8¾ [ÞÖ§Y“>­Ã &²£Á—L²Û Ãþ}¤-§©“´K"I“?8~ŒúÍóÁÅlpò)Â,AO ˜-†ózeoT51º¨”±÷ÃûƒƒÙé·Èãgaï¬LUëå;§7&Þ&žgÑNâùR8<<\u–ƒÓ­H^LWÏMZ窨lëƒ䏃>€ü",Ä»h¾RvnôªÒeAžëـ3ŽUX?noÀ=sæcTaì˜y`Lw€‰;phÏðæ3º)§ï¤!YG!âPG—a#¯ Òț”ª¨rN‡•3Jcäoö†ì‘Àèÿ-»Aï”ý\ñ1oߪª6…«w—õ#$ïl© ¨ó”Y&à²ëþ-ÈG©3ù)¶£ŸmEz¡÷§cï{Ø©Bª* ™¶é¨PÕ:ôZ Rkš|Ô¢-+ØeYg xP…ÖÚê"%‚-1b„…B9„Û¥ái© +Ðh E YY¤X‰9Õbö׿d¾ÊöLÎ;]̳z¡à•à„lyæ†Éíäanú´7bó½K¾p#×ww¬Œ±že“ >ÂVSÞ$Ð Ü¿d9ޖqCןÞ ) ^Ô“Ÿ‚ò¿ !ãÑÑà§mUüª¿¹Å²¡ªzFtD÷¬¢©RpžÙrk0…›5<€à'‡0f²ƒÙÃ€ÖŽCG‚Æøô 1Žhö×ð‹-1&…ÍÙÜk“wM¼Ì¤µª¬÷]c¯T"ë¬ê^ôÞ&i#G(|J.nÅÁåÝd +Ó2©ž$)S#óœþYµÌˆï¸½tzÍþ #2úœJÎ_™y¬ó—Á?X0Ë®endstream +endobj +2337 0 obj +661 +endobj +2338 0 obj<>>>/Annots 140 0 R>>endobj +2339 0 obj<>stream +xڍ”QoÚ0…ßùWÚ TÃÄ!%DÝ&u-­*u[W¨´¤Ê$xrlf;tüûÙ Éh´BB²Îñ=_®¯ý§ƒÁ³? ¡ÃÄYçë¬3¸‰‡0K­2c˜%Ý8_ë{"–×4%97óî¼×›ý.Aéì=4rÞ'M–´T=ˆv¢^”‘BˆWDÁ™sX{hܚ°‘,™÷.büÈ٩ɕХƕ:õ֒ C fE!)«· ¹ÅmTÛµ À¹¦:Vlm˜Õ×4bŽv¥ê‚*9´DC*U+‚Y3ÓUφÈwùÖÁM`±-ʼ¦ìÞ_~¿mâP±aJŠŒ +¢Yp›v—ûõšÆ,e¶`!¤.cb¬d¢p?ü˜ÞýjÍ»±äL¯æ½bwАkš Ó•ͽ"œ7«vÞ(JÛziÏ2µ±…ŒfRmh-cV€½0³*ÀZýâ ·2b‰'N}ò—dk~d~?0ó<¡ðɱêóZ}©>—wÀÉÏN~6pVÙ.#jl«Ñ?CËl]4܇û_w°ªvüMm7/¹–NžÌ:òìkàþ°û{¼u ðǛAt^/8LÝCÑð«%ìßE?À¯¯öDÄ2abYmkbÚMU$}4<–éí2£Ò³ ûXLÕ!ÙÿÞðÜÎç)î3øAh'㠆 +ôÝ{#ÞÊàŸû(ª†x\¯Ž2T ïe¸¥æ$ÂÐêÏ ððÛm¨8ߋ05joë nÆ»qêãQdKá¸|iàêéa +S™šw§”\*’eTiøFDN¸+ØÇA„0ôCß;ñ\a`q Gíºñ³ó×#èIendstream +endobj +2340 0 obj +650 +endobj +2341 0 obj<>>>/Annots 146 0 R>>endobj +2342 0 obj<>stream +xڍ•ÛnÛ0 †ïóDv“µjúÝtëáfº&½ PŽâxð!“ml?J¶œÀ‰Ó¤‹¿ÈO$Åþ™ Øô‡àêç“oËÉíS8‡å†,GX®gq³«~DEòXÄå:-’ÕluuµüÝJ½Vj¹6 ”ø­ŠÑZm;£ãk?ÛHµ²ÑڌŸv®VÞ3Zz¯áZý6äquuwÒ •ƒ{™4¹(ꪵû€¨ìhÏ h Q ‘Íi;-?ˆ*–é®NËBY—›Ù”’þñú 'µïÛÌ æ†ô'Äz,ìԎãª=½ZçÖëèHA^Ý9)ˆÃRãé o¹`LPÕ²‰ëF +öª‹ +òRT­>‰ºO´okÊWAá‹.Íæ ª sbؕiQ u 5‘‹® Šœ~؉òµ§TAõÍÀ÷xŒk:ºOZÏÐTb ›RjsµqºIiÅo@°„Á4­J‹s?´pzcúÔ¥¬ô©7Ÿ’²ŽÇÏòø/ÊwÙHÿJ‹8kÖ>«ݚàlûµ‹å`{‡Nހ»áÅQ·©û\›ƒEŒ±ï>7_À¤õAl¢&«UV‡ûûîÕû" îæÙ°f÷“âhç‰[½>>>/Annots 152 0 R>>endobj +2345 0 obj<>stream +xڍ“ÍŽÓ0…÷yŠ+±i%êÚ±“8!ÓԁdvݘÄMƒœ¤8ÎÀãc7?TÓ¦T•,Ù÷ôžÏç:¿<ØþD>вÊû”zëm $‚to+!'æ‹¬;¶_D]lU×v‹Ýr™þìu¬×­(F¡S>·¢}C<ýÀ•^š2w{@0âWú:Ånù;ñƒl3]MÙÔ£!£"ºÉÝöZÊ„R ¬¬³¨ÐÝe¦ÓöÜ„ƒx‘ðCÊÚɚL™£+@ˆ9ÃÍQÕÌ}ߔu¦º\Â{ǵÑáЂOúÌB¯N..2—I"%|TmãʛÔÃÛyº…¸åû£ÛÃÌ®ðÀ¦Þo$nÔ¯ôº€i¹ÿç0r/:eÆ\¯Úqn/0úŽç ñ`È)"£Ó[8åp5!lê¬É˺¸É@xˆèááÁ,ÄHzÅÖ¾¢›~HP0P?šv³ónÿGy{”Ò³©3£øö#ã}‰ÑgC¸ì¶Þòá­HÄí§BÉ©1|~~J iöæ·ÐžtShQUR·ðUԝP®ÝаØ>‰UäãÙošEÌÎëTçdÈá›÷ä}2—endstream +endobj +2346 0 obj +452 +endobj +2347 0 obj<>>>/Annots 158 0 R>>endobj +2348 0 obj<>stream +xڍ”ÛnÚ@†ïyŠ‘zUYöd³«T•ÒrÓJiqî"Ë,ƕԇ¶ßYÛ )˜€ˆˆvçߙo̯Š·Q6úŒfK lÁ-¾blÆQ³¯¾†y¼,Y×“Ið³“ÉN6”øVø\…±é¬toäž5ý.’µà£D»µ§—/5¼·ÿôµžÜãÚ>¾/ã&3y]uv³v­‰<•XӌÌñ5^?˜**“}¹µ,‚%ëpøúñR¡Úó(:cRcrL¥Õ€˜iED¯æo_©Û‚ÊèUÌQ‡.ǯ Òâ;ÎU]6QÝ «º€-։\A #ߌܪ‘õö¨¨šmp—”íÈüò”¸ÜÇ-~5¦WíM”l³H” ô»«×âo˜íÓ ãõ.É£´Ùøh1fÎ/Ù}ꇎ³nDÇìîd2 !ώÉ]ϕ1pŸVÅY»Xß[sÁ¬÷ ”‡a»CÚ5àD_Æp¬¤}Çÿ§z0Û°IkWõÁ€Já‘)z9$íC*AØ1ÖhKrv€XäQ±IòøM +¦|<‡Á}Jô5 Çz+Ç2mªÝ›Ü÷q¤„üpºáHo…x4owCàÐÉäõ:8Î[VuùªçþfKÕOԔa«HÚo&øòü´‚U±­ÿ„¸žÊ".Ã,3eß¼ Sëpj· ƒéœ·kKq{)©ý±ÒKëKñ}ôØ<š#endstream +endobj +2349 0 obj +562 +endobj +2350 0 obj<>>>/Annots 164 0 R>>endobj +2351 0 obj<>stream +xڍ•moÓ0Çß÷SœÆ›1/Σ£Ò`í4 ÄX;‰•¦:iPâÛ||Îy¢K›®ªd5¹ÿÝý|¾s~O(Xø£Øàø“O«ÉÕ"À*A‹Ï(¬6Ó¸Ú©/‘Hï¸^O׳ÙêW£rÕ¥cßèžT”òÆjAØm¯ ñœcŒg o-Ô"ì |\ +¥!ÞFފ¨àëÙõA>;4n72­ +.´jìPjìÔ +jŒ„†”莯o¹Še¶ÓY)Œe¾šXÄÂRôË㸠՞g¨ïhˆ‹ä°<"¶©CÂVmÛ®ñéÕuMݖÕ Pfƒ5Z F[m9˜×P& ñ^ÆQÎÉ+˜5€çbÖ꣘ÿ‹ìY5á#וm‰»M˜#êò®̄æt ˜ó­°@iYÅèØpήÙúàLÇ ‚íºaŠÐ5ÙÑ´”²®žÚñ8K2¾éê÷ûe…L(5lx’ ¡E˜¥kP‹ƒ$ߖ÷?`=‹4ÏÔv=ÛsWÕO¥3]i¾ßìüoTìò‘Ñx“‰8¯6ޛ_u»!ۏ-†M›ñz1Cìz "„ Þôåù/Jz‘È‹vºNúwN Éùº6>—KÎá&WåAËÒ¶ ñ(c¸À<¼š‡¼i^¦°ßx”…ûL·<‰ª¼ï£é0¸ßç£ÌOhµ ™ƒ7H›éÔå8€êæ".7™HO2P槇°} ÇðˆŽô<ŠE^acžB°}ßÌ{‹à8~ +£ç™uœ p\J¼žÀ¥¬%@̳ó/µÜ;†ÃXW Ö¶Ñ%eõiÂÂ秇%,ËDÿ‰ðâxe*£¢àRÁ×HTQn‚]R74•À¶Fn&7pñ´j+sÚ +|Ÿü_Îá{endstream +endobj +2352 0 obj +676 +endobj +2353 0 obj<>>>/Annots 170 0 R>>endobj +2354 0 obj<>stream +xڕ•moÚ0Çßó)NÝZ×vHÔmR·oÚ©kè‹IH(2åÚ‰¶}ûَ $-‰ï|÷ËùÇ뀖o–«>«tðe>¸™ú@Æ0¤ÅõÌ×ÃU¹a¶ +g›Åpqy9ÿU9ڕãÈÂÈU®/"ܰʊÁ7Fêè(ېÕ²É%‚‘×ZÝ/¹°,àJý–2Þuk¿â¬h®S&Áâòö‘újïߔ)Ë +QÙ DÙ #¿í£\ˆOÐXn—Ë÷L¬x¼+âNÿ8 +ƒ»Dä'­@ŒºåÜ£&D +ž#¹ºI*q·üùM|LuÏ¢°LŠZ4 =OÍ.“‘x¸?%6)= ‘}®kݧ` Ä$[åëévRÏEVƒA]¬Úúm Ãz6Ç4)ÅöM*gÝ@X–ÛœE/„!=Bëä Ë&Èil9c÷$èèÖ¨NCÝL=£¦ñäHvM÷뾀 Šß¡´O<ßð0Mðfe˜¨p#ÅI`4¦úÀ³Õ¢-9œqÿ$“Uø>ø¼J,§endstream +endobj +2355 0 obj +719 +endobj +2356 0 obj<>>>/Annots 173 0 R>>endobj +2357 0 obj<>stream +xÚuS]o›0}ϯ¸Ò^iq0LÔmR—%Sº~°†¾EŠ<⤞ŒÍŒY÷ógè:B²°Ïñ=‡{¿F<û` >dùès:š­€ ¤G‹D1†ô0Ϊ¢¼¥¥Yi­ôn¼›Lҟ5/¬yÓÀC‘c>•ôÄjԃEúsñ¢Ø—†šªÜǰöP|¡þoÅ»ÉUOÄ_8ò#3•–e†€q‹‡^K`²Ê™¦†+ ™’†rÉå Ì3aE`“$Àœº €BWå +3Í W¢ý˜ŽÎ@KZ?cÐµÍ ²öˆPYViÍ6GªÚSwM7ð…hjõœàù΋­¼øÖ5`«ý£áí—÷ëÛÍ2í\îÆêÍ 10Öw\f¢:0øàZ2s zþÔ ØÇu,ÞÎꗫ!Ô9©yðz½ŠÆ–1¸¥rð*yȳñv vËãW·û6u9áf#`ë’ßáë¼ X`ÛýšÖ%•7êG;ú‹r$¶7Z=†¯»ž ×’ÿ”ÞŸ'Ø·u¶h.͚ ÖZèW›­ãÆ>™#¡ՁåS²…­:šª$Z4ÍíOS•®Ü‡ Û¡)ñ½ÁÀ‡Ä}ӏçM¾þ^]*Íendstream +endobj +2358 0 obj +480 +endobj +2359 0 obj<>>>/Annots 178 0 R>>endobj +2360 0 obj<>stream +xڕ•ÉnÛ0†ï~ŠzIŠ˜µ ) +¸Í‚‚ª±s °í¸ÕVJêòö!饲\»²aDšŸ3Ÿ†?'ßGüpðBú΋чÙèò6Ál‘0æ0ËÎæ]Ý<õíSÝ®ª²y>{>?Ÿ}5Jß(ǞÃBÒ>5b)MԁÄ݀B«²¥Þs‡Åƒ‰ë:{Y¬rùÒÂ[üû¢§‡Þ…¡ìŠ—Ê¬?&§rVKìªçó«½·qZ?QË®eۘxœS<1}OB +žpáj||-›¹Zéü¹™æ`¯7?wàǨÜ“q×g>ð„¹ $LÄ<ò·j7 P¸UëMó-\àPV˜`5™Î¯Éf¯Òô¨ËÐVP`ûÙF'Á½=™Q«5™Ÿ„Æ';Û6@ˆÑ/RAµ«Á­†ë[¡”ø}„ÛO">‘Û¨rGF‘n˜yu…fDdlésFœjžÊ©ÕƒØØ÷5ì£l;UZû®BöŽö=¯ÊE¾š· ,ª®ÌØÀ™0èy›Îy/ñÁy±F8Ó¶kú›»ö%ƒûDÞTð*Ê,— ÊëzU.‰ó>Mí:(E1”¬Ï½‡íÀú?DÞa·‚2ÕÍ/QÔùÉõfUÎó.“ðŽ^í’~Øë{[ÕåÆÑ4Œ¶×Ž¿¯¦Þþê«vF!^4 ¯zc½'Cóô⯠G‡ÞTJ˜`ï÷<Ë­ ñ×Ð!/ Jпæ&7.ìéÕvÇgK:É2º6È`¹ØeÁ¦õ!.èØ‚Q´­sºE{PàVIÙóè –l\ߣ‘ýo zƝlO胋½ „çÇaIO‚H…júÍØÏxyÛ½'>ýkíñOé¦Õ¢ý)p ¥ªZ*QR5ð ÊNä”oL¼Ƒ«‡fÒCq3EÌ lÇçÑλ7Öendstream +endobj +2361 0 obj +713 +endobj +2362 0 obj<>>>/Annots 183 0 R>>endobj +2363 0 obj<>stream +xڍ•moÚ0Çßó)NLšJnœç¨ë$¶•j/ªu…¾S傁ly`NÒnß~g; 4 … Ìý}÷Ëùîò§GÁÀÏ˅EÜû4ë]L ÌVhq} +³åÙ¢ØfwLdüÛ6Ó$›ŸÍƒÙ/-µµtdĕ⇌­¹¶”Fӑ¦0É¥×Ô ~·çÞsXl˜€s&ÖÃÆh^è’"~Lµƒ£z±?æp~^î›.[OdÒÃX¬‹˜'y¦íP*í¾‹© %îÆ¿¿ðl!Bå_Z®g=ƒ˜ðúv¶jÇôÑ5mb ˆ ‚ôCL=‹ÐRmº +wjurv çÒ+ut0ŠLùWd³ ‡,a²ÌwÎÂDþL©€8E‡eZÈp#ÀC?\©;À®¸º€öN³­O\@ºª± ßÔÄÀ„`ÿŽpہ!‰OäÖêƒÜž‡V¤ëfÃ6ÅEä–ì&Ս"GßîÚk›ËŽ)»7óªÊ!¤ñϞK¸£é¶2Éë +æÍ0óAkÇk‡í³ÇIõüÃù9|5ÑáýÑ=åÆQ–¶ºˆ–  –œ›1xv”^Dº/z±†ý^ V°Kãx¹Ô´U¡v†óMâÔñ¨«Ú¶; Qô¼]œ!¨´µ ÀDðf¯t"P7 AÍ`ږ|üÍPž‚qÃóò`Ú±jËrŽ'¢"=▉ߍ\´^Lüò(G-ßY¾¡[>?ÜMaš®ò†“ãN¤kÁ☋ nYR°HúQ| +#Ï4ÞW¶g#¯’ø^™Žï½ÿvÒv’endstream +endobj +2364 0 obj +788 +endobj +2365 0 obj<>>>/Annots 187 0 R>>endobj +2366 0 obj<>stream +xڕUÛNÛ@}ÏWŒè X¼Ž¯¢­J¹TT­DIxCB޳NŒìuºvDùûÎ^lÀY“àD–wçÌÌÙ¹íßƁü§åèûttr aš¡$ˆ(LçûézU߈œ7WyÁî÷憐çiÜñØ!DÞÕɂi©±º¾¡ºàš:$²˜M+^7.ø®¤„‰£ž¼yz:âIÉ>¤ÔäM±E™¼ZñuùP­šÍlq„4ȇÎýÁéFüÜXjŸ‰Åºd¼©µÜJ¥< +Ðx"4¦$Dmܾ`u*re_J.§#‡8˜Ûîuû¼Ѿ¨ëhŒŸ‚ÁĦá˜Pƒv_êthU$ž!ç;hՋ="“4ÅNùPì¦KF•€´HêšJïáyŸ³EÄٙ³F[8k¦¡*ƶP,D¥¨#·Yajvf¦ÐƒÌ|_אªG ±ÇjJ¶”c3îLJ¡IÝدjÞB ¥3™Û ;´ËDˆäyo"Þî¼z7 QŠììœÏ`UérÄD˜'¥h!¶¶ÐKÿ#Eö–5kÁM÷· &§CØš=©:¸¾èb.Qq`BT‚X‹ŽCo@ÈñÜ3?0ä[ûP3>Çu "ãV¯Xšg9›oöw†_j3ç יÂKîiÂyÕÀ¬ s)içèXÏuÔs&á›Uk>‡Ù3®‹MÂÛc(ú¿’º¹”šúá¹ü—”«bàÖú”ó´X#ÏÒÁ‰|‘åWÃÖ¥º9¯‡Sˍ·y!ôQoÍaÈòùiÏ#!¤·£`ðziÜ3yù¶¬êFN¼½#Øk§YÕrù“2•ƒeïýëÌvÿÁÖKmœuµÑTÔô . ”“±„0ÀŽQ߅n’Z,àuc„ñKXÏž²ÒæÞêKÙ6Î(v³?àÍ1Þ°…ǝ›#Us›”ìµgõO}ïå´®+oÍ÷ ’»0è²^·6͝\Emô°lÏÑíçw7˜TYó”à|ºÕB$eÉD ¿¾N +ií˜âUAá8tÕ "¹éQ™2gp€`þŒþk¤àendstream +endobj +2367 0 obj +815 +endobj +2368 0 obj<>>>>>endobj +2369 0 obj<>stream +xڝV[OÛ0~ï¯8b/€ÀĹGݦ±Ó&1OcBiâ¶A¹tŽ#Æ¿ßñ¥¥„„¶K¤(öùÎñçãsñŸ _ + Ži9úN." ÄS”ø!…8ÛOÛEsÅóJ\äkîöïâ t5ðØ±ˆ/¡·M2cZjAd„¶'E¨/8¦ ûì¦uÕHç |RÄøQG ^>ˆYUmy?•Ö6hu–:ü‘‹‚íL®^ˆílZ +=c ÷ÒÝÁø•ãíHªŸòY[²J4Zî¥Rúh½‘Q 6NŸ±&å¹²/%çñÈ"FÅêsýÜÑnä¨íÊoDlà nzÀ4p5hÛ÷øŒVáårž%­†␇9lÅN­¡ØÅsF5‡´HšD­çð‡làrým9+tgÍÔwq +9­B¬‡+Ê&’êbEuO/$Öö<z§«²mˆán¼œhk^ +=ÈËöt¨«¼éaöPO@É6‘BÛþö¤z”å뺵–šo«Á`bƒ@Ár˜pž>>>/Annots 191 0 R>>endobj +2372 0 obj<>stream +xڅ‘QOà Çßù÷¸%ŽB¡”>겚Mª­o{ÁʖÚ*íâח3­šÍj ¸ÿïðF8°08…³nÈUE¢<.¡Ú…¥ÃâyQZ —®ï–Õ ÙT„QÊ0p ט€JTˆ ¤Šò1qP¢âÉ}¿‡(—ÀùÈHRdÔÇ×~mÚÚº›îi»Ø.ga©¦ú‹Æ¥¦ÉŽ¸TP1q.…Ï-}¸5ý°ñ¾óà‰üÑow?ë`²ù¿…ÂÚ!?8;Y8‹r=½U jÂú±(¡ìvûñ +ßí½ië{¸3íÑ8”Zq™…ÏY¥1ڌᦔØ/¿|O>`~jendstream +endobj +2373 0 obj +256 +endobj +2374 0 obj<>>>/Annots 197 0 R>>endobj +2375 0 obj<>stream +xڕTQoÚ0~çWœ´˜Š±‡Äê4©ëÚíeƒT{Aª¢`h¦„0;lýù;ÇJÒN„}ßù¾ûî³Pü08xSHòÁ§h0¹—ÀˆÖ™† ¢Õ0ÙïÌ<6¥Ò·YaÔr¸¢_)rìQ2µØo”‹Ruû6ô§HW6‚Œ’°ód»ñ¨«ÇÞã¿åèºUŒK›|£7û\mKãâ>0f㌠+š a’‘Óqû³2‰NweZlmä.PBQ‹ãÏü ˆѾO‰æK‚:IÂA+Xt€9 Žh^iqBW¢Šš"çˆCØ_Å̗ŽWô¤Àu¦Ô*Ρ, ±ÒWxz ˽™g…îäyRÙ§¢C*;V׉CÐkCÏCׂÛ3;•¤ëT­Î%CvÝ=Çù.»à©wé6Éö+,‹‰;’<}¬}ƙseÛV× !¤#笭^3.”‚›Ì­1±Zy\€G­ïs9j×8ÉgóXó¾|ß©íAéÎz¡ òXÉÓªU‘Ö+ø±ÔTz´x½à0Wñê+~•îeÂ)­vT<êÿ5*¾ÿÇe–>«Ìôrñ{1Á½#³‹\„ßÎå§NKu.LûØáU¯Ux  qrxaýzuÑ+6][±8—¤ÍbržM!ñÙø2T·nf XëòoŒ¯ÃLç¹Ò¾ÅÛ}œÙóÆ.ipÚóˆ@ tB²ºéƒÍÓ qendstream +endobj +2376 0 obj +568 +endobj +2377 0 obj<>>>/Annots 203 0 R>>endobj +2378 0 obj<>stream +xڕ•mOÛ0Çß÷Sœ´7e*Ævž±Mê {ØÆÒ Þ UQë”LyèœTðñw¶“Òæ¡0 $ñï~wþçúwĀâ/ËU«lô9]|ñyÆhq§ ÂõxµÛ–ATVBþڊüaüpvþ1޶q<·(q•ë]m„±Rðk#wš(K©Ã,+x¯œÐÆ(™öåHò +âõ¤åÇ?:dV¬T—‡³Ë÷ÕÆ™Üì2‘W¥±;À˜²;œ°¶‹ò`>#îÆåkQ®d²­’"W–y8¢„bÛöÿ‚¯`OÑÛ±|ìã`DæRÀ¢Ç—Q k1ΖeçÀ[·ßnب +Ê]ÓØx­²ëè+|'©€uÍWH¨ +ؕ‚¼‚É)±ßŒ©{0 õЊ0ª÷]<µZ3]B£ SÛøêîv± f‹p,ƒùìژ›Òǀ՜Øq|ç­-¯•M⿵líÜ{:/ʲ=]{ ªÌËc¥;O‹ +¶JYèÉÀÈÊJŠ(ë)òçÝÍM»I Õ£@‚§¨„(!e!IÎÍY´ôú|Ï4ô:t×ËnŒ¼x³NòB’I…·Ã$óç(Û¦Óà]’¯Ò +äƒÂ¹0™Èã§ú…çÌȾ54ðî²åAi­ |„v•tmÑ ‹…0KË¢£)Vë€3 Í`jáÅ<¤F&-¹Cip昽 ^¥E)š“èM8uQ†MF滨ご´N9U¯è>×DK­ vàÙ~ϐ'I8U}nP,êê4'QÞÿc¹MžEZžd±?h‹Íí=Ù Küv–{º8nL7ìxrZ+z¢àÉáÈtê§A±(wUבD4ÅqKº_¦µÌ˜ícËæÕ_œJû°(âê)ÂQr+‹Œ²LÈ~Dù.JU¼s³éÜãz†û\-Z¾× õþÁ5ÿýåÌendstream +endobj +2379 0 obj +709 +endobj +2380 0 obj<>>>/Annots 209 0 R>>endobj +2381 0 obj<>stream +xڍ•YOÛ@€ßó+FªT…Œ×ñ)h%h¡<´"M‚úÐTÈr6‰+_ݵâ¿wö0$>B%²wfg¾kÿ˜ø%àY0v!J—óÁéuăù +%®O`¾FUÁ§!/)›Òpyƒ?ÊÃÅÑÑüR·•úÉØ4\±áއkª¤&Zh9BTe<^gt)¤¸HLÃïw!Vï™\¾/á>û ë#·ˆp¿‘†Ä^õ´8:kA[0tÁÖUJ³’+¹„¹çNSEh€îÆå/”G,.Ê8τäj>0 ãúò7ý +¶ÚÎ8ÀðÓCt0 +³eâ¸èTi[>Ùі ²5œc +«–«‚ŽÑ‘dÒ¾$›o(¨è/ S(s4.aÅòÔxƒÖ2 ûpZ©ÝA«ъ-ˆT˜Päq&(/‘8PŠ»ŠÊ +Õ䨘¿En8˜\jwÆùµHlOâO)²dºDê,ˆò„”@ž¯¢ˆr>Âe|»º½†œe,gFG婨4*H4MÃôþ¬I†2D¼C‘k(±xA£xÓånQôs]=†i‘ô4ò»8‹’jIá\À*“Ææ“nP‹¨ªÄ|µ4‰3zÖ1^{]DËïS|éoõÐT­‡ D›Õ6‹ø‘&ü—Oëwsƒa þ‡MœPXôd@L$x_Ï•-sO­iÕv°Â +Y ELà#˜g2:p®dÇ74^oJ-9>nùxꘋ»Èyl¬b0Úöqù¯¤|BÙ7ô¡Çäå6û«—çÆÊsÏxQ + Ï[Kt3â ø6IÁcùÉçDubC›­a»û|§y…|NrNëöèôæ»ØèÚqöÁ–,vendstream +endobj +2382 0 obj +802 +endobj +2383 0 obj<>>>/Annots 215 0 R>>endobj +2384 0 obj<>stream +xڕ•ÛnÚ@†ïyŠ‘*UÐÇk|TÒJIš4­B¨¥ŠXƒ+èÚVREy÷ÎÜ€„ÌÎìÌ·³ÿÎþéÐñC`dóï"î]Ìz'×fZl—ÀlÙ_›lâg9eê/Ç፲y>Ì~KwSºtÍæî2E¥UO ‹›Š$ W ]r+]s»SðÑ{&†ïsø€oÃÚlD´·ÍŒh²Ê×óÁic†ÇgŸ³UÓ$ϤÝB¸Ýµ0xͅ{hÎÆáÏ4[°p“‡iÂ-W³ž®é¸ ÿ&_ÀtÑÛ2\ F CÃèžf£0mq&A£ô6lG#o±Ÿ¦‚³t•XrýXLA&⠲ٚ‚,6d9£~ yŠaü%,µ=´º‡{0­ðn¡Œ¦gKɝkÁܤaÂ9ÐáEP¶‡ÒôtÍ<˜RzwR:ZHj¥…2)â„Lxø›ÓŒ¿HÖ¥Ÿûeq÷ ’ƒ‰Åo« +^%lš{Bó‚%JÀ¥F¸À.~¡…”¡SšÀÕí5§Œ¥²êµS"kSS;ïµD»›KÉÕɳjý¸(!GÌlCaâ©ÝRo7ÔՓo¢Žõ.LQ±¤pÆÉNdHmýIµƒHi¢þší# +zÚÒÙ^{˜zx+Û可Š+ùRwÝnpꑇå§K<ãW}‚¦i5þÇuQ˜×Ê#ÒÍysÂ{™|>›Q ÷Üè¥ÍÊcÞç5 ŸŠêÀ™Z’ÆßÐpµÎ•å訑๥k·+F «V_ÍqÁ¥;¦ì+æPý|‹²Êþšå¥6òÒqL)…ó(K‡˜¨s‰À21H îå'Þ#y(kÞlՃhYõ«ñ2J3ZžÖl®Í›«LGl רžOWù\q%¨DC‹n@Un74Ù ÀÛ) —”«ï$P”‡#TeºÄÀRX%ÈÈs5o¾ã sºÍьÙîԅÉEˆ¥;ˆ*þt + ©ØÂvÃl"œ\»JQÄôpkìòւ˻ñ¦i?úxKŒYºb~S–Á7?)üˆÇ;–“ŽC\jžÉG¶‹!ô}Í—ý½÷JA¨Õendstream +endobj +2385 0 obj +840 +endobj +2386 0 obj<>>>/Annots 221 0 R>>endobj +2387 0 obj<>stream +xڕ•moÚ0Çßó)Nš4ѕºvBžÔnRÛ­ë‹Mc@µcª¢` SH2;¨¦}÷B!è@B‰ï|÷óùþǯŠ_®ɲs=îœßFÀÏÐ⇠ÆÓn²*å0–ßDZñ;O¹˜t'''ãŸÆ¿oüÏ\J|µã^Æsn¬"ktm/Þn€ý\žâe™í‘í«4O²Õ”Ã¥‚;7!ÉâU£ÃLâ-îŠ1Ks~Ñ¢÷gaۏÒ÷!ǵ–ÍCÓµ-,bQÇ,Ó'žÉï!‹œÍ „ÿžÊ«¹¯·ÈƦY!`ÒU§„·@/ôyáÒBòާóEe-§§æ"7@þì µ]43Ô6àúdγ·™ôú7öƀ‹O˜ôºNñwÏqW™,vÔÆ¬€ðû/@Í,!tՄÐ/™ÑOÃ_ÌaS3Œ…èºU盬¼îíք¡¯„m32ßS´=%µ)C5rÖ¹z ¾¶ñ¥äùA0ÂÖNÈÖEØ Q“¾œbˆw·­õV â­Y܈/ÿ7IÝ^¶Ywbv{‡[„öñ/ '¿gßööˆr÷ZôwŒáü6´½Åú^Ït¸¹Œ`T̪Çû@s/—\Høç«8SÑÎ̖³À¡Gg.þ j´_äÙcíü"ƒc@endstream +endobj +2388 0 obj +775 +endobj +2389 0 obj<>>>/Annots 227 0 R>>endobj +2390 0 obj<>stream +xڕ–moÚ0€¿ó+Nš4ѕºqțÕnRÛµë‡Mc@µcªR0)/Ì1j§iÿ}g;i!$ßùîñ½…ß +~(ô=õ&Ëqçô†õaõ*¡ö*½Àt +x·Òæ^¹5æéB.'Gg;Ç´™Ú~!넧27r(UrjY„Vu” +e”ø¸—?ò|*¢•Œ²TI®Ç‹X˜‹çÛð8j»v€¬Ô¥h’2bƒà0ªQ¦Œ¡žÑ¶ûq7´uR‚ε”Uêš`<5™¶¯ÉÆK&ސKÁÃd*%ø@öÀZ Ó0¬Ö®ÕˆóL)™ÔÕPjÌB>#îás˜EœƒùŒv#Ÿï£QL•Ôð¥ë䣘ÍááäùÁ>E_Cjíڌ¿Ô«ãhÒ!—k‘ÕZփªf¿ YñJž’š0‡¯Ô±êöŠÙ=³£ÄèšØ`”#_ñi4°·snWf3ÖõS˜¬â†ô&J§ñzÆá\±“dù¡65u¥rw6ÄQÊÏj&×ˈ*.5©Ú—<œi}óPUÝ_Åe:áG@™ý³ºRá¯þVû™¨ŽïÁ[ãµm›æ™€IWރu¦Ï ç$Q&oy´XÊBr|lò¸òwgÆî¢4T…†+fõ¦ÓKU.>£ÓèÒÅ¿†ù<â.â<Ûé7Z´þ€ÀǦI ècåèçØôOE[,`³g‚5·‚|g9/ëºÖ[àážÂõ\ E½?«ð¨1S:ê>ôÔÁ×O[¨¯fJA`´<}#AAy8ÂSVZ ˆ¡pK>£{C°¯ÅØ4»&»½Ö²ð¼až¨u¡4Ö*»- ×pz”†yñm®î#esùâ,ˆl!Â$á"‡/aºceíÄl9ñmý¶ažZì{̼|ZG.žø[ç?žendstream +endobj +2391 0 obj +792 +endobj +2392 0 obj<>>>/Annots 230 0 R>>endobj +2393 0 obj<>stream +xڍTÁŽÚ0½ó£í…­ ÄI ¤ÛVÚ¶ìžZQ=!UÞd®›Ú¶_; , ª,â7~óæyÆ¿;|û#Ž +;ŸÒÎà!CZXd4&æÝl»ÑsT;TËîòö6ýUEuP?ô½‘ [hºÂõ!iÀ`X1H¡ dkªà­‹°ñ½q›|'Y¾¼½;Ë$.r†f«„®Ñ9 ±Cïa#™0¨ÀH0k„ ºåtE‚–è]`ö"wú êL±aR*hñ_2á ¢ ªÖôT@j“ `´‘ +s`ÂRhC ˀˌ9ÃB/pB¨ÈaÏ8‡'i)öŠƒÂî™5 Ýøµ°ðº”–àêÕ^¤ç²­ÀmU%Vd¡dYWHÎ垉ÕQ«~çhí¥وWɨX[z>/¦óŸóÉìÇdÖöŎ))JvT1úı×2"¸Î\WùÍzÛ&ΙÂ̰:«Íñ$=zęÍéن-ÚG v®!<Ñpðl-µéÁ³„»ÿ7­¶ëWö47y¦å†_›7Ld|›#¼wW7p‹·þØHH=v§³U_×]+¢¹Äðº®ÍÙž¤ßóí+áâ–Ù£û€`8´”0{aóÁaîV¼ZÁi—ÃQíœÓòˆfJµÞK•:òb„œd$ar=¥ß¤½áK®^uIçÂ* ý2çDƒ‡q£}ZÊȮճ®ya. ³§ +aªäJѲD¥á+[Ê]ŸD‰G þå'$Š#KWIܔÿ½óiŸŒ endstream +endobj +2394 0 obj +601 +endobj +2395 0 obj<>>>>>endobj +2396 0 obj<>stream +xڍTMoÛ0 ½çWØ%GrœØF‡ÛÚ;ÈR÷´ì :²£!¶R¤þL(üQX®Í›“/Édq !ÉгŽ($ûizªê„Õ¥8òÝt7›%¿,p°ù’xk¼©YΝ—@Ü8ý•Íq` +Þš(ñ¢ç‰$Ãÿ%+ø‡?¢Ô€°\v³³gtüØ|Vù©à¥®”xñb4¦^ˆÑh>çuªD¥…,ç"™ RÝgû ‚Ñ«eŒ…Sbʧ±çƒâp=¦Aì-´Åy„¶’ ¹1Yýµ“³•ÂÒ³‡XzɁƒÑŠ¥š+¨µeZÂA÷ Ñ©QR©˜z€6ƒ÷J>ñ‚·×aÑ#u8ö$D/Òtýá^‹df©¶Û2D ·š×¯&Ï}3a‹¾Ÿš ´¬·\ŸTÙÌLÛ3S¡¨$Îʎz·ƒî0OºÕ‡N½‘ñt ƬOÕ7¾x]jÈyÉC¹€42©¬È.Œµa‹;¦º¨†ÙöBñTKÌÐÄõ†ºâ©ÈßcwÚ½\¢È±? S"¹ÚœßÓóòN(Yš}d Øí‘¿,ÎÅ=+ªã —É;Q¦ÇӞÃG£ÐÂ|¼Ã§†˜OÝöØë¤Õâ§¿Zÿ:"žÈÛ]>>>/Annots 233 0 R>>endobj +2399 0 obj<>stream +xÚuSێ›0}ç+FêKR5@ÛVÚv/ª´­Ò…¼åÅ'q6µÍf÷ïk²¹ɒufÎe<üó0øæÃΡ¨½o¹7}Hǐ¯ 2O0äå¨hµTT®F«ñ8ÿەD]É$ôÑÜ-ÙÐõ!íÁ`æúWŠ-‘ðÑVû(9¥~¬\oüAj랩n%WÆ{4¶è-4‚qM%hzK¡h¥¤\Ck¨9©) {o]ïè×òéé”nlíºmü¸¦ å%]3NKtÁЬøU…df‚ŸJ¼ÛÎï )»`N×9%J‰‚MKØ1½ıƈ2}¶èϛ+9K·1´fž՛ҴÞ?CˆçTÕõ„÷¯¤nª+ûñ¢jK +ŸmÌ©=ÐökÏàn9Ž7À†¸9Ã]°/p<¨k›Q +·•¾Ï=ùf‡ííñüh/†‘±^C’ °¿TÙõ>«—8Þ§0œu‘­“Gªæ5vB¾ò¢`Šq›‘^‘ô{Éd†f­Oîñ†Æœ‰ŒÊ—Ãæ ©¦Iï~ZÒ$ê& +ߗ‹ 2±Ö;"),¤ØHR×T*øIxK*K7ÁQŠ0LâÀ¿´§Q™¿ÔAiÚÇÿíýҕ2endstream +endobj +2400 0 obj +481 +endobj +2401 0 obj<>>>/Annots 236 0 R>>endobj +2402 0 obj<>stream +xڍT]oÚ0}çW\m/0Ajç;ڇÔvÝö2©éÒä^;‹vû÷³ã(M« +pîñ½çŸë? È|0D©ýVõ䢜œ})gPnL$Í1”ëéNëæ‚ËꎉíjºšÍÊß;Ø"BAj7Šl©‹"(†`˜ØÐ½dkxœÈ®~ixgçÀ„†[{Z",l–óvÛÕThåâ `lãIdêŸ@,8ÈÌnóú3UUËͤ°‘«r‚dºß?~~…87è$ÅAIa +󯥰Áb”îÁQ„MýºW1öܐřԡ—ÒÖOrG«ÜQøV–×PI!hõ +zqh˜½–^¡çH9Á¼èÇ´° hÃí@ ÔNv| ·„ ¿knìc°Lŏ3¾ÐIù«;éÁ£BL‰óáÉaÃ)óº{£ºÐ3.÷;§°éÄ ÕªÇ÷ µ\SØÈ¶{rœ\üƒ5ݐŽë>fó8rŽ8 <0Î]VXM•–ÍjæN3ãhhZ¹mI ÐŒÃšhL¹'Œ“[NÁ¨ˆ°' ,\Ë~³¢í=mƒ‘‰ +bKàê/©þÌØ¾e¢âéîCÕ5êÌjì> -„ØÉ}<ÈïGbð±ŸüK×éjúÆQz3‡F¶z5ó{02güä¾q×`#—Â’R8çJ>±,döYCfÍãÜ9èßná` +»o^îhuç1Z(˼¯„Ó((ž+…ö¥¼Á²Ð6T›÷Þ|‰Øô‘ ŽÒXöÜgOƒb§\Þ\/a)7ú˜1ºv®ªi«à;á6ÙDžif‘…ý…€²oc3{Ã16.F”“ÿù¨¬ìendstream +endobj +2403 0 obj +641 +endobj +2404 0 obj<>>>/Annots 241 0 R>>endobj +2405 0 obj<>stream +xڕUïoÚ0ýÎ_qÒ¾ÀT\Ûä§:Mj»®û2‰Aú iŠ‚¬Äa‰Q7Uûßw'І€@H`çžïÞ½{¿{8~øF$Yï.ê] Aø-0â¢yeÌæ~¥’çY6D¿,Ʊ˜áˆ3POe¼T6Ê!¬ƒÒ¥Pª ¼IB˟>ÒïlpsQ†tè¶Xn3¥Miã.AqÁ¶1¡`>ÇÇ_T™鯤¹¦ÈCÔãŒc«»¯É#8¢]O0 £µqY(˜v€¥ð™S£¥äH`®4sjv.§¬˜[6ÂUÔªµh¥à[!ɵVÉÉøù+t'ŽÀ®pX@d&Êl ] Ü´@ð)Ê!]€Y)L‘– s˜Ç&†ÒóT/¯Ð69_ÒR±Ž"™ÃItT!AרP—ßšc}Xlu¥$„(ÁäP*õŽj¬ÿ¾ã +ˆŽu[öã¤þÄÙf}ÄËR¬·sŸ’í¦¼&®lõ™°ö.¼uøM+†LgýÖm˜ l£ÜÎæµµ`ŒÁ»Í3eVÔ>hþ¹KSTèv]æVµ{8¹Æq°ÿ Âp·Y[ó´ðÅöÓ"¨ku£NîÖyòŒäšÑuV }´gSN#´ö‘z|W¯q@(·+yUyç?+µúIR" ûÒ°’®»ÛÁªiâ2ZÊ”'9Iï´É`$½K”jZ¸ŒÓDÅó†SWö £ç<&Àñkk¸Oaš/ÌKŒ×p\äË"Î2U”ð=ÖÛxM ‡Â ñÐЗ¼óÅÙ¿(µ,?zÿéö¥§endstream +endobj +2406 0 obj +606 +endobj +2407 0 obj<>>>/Annots 245 0 R>>endobj +2408 0 obj<>stream +xڕSÛnÚ@}÷WŒÔ¨Êfg}ÁV¢J)MҗH´vސ"Ë,—ÊâKÛÏïÌچ +ìˆ +öΙ™3gξY’>¶Çß$³¾DÖÍc8‡hCÏGˆÖ“]]©ŽËǽN×Õj²šN£Ÿ-Òi‘3[ +±/U¼ÕmTBЕˡ_Å~ µøàµ†ü?PWœz_n›LçuÕÆ]@ä8J_ç†`€bNétüUWI¹?Ôû"çÈCdI!iìãϏ'p|B» +èñ3ôXjÀ +çÂéÐJI"pBýœŽ+¹*ÕV½ˆ†ši`¨E; ߢh I‘ç:¹‚¢£„¼ž¢AR< ì¢#üNcðæ=Ý~³mhÜ}ò6Mn&ƒ„qÄiÚ]ê·FW5lL*lŠêKAĀ#h6¢óð'Îéˆ×>ìó$mÖî’æPÝ0O±ûÌX†`ëÕ­w;»ðéjz;bÐPk¸O«âbØ­„^À¶mÚB¢ ڗ´ÝȾÜÂIdÎsNZ´ÒôR6#÷ÛÇnèÛd—‘vòخߘï’Ž?™¿GϐzÒµÑé]Vè³ {ZÊg¥¯¦ÕOñ¼Â3^Cü.aFµ‰™Ÿ:ÀâeBXlêß1]œeYlË8Ë4Yø9Λ8åz3t0›+s¡Q*>u¤Û_ñ‘ Bú|·þX“aendstream +endobj +2409 0 obj +518 +endobj +2410 0 obj<>>>/Annots 247 0 R>>endobj +2411 0 obj<>stream +xڍSÛJÃ@}ÏW øÒ +]w6›Š õö"Tß +ÒíEr©¹¨ŸïN61¥MAÍ&çÌä̙ÓO ë Á`»§Ömh]<€„+¸>B¸mªj7MòR-F‹ñ8ü0i8›3—Xoe´Vå´ púÊ·KØëBÇ÷ +Îé¾_µUÝë:UYUÜD‘û,8ädž.ׯïTÛ]µÍ3BîC‹3®gýûy}ék¶ã"€.1ÐÇBÁ|€,Ðc²e Áµ€žÝ˜&[u§®º·èœk¤5h¤…Oa8ƒ8Ï2ÿC¢Œÿ_bÔØì dþ€Oý´¯“Û-Õ@CqèÊF°ª³f&ˆ‰QB”A¤_| Ͷ®õëOÞÿDé.9¥³m'õRÁU\ïÊ ÒÂ6×Ä% +š(îçërۋáéøÍ•‚›¤Ì¶ƒ­áúlÛÖ§­Ý<$Æï~±†ÞBª“}B¦Æ”Î΃Õ6•~~0ÛwÌþ`ú6›Ã<_Uߑ^ô¬È×E”¦ª(á9Êê(¡~S4ñü7Ë>œÈívÜëƪ Sendstream +endobj +2412 0 obj +436 +endobj +2413 0 obj<>>>/Annots 254 0 R>>endobj +2414 0 obj<>stream +xڕU]o›0}ϯ¸Ò^Ú©¡¶ÔmR×uR7e Õ^*Mœ„ ³Í¶Ÿ¿k’´%i¢ |ï=÷øØþ=¢@ðGa25OVÞ'£ó1Ð’F¦…$?YiÝ\ÕBðLߟܟž&¿Êw¨ñ„xSƒ»S钻(¸ ² OñSÃëG©²Z( Ù*•¨•iÅÏ šZêûӋg•Xl’]Êe[q¡•‹@©‰‡S=…©âlþÀU&‹Fµ0‘ëdD<‚¬ÿn?!:˜RLFÉÄ󁯸*9ÌÀ4`íÐ,26h+¦ß‘ ˆÉй™•£ëÖÒ³E,½dÅÁ C-áË Ò<—\)¨ 1¢¸üÃ%è2§ ¾¾Ð…Ï>>>/Annots 256 0 R>>endobj +2417 0 obj<>stream +xڍ”]oÓ0†ïó+ŽÄM‹ÖÌöœ/ ! V¸BkvE§)$nj”8Áv?;NVš¦ZU©j}^?>ç=þía@æƒ!"pB^{ŸRïúK8‚tg"aŒ!-{­Û{–7 év±].Ó_NFluƒüÐ +ŸTV2E AØP¾Ï$¼?Îä֚N_AÞ¥Á-p±]ޞœA›æN–]̈́V.Æ6Ž15•àû‘Ùn–ï™Ê%o5o„¬SùÈÜÿõëñ+ÐØ¨ƒûpl'æ§d°™rP”€ƒº/$èdu&7±æ¾=YŒWºg`ÖÚNƒÒ’‹ò :J,×¥t½z†Î1¹‚qqÄÅÅ<„øñå<½z¶Z‡^Ó$p~zdº“bèõXM녨ï3´ šIÐ h]ôÎ*lÆB>qÂLj[‚ÑÇ.tfƝ Øu"· +üÌ[…˜øŸk¤m$/¹Èª7q׳º­ÎÌÕ;.òª+|È»V][JÿÑj­»:ös5P¼¸ã~ x¾t™¦Œº‘kN8&<.ÆdÇÕä¨óÓ¼a î*՜8 ¦±¦"44t5$ÉëŸÊyf¢—%úe¥‘»•…]‹ãÎMüÙoÇDŽ&>7¯ðùéa›f§ÿdÆ­²)eV×L*ø–‰.«l¾•Û´Š:÷bÒ0Ÿ"Œ‚áÊß½Noéendstream +endobj +2418 0 obj +535 +endobj +2419 0 obj<>>>/Annots 260 0 R>>endobj +2420 0 obj<>stream +xڕTaoÚ0ýί8u_Ú +‚m’¨Ó¤®¥Û¤Mb¾Uš¢` SâPÛY§ýúÝŪ:&1¹ç»çwïüÔãÀðÃa4¦oVö>&½áC <„d…‘qÄ!Y^n¬ÝÞËBZùxùxu•üt ߁#æ ¶0éZº(ƒx…reáeZÿ°pMÏ>d•2²MªáºÖùãÕÍQ Sš[½®K©¬qñ8§8g‘¿Æ„ÇÜ q;¾¾—&ÓùÖæ•¢È$é1áé÷?³OàGˆÆÜÀÇ´æ1.µ„yXðÐówh!8 ý»€QVÌ-Z-jM†Z²‘ð9I¦¤ƒ’Ù}á±ó)6芎˜S eï`µ˜}[Á²éÚ?8 áEçsjН²šîǁ3ÖLÚZ«]Ó[YÉ!ET +LeҘ>¨J þH]ÑËUšµ–^‡›Ã±):’“ +­¥]¨sÚ}—°ªUÓA0R- ¤®³÷“¯“d‚§|ª%Z5µ˜ØHýKêÓô&¿Ór[œ©w¹ÊŠz)á}Vo͐Xy›„%wʽœ³›ŽØËyìÃÅÐT¥¢.NÏà\J¸-Lud¾ë0#·!)!x÷§p ~…×k8HKû¢¹;7­ÊÅpÀGûj<¡ûN”cûrm³¢€<ØVì7}~‹^Cj.íC.‹å›¬xDžni  +ÿ|Zí)þ×b»LŽìÊíàƒ‘™}¼¸“ÁÝb:‡yµ²Ï)NáTWk–¥Ô¾¥ªN Ê7à~ìq„¢¹8Ó[¸Ûâx(P˜ï½¿®s•endstream +endobj +2421 0 obj +610 +endobj +2422 0 obj<>>>/Annots 262 0 R>>endobj +2423 0 obj<>stream +xڍ”]o›0†ïùGÚM25Ôv͗:MêÖlW“º†^-UåC˜À0Ûhûùµ14 +!j„‘s^ŸóÚ= È<"7!dµ÷%õ®¿%€#Hw&ÆÒ|±×º]‹¬ÉyH·‹ír™þq2êd«ä‡Vø¤XÁ]A2$I`SٞIøx\ÉŚN_AÖ¥ÁJ±]ޞ|ƒ$¶Ì,ºš ­\>Œmcj&+Á ö#³Ü„ï¹ÊdÙê²6³N=ä#³ÿ·ŸÇï@c£BìÀ± N̫䰙rP”€ƒºo$èdu¦6±f¿=YŒWºç`bm§AiYŠâ:J,×¥t½z†Î1¹†•â¨óâǗóôêÙnfM“Àùé‘ëNŠaÖc7­¢~ÎÐ6¥Ð\‚n@hÞ;+°ý ùtÆ 3¥m F»Ô™C0®\À®™­9·" ~3ÅW!p´,‹R°ê]ÜõV·Õ™sõ¡YÕå>e]«®-¥¿ÿlµV‚]ûs5P¼¸Ïý"Að|;è02Cu#לp,x܌ãÊWÓ +çOó†s¸«Tsâ0<˜ÆšŠÐÐÐՐ$o*癉^p˜—•FnWöžOnâÏ~i<^&4ñ1Ј¸ó +_Ÿ6°ivú3n}M!Y]s©à«l½•[´Š:wcÒ0¯"Œ¢aË?½W²Ëpendstream +endobj +2424 0 obj +534 +endobj +2425 0 obj<>>>/Annots 264 0 R>>endobj +2426 0 obj<>stream +xڍT]‹Û0|÷¯XèKRˆNrä/®®×´})ä.¾·@1Ž»Ør*Ë\¡ô¿wײ/‡“”#&–5³òìì®y8þ,CºòÚû”z7_¤{DÂX@º›ÖWÆ4f;ÛÎçéOǑ޳Xrë©ÍÊ¡’ô‚JmáÕ!´üaá=Ý·óÛ³ý„‚îÌ¡«•¶­Ã‚pÁc–L9D‰`†ãögÕæ¦<ڲф¬R3Ž©¾ü=~#;óA„´ .‚Ͳ/"&¶ïspb÷žÉA]ÀéT<ۍë¥õ/襥…‚oiº†¼ÑZåo(}Æß.±g_”x28’Å$æQÙÎèÁà1*@4J­²Ö‚¢²-2 Mžwƨà‡rºà"k_Pv¡¤(î¼2WÞ:v‘ƒ.õß6ƒ}§{1Ó>Ôù?ÙºÇ'¸®wõ;«Õ•¶~Wê¼êv +>äݱ½!™¬øH\¢7¯›ýv‚¡ÛÙd0¶s—#Òweú3y`ŒA[4ϐé!ÍZµ4„LدÌ×F)¸«Úæ¬ýÄÐQœ:IJ4¢†ÄǛ{¨\CMøæ§ŠQ\à ¤”îÑcõ&½ÛGÆãt˄ ‘tÁýÓz›foŸ3ìäµi&«keZøžé.«è¼… ZD~?aø ]¹ qøÅï¦ûàý|™NÉendstream +endobj +2427 0 obj +522 +endobj +2428 0 obj<>>>/Annots 266 0 R>>endobj +2429 0 obj<>stream +xڍSÛnœ0}ç+FêËnÔulsµEJÓMúRu[ÈÛJ‘Å– 1ÐËßׯV"EHØæœÎÌ¿8°~„ÜÒÊù’8—÷ HI¦‘ "VÇ®kî˾=îWûõ:y¶Ïr6.Fa=¶<ÅÀFúú]8Éb¶O\˜u¿¾z“’2u«ò¾²k-î!'8Bìœc(„êpýù«hSU4]QKƒl#¬k}}ýz/Òl? ˆ ̞0½Uâ2%!òF6¥X ˜ÙCÓ¼QMV›N¤ ?¤%Gߒdi-¥H? Ñ£\âÀ^”87Ø'Šú4—a†Nr§¡ZhÉSØ +²^5Af¢.ÿi /d!s8ðŽC)²2UWÀáa›@­`÷#Ök#7ÁhÁº6-gû—WMùŽÍ>2-ûƒ€ë´oÚK£o ×Pˆµé©÷®°‹¾oÍX¸-ÛúÍäÈ8 }×uuÿ+`Tk·‡ÒÎ⌯r˜Ûkâ¼Ù=wÖ%S«ÏÆ>D¾6ÿ³UMÅcˆ€ùvÖp÷¸‹!®³îצة:W¼ª„já;—=/MôÆmBŠo¾7™`6–ÿÓùD-©endstream +endobj +2430 0 obj +474 +endobj +2431 0 obj<>>>/Annots 270 0 R>>endobj +2432 0 obj<>stream +xڕUQoÚ0~çWœº¨ Ø&D&uíö0‰AxCš¢` SâPÛÙªýúÝŦ:&ßç»Ïß}ž;¾8ŒÆôN‹ÎǸ3|Œ€O Þ`drˆ×ݝµû'iWÝU¯ÿpß!#æ ³4ÉVº(ƒè…2eᘂß-ÜÒwÒR é.Ñp[élÕ»;+ "Êq¯·U!•5.çç,ô¢×‚ðˆ{<ŽÛŸ¤Iu¶·Y©(2;ÌcxïãÇü üÑÁ˜{ø˜Ö<Â¥–°h >ñüZ†NèZ@ÿÀ.`”s‹FŚZ] ¦ï$|Žãé dzE_xìzŠ5º…¢#æTCÙ[X-ç_À–°•ö„„ðÂë ÕèVÍN÷£ÀYj.m¥Õ¡ã¦äˆ E” +L•¦Ò˜>¨R ~K]Òæ&ÉòJK¯ÅJÈáÜ-ÉI‚ÆÌ.t>Í¡.l*U÷ŒTk‰ëéÓ4Æû=WŽRZLi¤þ)õebӗ¤ØçÆè]¦Ò¼ZKxŸV{3$>Þîa f×]Kì8ƒ}¸š²CìÿÍå¹[H ÷¹)Ï\Àeä°`‚ +ˆ^ÃýÈ]__áõNŠÒ¹ðÄìÁ@£ok1êѱGhº 娱\Ó¦0 ë5ûu{ߢW“ZHû˜É|ý&+’•ZgÁ¿žVs‹ÿãµÜ¯+VmùÃ|0ò1³«Úað°œ-`Qn쯇o¦Ë­NŠBj_U%9åp?ò8 &¢~pÎh×÷G˜‰µü! *ß:sX€endstream +endobj +2433 0 obj +604 +endobj +2434 0 obj<>>>/Annots 273 0 R>>endobj +2435 0 obj<>stream +xڕUmoÓ0þÞ_q_V´yv’æECHcŒ1i ±¦Ÿ(BYâ´A‰Ó9Û@üw|v²V]:ŠªVuî¹»çÎÏ]îF ¨þ0p}H«Ñ»xtü!@œk‹2ˆ³ƒ¥R« ®šùÁ|<ŽXˆg!G.%>‚fM²àÖJ!êŒÎMé2‘ðzŞËBðC(„‚’‹…Z"¾+‹ÈäDìT.ڊ ÕXûC{@I´ A‹ ´·~üž7©,Vª¨ZÎã%T7àéçæ¼P£'>#DŽ.ŒEúŸä0À2·;Q@èÚ4Òë¸M(Õ¡¤uc~ß‹—% ±UC^”%Üj rYW 4æc_CZ ÁÓ=ŠðÍhß" x KݶÕ^ÓsêUòPTmÕ]#Ô¹!k úGÇ!áÞ x'Gik'Öçÿ¯uÔÕ¾ûÒ2àÁû_k× |â!—®Z):íöú@mF¸°ªõ@p‰:X7j ŸgWWPä j+Š´nË n¹N§1ü'ÏÈÀÀؤ[ÂHŒ-êgך†¾÷:€¼¦P4Ð6Ó[z²+}JÖ -œè:»|‡FŸ/Q3”f«,Q¼g4<ìྋÃëùÃÙìz +Ó:W÷‰ßk+µŠË>%¢MJ vļˆ08 +:ôRôü°Ñ0ƺ~|ý0éendstream +endobj +2436 0 obj +717 +endobj +2437 0 obj<>>>/Annots 275 0 R>>endobj +2438 0 obj<>stream +xڍSێÓ0}ïWŒÄKŠT7Î¥MBZØeAZVe›JÒª›Â*Q“fΌϙ9ó8¡à›‹B¸À;¯'ï³Éüc +t Ya"‹„B¶óöZw·\_3Í×ZЦÜzÛé4û鰑ÃÎBŸ,½Q¬ä.êC:ƒCyÛ( ùžIx=RT‹š׀‘úAŠ%®dÙ×¼ÑÊÅc ãÔIzŽAM)Yštóùš«\ŠN‹¶ÁÈM6ñ‰oð÷çá¢Ä ã%Ð81‚hj^%‡õ8ð—$ÐAH‰‚¶Œv±UMíy >KÍ`©e{›ûÏß`gÚ1G<±ªçÿáxæKyZô(Ïc—c‘=pÝËfèòANai; ]+Í%è(Í´ÈÍçfʚ‰_µÑõ)ËV'ºPÑJUÏE!øÎé?J'# ÑÈGèa;t¡yøîAÑ79–…’7\¨2âžQW½ÐìGÅ­«NòǞ+­ m Ë.4tó~±°›ß¬îª »óJ4yÕï8¼ÍûNÍQÙ¿Ž +¨Û½®×jë]X­­w¿¹»ÛNñzsa½ÖœÃU¥ÚgÆ£ƒ—|ôPeµi[bÌâþUÎKg ²„ã 0qáZrÂ0³ÌÜ,άk³“ÆG)¡…¡ó'|جְn ý‹#¯d[JV×\*øÂšžUXoæ’fËÀn¥~ SzØ»‹®0Ú¿NþåRbgendstream +endobj +2439 0 obj +562 +endobj +2440 0 obj<>>>/Annots 277 0 R>>endobj +2441 0 obj<>stream +xڍTkkÛ@ü®_±¸ìËw§wZ +i“¸-¤¸ÑúAP„|–UôpO§¤?¿·zØÅ–Û ’fv5;;Ò/ƒÑåBR¸±¸€zÀ·q} +|3Ý)µ_ +u+Á³BDÓh6ã?;¦Ý1ç1]ä®ë8J èAæ ¤tígݒª¬$»X›~:ҝØàF¦M!JUw¸”"N‰¥ß}ÂA + ¨éérýøVԉÌö*«JDî¸AL¢‡?œ—`ûší¸Ôd@ßÔÆúR +GȌ¸6³¨pd·.Ú½:‡ O÷f¨çk¥9~'Œï|â|ˆ,Ð"¨•ÌÊô?2m†_*³eÊ<šìPÛôQÒ£P,{“‡1p ^k0¬¿~þ­Ò§8o„9²-Ó1}¤N?„¥ƒ.‡m(žÂ¶)l +:9OBªâqAUz±Þ»ßq±Ï/¤÷UV&y³ð.iöõeš»÷ÈE +íÒ¿×oUÛh:y½‰¢rruöɽ̮À"ð¥)…^^eז}í¸°|à“hÍÞ^È(Üäuu Úo›à–_OSµØá.ï¶}R S8úŽÔކ¿4‡­ÃNâÕÖûÃGh&›õ¿ø¸^…V[õë°­d•ʸ(„¬á!.›8Ç~ó®hî1òßŒíúÃWL©ÕÏþÍøú“:®endstream +endobj +2442 0 obj +521 +endobj +2443 0 obj<>>>/Annots 280 0 R>>endobj +2444 0 obj<>stream +xڍTmoÚ0þί8u_`‚`‡$$ê:©£ÐUÚ+áÃ$$™ò6Çi÷ów¶è ©lßswïžóŸ‚ +#G~äóÅï gÐ1ø;´8.Û=‘?21‹X¼]w×½žÿ[Ã, ŒˆáHàªöL[ x•Ñ´¥)ÌÒB@x8|ü?žÜm„>íƒÚí¤ÏÔÿºw{‘ÐôdÌ{¾/–ŠBÛm TÚ)q ï#!Ô£ÆÝñø!re©´Lý1ãøóü–‹hÛ¡† ԑkêá’3X6€M:6¬ +mš œÐªªVÅÎ&2*Æ6ëÒ*j*¢æ|õý`ÉR^AÑ2 r=E…n ¨‰éª©Â·ñ:ß¡dš†{=%…n¬Ú©ç–gk‘=3Qò´êy]U©‰±ê7äY” +ÆAd ²b /A\2(Ò½Ñ 'dq©Š†ð²µÀµ©e:jÏ.ìÊT5o¥ˆ+VaÉ9ª²âµË¸:-rFHxû¦Ðíl§ƒ$[æíC”†q¹eð),ób(I‡Ï+!T—òíèÝ6ØðZz>ûp3,²„ KÝT‰XJ°oˆ}=D1 ]åÛ@0½^÷àîNÝe3ù1÷Ÿæ«éɹN”—¢Xw/߄¾vœ=M¿=(÷éÜßø¿¢ýIX2÷q‘]ȓVŠ#Jü6Š,ÏÄBêM¬w†ç{85Zú9§©èé¬;ޘ ߛÑ1uG8 -éÈ1]-×V3Qeì+Õ½GO‘Zžé°)[98#$gy#ÝB˜¬KXf;ñàø-x¶çA’0^À÷ -ƒX†PË3( Ʀz(µä©…3ëê7¢i°2?;ÿ&¨‹endstream +endobj +2445 0 obj +643 +endobj +2446 0 obj<>>>/Annots 284 0 R>>endobj +2447 0 obj<>stream +xڕUQš@~÷WL®/zQÜ]A ×4±w^íC«øfÒ\•owi›þúβ ͉W\˜og¾ýæxéQ ø£à3˜L!É{£Þø9êC´ÇÈ4 íúG­O ï¶ýí`}·×BFâL h£â·Qadž ¥BC›Ã¬¾i¸7ÿCH +¡4$ÇXÂ})ÓíàᢠM’™<”9ZÙ¸”š8%¾Æ ©ããv|üÄU"ӓN a"ó¨G‚'?_VŸÀ íM©Ã€N͚†¸”Ö`F}ǭь$Т+ ݚGLVÌÍ+jUŠZt䰈¢¥ÑAðäŠ.sÈí+tEK̪†²w°Ú¬>ƒ.àˆ=û#ƜàvFºS´¶ånèYS­¸.¥¨[ވj,á›(B€*“„+5QˆÑo. óp§Y)¹Óá%äpi‰ŽäFƒÆÎ6Ô1Í®>ìKQu;±íêb>{¾”MŽjjLª¸üÁåujó_q~Ê®ŒÒ»T$Y¹ãð>)Ojl9Çk Ôªö÷„=tÄÚ9ÂÝX9£î®Ïޚs˜eª¸0­{KŒË<Kä2<‡½Élk_áåZQ; ¥öhÇ Q¸³öä\ôݕrä\®iTà÷5‡U‡ß¢W‘Zsýœòl÷&+77´Žƒ{;­æÿÇksÚŚ7¬ºò5|4q1³‹/¬Êbð¸Y®a]ìõÏço)‹ƒŒóœK_bQƙÉ7¢nèPùŒt}ÜöuA©WËòµ÷ó珫endstream +endobj +2448 0 obj +603 +endobj +2449 0 obj<>>>/Annots 286 0 R>>endobj +2450 0 obj<>stream +xÚ}RËnÂ0¼ç+Vê˜8„GÔªRKiÅ¡-áÆÅM ¸uìÔqJé×׋yHªD–vwfw<ÞπBè> +þYܧAû1ڇtá*½…4o¬¬-ÇJXÁ¤øáóƼÙLß=0öÀV'$=„Î*¶ä¾B²+F],}i‘ÃßV˜œ7¯OúE Rx•QZ¡•GÄ@éÑGDºâ°çKÕî¹ XÔ*Þ ° +¬ë¤¸]kó!Ô2s`•Kñœçð¶Ùj•s#7(%³ m +c‹œ$Ú!ŠdLJGcµÕ³Ã;ɽC­ÏìbɏHŒãF߬(åׯ„Êdíîr“ÕeÕÆadu»Qÿj§–]z‘)çp'+åQ„$t„Åãõ ˆ#4¢€$r} aŠËõo–p4y±7ðŒ%Gfx`vL'„B”tÉÙ0œM¦0Õ »f†ÃÄè¥aEÁMÏLÕLb¿–'µúQˆJ{˜·Ž„——ÞÝù%øݺåÖendstream +endobj +2451 0 obj +393 +endobj +2452 0 obj<>>>/Annots 290 0 R>>endobj +2453 0 obj<>stream +xڕUÛnÚ@}ç+Fé D`v×w¥ª”¦I›‡ŠÍRe™ÜúBv×iÕ¯ï^l(ÁN©,a¼svæì™3öÓ’Ÿ€íAZ ÞǃéC؇x##^€!^wBìg{‘U%_ W£QüÝ ƒšØÈònɓ-5Qa$® +e¥€“4êᛀkuC*פ»„ÁuͲÕèæ¬ Už[¶­ Z +nâ.`¬â!Ë}‰Qb˗ÛåòÊS–éú*r…äù?‹àízØ"€]l€Cù—Qˆ:ÀD5hbû'h-¤Ó°s‘Ê*s“VMMMÐÔâ…Oq>>>/Annots 294 0 R>>endobj +2456 0 obj<>stream +xڕUQoÚ0~çWœºZA°M‰:MêºvÛÃ4FÂÒ™‡ÚÎ:í×ï.&0•Ð1ˆÉ}¾ûüÝwÉSÃ‡ñ„¾YÙ{ŸôFð)$kŒLBɪ¿µv7«Œ]ö—××Éñd8fބ@ “n¤‹2ˆöAP(WŽ9hõÝ ]UÊXȶ©†›ZçËëۓ +"¢$wzS—RYãâpNqÎB/z‰!¸7Åíxûƒ4™Îw6¯E’óžüð3ÿ~ˆè`Â=|BkáRKˆ;À‚O=‚!#º‘Ðß³ eÅÜ¢Õ±¡Öh¨%[ Ÿ’dF:(™]@Ñ»œbƒî èˆ9ÕPöV‹ùg°ì°gxý)!¼ðrR ºS·c×ý(p¾šK[kµïz«+¹bJQ•Sg™4fªRÃßRWtsæE­¥×a'äpꊎä$Cëhê…vWÖµjFª•Ô5vö5Nð„Oµl„‹IÔ?¥>OíáWZîŠ3Óô&WYQ¯$¼Íê#oûްáNµ¿‡ì¶#vÅ\LUÊÚàêüøÅRÂ]aNÀ÷½ed´`Š%JˆžÃý)\k_àõŽ¢Ò¾ðHíÞMB«pg1œíñ¡Çè»3娡\Û¨0 ÷µM‡_£×Š¥}Ìe±z•ÉÍ--ãà_N«=ÅÿñZìV©•-«®üá>û˜ÙÇgVc1¸_Ìbˆ«µ}NqþfºÚè´,¥6ð%UuZP¾!÷#Ãp*šÇç!ÝõÇªÏºÞ (˷ުǒendstream +endobj +2457 0 obj +606 +endobj +2458 0 obj<>>>/Annots 296 0 R>>endobj +2459 0 obj<>stream +xڍT]oÚ0}çW\u/P±“ušÄº®ëÃ$VÒ·HSdJf;jù÷³ã¤E4)_÷ÜësÏ=ößl.…™i9ø ¦ßC D™‰øsÑf¸Óz¿”¹ÐY<ŒG£è1šÌ0ò-ìE%[î¢Â6H=2¹p\žÿÖpkŸcH+¡4¤»DÂmVÉ2Ñc@Å£»³µhhË-ä¶.¹ÐÊÅ= ÄÆ ¦h~б˜tóûW©Ì÷:¯„>>>/Annots 300 0 R>>endobj +2462 0 obj<>stream +xڕUïoÚ0ýÎ_qê¾´Û8¨Ó¤®?¶}˜Ä |«4EÁ@¦Ä¡¶³Uûëw˜Jè˜@`|ÏwÏïޅç†/£1½³²÷1é càHVG’å对í´vO—OWWɏ1±`L˜…M×ÊGÄ» )”kû´øîàš¾ûUÚ:È6©ëÚäOW7GDL9nͺ.•vÖÇCàœâœEAüCó`‚Çqû^ÙÌä[—Wš"I ï½ÿ˜}!:ó@ӚǸ4 +æ`Á'Ü¡…`Hà€n”;v!£¬˜[´*6Ԛ µd£às’LI­²3(J°ó)6芞˜W eï`µ˜}WÁ¶vÿ $DO¨Awjv踌Co©™rµÑ»Ž·š’#&ePi°u–)kû +=ø­LE›«4/j£‚+!‡cGt$' Z3ûÐñ´‡.aUë¦w`•^ZH}O§‹ï÷\+t8Jé0¥Uæ§2§‰=¼¤å¶81FïrõRÁû¬ÞÚ!ñ 6Kî5û{¼n:b÷ªPNù1ìÃÅÐV¥¢.NÞ\)¸-lud¾ë-#“…,RB,ð&þGá[û +oÖp•ÎErw~ +Z‰;‹á\öÕx4Bߝ(ÇöåÚNE!¹¯­Øo:ü½†Ô\¹Ç\Ë7YñˆÜÜÒ8ò|Zí-þ×b»L©“žUWþhŒ$f–ø¼jLw‹éæÕÊýJqþ¦¦Z›´,•±ð5ÕuZP¾—qÀa0Í# F»RJTuü' *ßzviMendstream +endobj +2463 0 obj +609 +endobj +2464 0 obj<>>>/Annots 303 0 R>>endobj +2465 0 obj<>stream +xڍUÛnÚ@}ç+¦éC gw}ÁM¤4¥´Mh0êCEÖàʲ^+M«þ{÷b')Ø BܝsvæÌpßÁ€Ä ЀéÀ2í¼÷;§=ÀCð#q\ þª»á|{CÃUÐ z=ÿ‡†X20‘áHм×TGxUØ2gžsȧ;'ò³ËMÈàdQFe}È„fk¾ z£=*âÉll]¦4ㅎۀ±Œc„á.FB°'HþüKoyœg22ö;È@¢Oo7°\¶lÀ¶e˜€=ñÈ(ÌÀ™ªÐÄ´ÿA«ZZ•:ɬ"7© ª¤)%ÍßPøäûSXæYF—H´ˆ >X¢B7HÔÂtÕt„éð\ W²Kù+â1ÜÃÅ)t«8䉨P¢Ñ /+Ӆ—G°xä´¨u¾"QP;‡KTèÆ?Ô:†%EÝP^²¬2hmiàa›dUלÁCže,gFƒÿuú·PÔ³¨C C\ŸêBTfÊqJF«‡±<¾ïÊ>ló¢ˆÉ£Š2Z” — a2öå¦×3_25ØÔ†gô¾¤o¿Òøg˜n“–ýñ6ΖI¹¢ðnYn‹Sycs^Q¬÷Ï˵2ªé‘vŽZ2ÚÄß1"Öí.@î݉QCÚ åzmõáèô¨ÚL/N?lℂ†Ì·¢zT?=xs¦êwwy}徚Û]턳Uهz9ñ/šGA5¦"ùpПç€tO_¤ý½óêû+–[Asèx´‹¶%/jAÊWyÉ÷eÿiÙÎ3Já")ö÷®æ É­eº"K +Ý×_=N;x¶†g ËsÕ*…¹Ô–¬ýÜH&V¿ùĆÓðÚèÐ]=®-WXÍØWóô?yJÔ7ËîWíhÈîVh¡ÅÛEz>àr>Á,øC(6˔åk¦)e| ³2Ldº¶<Ã`HPÓ¿²å¸õÿ&¸*É×Î_`™endstream +endobj +2466 0 obj +753 +endobj +2467 0 obj<>>>/Annots 305 0 R>>endobj +2468 0 obj<>stream +xڍSێÓ0}ïWŒÄK‹¨×v“´Ñ"¤eYà©´Ù·JÈJÝ6(±‹ípûz>>>/Annots 307 0 R>>endobj +2471 0 obj<>stream +xڝVmo›0þž_qŸ¦´J)Bˆú©ëº—•º&•&-Óä€I˜3Û´ë¿ßãм5l‰ï9çñÝswþ= àâ—ÀÄ?„¸¼Ÿ.?NL`ž¢%Œ̓áZ©jÆ**¨b‹áâìlþËÀ»ð]'ÔÀGIWÌX]˜¶Fo¬MOp¿ùyøA„è±?Å8Ž}Ç2ÅmƒÙ,q=ÇmÁ¾n¡›–›«7õB“ ±þûfû†×|Íàñá (²MÊ ~žë½ù5àü +w‚V$a²½O̬Ãb(ã5+0/ÀSP†ñ –®NI_– øË ŠpIÇ®UÙ>OkA¦´L ¢R>s‘ _-?Lù+Þ¨Ëhùò6ÿ 2éíÅ߀ò]êšØg®WæÿM4ô°¨úmÀG‰¾ ´æ²¡Ú +W“ÕëPÖŒ H¹èˆ² P ²bq–f,Þ¼',¥u®,Ü6‚öŒ¾.ºNœÓßÈÞ÷ðéísúì;ô朤•½í7ûi±Jdåj„ +«iž¿…4ËY“1L–JäÉ?Tƒì)]?ô£à@W뺎î˜{; ŒéÈ$±žCHë2n´h’4ݤV÷+lî2%!æEÅKl¸XvBIºÆ1ÚIw7&¬ìG ëu'Ú¨¢5¯ó– ¨‚œQœP;gø<Ÿßÿ¼»þö³íD¯ùëaBcń„œ—+ÝZ©ž|;l*®uFsXÖiŠòå˜Ç4çÏP ¾ÌY!SÈ(çö-ªüȔm†6úï¯Iþ¸Ú‚ ÊÄ©І®TǶÌým¨žáºìíºGL;ØÖPsqhsÛYÁ»æ +§‡ûŒ1¸Î%ß«%ÒÖ¾  +˜ê²6/¹)¼XA§ítÌoxY²XYñïTb㵞$˜:Ɠ±I<Ü<ÞÏ`ÆSõL±.ï_ ZZkw´Ä¡÷»0NÏ=vs ÂÈÞLˆç·'þ:ø O$©Eendstream +endobj +2472 0 obj +855 +endobj +2473 0 obj<>>>/Annots 310 0 R>>endobj +2474 0 obj<>stream +xڍT]oâ0|çW¬¸—RÑ`;N êõ$ÚÒéŽöJx9!¡(1S>8'iûóÏk(m¨ˆ|ÌxwXÏø_‹Q +¶‹ß0m]û­Þ´þR!­Ër3å],’h~6ïtü¿†Æ íÂ&–‹ÄY¬„A x[9½äq‡…ðiQÂ9^»[,Qïôµ až%„ë@ÂùKTbÞ¹üԜyX(WU*²²0¸”"N µØGR¨G­¾Z®^ߊ"”ñ¦Œó ‘‘ß"QƒÙý<ß(¶ãb1êØ– ÔS·RÀ´Ì³È–Íl÷€­'Ì·ê‚UUmVYKÓ ´4-àÁ÷Ÿp™OÈ±õÉ5»A¢f¦¦÷☮ø…$ƬÁé’4û¨$â)í„nhU”2ÎV aXæJõò‘ÄV>Y¤f7níޘ¼ïZ¼Á_ûíGóökåul t$sõÊ3XV™¶¢,ô¿ +)•¹?ü÷b#ÂX z·_VC†ŒÔÑ[n’#þgaRE¾‡Õ¦è¡Bký¹H¡æxêËì0þ]­jq7ý¼] gþÃãóøÏÐ?NºÐ¾Š8„hI›sÇæ·™Óžw¶‡€*L‰q–ºe]³Ý+òTô*·?s_×q"ÀPg›((…¹ŸwàêÊȹyœøãÉltü´™ +äÈ?™Šn}B0W}[Y#©áš‡ÄØä_®`¿ó¸Žï„üڍÍÔQfïºÑ­ü|¤Ùµ«4p0nuÇ®¶áWòêY³©Á`»ÀÅH©ý3Ӈ›ÙÓ¦ù²| Thžd¾’Aš +YÀ¯ «‚Ë]PîY.úLçš2Žo9£&çMÑPsùÝúgS»ãendstream +endobj +2475 0 obj +661 +endobj +2476 0 obj<>>>/Annots 314 0 R>>endobj +2477 0 obj<>stream +xڕUÁŽÚ0½ó£Ý ¬ Ø&!‰¶ªD)ÛöP‰B¸!UQ0*qXÛiWýúzâÐv©‚“yžy~ó&yîP æGÁg0C’w>EáSԇhk"ã€B´éîµ>D2Nøº»îõ¢_ãZÌ`Dœ1¢V*Þq%ÖAæa(Βàò§†üïCR¥!ÙÇJ™®{%XˆY&rWæ\heãPŠqJ'|A ©ã›íæñg®™tZŒÌ¢qˆ9ûñ²øn`Ðޘ: è×44KÉaÙfÔwÜÍ1NèJD·fçÌjr³FɊZU ¢í9|¢9ê xrE—9ävŠº…¢%fU3²·°Z-¾.@cÓޡĘÜN©B·ªvê¹zÖV ®K)êž7ª¢'|Œ(¨2I¸R}…üå²À‡Û8ÍJɝ3—žhIŽ"4†¶¡¶Qh¶ua[Šª ¸Ø(ˆm_£Åd:3g|.¹ñ9 +jÒ*.syÜì%ÎٕqºOE’•’ò †ÈÉÙD,B¨Õí|È[bg³Ø‡»¡*r>4>¸»>KÎa’©â ´n/A§y¾©‘CÈÌAìMf»û +/wpÒ÷'nS; +Æ­ÅÌpŽÕh02Ö»RŽË5­ +<4`S±_5ù-z©%×O)Ï6o²¢º¡ÅÌD¸·ÓjNñ¼V‡M¬~lËÔðÁÈ5™]óÒª<ÓÕ| Ëb«ÿÄfç²ØÉ8ϹTð=eœa¾uC‡ÂÀg¤õSàžÞ”yµ.?:ÿ’«’÷endstream +endobj +2478 0 obj +604 +endobj +2479 0 obj<>>>/Annots 323 0 R>>endobj +2480 0 obj<>stream +xڕ–moâ8Çßó)F]§4óHÔëI½–m+í¶„wH•/ÈmⰉ³»·Ÿ~ÇvÂc@ +MìñÌoþžLü­CÀÂǗqÖù'êÜ| ÍqÆïˆfÝ¥«ÉjF›v§½^ôŸ6rµÑµc™¾4›”tÁô¬a=i{‡÷RPQ•ï¶ý©ÊÿÓÞís;”ëï‹E•1.J=ï!ržX}3Ü·‘&$$f€Ëqø‘•q‘¬D’s93ˆ:–iaÚ럷'pûhíùÄ´øòš„xY0·Û$0ÝÚÚ¶-ØX+ýܚγ¤Wôm7(4@¡EKÏQ4‚8çœÅg º¶i¨¬[7{Ä5û捉ªàµÀM +r‚T½‰ÏAàP\JŽž¿U¬fËö!Èá.‰Ðžj­»f]æW’A¥LÊ6 ׄI UÉf@ç‚@ùÿð8ø4ˆ< "ž÷†ŒDÄÑ{6E/Ã×±£áMFüÉ ˆÞîë"‡yÂišüb +AÉÔLR>ÃkQ$컞ݫھ–iœð˜ÁªÈ&˜\¼Ô¿iMø²|†£”ãSÚñ‹4‚~eæ|Á +CúZ4+¡\æU:“¥&^±½Lcš¦ÒóE;P¡«´Ž.‹§)TšçB£ç‘ý;M«ƒ –R½? _£—×É`ÏûñZü¤Ù*=Òi> ‚i…òüW«òF&`.ÿnd&ºSm7ÛF K?»­J_ܶ¬bBw/®nÊúвŽh¨Ê:…§ YÊ6¥ÜÊDKÛñŽkpÕäp•ª¤H¶«;¸Fr,}wR“ÁeHόÎN29dSÈʗÜÙLM +—1 ÕÛ£<‰åZŽz5j,××wç`ÕY\†5ÊËõöòÞ5N?tAÍÀ“MNߜ÷ÐuWT,ÕéJò]©{‰8,ÖöP‡ü5XíLq¢‚Æì”:ýæqÕñ¦>IÂÃd4†q>?(ZFú–±¢„Ï”W4•š®[¦ˆíËQ×ö0G«ý؊¢|éüG7ϒendstream +endobj +2481 0 obj +926 +endobj +2482 0 obj<>>>/Annots 326 0 R>>endobj +2483 0 obj<>stream +xڍVmošPþî¯8ë>T¤÷ò*qmÒu¶k²µ®böa4 Ջ² ÐË%]·ì¿ï¾@µ +«1Qà<÷<ÏyÅÇÄ?\Lf«ÎG¿s|ávÁ¸Å`ðçÝ%cùw3tƒ^Ïÿ©0–ÂôM¤;5-ÂQV^e4laŠSNÄå=ƒ#ñ«ÁlR8z(£ˆP 4!é‚-ƒÞp‡Ëð„»3º(W$e…²Û€±°c„uw# Ø$"ŌÆ9‹³TXF~éˆ'áåëö¬GÛÖ À¶¥›€=~I LÀ2uT¡ Ó~…–Ù´*u6^¹o£N©”& ¤4Ià³ïa–¥)™í!Ñ28õÞ%ºA¢¦²¦ªÐ L€eüX8UÊÞgú`qÝ*yÜʕ¨Æh—–«./‹àᙑ¢Öù†DNíì/Q¢K¼nPËutKˆº%¬¤iÕ u ˆvÛ$˼fú²¥Õú_¹ßjãŠz•©iŒëc]ˆÊT¶œÔQÀª»`dXwÛ±T‰† tã¬`j¡ipp|Pí¬ ÐÓ2NðŒwU™OxVy†ƒn½ð°Eü›dQý(èiåA/èÁ) U© =°½I5¨]I†v <Íye«ƒœà݉¬íýù͵u=í£_½•!¼fߎú€[£ø³UUÉrÇiƒw`Q^²b½‚ͳ’­e×À¿-¯Ž !p–»Ë WÃÎoÀµø× +<ƒ7¦¼NÔ¤o¡éÖÓÅOÙuSœ«I©Ç¬‘‡¿’ÌšÛn}³Ã„^˜êYØ>>>/Annots 338 0 R>>endobj +2486 0 obj<>stream +xÚ­–ëo›0À¿ç¯8m_Ú)aHÀÚ4)]»©ÒY“~«T¹àP*À”ÇÿýÎ6*J»¥Qs统ï…ïgLü#`¯ä×Of'»ÙÛOˆ »=JV]peÙ:N„ˆ9K¯Ž®ŽwwZÏÑz Û4VRó²`!×Rh-´–µ‘kV–ytS•üº„7V¥\?ƒúÍB\‡¹¨²¹´ˆ†ˆixÒŒ|‘%ø·,‡7)Kø\ÿþÉâŠ_¿{oQit‡UÂÓ²Ðò%"åĤÆòPGªJ ·ããS^øy”•‘H¥äl73 #Ûþ»ø އÚË¥i8@VÔ@÷Ô° ç°íQ¶ˆ‡ñÔÚ*º´UŠœš5Ðªí¢ž±"SöÙî–Ãùfƒ;ï+^”OÐٝL¦SÚ=tš u,I 8@ÕÊF˜ˆe˜Ó™”ö“CUeIôÉÇ öÐÖè8˜C-,Æ©`Z{Ì¥º°U‰ö°Ýè&V>ÂåÚèo2—Òî-±®Ag¥ë낗UžÖ Ҕ l W5d"JKžC) ”忺h‚ÈáÛå—/핰ø¢ŠHE 7¸È9+y`ô4©f8èµ°fiÑÐk¶Á¾J}iXÀ ˆÒ0îâÞÁª 4,2îGûˆ{lýì7K²x`<¾ŽR?®ïý*+Þ"±qû¡ž{ÑÓµ‘ïKfé\2]ï֟¯¿oÎ.Ö»óïßæð*ù³¸7Å«9áI¸åÖq!©kǔMfzxª#hÉ1 V±®ƒ y]*äFÚN«Ž¹h²ÒëbÎ%5 {È¥ÙºtÚ ¾”5Þ¸«âc¬ÉN±Ç©èR6uMeQ§]M¡ªñ\ªs찐ç£`¶Ù(ÏO§ƒ5çx!X›È1GóÑڒµÜ“ñՋI¥EèJ¿t4ÑKÃñ â+Ün½ÏVS°×Ýã3ÔpµÇÉaRPOT»''qƒecâÌéXÍ)žÍÅ WrŽ—±ñ:Ô°9¶§^3Ùð(ÿDö_j˓W„fnéÕ´âòì®´¶>>>/Annots 350 0 R>>endobj +2489 0 obj<>stream +xÚ­—YoÛ8€ßý+ݗ¤°UQ·E·Ízxcçi³0‰V´DUGÛý÷;$u4Ф(í&ŠÃ™oNÊ_Vtü%à`:¤«7‡Õ«?| .N¸ãxáYœçÛ0|ÃyÂhVޞݞŸþQ‚–ܘºæћ’FLíêà7›†Ýh9Òª*⻺bÇ +^Õ +õx òá:*x¯…JÔDtÍºà‰Ÿ€geÁ=-àeFS† +³ +²:=~¥IÍÊ_ѧ4ܞ_< +‚á ]Û"ªS–U¥Ú·±OЖ5”"Ä'š‹Çññ;VEœW1ÏÄÎåa¥k:¦¨û¸~–‡Ò¶éc¼‰KŸøšƒýˆ°aèšÝHÄ} -sm5t¶.´ŽÊ"F_’Iý’ìpÏàj·Ã“_Ðùê :C¸º˜NJÐ)&ÝÅ]$u0AÕíÍ0éU/f’ÒSL–çá#´/JkI<~‚®ÚçÑ,ÏÐôÅhJz͑õÕWú^Þ±Bö"3tŽ!,-¥“Ò“t–¯úm’íNMƒed–ùŒ&PÒ£Mз°EUm׬ª‹¬iá¶ID‹»²}!ç8P0ˆ‡J„”}ë³ ¼€O7>@|’›ýFÀë$„ŒWp‡‹‚ÑŠ…ÚÈQ ƒi0Â!"Ö[µ59«Û³gpª³@è†%ðLò¦¼èƒß«4´^–9 âSÌÂGÖŽRSõĕrz€ÕçóG”6Šq9”ñJ£Zdÿ¢ ÿŠòœyXô\¦IÙ9ƒÆž ýåwšæÉÄEö[œI2ø=¨óòF\»ÝDÁ ÝmÁU#/…òÑÿ¾x|px)®E¸‡íûãçÝåõöpõùÓ^”$øáv ìdÊâH"@ÿYÁÚã˜Ï¢ùé@ä´n¨Lbu«%Ó¡qâg¨fÓç5'6ۗß&áíÍn{~ª¾Q|éØ<*hšâŒ4«i"tm¾*ظ†>ý Ôr¼ö›¢7‘ùsõ¯o˜Gendstream +endobj +2490 0 obj +1000 +endobj +2491 0 obj<>>>/Annots 363 0 R>>endobj +2492 0 obj<>stream +xÚ­—m›F€¿ûWŒÒ/¾È&,,”ª’Ó\£“ÒÄ=sß,¬9*` /I~g_÷ ”K{> 3;óÌìÌìÞ×?ìøòÕ»`õæ7ˆ Á%;@¯Ó²ÜÇñû°a§õéæ&øS)Q¥´µMc'Ôê0aJj‚¯…–£-<†MS¥_چ=6ðúÒ¤ªWßߓзåF˜C+Ä4”W˜ž«h#ÀÀ®LŠ$œÖb÷N7ÓÓóÈ쳚_Õ'Ñ%gŠ6ö]DÎq¦:¢LåS¦Jîق*aÅBï2Öwœg,,ºíõGLŠs»óhaœdÊ£Ù{ìÊÂ÷—:U3|ÿ¤ªg±,2„žƒMèt"®±º(^Jv‡™°j̶† å@-G……`]?Ö§lÎÇz3_[ÅNËÁsÄX–ËJ С´îÃ"a³‰Âcßî½Ïywwƒ†Ó§IBÍ×ñÄï°lÓëS²«‹âÅ\¬æY+¦ç|i[´¢f£¶'N§¥lÊ"û_jËWÜm¼^XúiYq¹–º)ª#+Ã*lø|'âŠÝÐ>uϏûÙJ¨ý.NØO†"Y2º4—nù¥\]?ÆU/]ŒâUæ ëâxØåù8]]ž^±%;À¡®>k}8áÈÏÍ÷¯\‡Š'U˜ç8á÷°hÃLÜ*âØº–¼Ûo©%8ÍñÿÉ09¬þ)MËendstream +endobj +2493 0 obj +956 +endobj +2494 0 obj<>>>/Annots 375 0 R>>endobj +2495 0 obj<>stream +xÚ­—mo›H€¿ûWŒÚ/NåÐ]Þ jUɽú¢HmêÚä[¤ˆÂšPñVX®wÿþfÙZ¾k"Y^fvæÙy[ü}Aà?…µ† Aºxï-^ÿé]ƒwD‰íPðÂe\›0¼Í8‹Xù°|¸ºò¾I=Sê]D³…æ}åGLJ ¸J¨[ÊÈ£Ïy­9{äðêĪË§+h¾û®£2¯‹•°ˆ†(Ña +¦ÿúÝø¹‚ Ï*Á“_«ÌOÙ¥Ö2ùIͮޜ[w……MÕ)Ëx%åP*䖁NT„u©¶ÆÝøø«‚2.xœgB²õD#˜“îc¦ƒÚ–áb„-?¨«éP28 èR²Ö ¥lT#?i7¹5[6"Œê¶LFL¸oÌ7\ÞƒÛÝ7~¯YşaӉfÎfk”Ø$꘠Éû0S'š "-Ï%j”LjLÇÁGèk震ÿS0ȏ¢HDËB‡%r>z››ÇÛ;o{³ÝC^Bûh{wÿIvÐ8¿éè3“_*òÛMý‰Â?ÇO~חÏ`Ù:Vô\¬FyËte÷5;'û% ÏP™Æü֐ʃ­Ñ·µImY…{Æë2SmݶŽhûuÓÓP䂳žád?úPŠœßÝüñ±ö‚ ¯“²œÃW\”Ìç,ÔF‹d8"^í̕¢±‰Ýn]±Îaü0¬À‡*΢¤{++Z°*Xcþ<ÆÑ·ûi‘ŒÜ/ã,HêÁÛ .ª×H¬=½S£Y§Ý\Rw›sÉÉå±ê:ìón»ßx·ŸïVð"‰Ó˜¿XaöÉøü>0›¤ÊÏꌪÚ!¢ZÖž*EK–¨´f•ÈÚ9ÙPFЧBlTáÌïó–«é²-œC)8– ióêʶåÍ$‰ö~M +_;ŒÎu œ#îÎÏ à”ÇÙaj ¦‹Š:b ·XqºÌÀjOq1«ò¤pº´¨!úP±™†#Jk.å‘ý–ڲĻf›ê"ÈÍj^qYF_ZVø¥Ïór:‘t-r¡<ªvö8Hh\¬ÞRY4gf)*ƒšÝjþÌúOT“ésԎk›‚e7·8üq¿;À!?ò>¾”ìÊ<*ý4ÅŸü¬öaëšâ{…ëµNF˜™¶Óþ¼ Uù²ø¢Thendstream +endobj +2496 0 obj +963 +endobj +2497 0 obj<>>>/Annots 387 0 R>>endobj +2498 0 obj<>stream +xÚ­—[oÛ6€ßó+º'pTR”d ¸«hSÏvž–ÁPlÚñ`]JIíúïwލK"˲¼- Œ<äùx®ô×+ 9‡þÖÁՇåÕûß<à#XnqÅq9,7ƒ}7›i˜ÊTÉÓàéúzù—´´à­`†C¢‰¿“z•W,švqÊÊOSµÎR¹Já¦y, èé!äÿû;ïT”ÅC:OâÌpé,8óSoÇÏ!¬£0Iaýâ+¸ ý@^|\˜B˜«oþ!“IyÍÞè©§ë»#“˜=V»,ašèu8§uÛ6xS„$¸ÇîÆé2Y«}œî£V&Ë+f0ôWõ1¿ËEi[xh|‡èJÏ0AIX´ÈræUÂÂtñ³–Îýn•lŒäLG{MIꮩ–/¦³nûŠ÷Nϐ™Ì°z“åÂ-dš‡pòxh#ª:xÇsûòä§x,×Å)TÖ¤IÄ¢-…6ä1O¤\-Ç÷«éÃrr?™C¤ œš<<~ÖiušÞrMïI¯…OÒ;yäQ.4áiŽà«T=嘘C}¡rá“P–§Ó±Nµ#¸,xFƒ"^½ÞÁf‰þ‰¡…O²•®ë§ÏQ™Vÿ¤Ð­éZ—át,Îeš©°(5e:S)åuâˆ@¤¤dMù½v3EãÃã§O°ßæ‹õÂ:Ê£žq ¤ŸÊÑRît~6ÊV ¬lzéd‡)÷`›…k:üÍ&(ÌyƒHÕ¶¯µÊ[&±\ï·{¹y]· ˜nË& ŠD>ƪÝù¥´â>iʓýšÒx,BãŸRþŠÜƞ·Áþz'+/‚ŠÎš}ò·ć­÷§}¸>d ?¯³8yÖ6^~)®oòªÎÝ÷®Ñ©Ïi’?8cÞol¶ñaU×¾Ì&óñrúåaï’(·•—Þ 1ÄÙÎ5Ѕ”0>$ÑQRñ"Q%’°Ñ‰žhS¢ä£ƒN”ƵƒÚø´ÑÑÞ×·øEé‡e¶êãÌ2ìJ£‰Vâ§4²JcéUÏ«UóPèâ{K•tb™¼¾:by:¯7Vy‹KÉ>bPvR Æ QQ Ï«F}¨ŠK\JUÄb Ö¥b0ìŽ+“ºh®M ù _X™¢ª¹„>Qéâ®ÀÂBÙñ +4q‘…r¤îxâ.µ›J0·2G¨òRÉ$:dTå»c ++¶]‘YÂ5¼þdx‘ÿÀ•ü1…¦tÉÏÜ$ç£~AŊ÷‘¦ZÈØW~©n7òy¢ÐYäy»Î7ˆ…ÞÞ[`w}ÊUÁ%¸Uú—«ÉÕéD·Øq‹Ï;Õä•~}œ-`mÓï>¾8f*Ú)?°ÝÁg?ÌüvËñýŠ_êFfþ,ä¤Y ;Rñ…®ý‘ƒÖùýê*Ņendstream +endobj +2499 0 obj +1064 +endobj +2500 0 obj<>>>/Annots 399 0 R>>endobj +2501 0 obj<>stream +xÚ­—ÛnÛ8†ïýƒö&)l•ÔYèbw›-t[7vî¬DËZÈ¢ªÃf‡É9HŠ\l¡f8ó‘üg(ÿ\P øK!°Áñ!>.>îïÿŒ€°Û£Å)쒋¬,×Irʔß]Ü]^îþÖ^®öZ9Äò¥ßmÍR®­"c´=âž5M•ýh~ßÀ»'1¥U?[‚úŸ¥8N+іKÃPb…2LýÄ¢¨ˆ¬‚w;rŒV4‹‡³¢È9‡,=Ü]~x±T;’Ó×UÚyÑÔÚî¥ÒNIdyÏ}¤ ¨àt|ü‰×q••M& +i¹Ú-ˆEðú›Ïà†èí9î*õ# ÓG– ‡í€³MCôÓÞ6:¼Õqº†Î#2ªíë³ÂmVd*¾"Û8\o68ógËëæ:›Xî|:å=@§™H€V$P>BÕÛ&˜Åг™”÷“†øóK ÉÇ öÐkzÍ m‹ÌFÓÞ£h¾Òªz€ Ÿò +þayû‘oc)Ì&RÞ£Dn¤ËJV͔|<“Êuνöý©d]êkuÝ𦭠+S²]QȒT¹B)°ð³ÐÈæ§ÓQÁ×Û/_ Û+ãÉ‹6O  üÀAÅYÃk mh†gÕ?À!÷«k¡Ú4Ü~»‰°o‹X–$50¨³"Í9TÒÿ¨ÚýnquÉãlŸñäqŏc_ýˎe>ÒÚßfEœ· ‡ßⶬß#­uøÝô[›öÝÆ4ø/-O$ºß­?ßÛ\ݬw×ß¾.áM‰ËJ­¨~³Šd¼;o9‡u^‹R£F=DÖbâڎȓŠS£\«çل*…ÓaȉfS4ùG!rΊî`óQââ½Ðe´ñ¢cIŸ±;à(:¥\*iLñ=¥ª'±lzZ:bE®ls±ºUœKö d’Ê!Ärz*'ŠúÑ*³ˆs©®±òS^u`S).–Óºò=lD½®Ôhž®|_ß8Oˆ¦OR*Á¤´‰#e6œòåB:B“vö^©Z}EYø"tÚ +ÇÔU3“«[ÆÙ\¼y+;á´¾G*ʰ¹ž¼vf³uKùu¶úÿИ'ßPcԖ/ÏW×9üq»ÙÂV웆o'›J¤;±°á/V´,—±V_ (¬›Œ|Ýrý°ûAÇlË÷Å‚CÚendstream +endobj +2502 0 obj +944 +endobj +2503 0 obj<>>>/Annots 411 0 R>>endobj +2504 0 obj<>stream +xÚ­—Yoã6€ßý+ۗ$µ$uØÂ¼Ýt`»ëÆÎSSŠMË*txulÚßR‡íȊ41“Î|ÎÁ|q`øËÁr鳎G—£÷¿yÀ'°ÜâŠ;å°Ü\…ûýl³¹÷“@æW××Ë¿µ˜­ÅÆ3]|Èý@êU^µ(œJÇÊ/Š,|* ¹*àæX)-ëIÔw?Àq¥åÞ …¨‡3sJš ÷g&y띟ÁMâÇÕ%$e¼úáG¥Ìߢ4ÜDésnNìÂ`—?^xá á‘âY”±LŠ\¯;À9­sf™ö© ‰p›܎ӟd¾ÎÂ}¦ ­Ü.GÌdxS͟ûÏ`OQÚ±Ëh{:)³:øpñQÙÖi ¥ÏRÕµL¥wÍåö  ¥;Ó³-.–7Ñ1w/‹2KªâR§/Ÿ‰*,°O±H!g‘BA—-ŸÛ8„4ƒ¯_¾@¸U‹íÂ:-£ $iO8Ȥ_ȍÙQàt.žÔ©rXÝôҙfR"m™¬I#ø›Mi¢h㝡ô…ÕWPŸ0ßËu¸ åæ°@™p§ŽxÌ@åßÒnl¯ñ¡v^˜ŸÒ“ÛN¥Q?Òâ'Ëü)ŸNögááNf0}ªœL½êïÛüxi°?…É:*7~^—ûü=ºÙÜýR5;Á›‚^uÙ'm:åáŸâ¯®%• k +›¸AÞ_-gŸWßæ·÷³åÝ·¯¼Ûã³`¬úÎa€n¦¯tЅ”0‹òôE’ñ*oÕK•51öU‡j€E:oN6d†Žöª>ÃÇ4¤ŸÔÙi3Ût‹ÄÏYdÅú¶=¯5i¨éã;¦Ê{±oŽXžM%z(V}ŠKÉ>a¨öRYŒ™VCey^3BUâRª;LÛ@f5XŸ‰+£?®8µþ&®ÔhX\q¡KËQÿ ’zޚô\jÝ&_¤&¬Ìö•ÊÚþÀb‚úW…e õtŒUâb,™§QI ?¼ð‘:iØlG4ÀVåílùÿbÞÿĆ +0Ïk£k!÷~æiöJxÑ ¤2§¾Û\Ç-j8ï"7-°C'Á€šU!YÜ®ƒ+֛zomZí»\¡þñ…_æ X¤ÛâÙÇÈ>>>/Annots 423 0 R>>endobj +2507 0 obj<>stream +xÚ­—_oÛ8 Àßû)ˆí¥O’'Æd[oW`×eIúV ÐÅõÁ±=YޟûôGɲ}ml×®‚ȤÈEŠt¾^P øOaÎÀõ!<^¼Ý^¼þ#:‡í%þ‚Âvçùr¿_‹"KJgéýåýÕÕöïJÕ«T§.q|­|WðHTR²™µ³ãJÉøK©ÄNÁ«SÃZ¥LÀ|ç®#™•ùDE[”8 m žý ³´P>p ¯R~h2UðCŠâ|[zçO½Ó`áÄ*ÓX÷WoN΂ÚèRFåQ¤ª¨ä3 TË)™9ó§:Z…D?~/ŠPƹ>-¹Þ^‡`®šõð¨=sBÿºº:ôcÈÐý0š·`èr,Z¥Ý‹æ›úÒÅÞöÉøŸ,U<Á]õí{-,ÆÃí^8/¨îÝÏn¼oBª8<Îsϸ•v/\ÝÉÌõî k¡ Q@cÞw ÒmqƒyUvk¡J™ÚþRß`Ý榷@žaÛTJ—£øÞ–"dnï>~„ø`„­ ÌÊdi¦à .¤àJ읎W]Ç'­ªƒCŸY=*ÑÀD©w_¡LCsÈ|¿/€C§Qòèô[äo<)Ef‘‹0>ÄbÿßFÕÀõ~̓ž‘õ2NÃ¤Ü ø-,óâ5r;¿ÛáÁhÓ$íÌzs*Á0ßfY"x5Ü&ši·]~Ø}Z]¯—Û›O·x‘K“§iۋá 5gdR}hsëëÍ­ínnßýÙ?Ž6BÀ2)²“r¥¶‰n>X³͐òí*©*ðÉA›P½Ñ瓘«¼vú£ÄsfG†‘Ò>¤ñX×G´.'¦¼†øSƒXŒ¶¡#Vàé¶7«Žâ\²÷xÉ©\BtK°Tn4«1T6ˆs©n°*#!k°!—“áºrgزšº2«quåúU¯{D4œAŠ­”¶.ß ú\žRZ·£ÏjÍÓh8…Œ0= ,–ÍÉh,Å/acJËryL¿žŽæªÃ8›«iuÅÿQ^L¿ a®)Ó/wf5®¼˜Û×Fä\r•Égªk®Èz´¾ÛcG- {ÖampΥј®e©\ê5«ñ]뗨Ó·°;¦>…Y`ÞàÝÝj›ì ¾s|¹YÉ,’üxÄ; ñ´ä‰¶5Õ½ŠÂGÜÐPÏ_Ô¿˜°`íÙ|¾øsl޼endstream +endobj +2508 0 obj +992 +endobj +2509 0 obj<>>>/Annots 435 0 R>>endobj +2510 0 obj<>stream +xÚ­–_oÛ8 Àßó)ˆÝK[$žåÿƆ²[o(°Û²$}º×QRl˓ím½O?J²7µ§·¶&“"¢HŠ_'tü%`:â/L&ï֓×ú@\XïPâxÖۋ(ËæÛí’æ,.‹ˆ¥ùÝÅÝååú_¥k)ݙ©kŽÐ¾Íƒ=URüJhؕ¡MP<º/ º)àªÃ²ÐQ’)Èÿ{\ï9+³©°ŠÆˆ®yœþ ÑfáCÀá* Š6ÓÒ2Ù| â’æ/6)Ì\ýàh¡ýá‘ÿ“xZÜ/N_¦Q‘ß]¾ydÃ&ç|_&4-r%·!÷=Í>VÄ'š‹»ñó{š‡<ÊD¬…äz=Ñ5“ ùgù,µmÃC|b¹z÷58…U‡2ñ¼v¥mXÂÏA[f“UÁÙº°Jl<«$“ö%ÙúÂÍb;¿â½'èt½Ž¦“Út’É’:H s¬‡ª‘õ3Y¾®Y£™”v/“ë¢ý‹œí@Ÿí )¦h.A£Ñ¤v/šíá'ÖQ`™ÜS.ySÜpÐ@µ M*µ{QMY +¢J;þciÄ-ÆSt¦qFU(í^:ü$kᱛïåEžEGÌ3ªBi÷ÒéU;—­¨¯u¯J?šé[g‡Òîl'‡^h:®JÄ%-JžV½°n7¢Wº²Bư7c2 +‘šôû¡n€qøtûñ#D;)<BVÆ[HY÷¸à4(èVëèǪNúj‡ˆYý**ÑлZo¿€]™†2ÊÁv›K%rÂø“8`««Ïšg4Œv݊&V¿K¦ +[Õh5¸QG?‚;k›¦Že”ë‹(k£YdÃ?΃GÑ ŽöSqS›õüÃæóâz9_ß|þ4…W—aŸµB2ËË,c#òjxâ°§ æ9œÀ‰ÑbE)Ìãœ=+gRU(.À}-¢Ûx ¹ˆU}©ó=n·™M\Ú§V9ßéŒèŽ4•;ÏGzÜ鍻:‡|¿ñ7•y7Äö)d2HsjdÂNåfªNp.Ö{ÌûA$›µY#™¾_/Æ ©œ‹tƒé¸§¼¦òp1Ì%[Ìfu.ÉŨ\rôvU8ÃGÁè×þð¡ñ{ü=?ƒ¢«}ŽŽÒ2H÷Ã7gè6¯ŠIÝÅh&y‚—1å#Ò©‚c + ¥Žp>TÓ×~AFY†o˜øÐÉŨŒ²ª‘[­hð `üDJ¹bVRUuw;ì¸>…W9©>ôé~Dƒª LbÕ‹Ñ ê…PùÐÝyՎ™CÀÁæ$óþ¸]¬`ÅvÅ÷šg{$ 2ü¤e k3b‰ œ¹†œ=‰éˆ¯¦ç©Y´wˆÂØ|™ü–¾!endstream +endobj +2511 0 obj +1111 +endobj +2512 0 obj<>>>/Annots 447 0 R>>endobj +2513 0 obj<>stream +xÚ­–mOÛ@ Çß÷SXڛ2Ñp¾<5bšƒMHlêhy‡„Br ™Ò$$±?_rI MC@S«ªWûìŸíÿ¥÷4A`ôBp9˜›ÉùjròÝtaµ&‹3GX…Ó8ÏÏÂp)r¿ðeVÜMVO«ñœ™Ìp”ïméG¢±2ð´‘Û:̽/e?TRÜKø¼Wy4¿ßî¥àžŠrVDÕF¤²lì6 *;¢óÚC9 ‡†K›éç QEœË8K•år5a£ú»›`ÍÉÛvÐà€snÌ=úZXö8s [{sæ¼ð®ii6›©¨›ë6Ôduüšlõ(àj± O•(åt7ØxºÚ»—nÛY-2ȍU‘êζôªónÝWȳ8•¢™$æTK!à,)³=ñ ÖS:p•6€Ì¦Í*iôðjCÁ¶½j£Û(¤:ϲDøiÛæÞ|È,Ò_›‘#3ðPFÖelÇåy۔Çõ°‡ø^R•ƒX·¥–§”?«­â½d$ùA*“1Ãì¨LÏëVc¨t梁¢³‰î° ¥˜ëÊ1©©®êÕ8]9Ö®Ø5ÑðQ ¡Mé9†w(å~!-¡N;ºW7~ 3N„KÏd4–®âCXåii.‹þp>>>/Annots 459 0 R>>endobj +2516 0 obj<>stream +xÚ­—mo›H€¿ûWŒr_’ʦ»€±QO'¹×4Š”&¾˜H÷!RD`M¨l–ÂÒ\ÿý;€_Ÿ.‰,ÃÌÎ<;3;³ù1¢@ð—‚ãÉ¿h;úŒ>~õÎ X£Ä›Sâó4Ïq¼Eš%çÁw­æjµ‰C,O*>”a´”€o„öÔØx +šx®{ðáШë—cPßß“‚WùXD;”Xsi zv‹ñs ÏJÑKXÀ‡,Ü²ÓŒí¯–Ÿ%‡&†›Š=^|zۗÖERmY&J-Ÿ¥Rîû=V‘Ô§Ö Wãë/¬ŒŠ4)Ϥä2‹`²šû+pç¨=u|Œ=u¥Iê[6 V-ÊԟᎵ¶íkº§­²î¸)‘VmOgéȔ}E¼0¸^.q及•â:›Xîp:¥ÝB§™È ¥H ª¢ƒª‘õ0Ц3)í.&w>ÇWè‹­…HüÊð5”ªÊAUK?œ;·-2NkwÂyªÂdÙ·°Éג­9”ï€y6: ¦´;ÁЊ:}æLµÐII VÊaÍ øVÇñP×9á@híNк±5™;Â,,¶Z>”G «…CÆ«ž ZÔ1Xê•ç°®²HZ„0ŽK¡D½MõªŠ½½2gQºNY¼ß¦,øÊ‹Cïr +8:€¨ø,®žnß.o·WÇa£×K‚Ë¿ƒ¶%š±+$Sç†3-!/øÏ4FÄ×T¼ì•6î¡P µ2‘®í+±,â±üR•˜¸CQñš–¬ÝWšd¼èKÝå?á6ßtÌíßÒ,ÚT1ƒß£*/?bƬ—? £M›!a†÷§·’Ã!?†:pwËËûEp}w»{%Ã?†³ïüy"»ÓYﰖE‹ÊásDmç¬{¯ƒÅ¦äoŽ'5'ŽÈ†kËFºJ¦²y¨§>qG ŠöK}ïöù™ó ³º’[½QâÊ3müÙ¸5Úå4þÜæâP;«zìc;d*{¡lºÛ6Bù®lõC¡ê=œÆõÛI/“Cˆå4Lޙœ˜ÌNcºÆ.™°¢Æêsp>î¯'2GÿM=©§aõDÌh< êÏ¥T& vé{–ßåòíFjBãvp¬îÃ,éO Ml9ñ –ÉÈ`,³‹ÿ„U),ÃåR¿ ÞðÂ:‹•|SÉYö?T—/S†™¶§`õ0¨¶|o¿)ïˆÞ©.¼ùµK¯K´ÃeK5 q;8V+–ãåO𢿼ðZåÕ\Ž;«†$Qïâd.=Òû87+&¾ žíèù +>,W°âkñâ=nYð¤·[<Öð-̪p#­MôÕp2³Õå’:sùÖ¥^ýaÛ] ó×è_×Ðendstream +endobj +2517 0 obj +1088 +endobj +2518 0 obj<>>>/Annots 471 0 R>>endobj +2519 0 obj<>stream +xÚ­˜mOãFÇßó)Fô  àóú!‰E[)Wr”µU©±7ÁUâõ­×GQÕïÞÙÇÁ؎S${gg~;ûßñ„¯lü%0rÀB´>ø8?øð)2‚ùG†cóø(ɲIÏOÒeþpôp|<ÿSÛyÚîÔµ­¡´¼ÏÃ%Õ£6fÐñ“ÇP §BÐG'5¯r\?€ú.ñ~ÉY‘ ¤GtDlk,]A÷O5¯ˆXš ˆžC'i¸¦ûzK¤Åúñ[¸*hþ֝¼æTìéqÛÉvûp|ö.§N }Mø²XÓTäzÜBäxXnÝDZ€X#œÏiñ$ KåÈt~`[6î÷ærwÞ­}gŒÜÄ ,H`9À)ÌŒI0¶ˆ±v< +k%ÏÀù¶ôJ| ÜE¦ü+²ù3…ËÛ[œù×.vÐÙj«7²n SL^0Ô:U²j¡ÚŒµ3y-iz2iëV¦ÑG1>еH¼fØruN@Ée܈È@}á”u+œ?ÆGˆ"N|,é6{šïXv4e݊æ*ñWG³ ¯X?Q^¥/߁ç:{m݊‡”üMh “#a$ÇaÁ8|ڏ”¸{ +mÝJj›âݚÆmííso“¡­kIUÝáHkðŽŠ‚§¦–µFʑª‚1¬Õ˜MÁT"SúRé0»×÷WW,Ô`5±bCÊ<á §¡ ±ÕPŒõ!­Õ™°ò ¨‡ÚޟåÔ#Xi$]BÇ9°Tá®ߤ¾Â՛P®1Ïh”,o×S >1þA¾œ\E4|œO.¯'_¦W“ë‹:K˜ÆuþrÊ|úë¼iŠ‘ì@!½kPHrÈ8û–Ĉø’ˆçm‰ã"ʧaC³T$‹×-+ iÄbù¡Èqcà‡øK’Óæ`É2Å´¡Ý¥ÞçÚJ* oó—ÂÁù5{)™º5ºMkÜ!îç᫬45oëÓ¶%Ç2z§ö¦…ëlÕÒ^}—¤Ñªˆ)|Yþ%g=ÿh0¢xÕbÕ:݌hÎߝ?àøQ‡‡8/ìþ9{ï«Ö½  ÔÉÍíôn2¿¼¹®}žþöËÍÝ9º“R>•ïÃî¶É¨ `W‡4£&«œ½+LÄÔ¼ÁN/k ¶øêf¥+M͜/aûÔ ƒj­[Ñ0-Ïoc(b{–_spa¤%˜½ æm::m $ÔÅõ(ï$rÈfÅH„õvܛÈðïuŽîrñuã–@®êc{iüý€.ñh/)/™ºü :5äË襆ÔM/ ùU\áto!Dö²&6­AK¼÷k0t&fï,݅é²{ßÛÁ2d˜ôNôfÒ+øOLy1(Ùr‘ÞPf {Cќ­ +ù²þåÉbŠ;ìø˜ZuÓKQž³]ƒ+¢¢Â/éAÒñ\Õ6…lØ@ hÂöÎՌfØá +Æ»……ã°ärñ¯Ý›Ë¬bo.õÖêÚ¿±™px0,¿ ÁO÷·3˜±…x ±5»ålÉÃõ3| Ó"\Io§²÷%p:rì֝xÃqù%¸IÌÏÿ\Qendstream +endobj +2520 0 obj +1198 +endobj +2521 0 obj<>>>/Annots 473 0 R>>endobj +2522 0 obj<>stream +xڍSïkÛ0ýž¿âè$°¨’+Û1ƒníF?ldƒyá(‰‡M¶»ýù»“â\‡ãè½;½»{÷k&€ã#à* _ZÌÞdzˏˆâ="ÁJ@¼›gu}«ZWqVèdž,ñOǓŽ·¼â, æ¶QíPÑ ô|‚ZŒ}la”+­ÊÆ>véQ$ìý.ďdqýì/¢L7æÐºl‡û á‚cD$XˆÁx|«›Ôdu›U%!wñŒ3Žø÷zør…l?Ìx /ðÓhØL=!°nÇö¼#¶m¥Jpÿr7üQ€9À0 + Pé‰+ÒÖdä4»ê·QFL€DÏYËÇíz›jßþV軵©F…6 |Ve§rÊ·tAËг;!$§SÉ%óݖLÚ«þ:û ¡Ó@gendstream +endobj +2523 0 obj +514 +endobj +2524 0 obj<>>>/Annots 475 0 R>>endobj +2525 0 obj<>stream +xڍS]kÛ0}÷¯¸°—dU’%Ð1èÖnìa#[Ü·Àðl%õðW%{]ÿ}¯,» ‰Ã†A–}Î={õè1 ø09ød•÷!ñ®>ÅÀBHvˆƒ$_m{«JÕ©íb»\&¿G8Îʧ$°¬{“î•C)Ä#È¥…þ4EG*¸ýÙÁ[|m—×g‚<¶57zßWªîŒÃ%0fqF9á§Ka1#!–ãï[e2]´]ÑÔ¹K>>>>>endobj +2528 0 obj<>stream +xÚ}‘?oƒ0Åw>ōɀköHÛ¤S¥4-‹›8ˆŠ5FíÇï9„(ª¢‹áÝï|?QâÏ¡ ž‹ài­€¥Pœ°’HÅqQõýºj™s¶úÙ/öËeñ5¡bBȒÄûA—ÆWQá^Ël96¦uÃÔc¾‹qJ„\Ý2aŠ‘/EùÕ [õ®êZ_Y%]_Û7é8åw9w2…s­ü̅:Ó)Q7ô¼þe§8’Dz[ãFÛ—­¢{Æ®úêW7}ý?ÜÈꡛsB\ +t„¼ì69äÝÉýhô³±]iuÓ;À»nG]ûîpj +S~Ç÷ª 㧏^ £ûþÏ­€¹endstream +endobj +2529 0 obj +284 +endobj +2530 0 obj<>>>>>endobj +2531 0 obj<>stream +xÚm‘?OÃ0Å÷|ŠÛ!&g;±=(, •&ݺXÅ Aù‡>>6Iª +U–<ÜýžïÝóW„øƒ (° NMt_DwO +P@qöL"﫪ï_L[ÇÕq½.>'†OLÌ’êàtiB××8#4Ô6¶ÓnR¥€THÂ!¦êš *$Â?êˏƝlÕU׆ζˆ’x»—kÿ \z:”ø%þ”¨ü\k ¿S†.´ êŠ^öžwJ™$2˜Ø›a´­›·b·Œ]êÛÝôõÿrc`S»n +@.pE¨äޑ‡àá°Ë!ïÎ÷ö~v¶+­nc¼êvÔuPǓ(4¹ù)<“KvÈٜÙ[ô :){!endstream +endobj +2532 0 obj +276 +endobj +2533 0 obj<>>>/Annots 477 0 R>>endobj +2534 0 obj<>stream +xڝRMOƒ@½ó+&ñҚ”²@KIÕ¤Új·Ðµp)û©¯"Ã2­j:hc´­ŸèÎdVœç›vsH!¤Áùŗè$]ÓhUÇSÔØ¦Ùé¬ݬÑ1×7i<›)ƒ‡MB(öúÌ%B ÅAò,C©à…ç%OÉoT‹Fžm‘†¹.ݺ®V˜«>ߌoAÞÍÈendstream +endobj +2535 0 obj +363 +endobj +2536 0 obj<>>>/Annots 479 0 R>>endobj +2537 0 obj<>stream +xڅS[Oƒ0~çW|‰/›qŒ26X¦&:/ñÁ…½-1Èʆ‚¥¨?ߞu›·©!iÓ|—óÓòl18úcð] FHKë<¶úWc0q¦‘QÀ/:y]‡•TóμۍŸ Ã3ŒÞÀ±Gę5ɒÔÁxºÃµ\(ì,^ª|1ïN~ø¸c¢ÞsÕJÑÔc[Ô'4^q,x–´…B< û7!jm +і\"«$nÂ’?·¼Q½§ˆí‘ÑoR™×*¯Ä¥¶Ýèç¶¢²V¤d¦K¯óC}JJ‘¾Çü?âå[RÖÅ/=ÈEZ´ Žã´­›þJ©Ú^WS˜c{H:þÇeæÖHù pHûd†Ð6­„à©nœ"._¸¤1áÓL~¿ÔˆsœMEðel9¶£_-Œ–ûk:`àùºl‰`¨Ó›Cˆä7¾\âãRH˜¸_£­{Ù 0Ø™7¶>3ÓÆtFˆªL½&’#”ÕR&eÉeƒÛD´IA~=#êù®³ç¯ðFíc0o¸éõÎzç +íËendstream +endobj +2538 0 obj +403 +endobj +2539 0 obj<>>>/Annots 481 0 R>>endobj +2540 0 obj<>stream +xڕUߏ“@~ï_1Æ—ÖØ=–B[ržIõÎÓµ¶\|irكm‹òëØ%gbüߝa¡½5mX`¾™ýfæÛáqÀÁ‡ɔþA2xç.>xÀgàoÑ2sðÃa”ç+)ÂÍp3ù? Â1ˆñÄbSÂÜ)±“ÆjWm·v¿WZhy¯áj¯uŽÏ¯h}M¯é—Íè²³‡íQ˜E±+™jeì.pNvnÙÌncÂ=Îf莯¯¥ +Š(×Q–’åÆXÌÂÔ—Õ-8sD»SŽÁ¸ëÒÕÃK!aݶ­ ój´=q˜ó ]ÕЩٹEÅØ6ñ d+jÕ5/á£ï/!ÈÒTgPtlfO±B÷P4ÄLÕ°ì=¬>-—ˆ~,¥Òx«ò,Uòìl›ÍÏgW¡{ xl¿ã¹Fb+©Ë"­Ûߘä1k(eQ`÷1Œ¡’ënÖÕĉˆ¢©{§!lË´ê^µ¹ªª'´.¢‡RKÛ"K@c@•Ë ÚF2lwÁ²Èv…H¨}VÆ!m€\øÄh‘:JKLRÄq”îþƒZ‰žqïoV«¯«6{ݽ^ø‹62R˜,õD†§ë|óK$y|b4¼ŒÒ .C o‚2Wt>Øþm“¹…âè‚0Ñ#ÆæFÏÇÉeËÿ8\ú,Íd¢µT—­¸ˆ€+O_ä•¶mÚG±´ ¿G\5Ú6£Í^\Á¡ä¦EψD[8Æ0P*yà%ö³ÃôÌ¿;cæÄˆ0ŒHŠ"†4KÇ$áPh¥"½Q:Âȧçω±½–±Ê:sƒ×£À¢qÆŒ’ÀÌÆdÌCl&A _ìà(LZÝC'¿‘–ü[§r›7_ Çc¦–c¼¿[®amõ“ÀùSŸÂD +>‹´1ŧñÌ®æ#w¦ơ̂֙OLëøa¦ßBïendstream +endobj +2541 0 obj +708 +endobj +2542 0 obj<>>>/Annots 483 0 R>>endobj +2543 0 obj<>stream +xڝTmkÛ0þž_q°/É ª¤ø•nƒníF¡+YãÀ>Šp”ÄÃo“ån?:É^V×acœX÷Ü£çîžË÷j> B«²rö>™]|Œ…ìM$ˆ$»yÞ4I^ʤ¾Z¦ót±H¾9œçpË%"·­8H¥÷Aî÷$]vêQÃë£6¿Í1~¥‹Ëì2šÍ†UôbÂÀ3–³n‡Ûõ6õ^ÿÆvkU”(K©Zø,ªNÈ·tIːӳ5^ ›Ì¼°¯úË쥘<­endstream +endobj +2544 0 obj +510 +endobj +2545 0 obj<>>>/Annots 485 0 R>>endobj +2546 0 obj<>stream +xڕU]Ò@}çW\㠙픶Ьk‚îºú "tã ɦÛ0ZÚngLŒÿÝ{;-R"2¥sÏ=s¿æðÜã`á‡ÃÈ£o´í½ zW|àcVhñ&‚¸/óü{!µXö—ƒAðÃ@Ž,æèA…ka¬øµÑvkÿG¥C-5¸6Zç¸ñŠž¯iŸ^ð±\ŸbûÄ3-ÖåV¤Z» œ“[6³Û‚pŸ³1ºãö­PQ!s-³”,wAÏb&¿_æ÷àLízɸëÒêãRXt€mkÄümæ¡«*:ut®E¬ÈmS”lZu@Z°ð1fei*¢ Btlf]b…îÑfª†eïˆêÓl†èçR( Y?Už¥Jü#:Ûf“Ë£«Ð<´ßñ]3cs¡Ë"­ÛߘÆc܄•EÝ‡ÍTCÇ:¦ O;Š3”ÍLSÇeh¼ú°*ÓªæxU0ÔºO%½ê 4ª\Dr%EÜn;ƒY‘­‹p«@m²2‰‰cá#3<ˆÔ2-1Ë0IdºþŸÐJtMÚßãÝ|þuÞFc·; ·Ó`ÚFJ…-£®ˆø|¡ï~…Û<9£/e%e,àMTæêŠnÛ¼mR·pî4nµHv™@÷¾9Ä0Ia%ËÁr/n`ßÓÈ£Ãä +$Jé@<"üy’Ï…¿O)SdŒ)]I&f鐿<u¥¢±¤töƒxT‹†èÏ}_ÓDe'ÃkͰH÷,×-xÞþ%1’ÑÂk8Ì/A›ÿ¢9fÐ\‘–.U>“æÅñW~ðþa¶€E¶Ò»5ª¾¨[Q(ø¦e˜Ûи Çv¥¡Ü™Ð®3òÙȨjû†b–ßz]ºûìendstream +endobj +2547 0 obj +714 +endobj +2548 0 obj<>>>/Annots 489 0 R>>endobj +2549 0 obj<>stream +xڕTÛn›@|ç+ŽÔ»ª7»ËrSªHi.}ªâÔäÍR„`±‰¸•…¦ýûœåjÙ8M…„€3;gvΰ¿ /ӆ03¾ùÆÅ½Ì?Ɗí2ð£EYF7i¡äv±].ý—":ÈʤÄÖ 'ìdW¥àõEnéÒï"‰`"Á§ç8Iås Ÿñy»¼0€ÌLõcû»?AV¦gõ)Éô‰$| ›R] .²¿ÒP`]RvyZžâx>‚)á:UÅɤXo>¾€išèw¶=¾¤÷Gøj“*Ɣ<”2|md òЉáÈ­s­èØj̤6uìö¥ë{ÒA÷Ñ»’˜0vϹ‹Ùú°¦a ÿ/ +‡:ȚkàŽÇNÚt­.ðpó´ÞÀ¦ˆë×ÿŒuUìª Ëd¥àG7AªéVLx„ÁÊátîܶ;œ/ìmy4ÞXJendstream +endobj +2550 0 obj +507 +endobj +2551 0 obj<>>>/Annots 494 0 R>>endobj +2552 0 obj<>stream +xڕ”[oÚ0ÇßùG&ÁT\Ûqnê4©k»iÕXIß"UYâ@¶\˜“¨Û·Ÿ/ 0Hçöóÿœã_X¾XŽzÇÅäc0¹úäq!H¥ÅñÉt³In«2ͳ¸©Ãi8›?Œ3ns #G9>Õъ+¿3R[™²²óȧç4Ëùsïäïpv}”—ú*ôF¬Ú‚—Mmì6¢ì„øˆú(âäÊpù÷¯c‘mš¬*•å>˜`„å™·ŸyÒÛvˆLF<•Rç–ÎÔr‘ßySŒÛóÖâ±ŽÎÆ*«ÌM;5™Î¯É‚5‡Åâ”ÿAcáóÑ´÷ ÚNX›0ä)ŠGÞ´¢ì„íѕðnÏX¶Åw. J¡Ò2BÜw²é¡N€Z'Ž;0R¥Ÿc¸>r +i[ÆF~ͱ#Ý!¾dÍZãV9ù¨yÎã†'ÝyêqôûßQ±ÉGæùMVÆy›px·›úJ£õåª<ˆY‡ƒ ¿>4 ¹i8½x›ìÃ°¼¸<ޔp6¾KÎá&¯«£1"Ýd`5®#[^H =ùmžr3b»V¨@×̊:çC$~~5ºõ}¬Hˆ+'·¯I±…챚x[“m›ªíêë^êé8©ú¢Ùxr‹bO +‹ê->«?Å«°ÔO£6oN+fQgO1FííÓhýI^fzك •ðºˆ9q)"À57Ü>-–°¬Òæ%’WÌBT+5>>>/Annots 496 0 R>>endobj +2555 0 obj<>stream +xڍT]Ú0|çW¬Ô8AÎùÔU•h §J­J{CBQb¸TùªãèúóÏk;\‚@HÈɌדñìþQ òGÁ·aîARŒ¾îF«¨»£D¼€Â.×u™Ø÷“Éîf8š1›ËCÎKŸ˜F „´]„²RÀ¹„\ŽYÎäz +«ï?"xÀWSd–ˆ¬*%nVûÉÓÅ©vˆ…üÔ¬Æ] qJæ–Óç …†Ôòåvùzɚ„g5ÖG$ڍˆE¤ç¿Í38d»µl ®/×4”KÎ`;@¶‰'Õl{N­ð?¶rÕ1ê\‚UemÛX«”©úJÙî•Áz½tä†4ǶÈýÒ{@š¤ÝêíéÁ× *xã™ÀÅ ]¶m÷ëR쫺H(Q)Äa@\¥n±KËYæ 2#Þý{ðZ?BéøH•¢6L´¼4¡ì®Cë#JŶIšf +3ŠŒóŠ[)×{a(Š>tͧ¡Ë¦í6áؖ‰ñ¬L¨¹ìPÆgM͒ì˜%£IU1¤¥B`p–ª<\—ý‹‹:¿2 >ee’·)ƒÏI[7R¥õú©È z–ôfÄÓ%|ž%ShDZµbŠ=søµYF›Ãzñ][Æ`‘7—¦æÊ‰j“@~K~¨Úr}ã=>?Á‡ç¸Ïx`4®ÒÎÿ^´Ô¾ XNhQ™K3JáÛËz Ûê(Þb´5¯N<. +Æø—mœc½™Þ4óm20¢/èZ„ºÔ|êïÑ;ø‚:endstream +endobj +2556 0 obj +581 +endobj +2557 0 obj<>>>/Annots 498 0 R>>endobj +2558 0 obj<>stream +xڍTێÚ0}ç+Fê TµM.D[U¢…ݧª²oH(J6¹ÔI´ýüÎ8» A 8>Ç㓙3ógāá‡ÃÜ¥o”¾£‡'¸A‚ˆ»àÄ㲌×YZ?Åûñ~2 ~·»åÌæÌr‰õR…GÙ¢ | +‡ 4¯áC\’ô$5|ÆõOðŸ€JFuZ䈙Õ~òxq§ð)ìR›LæuÕâpN8gÌrú¢pŸ[Ç핬"•–Ÿu0bÃdœ¶Ï`/í¸ÜÀn-€û¸Tvd¡/mÙbîýÇÖYµ:‡QTŒ-Ljµ2_+ ^%l6+ ݐf ‹Ý/M³¤µ‚Úl%CjH Ä&a…‚º€7•Ö7 +A—Ý+P³¯ +d>î£"㊝….gg›³ÌÙí{·Fͬï»;mϵlµ•u£rãήþä^P$¶‰"YUS˜qz”Jʰ{°çځ ”‡®[h¨{»ccHš<2YËã +J…­(Õ¬*e”&iÔå4*²,$&µÆ+ .ã¾9®k_ÿ ³òte@|JóèÔľDMY= dëõ+Q‰ÁÛùқ—ð‡ù2>¥6:üÜ®ÖÛÃfù¼¾>GvRÂòT]º™›â3Ý9 |‘ \÷üpjkßã«#¼gŸ¨&F`W…žÅô©E7ÁlßâèO3YáûËf»"©ßB4ÜFGf™Tüó&>>>/Annots 501 0 R>>endobj +2561 0 obj<>stream +xڍU]š@}÷WÜØw£,3 (±mb·»}q[»â›É†À ´ÂP²›þúÎØE4Ƅ÷Ü{Ïνþ °ÅÁƒãA” ¾ƒ»GЂDD¼‚ Eü˜æñýž¥ݎ¶77Á/#7ql˓ÈMÚà› vM‘—HUxápÛ))ƒ¬à)ËePߍ!byÅ!ڇ%ÜêÔíÍü¤7öeùE¹«3šóJÇ]@HƑ=µp#!ÈGÖT¤‹×_i•©ê)#ÁÀ¶l!L{yþd&Ю‡D1乖È·%…u#bٍ1y‡V +ÃεeUQK¬¥ [(r (XšsZgÀ÷Ø5D ®&ªÐ=D5=­Ö¿C.|ò0¤ÅíºÀ ckv=7…îñhâ»Ú~ϔ×en,Ј,-2í•RӅ8ä!°¾o–KH“w!F+Èú–VÜêñžEz,ÔÓ\JÕ †«&uIG²¤8´:„—Nˆ#ÈwUA£4Iil¬ržõÃ[˜‡3óú!Í£CSøÕEu'ÈZûÏ*Hë-Ç6IÍDÏMÙ⛙pwªû0ǵ ïæ6:>Qì‡zV[c ÕX9ëô/šåð_q#O›ØHÝ,˜á’r¡æðüZYS +‹CÅN<ŒMm5:®pf&r]5ñòzÐ6í$”;8@&zzô ¿§°üM;†è튱PÛ§}:ék·}c!g&tm{•//ut×ÄúZÌÚµk¹b,ýà~³ZÚ%ü5ó»*Ù® ³Œ–<…yd¹ "¾8ÅdŠí³ÿ9ě5K¹ŽQççà“HÉ×endstream +endobj +2562 0 obj +639 +endobj +2563 0 obj<>>>/Annots 504 0 R>>endobj +2564 0 obj<>stream +xڍTmoÚ0þί8u_h©í¼@Ä6©ë˾´+𠩊¼’8s‚Úí×ïl'0 0D„œÜã»ç_ +Ü@?qÖù2í\?„@0MÑ )L“nQ$"Ož"õʓۥ1Ÿw痗ӟíYtß%N ñ³2Zpk%ÖFæ×®^bã᥂«VÇ’ŠUèA,ó²‚x)¸zå¿ß¤J旣ƒè,ÔnÔbñ¼*­ÝJµ’ãíc4„†Ôàuü|ÇËX‰¢2זûi‡8 ´ù{þ +ÞÑ~@4ð1]âQq˜´€õ·F3æ9ä´©´W³ó‰öоY]#ÃÌø7̦Kãñè²ü‡šÇt˜s©t 5KÈV«.y ¥<Ê8È*<ËsêÆ˜3<ŸœA·ÖmÛu/ô­æžyµVyÝõ¦®ZÓq(¤È+® ’†®Õ $QTðmöø"Ý1I^B.+àïå‡ aß3£V§E¨°Cµ°ÑµkÆÃšNXã  é:µc¬…I¢ýÄ,»üRä®MeÁc‘ +nZ‰d¨kõf[w<¡û÷(+VGúƒÈãÕ:áð1^å5æá,?×µ½Ù›èQŸ`v‚=ö\Ôù|‚c+£cÜ:ñ‡_ßÎáfUʝÒZzDσëbÐ w†Ö–}[Yéí]P ØöP_ô6 k’»}lG‰çø›ˆŒ¸›·ƒˆd±ÑCnCöŒ¢NñkX}7ínXµùn×ÅÉõ­ àv6žÀD¦Õ[„£8Vr¡¢,㪄§(_G+í®O½/õÌl ê{ú«„vkœ9–çGç/^$¹Zendstream +endobj +2565 0 obj +632 +endobj +2566 0 obj<>>>/Annots 507 0 R>>endobj +2567 0 obj<>stream +xڍU]o›0}ϯ¸ê^Ò*¡¶c (Û¤®{i·¬!o‘*&aÌ ¨Ý~ýll’Ž@EŠçøÞãs?òk„É—À́0}ñG—w`üX"΃‹"ºKòè{Q%<ߌ7ççþOÍ£š7!ËQÌul™Fx$¶ òěO\tB*0NRf  „ +«2ÁԚ6!ÔBo؍»Ô¨³‘Š*cãN£¬‰ß(ów –ËP¶üG%*Í©Òv4-H»e,C%Ÿù)¾bÍO×°{};Tz¶î¶GVÕ"7Uo}U]á6‡‚'yÅTü\ˆ‚*.àÛúþ’øˆ³r^{MÊÊêi7ÙPÇ]ӓ\YÕ΁††¦¨=:†¸ÎÃF†Ð÷‚à½Äò +ê]Y°0‰tXõíkéÀx~Hò0­#ú(/¥Xk÷YQk¿;Sº00F²fG®ŸæŸàxLàl)·Ç*ùÃΆg}Å\¥%?ê:l ©î¦Ž””É  :EÿJu#uˆ-J¤ºû»(y×;ž„¬-Vo>Œ¨eï3:³ðPF´ÏØÝó)'Mü§¯UõˆgÖÑ֗e~X5¨Kôªëõr+W/¯¥à[d%<y¤*ÜSOšº þPgÞ®QlÛÆ £¿>>>/Annots 513 0 R>>endobj +2570 0 obj<>stream +xڕ•moÚ@ Çßó)¬L“ ¢é]¬Ó¦®í¦I«Æ +}©ŠÂ²æÝ%bÛ§Ÿ}—€šFKU’Øgÿbÿíþêq`øá0òè7ÊzŸ½‹Ï>ð ,b´xS‹e³Y~Uw¡|Ë  ‹ŸÆË5^ç#f{ä÷ Â•0V~mtÆdJòž…Á›Ç8IÅc gx=„¨ÈU Ñ:”pö$þl IéÖ<‹ÖE‰`pù"½ãS†+¹ª2‘—ÊØÇÀ9Ù}ßµ]ȃûܞài||#T$“M™9Yn=f3,ÌîÏýp§è=ö¸í`^ßvûx)Ì;œ¹?µyíí¸ŒÎì¼u…ÝnÌ(*Ævê2k2_“-Öf³ BýÍulv:šöî@3@¦Zu:ò0PÄPâuqJÝǞž§½Â1­bôpì}@²ªødHíÝÙܽ2݉‡Áë^”•Ìke6Í'åNÈÊ!1´™ž’!úhÛD »C÷&zK¿¨,Í\S÷L7ûWy¤K' :lׂH ¥ÆU%q"–Ï˼ç?Œ|û;Ì6é]ñ&É£´Z +xUu¤öú¹’7«¦µ>.Ûf‰ 'úÖ7Q–H­’¿Þ*P"Q‰dA[ÃúgFQ`~ÚkjÖ ÷ÚCXxm"ZÁ>‚•( ÞÑÅ:¼œæBÀUªŠ䵪Í£3Aú {0¥Ðw©QUë€\Á¾•tpj^›êEäßu?TÓØÎŒœOPõMN‹Àåd»œ@8wh·5y‡Z]Ç ©×E§ITçrø˜&«æ1ŽŠ9™«yWqµç kÄ<Ûßa¹8ó¯(Wó¯Â"¨‡Uº¯Ø±$ýáquq2ú‡ØÜœ&.ì‡[Ü^[ǀ¦H\_oJ×¼5\?Ìæ0/âr⶜Éb%Ã,RÁ]˜WaJñÎÍ¡ó‰£÷9{ôÔåžÍ͆ïî׏Þ?H¨.ðendstream +endobj +2571 0 obj +748 +endobj +2572 0 obj<>>>/Annots 519 0 R>>endobj +2573 0 obj<>stream +xڕUËnÛ0¼û+èÅ.b†¤ÞHQ Ó¢‡ n­Ü ‚DÙjõpõhóù]’’X²jÀ`jgw‡³Cê÷ŒÅ‡ƒaC˜Í>ù³ÛÏ0ü#¶ËÀæ‡Cô”¿V"š´®¶óíbáÿÔHS#—%¶Ä>WÁNè(¯ rK†þIƒZøâ%NRñRÃ{ü¿]Ü jsO¦ß—»&y]鸌É8cá§ a#¦ã땨Â29ÔI‘ËÈ£?£„âÖûǏ/`ºˆ¶l†Å˜+Kªº¥€Í˜ñZ4§”˜oÐJC³egQYkóVHÅLÕWÌü½€õzRÿP39¡—SSèQjGa-fwDŸ#})¾Óñ즪Cç]Ñ%Ï!nòP… i +E 5֊t„û" EI®^wRàNÈãkÒ3{—äaÚD>„Í¡ºE†dÿQB%‚iƒžøínøó¼'7BÀ}ZƒÑ±v¸Ã0pªâ¢Üz•êiœ$”;8 +,Mí¹Éê›Q/õhGÆtKד3Jعž´ïiö‡‰#°ï{£f>ERÊóPäqš„õ4/Î,T¸ãeP†ó¼˜W·«x}Uš‰h’–Am<.-ÏÊru»¸ŠÖØ¡™j2¿™v—Ï <¯_\f.þön×Κ¢ãv1•Džò?<<¯7°)âúo€7̺,vee¢¬à)ț •Õ–:eép:ñ51m·»®™å´[þ>û + endstream +endobj +2574 0 obj +568 +endobj +2575 0 obj<>>>/Annots 525 0 R>>endobj +2576 0 obj<>stream +xڕ•moÚ0Çßó)Nݨ¨k;Ïê4©k»iÒª±BßUª²à@Ö<0'Q·}úí´P8¹óÝÏÿ;_Pü0°\õe£‹Ñ姘‹-®Ï`±o6ËûP¾|ÛTI‘?Ÿ&“ÅOãg¿ ‹Wy>–áJ+… 1rG™’¼‚N ||Ž“Tž'Ci|Փú)5õîl+Øi¬66B¨îHËVïތŒy؏mNÎ(aC9é6g[7Ƹ7mÞ©.û!H%ÚMÛs¹8sTÏ7\eø{4W{Œ“¸¾hÍÄò –E]l±l¼'È՞â$,u+â°NwŠJ2žî.î`É2‚íÃqÍÅÝíŒý«Üä·Mb+‘ìÀ23ngs˜qõâ›Éb%Ã,²„û0¯ÃTÅ»0›.<®G,s|õÖ¦6qÌÐí¥ÀCý̊‘endstream +endobj +2577 0 obj +685 +endobj +2578 0 obj<>>>/Annots 529 0 R>>endobj +2579 0 obj<>stream +xڕTmo›0þž_qʾ$UK11oÊ6©kÓiR¶e ù©¢`R&À̀¶ýûm YBºNH!øž»{îî9ÿ0ñ!àZ0s ÊG‚Ñõ½ą A‹ãâIYÆ_KVl'Ûé4ø®T#®f¦áH̦ +wL[Mð[£e·îIš±Ç.úP÷Ÿ– ¸ÇÛéü$ªåKDZkrVԕ¶Û@ˆ´bä#!Ä'†‹îx|ǪH¤eòBZÁÈ4L,¶ÿyøÔC´í †$>þ Ö` ^‹¶ˆgØhÕ5Ú²³Mc[’‡,PQS µà™<†š£{C"xþ’Ô2ÌדTèA’ûۄ"é<°ºEÛâ®9WµJž5’m«Õæ^Õ¢‰Ð‘ðe³\Bš@•õˆˆ7Y ¯á‰©:)t`X4dÏ:qiÓ©(;§ $MÉ`*muH[¶ZѬJ¥IÊb}Ž%rÈYÎÅïó4¿Â¼ÌΈüMZDY3x5euìŒç÷*DïÈÑ"Ì[3ÊYMb¿ó#GÅñ$\<–ŸE˜3ƒŒ/a,žÆíDCºô]:Ø´Pe¼bYöpÍÜd?)iugJ½QŠmÊñ.AÎú#Ó²;‹ìÇ(ýlÝ^¤z«Ùè‰f°ûTßä\.³ÏÕ ÃqöÉ.•œ^bÖ ì>~‘¡~_oÖLÆ5£®€ÿ'%çÕÒJàu—P—j Áífµ†5OêŸ!®íJðóœ‰ +>‡Ef2֕,ïV×2.~êxÝýJl¿mÉ·Ñæ•Cendstream +endobj +2580 0 obj +619 +endobj +2581 0 obj<>>>/Annots 533 0 R>>endobj +2582 0 obj<>stream +xڕ•ߏš@Çßý+&×mNŽÅ$×6¹žç½ØÓ*÷ÐÄÄPX<`éiûßwv”(^¯jHt¾;ó™_ëÏß&Žü„Ùà³?¸™{@\ðc´8S~4,ŠhY°|m‡ÛÑÈÿ¡5TkÆÓp¤ê¹ öL[Mð£e7vq’²]ï;Β¼‚8ڎnÏ|ZžÇì·Ã+é#2f “«kXîÖ³åÓâ[³]hÇS²V°# +S^²Ž©g;7ŒÁ]Zò³‘%Íšjú(Ö)×Bbý%ÕCx¢{86Už³u}‘ó^³èîöFr‰aB¼¼K±ÌC¬vHçìZ ×kdí¸½ŠC&úky,ËR—ÆyZüÿFšã´X}¦my7Q—ê‚ûçÕ6<®~¸Å+Á÷"È2&JøäuJwcB=ƒÀصÔ%FSþJÕš½ÿX—¯ƒ¿Á"endstream +endobj +2583 0 obj +632 +endobj +2584 0 obj<>>>/Annots 537 0 R>>endobj +2585 0 obj<>stream +xڕTÛn›@}÷WŒÒ;ªÉ.æb”¶RšÄ}I[7Æo–" +‹M,]@iÿ¾3,àÚÆi*$;gϜ¹þq`øppM˜9f£þèjáwÁÑâÌ9øÑ¸(¢¯…ÈI*6ãÍdâÿÐ(K£¦3f8„[—ÁVh+¯5švKñãý§ +.èB™—„»@Á%ò ›Éõ‰Ó#šµ­3‘W¥¶ÛÀ9Ù=Ûp!„àG£ã;Q†*)ªDæd¹÷GÌ`}ÿzüÖѶà ý兔‡ŸJÀjLܬE›–{€nÒhµâlF¬Èm’Ž.ÆF^㤑çïÐ1È*ü&Té‚b%³ˆF&özÑ zPô>ã6·Œ9I{U­ò6ã]PT·I72É+¡HmËåÖ^Vªñ"F¤àËúáYeFË +¾‹&Nc è†5P¼”¿®ó´i¸k»‹cˆë<$ÂÆuù·tJw#• +é3 QB&2©~Ÿ—yÿ+Ȋô̼Iò0­#ïº(¯P±û@PBp=@GSr}j†÷p×E×O_œœ•p“–ò¤xÛŒ:Âu°ä®ô§RÝGxµ…}¢éž«[5ܦ²ìó=èÉå†Ý»â¸;¼s¾Xï«+›ã읽m +þ’²®^”ÃgV¯Óc2¯OÄ+ôtòÿ[Ò"êD ÑÏ;zZNk³:àv½\ÁJÆÕs€sµTr«‚,ª„ÏA^)ÑM¹å¦®Éάn˙wK‘;¼ÍË·ÑÀ ‰›endstream +endobj +2586 0 obj +588 +endobj +2587 0 obj<>>>/Annots 541 0 R>>endobj +2588 0 obj<>stream +xڕTïo›0ýž¿âÔiRR%®í@u›Ô­Ý¾lRÖPí R…À$Lü­Ú_¿3†0h2E†{ö½{÷οf (þ¬7ê ÒÙGwvóÙfadc3pÃyQ„[/¾Šl/ÞÜ[,ܟghÜjMÉF!Ÿ*Äé(§ rS…¢$÷% ŽÂ×ç(Nij„k\/!ȳJBpðK¸ÎüTx‹Û“dÜQçݕû:™¬tÜÆTœQcˆPæ0báfü|/ª Œ 癊<¸3J(êpü{ü†hsÃfÚ“;¸,ìFÀœZX½FsTÂúÝj´ÜL3ñlÞªÚ0kÎo˜¹Ûí=(EÎP38¡—SkÐ#Ô4!­–R{„ú y×vªøÏ9rœûrr zT·¾ç†cjƒ= +Y—YÛóNWå «#œ4Öê(W…â(aO⠊ÔÛa¸D=#o~¥ë‚÷ð–ÐÈó²«åÈÈ/qRŠòÊ[LøN¸KªüÄl¬õU¦6•‡R{eý–hÿ 6”{èÛ 6ÚÇÊN2š¯böJÖSé1c×XÇéS.S¼Æ¯cµÃ®¾Î Ã>rⶺ[.æÔ•ðß´~Äa¯ÕX»Ý°2Ô¥hàÕØØ>=mw°Ë#ùÛÇ1ߖù¾ôÓT”|ó³ÚOÔy+f8„ÁÊâÍ%Ä6\}5(חÒT¿¾Ïþ’»¢endstream +endobj +2589 0 obj +618 +endobj +2590 0 obj<>>>/Annots 544 0 R>>endobj +2591 0 obj<>stream +xڍUÛn›@}÷WL]Ur"›°˜‹QšHI“öŭܘ¨/H…Ŧ–ÂZ‰Zõß;» ±ƒ×NdÉÆÌ93gç¶¿Lüð,˜ºƒë`pöÙâA¢Å’QU%‹hE—َ““à—BÙ +5™š†+p÷ ¢”Õ¿5ZNëâ¡Aþ‡Óî„!ÍòÎ0†˜• ‡xÕpZF OÎ÷Z¾ðyU¯6-y£ì"ìÄ´û >1<$ãëÚÄuVñŒ•Âr LÃÄL<Ý}{†hÇ%†ęÜÇǚÂR¶L3 ÐfÃÛA˔ڭ6GØômµI‘ʤ©,XSX,n@däi¶e˜o—&ÑiJÊ–ȶFx ,ŽÏÖ D_gYÆìíâ$Z›·mÍmßQMvGù¦.ۚwy=áɊCŲ’Ó8{©½Æ¬Nº“4³4£É"+»V÷ûù²Þ±!a´’q OYà Mg¶¦Å4JEj»YQ&ýœuĤ›2ñ$2úó¥¨ýÀ˽}ŠŠ*?0»ï³2Î7 …ñ¦jÎP¥±¾P ª*½1>oÍÄÄÊöÆ_üž÷èòÐß cÎ)ÇjÛ-°ãK*Þ» Y,•°ÄßÞ€ªÆê¦áh?²„¯1âÃLðŽe‚&—âý~°꜖+-5—†£\€9M¹–›òãÌ»lµÖ1kñþ(õšqÎ + õ§4¼"Vi¸œUûÄõ’R¸Ê¶·4H»L±Êl{¡Àõ-]ýËÕèêl‡Fì@ó¹E÷¨u¤‡W„ál#ú®ØSúˆæsÄn}r,Gø˜¾N•l¸N”Îýl{E¼JÚÁ„O÷‹%,YÊ#\‹‹š­ê¨(hÝÀרÜD¹p7Ú L<Ë>>>/Annots 547 0 R>>endobj +2594 0 obj<>stream +xڍTao›0ýž_qÊ4)©R n“ºµÝ—Nʪ}Aª˜ÄfŒZí×ïŒCØXª ÈpÏwÏïÞùׄ‚…? +˕~’bò9œ\Ý@=3Œ¬| +a:«ªtoÙžª]4‹æóð§9v¹´ÈJŸj„™¨Á>h»:”åe¬àßLøöœñœ=+¸Àõ’RÔ +’],áBÄ‹æ×'µì@§»‘Û¦`BÕ&î¥:N-ç¡4 ÄÃÍøù–Õ‰ä•â¥Ð‘»pb U8ü=~ÇG´»¢Äêú‹¸” 6`Ûòððm£Þ_èVNgÏÍÕ1sÛ{M[fmþ–Y¸c°^߂Vä 5Ç&ÖÛ©µèj†QK«=ÀG†2…ë +5ÿ}ŽœmÿíäZô n}ϝÀ5þzdª‘bßóNWí ¯#ü¢Õ1®+–ðŒ³´ç\@Ur4”·ò£³AZ²D©€½òZ‘ûgÀG#tºY0¡‘AêvÎ kD¢3¢ +íA{nçÎ5Nôî5.ª|d*ßq‘äMÊàCÒTõò#»OªԈ~4¥×Ça‰jfÑlڞ +>Â{beQ$¦‹Ói_Àô)Åä4šÏö†1¸ÉëòÄgtoKûÙÕö)pâµ7Ì[n¬s´An¡oÞèÎ¥Ù=0±í»1Xoâö‹,Ç*Z‡Š]Wƒ /¹h ñ?~« ö´ã4”Ýï/ +^>m¯áËÓz›2S/1ÒZ–[“5|‹Eç:Ý%uÜtéÙí˜Ó•£¿:8Ž®ü!—¢.ß'P˜—‹endstream +endobj +2595 0 obj +603 +endobj +2596 0 obj<>>>/Annots 592 0 R>>endobj +2597 0 obj<>stream +xÚ͛QsÛ8€ßó+ôx÷PW¤D‰z춛NoÚnv“Î=»Ž’øÖ¶zŠ“Nÿý(‚NBzoîjµ3mX_MA‚þ÷™*Jø­ŠVUS¬¶g¿\½>ï +]W7…2]Ñ´uquý·«å×M_ 7ÅÛa·ïwûû¿_ýëì׫³rQÿPøÇï±Q4•YØb[À_576Å%ÂäÇÛâõ¹)”Âÿõ…ÿîbìo–«ÿ“ªZTÐÿ¸˜ý/õ¢U``0<­ ˜¥U Å 6ËëóšÓÐè +z`À—?î÷ý¶x*8[P¯&¦r?Ó~{ìÇÇuÿqµZt32jÎne~´-l #¡­¥Ê…sÑwÃêa ®ù²½„>ØK·`ƒˆFýžÙK/ô<ì¥Ó¦2]Ÿ\¬…¿¨Le:üWÄça¿Ü¯‡]µ‚>˜ªÒ`ªˆÆý̃ ð–¢‹ ÆÌÁV9KÙ +þܝ…øB a)ë\àÍׯcÿ¸^N#kʅ™]0ª2m:Œ› +þ¢†h[RÄým׏/ûƒPÆP£mŒ¢~û£¿éÇ~·êÑêf^F«’{—©+ +6èàîç)F‡ÊÔ5 •ˆ6,Ö¢“Iõ2åÕË¡¹…=Âp7s.Æ5¬ÂÝíË8A×701Ž»—Û„> ±.Ñ)$ûëgâééÂdVMUºØg †>×xn¯6•¢xu×'¬ `õm,‰Üͤü$ +g…. yÜ?ñÈݶ.—Â|l+1g|për2¾kˆ¥ì‘gŠ*- ;Âp?úÕÝnØ ·?ÜÞ¥ ˜S„o2¦*+“aD 7„©Êšò?†¯.«nþÉtfÀuWº|vß®;EÉîÛÍòþž¶ŸjÎ#Î ò, ® ®hjˆÁ¶–"ëùz³ïG7XHjͬ'87`©Ë_-8.5ĀC!í—åêÏ~w}ÏG=×ç ÁTca礆¬ »A23 ÊêÔ!Šûìݸ~dG©Ê™Å9øÕfÌUµ.ÔY >N a®ÊR¨ûÜï¿㟰ºp®çðÚdZ+5å ôó39h Y¸[þ:ƒz˜K#õêãrP©0èDîfNr_Ê.‚Û˜ÄÝLzûåâ2á÷A۹Ċ»õæâƒÛþìLòŸƒ_]Úñ«Î†\”Ïå¢U×›‹z¢m`_‰ˆÜͤôm =Í¢‰YÜÏ,˜ƒ„‹ mÌi»C–`ØÇõ×q9ºŒ­šÅðò¶§Ð +Ð +7hjù« m—´¼ë÷ý*úK}´SÁ=¢yܧA* +öÚòÅMÞ¤6°,ùbVS{RÚ„ê¶ÐO51ˆá/ã$pà*Æ÷·N\ˆI] ‹®‘XÀ‘Þþ’@ e@uÎ×# ¹öÃjØÝ8WïþW®®ÊLÈi•Ûk[ÌÀ¨öÚ +\ÚwTúèüÎD’Æý̻ľ5ªf”ž$¬E«&ÌÝÁ—-®×«Ûtt(ù°[m®SKRèã 5ÞÆD4/À@Hü{>×ÍÁXY3Ն2åk 3Õͱ·X@1ÕÆ8/ÀÄe: Ú€ªÌô9E@µ…&w¯çJd-^iÚPÉ®%,^ÿ%‹{œÁ‹Þç˜øéa³_Û¤|]009ՇÐ 0QøúijWY[«Žv?I'µ„­µûÈo—»U¿Ù¤m-x¯àÞ2$@Äéj÷ŒÓ:¤R •TÆ(f¹%,Trñ÷}¿Ï8£ÐG{W˜²Jš``: ê˜u¸EE0`؛Çåzãªá‰l(@`ƒ/1tÄHhÄ6 +çòDÊ ˜Ü$Ñ 0q¹»N%EA}Je" 0LÞ¥•ÿ§µ—sÝù*7†j×Ñ׸ dމq^€‰ß×û»TôÑyð$ÓXÀ×à¿M¥Ä +kh'Y¯JglÝr…¼Ä³ µ„­-×Ç/óË4裩1‰h,àÙ«.‰À-£BÓF@ðÀØÚ'‰ŽªÊغịXÔ¶n¸À~dHœh^”F4/ÀÀ_Çq˜nŒO|V™¶6T¬‡XÕq#G´!÷¹x—¸õŠÛÂ=dˆ(Ü]?9„`ýdfFªÎ¸TÕM»lË-áR5×è<ŒL4w‰h,às;Œä̤›éÌf¹%ÌË¢ù++ÏÓ"š``ò,”)`V(`TÒã¥:fìx—ÃX  gÉT¶ô)ôØÌ 0ífHÅq¡Ž·Eê‰ÉXà“ eÈe”zb2hE‚Џø~’£f]Qñ +wM-ኊP|–×™Ü&è#­›Ø“ÿ@}ı¸“¬ÖOQ]¥±ŽÆèž˜Ä¨Z r:_Ÿ®Œ™®’_^¸wÔÓUò»‹ó±ï3‘#èûwÍ ø‡éåÔÑÊøô3†±€ +ÇéÔrúx‚Á‹à˜ÆLû°ƒ¿uïä\MögѕIO—²ô ¤Ã7¯Ô³¥lþ1‰P¤g¶6Æp¿ÍϑÐÅ Çç¦É Ø#fHhc@6ÓH§ù&ºXݏ«ýÃH/ªíI.P²óÔVÓë†[b¢Z~Êòi銻)+} ]X‰h^€ò”PøROµ5%§ ú\SFI‹jü뗻~•3Røcp„óê˜ý\¨ÓUž=€±€ÿxÃîf³^ї\rŠ“™M–àqùh.ÁÓÏϔà霽J—à=ÌUÊ#õ2%W‚÷óÃÝÌùç¸Î¼•4‹éiD3M¾.²³|k£3ßPš^Ǹ«j:ª`”·|Þü-(ƒ¦÷‰¡ÞÎ_jîxƒv†hO|êÑîö?Œ¨œ¾l}v†_dí¸¬S¸·h—ÃÍþûr싋q¸—Û-î՟–»‡å†Žrøå£W-É×lµßÏþùi[Bendstream +endobj +2598 0 obj +2525 +endobj +2599 0 obj<>>>/Annots 636 0 R>>endobj +2600 0 obj<>stream +xÚ՛[wÛ¸€ßý+ôØ}°B\I<ڎ“õ9ÞDµìm÷‘‘‡]‰r)*Ûô× @±o{bªNŽa >`0úŸ'dVèdÆ$ü_mNÎoOÞ¼S3ZÌn?ψP3YòÙíý_nëOëf¶ý<»ØvCÓ »Ÿnÿqry{RÌ M€o¾Ý¼Ÿ•t^Ì$ój¶™Fç[ëÙð#ú‡Ù›w|F|` ²RËêO¼ì¾¶ý¶Ûè›=ûa!_ZÉç,þ4'€Ð_뾅™˜ÇçDKðëùk~QöìtôcjÝQ:—z6•€'7 œŒ^"I™nëG~ÛîvÍjh»‡çµ´r +2ç1û‘8|iŠFk/ç2f9„ý¼8}ý†&€VŽÌÅø®]M8ý2Á²¥ÖÍîùBi è¹èt-œ ìkRÌÍIºêÚ¡­×í¿“KBà)X©©<3½tÁ`’ ¾e,Òôä%‡D(©ŸY>6ü!ªÔmý؋ínX®úö1aB‚ÖázF¼Š{ÞÇýð¸ŒjÔDŠyBUüÙ¹05©Œq¬ôìÏ8±7ïš]-TÖ@ò„¢FœW½3"šéu”ÓÄnô#7zÀ!Æv;Îßú6máDHSü&"Ú¢oõÝÕ?O pŒÕ¼Œq¶ßáÞöíצ77 C:ý~ eæÐi¬m ‡ß6ƽà®`8>¢´6÷£žß×¶ùcÂËò›µ±Ë‚3kù + +ËgZÞ. έٻ¸[,S÷Ÿ öŒh„rH»©wÉ­4O°¹:à¡òÞÖC 0RéötːÕ5+ŒÕ”`#P5#h–ë‡Ä}Œµž†ˆI؏¬³Õj»ïÀJ˜]ªæÓfZe¤ \ +³b‚ˆ1,Ûõ6e¥üPØ9p5E ì7¨_êNë|hÀÙ©´“ÕLÁ¬Ý-œÓ +TSp´ºÍ×v•tTýp0âæ>aNyuwŸòÂüpе¹" + ì¼6õc‚6:È"°RøÔáJbµÌUÂUáƒÛðþWäO)g£ˆˆ‡ýäÅAÊÈÒ¶SÆ,'@Æ eqqŠQ<|p‡c +¸éÀ¸‡rš“FUúñ²4Žöd6üãee/›ÅâmÒIR#‡ : AØ_Á„ݽ¼¦#ñ²Z’£³]L+P“öê¹iêûtŒ‡ýBDs˜s‚äŠ + Ï9 ´˜Ìî³"œpVŽÁ‰ýù‰à„³ÊšC‘NÌÄÍöV/ NF|‡ÁîêÏ'ãCiÿPÄ8áÎëÕïMwoM=×·À19Û,ŽsÊ}daOEœŠÿ§È‚e2>ÜßÑN˜ï ÔÚÀe³Úë½ò-k(ΘÓçx±íví}Ó×C«¬äS˜×œ‚˜ªF/Þµ¼‚˜RÖN]l7퇝^·]“ÎHYÞ©<ó¬Øo\¢šWú콞v²jÑ> *}l#ÐJ%­N&éb¤ˆƒý†ô¾ép§U”“/PNIl6Â<Û”£Eª†„ê I؏¬# !Ï(HTÖ%Ì´ éÂ,ûå¿VëýN;¤)³ã  '¥ qÄsˆÔŠjv6áNð„JÊêˆ Ìù0ml+З˜¥i†¾mpFÇuáòô…ËL] ã/Ûðñc À—Æ_g¤ˆ‡ýH|Aü5²($""–@زÑáí:~{„ß…>™1˜K÷÷©Za0^Ó*u8S'€4tÈÌæ¯m4³œ(kûM}̶‚ NÍÃ.÷Z%ÙB“ô8aleˆCKÌf_‚ñà Ó¬ÒÚÝj«=ÁoÆî²W¼£³ê-°¢L "i[z ,'|lºLèÇÃb¯ќÓÇ+î21 –=^¼Nq8U'€<8^&-'qؙH¯U®Ð­Æ–_3ª°œ ÛÂñö Ó´€ÇAŒ~?Ax‡T_ÌBWƒß¦ü_?¢ÿâp–NàEõü`8¬}¥—4†É£¦]ùì—*HFÙV°ðÕX×îÚݗÌqõwE<pÈ»G£vÕ?&“©*˜5ñżį¹*ÌÄÎRÇcQØ! »y.ӢЄ|ALQž²Ü~þ¨ûÄfÆÛDKÓ°ßЮõýÕíšt¥¯ò4Á¿Ÿ¡°Šzè__!SÆV,Sý¥Ì¶K£[½ äh(Çú6DåÛîyEktULµýŽv÷áêïi›«<ŒCØÁP€‡¥üôQàíAî>&ZG\~Û Í&Á Ú³1)՘g/»ÏB„Ju8epÀh§qùÒ=,SÜ¥Ô¾>@(¸Ã¶ØYŠo \uC¿½ß¯\ÆAУˆ¬²³#X‹7%=Û +fG°Û×÷ͦîßÓÜ2µUZ`5½0Ö¬ˆëòP‡´OÛÕ}*M ·ˆŒaN€Œá§Ž¯?ía'¤]é©d!b* + õ¦}øbÓzf¾nX–Q4©°,o|fÛòŠ&U„e&°¤ÇS3óSé;j `®$xжáÓðú­™àûw‰ËÚµ.[ƒ°ß¡.?\ޜ]§]¶Òódz#ž@àâîüúê"yD°ìðùœò4ìòÃòÒeúŠ,/2+%mÕÚªSÆz"±bý‚•B!ì„ýˆº¾:¿9»ù-µR,äÉ4òœ€{¶ìÒX*ëQ¹¥ pðà‡<'0ÎØ/=ûQ;.’^=aX .´û`Oxõ„aEø<é׏S‡8ìFNÚ³÷ ïAÄr 5Ô®JÃ'.M¤¿D¦J(±Ñ „ˆ¶ñ”M(Í¿n0¬o]ÆDìB‡dNH‡"Sì!E9†[Á}Y`müצߥ}ˆ`<Äâæøa¿ùdßÔalêR{NGŠcZ |+Å#§[a==ûjs0Ú¦Y„Ân¤]ԏõ§vÝXt +}N=•«ÁÃGU\‚¯°^~Ù­¶ðªÎîÇÚêÿbr™2¬¼•UTä‘Xèþùöv‘4$ÔQì1¶W͏ߎdòõ+ádŸD\Pö²n7-F å±½o’›ÇBvŽ+â‹ØË¡ö»tmNŽ$ +·pHÂnêR?÷øÖž˜æo­¾ÓP.lKت‚$Quøw@Ö¬íÛU&À?.?ÃÎÏO®ÿ4²BÏA€³-&žgÆ}3£‹~ûÐכ¾&g¿Ôݾ^î*údvZÚj[Û¢ÿzò®QÇüendstream +endobj +2601 0 obj +2478 +endobj +2602 0 obj<>>>/Annots 682 0 R>>endobj +2603 0 obj<>stream +xÚ͛MsÔ8†ïù>Aß¶ŽÈ.CØ 3c²Þš¬gfwù÷«–Zv+$Væ’1T…j,?3ýºÕ-©¿ÏxÁÜ_^”¢¦X¬Ï^_Ÿ½¼°…`Åõ‚k[˜R×Ëg×õ÷USlçÛ;Ùìwϯÿ:{{}ÆfÌà‡—¿9ΌFêYU¬ ­fUqô;7t7ÅË UpŸ'a¬qcݾ›Ï‹?ƒ`ׅ­úÄÏÀËHrßx·¯ñ++>³Îc÷ß³©üÑæA?K® áÜYœ±Y‰:ê›ÒÙΟíº >Šr&§åcÖEfg +¥tÿƒxÈÙ cðÆûǧöójkfž¡{z +­ÁCmKg;.›ÝvuØ·ÛÍñO¨Œ{Ø 0@æ—M ”S +§ËŒH•t?O¼t37XD¤ÊÁE»iw¶› +Jº)1‘`Ⱥg¬ÏW\x>Þ"î•,¤«O]ëòk Aà]Ôbf½Ó&d)ÎÝ# ñN—!K}>Ô«vß6Þ5YÍÄt¦rÖC%C’b½AT*$©÷ÛïÏ]r+(å§.Y6€®\ ™„žPW‘$ y‰)o•$IiÞµnэd9r¿£¹ûXJ‹HÔRn^­¬P.Éùd'D·ˆP<ä‚Û¦2Kõz"qõŽÉëwó>XÄ;¦B®ƒ§v؍EÁp;Heg<…Å*.õ–ý”áSJÛñu²r²¦®Ü²4è™[ +ËCҜÏߌ¬…‡[Aoá¢)áuD¥‹a9 •#—+U–!+ðÉCT©² +™sT.rkˆ(‚ð:¢.¶ÝºÞ-Æ€ÃêS\€¼¯M·sÓÙ¿S­Ñ³";/D/²7ˆÈFcϋŒn`‘–€ð:¢¾ìšîÅ;¨?êE3"69¬ò ÷úç-fóÄ"Ã2kî“ÐÁDbýX‘Â¥˜‰ƒ×Cil} ‘êÄ{€Gê#˰µ÷nxƒè㖍Õ#BWáõ*ŽÕ¶Ûݺð kn~âÄ8"P¨Bù|o xá R7\õóÉþ²Þ.²Èݰ…ÕUÂÂëúþÒ¡¦S:²ñä6% +Ë£E‹!;çô¢·Cñ€=M‹wõs³«ÃýަÍݯ ím·Œé섓8§µ´î@‹` ZKkñ¨ãQZ÷0˜—Àâ7]S¯Gx„5ɸ„òpò>öKÉêT«î¬Ò•ù?(á-¢teŽÐ9¢¬Tài¯·ÛUSN€ÃU°uMq8àž”"žü4 «pÉqã5ðQ؍©ŽÐ8Â܎ï,@ÞûíÍXÚ`¦!a¤0€°¯õêÐÄsᓞœžQÛmUÌ ¶·ˆÚÚΎ‰èÓ>),@9p Ä5¬(S(@(Q½zòóˆ¬ÐJ“r,"´2ǔæÀõ ïü°ÿØ,Ûz,{ PV$) ‘¨lO°Éêìæ½ÎÞ":KyT)Œ0?±X€¼WËêÍ¢ÉiM8ëB0XÐ¥T€Ô$¢Ÿ.Qg5æ–Ao;BáˆòÛø…íCS/ÛÍÍÛåÍèfu€ÀfN¨Rd‰¸OºÜÈêË4-L§%™£J`„Ihe&°8À ÙØjn@އƒÁ‡Llª,G¿@ÞñI&ÁáóKM}ò†ãLXAªh°†&¬<¦Šö0 ª ,qwwÐãE”Ì +6–)È_ŠèÓ§÷¡‹# 6`!΂N¼¼Ðø>ŒÂ.ìù˜Ò=Å]^F΋Ž%ۘ”c)Çm—‹ý¡ òºª*'×Sï„? :´ýiE0ú'AÞ,Z=úL$"¡™©S&^W÷ˆ8­#™IҒ¼,’&;&¯÷0Qöè4MDÞ¼-šä~H:pj—ÒD9°~wu¸éü±&;™ð#:û4Á±Ùëg1'½Þ$Mplú¾É¥‰ˆ³wqx9Ù4Ÿ RŽ¥œ‹Ãf8 ¦õ|³î•’©‹øWb[øUwsXǗ'ÔEϺgbW¦i°ˆ{{º—«AØßÓyUäQªØˆ•n,â¡Â¶é›f·èZ?§µ\Éú'±YÉ¡£,âŸÄNåÛÿêõíª™Þ;QYÿ62!4ƒAÜØlF߈2=…ûîG‚Áëá\cµÛ†÷?'ÑÄÌKäËg؃dµÁzuœaŠÍ9Û¬Þo¿÷ņO&WyW3oÈÙÐIôÅÆª$YYl"N¹Ød¼«bÛjM•¶+ìÑM¶Òd|3±g…Ƥ-;;v.3ٗSñ];¨2:í“i3í +SæZÛ!»ø£Ò•ÂÐtËKÆ9Ú-¾ˆêÎAVH(ùꂐP\(%\EÎD‹‹hpŒõ¿3SÅ ÔcñW$Šó/ó«âjûcÿoÝ5żÛÞtõzÝt»âc½9Ô«ðæ8þ¢ GÏmÛ¢~ŸÏþ¹l}*endstream +endobj +2604 0 obj +1958 +endobj +2605 0 obj<>>>/Annots 730 0 R>>endobj +2606 0 obj<>stream +xÚ՚ËrÛFE÷üŠYÚ Ãó~,Éò*E¢wÞ 2¤RŠe€Œóù™™n W™Ã¬Ò±\TÝÙÔ4o.øm¥„Ì?J_þ?lW¿¬Wïo’ÐR¬…rIø`Åúë›uÿÇf»Gqµ{Ù/ûéíúÏÕÇõJv2W(ª<Ü}Êu:)¼q][¡tꪍ¸/åxÅø$ÞßX¡TyÃü7øüúXÞñáð:]ïnž7ÃÝðí0Lû/o¾¼-ïšd~‚,OéþÓ>þt ‚.k uçó¤ºUàµÉ:3|žú§¡Ò¡Ó°þ L­'Yv !T²«­óa|:l-c}^ ”-<—|>#O–ß f<—ÊùÊwÃþ0¾T8£»Àé6 £ÉåšÎ "„±ž¾ëazŸ_÷Ï»—zS~* Æ&OàAJu +¡ |æãßýöuS?‚&rú6ùœ‘ù‚çøËý0ˆŸÖ!/…u²ËBxK}ØL»RJ¥¬ù,S:?Šœ5àRJ¼ª/g-¸Œ›FM°œ"ÈFCY «¤!Œ¿b‹9_Knñé9ØV¨ŸÆX›¯%·ø$Ûà›Ê,6DZa°}%+sÊ­ì²ÇRL-Ù6,YJÜY¥.¡"–,1GK†@æäȊͲ¢ºó¡"äՒAÌ¡"û@¦…0"¯— _Àˆœí%@ Ïc>^ç (‚ç1ç‚4ƒüäã ÀDãñ´LÇ÷p¼Á1¯V—ÑxÄdœ³7ðIÁ5 ÁËN3ðã`¹½>Îo8å.3”¿kf”§¯ÊFüª¬-Wë>až$®>ßދûÝãþ{?âvÜ=ýv;Œ“øµ9ô›RîÊ/Râ]€¨õù/\ÊßWÿ{™»Dendstream +endobj +2607 0 obj +1220 +endobj +2608 0 obj<>>>/Annots 778 0 R>>endobj +2609 0 obj<>stream +xÚ՚KsGF÷üŠ^ڋŒûýX:¶¤MR¥¼ó†È#¢e€$??Ý}{˜;T™«å]…ë3¨áÌ4çúk¡„Ì•Z/žv‹ŸW‹÷Ih)VÏB¹$|°bõýÝjýû¶‡gñé°?õûÓñýêÏÅÝj!;™W(7ªÜ|yÈKuRxãº(v"¥Îµ°˲úÕ ñáÞ +¥ÊóåWáÏÍOøõ¸ÞôåItèt~ù¿:&B àµî|†WZv©¥F_µÉ9ã|6çÝx(­ÏŠ%‰'Sg žôùÌ@BxJvuÇ|éOça_áŒî§SHºTÈÊ 4ii"t©ìÈ ó¹?> /¯§—þžÂ”̂’ä‹&ßf>¥:Õâ‹õüÝý»Þ½në[ÐDNoÁtY™Î§ê¥Ê R£ËŽsA‚`žÎ¯Ç‡þô8¼d¡ Çoï¾½/ë>;5Dâ4:_=S% E@3œEJZ¦©"…„­Ó°)…g$h¦ŠÂ3 +4ÃY¤¡ + iMˆPEÞ¥è¤i¢©­ ÑI ¢á+R‚Ï& ~)ÿ@˜ðlRà—eߋ®ƒ~Ž“/ÔîoK}Üe)•rþ?¦:ol`©ü²UKÓ¼±!‚¥Ê¼ùe½ß|îŸ×çíiœ7QóñU"öƒ·ÕWuÞ@@ûÁ;ÐçyC:ºªB†„{S|&€°ªŽ!!¾l'æB¦ø´½ˆFµ„ø´Íð2ÅW: +¹„§4ˆæ Bnë4!ã…Úým)¦BN·…lRlßbÞ¹&!›¬/…|·:|ÙoF#çCÀâ]åíÝ`¢«¶ª:†0í¹_ü“xA5Y•‹Hˆ/?&r¾ø'ñ\WÕY á¹®bV¾õâR_Òäcå[+>úø¡¿”ÆÞpºv¬¬†ØJò*dhKØÖ‘s2hl3V2$DhZ;ÎVÈžÆÕ8$„§¹Wã$ŸÄÕ8$Ä'¹Wã_ÂÍxšã‰{/NÁET‹Çy+ß\ŠG܉ÇëJ<²nÄo :i|+ĕÃ4güU¾< ¨ –ÕF°ÔoÄL¸›âŽý¿¥¾üAu¸·á–{N°i܅ëxU.ñoÂ+ÞÄ&/¿ÙÛo¶ÚRöùÔJ$ñéëãR,ϧÖC/‡ÃfXïvýp¿®÷çõ¶Bš¢œŸô£·øÛâ?8ü§Åendstream +endobj +2610 0 obj +1172 +endobj +2611 0 obj<>>>/Annots 826 0 R>>endobj +2612 0 obj<>stream +xÚ՚KsÛF„ïü{´†÷ý8:Š”K\V,úæ ¢@*%|(•äçgwg@,\Žn[.VµA ýÃnª…?7JÈü¥„ñåïý~óÃvóþ& -ÅöA(—„Vl{³íÝ âø ®Ž‡Óp8Mo·¿o®·ÙÉ<¡<¨òðù't'…7®‹b/”6Aµweü7ß1>Š÷7V(U^0èü\ŸŸ›_ñÇaºŸžOOÇCy-›ò YtÿóŸh v­;_ؕê*d/|ùŒø‚qýO¿Þ e–‰æÁö*>™:›ù’Ì <%»º0wà þsNó­pžìzŸG}ØMÇ2J¥ü¯ßÃiÊ+,…K>_Ռ']þoƒBæ÷ÒÌê.¯„‹&?æ•HC±¬„‹õ*~™úǺí:pÚöWáùn&ËEÕð Žõy8½Œ‡êŒFwỺ€ÎƒgU¿ÕºžÅד)>kÎ^£P5|ւÓðõdŠÏÈj6Õ8A4xF×О<ÏO^ Âã8Š©';“U¨>¥r(kT'«8;òÇ~üãSÝóiöäè¸,DôÄ2HSí +ܸŠf¤·âìÇ ­»X.£ìª…Ð&nõa||ÙϟU­Ï'ƒ%‰˜UP ^ˆ`Vœã†"ôl¦Æ ¨†Ð;0¾qCñ9>SãTÃç4ï°¡èL)ï; œ‰à/tØÌs lVƒð8Žb6þrØXmÑ¥J؀ZÂÆj.Uâæ¶§oÞbêõüÑìƒÒûÏÿ Iíªä ¨…ÐdnÍ:o(¼¼jòœ7 ¼è¹§ ÅTSFjøòs˜NŸ‹Máªás‰{áDñY·N ¼üF{eá4ρ¼Y Âãžuá.ç1 '}VKÞc–Âév|:œnžvùpò¬9Fb#ò•9÷M šÐ’{ÞPxrnÏkÞH·6,‰ 9Û¼!ðt‚¼æ ¨O',È9'E°Ú®‰ª!ŒXlóMŠÏûsM¤P5|»m¾‰Cñ9ì³K,€hðÜ+ófžy³ƒÇ9§M¼œ6Ú,¸Aµ¤¶Ø‰¯ÒfbûûD샆z¼æ ˆf4¶ãœ‡T؏×ÄÕ*ìÇÙ&…'±Ö†Ä‘ë~\K,µ9'A¨âÜl—ĵªÈü'Š.˜sS¤P5t+m¾yCñy(´k,€hð<öÙtâÌs qVƒðø\³Ìœ$/g޲XŒ+Ÿß –ÌQ‹ñ’9Ÿûé4ŒW»ãtþ'$>¡“± +ò8 š…0؏3PcC^TC¨Yj$œ M᪁“‘yáDñ%ÛôMÉ®Ü*9æmÕR6Åu—õk«&>ÜN£šsÏtáUöX†«ÒŸù¸j™|ZJ&°àOÏÃáìÀ|>R%MÝÓÜд.Ä÷û›UM»d×m¸Õ¼»%ŠMǶZŠß4Kì‹%À[Øäùو·ÈZ[n¨MØ ‰«/·wâîøpú»q;Ç~¿ÆI|ì/ý®Œ{§r´(ñ.@1úמÂ_6ÿǞ¹endstream +endobj +2613 0 obj +1201 +endobj +2614 0 obj<>>>/Annots 874 0 R>>endobj +2615 0 obj<>stream +xÚ՚KsÛF„ïü{´÷ý8:¶•\R¥ˆTùâ #C*ºøP@ÊñÏÏîÎB¨Žn[eVµ ôÃn¢…¿JÈü¡DÐÂxq·[üºZ¼»JBK±ºÊ%ძ¯oVë¿¶½8܋‡ý©ßŸŽoWߟV ÙÉ<¡<¨òpó[ÕIáë¢Ø ¥MgšÚŠeÿâ;†ñîÊ +¥ÊÌ¿†7>mþ‰ûãݰyŽz¿=Ê(•òg†§)¯°.ù|V3žTÃË/5—BÖåîéñx³>žúá¦_ý=ÿï‡/o¾¼­À2\z1’9¿ .šü˜—!u®‰i\¬çïö¸~¨{®§=žOÍÇd—šB|A‚W½žv£+æóí˜P’x΃Uɲ ž `U7ýéiØW8£»Àé’„Ö€ÉÔ …­‹á6Ÿ‘à25l@!>£Àeø† ŧøKIOÅ×EÍ8¢f6¦ŒƒÆA# x”­+P +iÁ£æAs½ùÑoSÐØ‹{V²ç7ÁÖ3ՒÄ´ 6)°*ÎYC†Ð¬ªd (Db{7Ä5k(Žbš5þ|Öh Mx* +bŠ­[^ÂfÙß§Kçx¹qA ÄF(¨Äkâ€@¡Z#Î9q(@)QÓ +JÅ¿i"U ¨i5ªÈüè]0¨i…è‚åÞ4Q|^NM„çÕk›¦qXòlP;®X7Má¼%+žßY™¦&O†þ©yòªß=^m¶ýèʾ”‘œ^ϑØc§Â ÚãøN V¨p…µf} @Áɀ +'PNFþ…A˜,ê›Ò¼OŽ{ÛDÀE…ʦ¨fo‡¢æ^5Åó&ê¡É޶܆g· ù4݁t{œÞÒæW^`÷¦¶ &êft'Ò¼Ñvìÿ6L°Y\iÛy£m‚B›ÀÓ¸ÏÖñECÄÝ_*ÜD&Ÿokí¶V]Á§V‰·×K±<ܟþY½¸Ãz·ë‡£øc½Zoá –KÎ_”œß7›öþ¹øRÛ­ôendstream +endobj +2616 0 obj +1191 +endobj +2617 0 obj<>>>/Annots 922 0 R>>endobj +2618 0 obj<>stream +xÚ՚ËrÛFE÷üŠYÚ Ãó~,mÉÊ*UŽEï¼a(ˆfL +I%ùüÌL7†«Âá²#©¨ºÙÔÁ4nƒøs¡„ÌßJ_~ÖûÅÇåâýCZŠå³P. ¬X>½Y®~ßõbxwÃáÜΧ·Ë?Ÿ– ÙÉ\¡<¨òðåt'…7®‹b/”RBµ¥üO¯8nÄû›ŸXÞ0èü\ŸŸ›ßñÓ?«ýË®/ïcb§ó¿™ÿØ1øJ©Á®uç3{’ùD/xÚdIû^ügòR؇v^·c©»ÓPJ©”õÿa7å%λI¦Œ•ñ¤Ì  +ñr+z%»ÚxßÏ痏»aýc{Ø|{óím)êMgø€v]F¸Þ.ùÜÁ¹%RçPL-áRÈ:Ã|=­6µßuàÔï·ðE“óZjÙ%T0֕üpܼî/Öa}ÞÛl>•éÒu [`W÷ýi}ܾœ·Ã¡ò%-ÚÆs~t…Šà¹ÃԍÛxÖT—©Ž ‚ÐY &Ó6ãK0ãY!܎¥8šñµ½T½ØYý)ÆâOULVìŒ*V|÷½_ÿ¸ø°Ó¼|XU£#T¨^^\é™;q‹Nt«êÄU>>>/Annots 970 0 R>>endobj +2621 0 obj<>stream +xÚ͚ËnÛHE÷úŠ^&‹aúýXN;«2±²ËFqhŁJÆä󧻫©.ˆÊ»)pE©¨Ã.Ö¥®øÏJ ™ÿ•Z/î÷«·ë՛Û$´ë¡\>X±þöj½ùºÅñA¼;Îãá|z½þ±ºY¯ä s…ò Êç¹Ô …7nˆb/’|;qWªÿò†i+ÞÜZ¡TÙ_þÞøüڼûq¿Ý*»ÏïUƒ]î¤mo¥þܝŽ¥”JùYYžþ÷?%ýoéòçÎGPëüi3´…®ªF—WÊk“u&ù~>?ÝîßFo¿¼úòºõl(+h ZE¦ ˜[% ®‰ÆYÚAÉ¡ößçÓf;–B: šÍç’ÏŸ8/¤–CjªºTxJ“NÛçý|bYŸHš.šüXÚ´pBt±.Þ§ñü<*™ÑCà³|4žO0còùfšBxA„y?žî§Ç§óãñP—/å3€¤ñœ‡!“G¨j +á¹Cææçfÿ´«§Ÿ‰|N?Ï-Å@ :ka´ÐN3×§YjÛ[)žN®;3²¨|î†&ºÑ8£`>U£™¦ã4»Œ-îÊhÏ´‘è êÀªvõ„ŠÌ͆¢“¦Í«j6U!¼|-9› AgëÙ6› ¨Ng“‚qÅØn(À`ÐT»…C„1ÃÖn(>>>/Annots 1018 0 R>>endobj +2624 0 obj<>stream +xÚ՚ËrÛFE÷üŠYÚ Ãó~,Çr²HE±è7Œ )Lñ¡Pŕ¯OÏtƒ3p•9Ú¥c¹¨ºÔÔÁ´îZó×J JŸÿÞ¯~X¯^ß$¡¥Xß å’ðÁŠõ—ëÍï»QïÅÛãaÓùåúÏÕ»õJ*ä•_>¼ARxã†(öB)5(R;q—Ëó§ñúÆÂ‰ù ƒ†s=œ ïøîëfÿ¸óû˜8hø1á‹ÃþO)ÓA×zð€ž$|BAä™NÐr7Žâ»ušoÅKh—…è8•z³;s)•@ÿ®,0\%™€ +®R ‚ƒ>ôJ¥ëþ˜¦Ç÷ãt³w_>½øô2×ôrp\0‰Õ^ï—<ô/°&øÉQԎp)€šçÍCévøtû󸢁WèT-a1Q5€±,å›ÓÃÓ~6뙬aŸÍ'42™— UÃ$šÕ‡qz: +›ÑCà³|}@çÑfÀN ©Ð4™ÇóçÓöqÚeœÌ²gMñ "T žµh4læ‡g$ZKN Qh-ý°™ë`Ø, +Ñq*Å3lìõ°q*ƒg +$jØ8ç¨ùiÜ\bÆæÛN1C¨®Óҿ¬)¢iiÑ®gM‡Ï–vœ³U´IÑ=Ó´éх€nUÒUC"ºã´éz‹>SÒUèº Û´éá9…wB%mP5xN³Îšœ h-ùwEÃ(ñyY3×Á¬Y¢ãTŠgÖ¸ëYcµÅÇ¿lÀ(jÖXíПrÚü|ØNÛÍnûÏxy´1<ú¼ÂúNK”%œa‹hZBi´+ÆiÓá3)6v…ªÀæmW=¼è»BÕàEÏÚ®zpAU»BѰÁ)Ï´«¹ÚÕ¢לíÊ_·+ã"Ú•Ë ^Dµ+ãRµ«_KŸg¯rÛý±R¡ÓÖU·BÑtÜ%rw«Ü ê˽1ªÐz„czoÜ£ƒß+y¹7FÕÐiÉüθ‡'ibŽQ#ÝÒ¯$MÅÙFMO§:ÍV¤*žN4Ëf6=¼@ãìœ(ºHãì~ØÌu0l…ðø\Šg؄ëa£= Š6ÚÓ <‡Ííñ<]&1Š—WÜØi +‡sñ’7(š¦pÜÓ¦Ggh2^ÒUƒgi2Î5mztšÆâ%mP5tšÆâŒó¦¨h0^òU¨h0Î6ozx²´©OÒ8›mÞtðTĉv •NÅg>ÚÌU0meè8ã›x=kTÀA8<Ô:5kT AxɚÓö0Ý_Ò&1ûó2Ò¦N?xY§N(š~ð4g6=>Kƒñ6¨@Kƒq®aÓ£34/aƒª¡34g6=@Msñ6¨@Í{ŠÖƒ“¡Ù넪“‘ù~¦^²u;S² cI™¨M[:Î;™Òõ ‰8?ªÅ>¦¨ë6¦Û§Ë ,¿ãø@3€»vö¶Åº‘É/‡á>qßÆÔƒs®ÝÅ´œ…;ÎUîYÕla²ËA¸ÕÜ70õètlö/éøÍ\‰÷î%d«`ò²#6ҎXÓÄ'šúˆ·oïÄÝñ~ú{sÅíéøpÚì÷ãé,~Ùž6»\î•>%^‰~¥Ë÷Ûê_ÙS¯endstream +endobj +2625 0 obj +1217 +endobj +2626 0 obj<>>>/Annots 1066 0 R>>endobj +2627 0 obj<>stream +xÚ՚KsÛF„ïü{´÷ý8:Ž•Sª‰ª\|A$HQŠ‚*þùÙÝj® +‡·Lì*¹Ú †úˆa7ØÂ_%dþ«DÐÂxq·ßü¸Ý|¸JBK±}Ê%áƒÛûwÛñ÷Ý$ŽâÓñ°L‡ååýöÏÍçíF2O(_Tùrýs5Há¢Ø ¥Ô PíÄMÿÝw̏âÕÍ,O˜ o|~l~ÆÏ߯ýón*Ïcâ ó™ÿsøÏÿ(- t­ŸÑ“Ìÿ€@òB§MÖäfšÄ¿Îé¾^B»„ÇqÔÇÝ˱ŒR)ëÿÁ«”Op~•dÊT{͛@¸¼‡^É¡nÝËò|=÷_ß}}_æÙ²L{Xu~%\òyóJ¤Á¡h+áRÈ:#ݾŒuÝuà³î—ñÕ³˜WUË!¡êc=—çÇ×ýÉ9ò‰t,i6ŸÀÉd9m :¶ Á­®§åu>T6£‡Àçôр΃Ïd?1¨:@Àe~š^îæ§çåéx¨'0å3€¤ñ¬©FIªÃ³œ†mÚPxF‚µ”HÑÑÖB§Íi¤ÍjÇQ<ÓFO§T~'T-nœŠ-lÃt·œÇG^ofM¬ƒ4Õ­ iªèÖAZ0+ÆICðÙºŒ§¤ÕmRxIÄ4k(ºÀ«jրêèB¯bœ5 ·à25k@u€ÞÇ°Í +Ï)°™š5 :<§Y' gXKyρèØ2J¼,iNs iVƒð8Žâ™4ú|ÒXmáÓ_, ^E «øS‰š›éyœÇezKÉĦ«!6¢žA ÝF( nÅ8l>“"ºU P ÐdlÍ9l(ºèðC[ñbP]ä}ÕOÁÕõO :¸üÞ…çbë˜@tt.]Ú1æ€¯áñĹc2ç½ØXþÊTѼØäwªm^¼\=M»{Æ^l‰ÈW‚oˆn#Œa_1Q|yóZŪԒ³SlËrpbéÖf%±gëÅžN­ÈV¨žNXc³õb +/@“] DG±É¦½ø4¼x5ŽŸFñôb{ދµ‡ +<_f8͋µÇ +¼xñvï&#vÂA!^ÝD·Žûu1Eg°¯^ ªÃ³X‰sucŠNc^KPÆ>œq C*lÄk܀ê6âlã†Â“­ÉV¨:<‰=6Û¸!ðT„*»fˆF§â…%Ìi +„Íj g\Á¸óQ£vàå"D‹°/Qsû|ß0Î1K¥=± Úð3 º]ðX†3ŠÏb^ƒTh±ç4Á2¼ ¨ŽÎ`Î8h(@­º† T¨ywýœ ]ꃓ‘yÃDà%Û +¦dWƒܥõé§ÀQǹ[òçC&Bõ]?ÎDµj–¢nÅÒoóÓÒ˜ ?Ì↶ؚ%¿îÀ}bß+êî—þÎ¥uîXÿ.9P¿œén[²ëþÛjö7-t:v÷,éø]£ÄüŽ¥ÊÖÀäÛm°oƒÕ%L|¾G|ºýr#nŽËßã<‰/óñq÷ûi~¿Œ‡×qWϟ‘â‡5è·'|ñ~Ýü¿‹­“endstream +endobj +2628 0 obj +1195 +endobj +2629 0 obj<>>>/Annots 1114 0 R>>endobj +2630 0 obj<>stream +xÚ՚ÉrÛH †ïzŠ>&‡0½/Gg›šCª[¹å‰i•¦´x$¹’ÇOw›N [Û%×oҐ?6ˆßD㿅2*a|ùú¶]¼Y.^HBK±|Ê%áƒËûËþŸÍ öâí~wv§ãË忋÷˅ìdŽP^Ty¹ýKÝIáë¢Ø +¥T§PmÄ] ÿì7+ñúƒÍ'–7 :Ÿëó¹ùßÿ跏›¡¼‰Îfþa÷Û?”ºÖÏèIæo ¼Ði“u¹ñ¿qš_…Khçð8†ºÙ÷%”JYÿW)/p¾J2eªBgÎ +ér"z%»švëÇǛûû7ûýfèw__|}Y¢Ë)âåtpÉç¿6§CêŠ)\ +Yg/Ç~US]>l×ñŲ€y!µìª0Öe¼9¬ž¶cÕ°>_ ˆ4›OPÅdY6P [P©n‡ÓÓaWٌîŸå£‡“k‰AÕºæÝpüvX?žÖû]]À”OfIãYƒE¦¸¨ÏZ(2l†Â3JK± QPZh§ã€ÓÌáq ÅÓiâe§q*@Êß ªÉiœŠ¿øÌñl4å†gÁ©t"rAšZªÀfªhrAZ¨TŒm†à³5G›5Ú¤ð!¦FCх…ª ¨†.D(TŒ†ôJL5P  wP`Ø …ç֘b4 <§YÛ g”–rρhØ2J¼ÎfÆ8`3³@xCñ´™tÙf¬¶ðØJT1¹ŒÕêøÌ»þ4Œã%“"u&5’ȇº~h5 š|Pj_«¡øLŠX«ŠÕ€šMÆÖŒ­†¤‹JUµP ]ô¼†Ä +ŠL5P ^>'r6ÏÅsSH¡jð\‚2ÃÕjH<ë ´?ÑÐå›Ì^g5c°šY <Ž¡XZͅ«T­Æä{²(rÕ5y1 +xÍ߻Ӱg»‰¼ngE$D^9z ˆ&!´dî4Ä.98tób%±ÎÕi:°]ÔD§¶¯{ °‡]½T±‡ÍÖk(<ïÏm!…ªÁóغfë5žƒÆu5 »ÒiÆ(à4³0xœ±Ï¨Ë>£M:?°ET“Ïh‹íï™ÏYnÒM䂆>xµM.hlƒ36ŠOa#¼ ¨Pa#œ«ÑPtû×`4rÞ׻׌†T[ØÕh@M€*ò~¤¡à‚iF@5pÁò ñ¼œÆ@4t^];0Æ£™ÂãŠñ8À…«T­FÙ±^J¨Éj”í8Àm¿[Mý3Ϩ+cˆl0všÑdƒqܧH>­šiP  fÝ9£Ødh¦@5l2rŸ “m†’UªäxPlQ5“qÞ³Žš÷Åæã4àçÝjŸ®À 8mŸŒqxš‹!&Ǝwé}97ßÿ÷Ï|ez€QŒ6f²UP›2Óö¿7½­æ¾ùOÁéØìýëø¬ÄzçÐ&.yžy8ójàþÂf‘xûåӝ¸Û?œ¾÷‡A|:ìW‡~»ÍÖâc¿{ê7%Ü+•뮯4@¬×xý>/~­Ï«¢endstream +endobj +2631 0 obj +1201 +endobj +2632 0 obj<>>>/Annots 1162 0 R>>endobj +2633 0 obj<>stream +xÚ՚MoÛF†ïú{LeöûãèÆIORK¹å¢Æ´ B_¥d4?¿»;Cqh ZÝ:µ¯(ü’£÷g÷ï…2ÿ*´0^|ß/~]->|NBK±zÊ%ძçw«õŸ»^_ÄÇãáÒ.ç÷«¿ŸV ÙÉ\¡<¨òðô[.ÕIáë¢Ø %}§QíIJ”óÃF|øl…Rå Cy­Ï¯ÍïøÔ_^‡C}£»ÿÍüdÇàGÛ0¯uç‹ym:ƒ +̓ùY_¼<öçïÃötÙ¥žMùÅ L¶íÉÔÙbO©N¡"ö”ìjÇ|ú±ÞŸv}½~17“ë×´çRiÙ½H2_&“;—BÖÙȲïÅOë?…Ódç…ð8–z؝¥”JùÙÿÁYÊÐ|–¢É¥ÇíU¡»$.Ö؞NÏÏOýù¸{-mþíÝ·÷¥lŒ |*ãàSͰ”:‡‚4BS_ÏëMmrø4ù}þœÇ˜’]BE º1õ0l^÷câ[ŸÏ“mwÖ@JU"”bL™–A#!_*e@ƒFAº°¥L˞ +0•2 ˆ=Y3¦eNˆ– +‚*ˆ7i!Zî` ÖAÆÐBxKñdŒ»Í[=”¹iAMŒ±IA@½¥ÌyÄL*ýŸ›UÆßnBMªÊS3Ø!¨s¦åÏ[ ªÂPÄ wø5ˆ)gZœªœEÜ9͜2-{&@ÂTʀ"örêF֔iÙË__ý•2 ˆ=í bØr¦e¯r9‚¸S¢¥Í™±pfVc)žœñ·9cRÄ;µ˜SÔÄ“sYOœYö§õ°¾‡‘2!qù@+n·ƒ‰®fU% ˆ©LôÌ9ÓrFUá (b/¿&ræL˝‹T•3 ˆ;— ©“¦eÐ:ȘJPÄ`¾R–5iZöòåÐWҀ"öŒaKš–½œør$ âNËû83VÎÌÊÀq(ē2¡A9ŽÄË¥E(#q썔¹ ÛÃfDŒ÷Œ‚X™x»t‚ñw¥ ˆ©tÂé7cδüœW΀"#ο¹r¦åÎãØºrqçqh͘3-ƒnœ\΀"oʴ̙t)TĜš5[Ê´ìiYW€ î4N¬Ûœëgf…ðø8üfIšx›4Z£ïPX‘Ñw&V8ú¦¤¹ÎÌò·fÇæÃ¬Ljôƒ„8 FÎGàZâœ1jþTÄ!xE ¨É Š¬ohZނ![@oÁ²ßÐ2è%ÙŠôŠù6€–=È6PЍ̷´ì;mAÜwï6€± fV;ÎÛÒmÔ(ÓoU¾ÖƒšP£ô88{\_úÕqµÝ÷WÐpù(++ ôé¹ïhùK–lHó xr¬7´¬EEöÄùø;jî;Zî|$|œ%”O¼—ÿ[ޜ£«ÿóIµc½&ÓrfÕ´ôoç3j«ï]øÇ"ãz̛eÿ±K¤Ü8?p÷sîèË lœ-ùët]ñìwýå +›ݵLNUùß&›òºß5â~W_¨éNŒÄǯ_–by|¹ü³zñe8n†õ~ßgñûúðºÞAF¹|b~ 0 ý±Ýnñtþ±ø ¯Aendstream +endobj +2634 0 obj +1225 +endobj +2635 0 obj<>>>/Annots 1210 0 R>>endobj +2636 0 obj<>stream +xÚ՚IsÛF…ïüs´†g_Žò¢\’”"Ñå‹/´1LqQ@*öÏÏÌtƒ(¶ŽmYŪ'€Màà=ð/”ùŸƗßo»Å»åâíuZŠåƒP. ¬XÞ¿Z®¾n{qxïûS¿?_/ÿZ|\.d'ó„ò ÊÃí/"èN +o\ÅN¤Ô9[qW¦?{°o¯­Pª¼^Ðy_Ÿ÷Í/øé¸Z÷åEtètþ?æ?u,~”U»ÖÏìJË.¡Bø¨M֙æjX?íÆ#i}>N i:™:[éLgP5tJvu½|èß†ÍãisØW¾”wfÀGâ¹äórËxJu +ՄçRYŒ™âãÕîq[×§‰|Ö'M~Ìç¥Ì‹DCë[w×÷â§4O„ƒdçcp{tµ=Ê •òß~‚#”­'!Ÿªs)ò’…lÙ!]`O›ÇÇëÍþþêt6_ŸNý—W_^—Á¡ìςUYM¬ç«OUѬÀ¦û0Åg :UñaP  µàT\}˜¢3ŒJ‹ÕÐFu۟ž†}e3º |Þ@0Ÿ€ò4 @YÇ ' ºL™ª8iÁeØÆ gk `̀˜èlR`-tЌs hfƒp;Žâ5úrÔØªAŘMĔ46Dð§œ4¿öûõéÏ1bœæ±È笆XÞV»ªa¢Yށ[1ŠÏ)t«6 @§9G Åf˜UP [v¦È6mR|V&±ï’*ÜD&Ï7ÁF¼ ֖OÖ>ai$Þº¹w‡‡Ó÷ÕЋ›á°V»]?Åo«ýÓj[ƽQùIJ¼ ЉþØüƒGðÅ¿PÛªÖendstream +endobj +2637 0 obj +1212 +endobj +2638 0 obj<>>>/Annots 1258 0 R>>endobj +2639 0 obj<>stream +xÚ՚KsÛF„ïü{´÷ý8:²”“+ŽEß|a$H¦Í‡BR¶~vwÀBUáðæ‰TŪ&¨!?bÕ 4ðÏB ™•Z/ߗ‹77Ih)–B¹$|°byÿj¹ú{Ӌýƒ¸ÚïNýît|½üº¸^.d'ó„ò ÊÃÇ?ò¨N +o\ÅV(-»„j#nËøqxon¬Pª¼aþÞøüÚüŽoÏÛᝬï\þ ùéî×þ( r­;_È¥ï4*$/tÚd1>ö§çî²ÝlÊÔÙºkMgP5€JvuÁ¼ëw‡õÓi½ßÕ˜ò‹@’x.•ý–ñ”êª Ï¥u¦¸þ¹Ú>múºÿb~ŠÉþ£ñ¢É[‘d^‡ ºXwÝmߋÿœÒü!|Iv>·×Ao7Ç}¤R~îð eëÉߐOÕº¢ÍÎѲCº Ážžî¯6ûcÿùÕç×hP‘Ï?ñ›ˆåà|u«”²¿‚h–ƒ `VŸŽ«ÇºÔuà³Ô/ã³ͪä¨ÐZ0+®YCÑ ^U­TCgx[+¦ðT]F¡jðTdmÄœ4ÕfÀ/«hؤ›¹ÀŠqZq;·ã(žfœÎ›±­ åhª¬mP“Û¤À Šïw›õÝé88²7̼ÊÉó+†P½ªz1ˆiEØÁªøz1Éç-ºUñbP  wàVL½˜¤s +̪÷ƒjèœæ}ÔO♀'t%j@5xÙz#ç¨!ñ´Ÿ©QªÁÓ|†kؐx50l@4tJw÷s lfƒp;Žb6g¾¥6&ÅjP±7˜²Æd[֘5×Ûõi<ð·üû3ª:¿ LtpX²Ä´ Ld~ÔOÒÕ´O ¼üÎ IçbÓ0jè\âÞ0‘€Ö5 ¨0ï)Ö ‰—wÇÔ0jðŒáÝ0‘xÙódž DC§åeI3L¤™í0ˆgÎ("g$”ã©øˆ&g¤¦’37÷CÒ8Ç,i”Ó痂Nzj—@LKA'ý]"ùBjÚ%P `”¬Û%’Îc^sTCç± gœ3 Ã»æ ¨ÐñN +Τ±R¨8‹=6۔¡ð4×% @4t‹k:g†93³A¸GñL}>i´2ãùšF5EVX稹Yïì×wã`9-C, M8$œáZbÎ8i>± +¯IjT‘õù ŰÁ®9ªa Ø_3Î +Ðc‰]sTè±Äf›4ž £É(T žÅâšmÒPxjë :ƒ­54ÃHšÙ Ü>à,“ÆœO¥±þ®gë ¦¤QZ79ó~uøÖ¿H%±%+g‰u ¡¯¢Y pÆCð%lÀk¤yž°ÿæš0ZÄÖºLœ·ßkÆñBÐùØÜàã̟|â} Åæ\{À¼¦v¼/ÉXê’ÌtùßÎ j«/½øC†Ë1/.ýsxŠ%N]°äVõ,,ήûë4^ö/yòg]×<Ï[\ùH¢oyxËk½rêVEâêӇ[q»8ýXzñá°<¬¶ÛþpïW»çÕüÉg‹þ-@úó;~‘-þ'«©endstream +endobj +2640 0 obj +1214 +endobj +2641 0 obj<>>>/Annots 1306 0 R>>endobj +2642 0 obj<>stream +xÚ՚IoÛH…ïú}Laz_ŽÙ<˜CÅÊ-NLÎhINòóÓÝÕ$‹ŒJÇÛðL¹äl¾'>ꟕ2+a|ùù¶]½^¯^Þ$¡¥Xß å’ðÁŠõݳuÿ×fû{ñf¿;»óéùúûêÝz%;™'”U>ÿ!‚î¤ðÆuQlEJkb#nËôýÁñA¼¼±B©òzAççúüÜü‚_NýÃP^D‡Nçÿ1ÿªcñ¥œ#صî|fWZv©©_µÉ:Ó¼:>Ç@ ¶ ÁZn‡Aüçô§°“ìrlG½Úœöe”Jù·ÿƒ½”Ý5ï%çÁ ¤žT£Ë!à\ƒ:îþ<½ïw_Ÿ}}^fzÃc•ϨžXÖT·ª9-kÁ¬g Ågd3«’5  Q`V\³†¢S¼ªf (D§"ó¤¡ð¤—¤© +áI Ã6i<[­rLP3žM +l†mÖPx!€µ.ˆ.D°:kÆ95‹Am{Å3kü嬱Þ"ƒ5gõ *gMIš·Ã}ÿ´9ŸÆ¼‰šUb58U­ª ´œf3 Í©êQ¬ +áåó6rŽŠNÛvÁV|¢ÓŒŠ­SxÕX&® +á)Ýñ~ÏOà™«ÃT³1ә|>êë|xœ>¼Ô¶·Q<}8\öa]»ì+ jöa=ráu¸¼¥R.+!¨¹tVB~ +÷b‰âsK  K¼‹%ŠÎ:T,Bt„{±Dæÿw.–@!@c˜K^öùX…ð´d2œts±±Im±4Îi!ƒµížs±/‡ŒNÐ|G“OLsÆèd¦^éÃa˜òÅbF6<²¦Ë+B‡47K æ¡£dß,Q|Þ£ 7PÐÞÍEç j–@!:Ç=j(<“P³ +áYɼY¢ð´GÍ(„§óf‰ÂSfn–@ :e¯m–Æ96‹Am»åÜ,%"l$Tßɕ%.å¢XÒRMÅR ››é† ÜâFyyy=¨æn ļTd~UCÒƒº%P/XÖÝIç[ ^ƒ¢ó­ç5$ mõuPжòškԐxÆN­j +á™Ö_sO·Úº¬KˆN_YS hcÚv¾Åم=TcFÉV}Ëò¦ Ԝ3J¶ê{̙Ç̀n–3sbuy1$¨Ák̤e žZÎ8f¸ØJðš2qفÇVsÍÍ·â>‘µ,À}+­ AçZq 7ÉÝò#¬oÌPdVM]ï:¯° ‚MCU ×Ë¢Z·žúŠ ˜8]æÙÅØ:öÝ,c¥îŸ™KNvíîõ¦©O­(o¾|¼·ûûóÏþ8ˆÇýñßn‡ãI¼ïwOý¦Œ{¡òÚVâE€2õ׏Ƕÿ>­~w”©Wendstream +endobj +2643 0 obj +1181 +endobj +2644 0 obj<>>>/Annots 1328 0 R>>endobj +2645 0 obj<>stream +xÚ՘KsÚ0…÷ü +-“E½Ë4MºigÒ@¦›lÜ`( Ԙ6Ó_ß+]9ˆÎ¤Ê®j2cæŒñ5ßÕÕ9àïNüsb‘†n“Y…¬A•rWsҔؘD¯Â¤‰*cc +½ªâ¤)ªè%cÒ :*ÏÑcªÍšžµh31kPexÖ¡ÍT›5%<£ÐZ²¡ÈèŒFk)gÍX³æ¤P:ŸJՙ5òïY£4Gƒbö&ªcÖ(-²¤ù¼šg?ix%>…˜ª0 ÒF¯Š9ƒ"˜kWyΔø„JVrU(tú:TiҔèâÖ“UF¬×4@ézLLTG@ S+ªNšžÓh21iPexÎT3%8pB7æ ŠŒ Þâ^—3c̙“Bé|*UgÎÄ.ÑØóC27>$ &+Uzþ@®îo§dº] ?›¾%·ývÙ7]×ö{ò±Ùš5îbóòƊHùôcµJ-ü4ù puüxendstream +endobj +2646 0 obj +714 +endobj +2647 0 obj<>>>>>endobj +2648 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS04±Ô3T072PIÑPp VÎO+)O,JU(ÊO/JÌÍM-*VðMÌ+MÌÑ Éâ҅hхê©(ËÌ̉»†pr÷Á5endstream +endobj +2649 0 obj +104 +endobj +2650 0 obj<>endobj +2651 0 obj<>endobj +2652 0 obj<>endobj +2653 0 obj<>endobj +2654 0 obj<>endobj +2655 0 obj<>endobj +2656 0 obj<>endobj +2657 0 obj<>endobj +2658 0 obj<>endobj +2659 0 obj<>endobj +2660 0 obj<>endobj +2661 0 obj<>endobj +2662 0 obj<>endobj +2663 0 obj<>endobj +2664 0 obj<>endobj +2665 0 obj<>endobj +2666 0 obj<>endobj +2667 0 obj<>endobj +2668 0 obj<>endobj +2669 0 obj<>endobj +2670 0 obj<>endobj +2671 0 obj<>endobj +2672 0 obj<>endobj +2673 0 obj<>endobj +2674 0 obj<>endobj +2675 0 obj<>endobj +2676 0 obj<>endobj +2677 0 obj<>endobj +2678 0 obj<>endobj +2679 0 obj<>endobj +2680 0 obj<>endobj +2681 0 obj<>endobj +2682 0 obj<>endobj +2683 0 obj<>endobj +2684 0 obj<>endobj +2685 0 obj<>endobj +2686 0 obj<>endobj +2687 0 obj<>endobj +2688 0 obj<>endobj +2689 0 obj<>endobj +2690 0 obj<>endobj +2691 0 obj<>endobj +2692 0 obj<>endobj +2693 0 obj<>endobj +2694 0 obj<>endobj +2695 0 obj<>endobj +2696 0 obj<>endobj +2697 0 obj<>endobj +2698 0 obj<>endobj +2699 0 obj<>endobj +2700 0 obj<>endobj +2701 0 obj<>endobj +2702 0 obj<>endobj +2703 0 obj<>endobj +2704 0 obj<>endobj +2705 0 obj<>endobj +2706 0 obj<>endobj +2707 0 obj<>endobj +2708 0 obj<>endobj +2709 0 obj<>endobj +2710 0 obj<>endobj +2711 0 obj<>endobj +2712 0 obj<>endobj +2713 0 obj<>endobj +2714 0 obj<>endobj +2715 0 obj<>endobj +2716 0 obj<>endobj +2717 0 obj<>endobj +2718 0 obj<>endobj +2719 0 obj<>endobj +2720 0 obj<>endobj +2721 0 obj<>endobj +2722 0 obj<>endobj +2723 0 obj<>endobj +2724 0 obj<>endobj +2725 0 obj<>endobj +2726 0 obj<>endobj +2727 0 obj<>endobj +2728 0 obj<>endobj +2729 0 obj<>endobj +2730 0 obj<>endobj +2731 0 obj<>endobj +2732 0 obj<>endobj +2733 0 obj<>endobj +2734 0 obj<>endobj +2735 0 obj<>endobj +2736 0 obj<>endobj +2737 0 obj<>endobj +2738 0 obj<>endobj +2739 0 obj<>endobj +2740 0 obj<>endobj +2741 0 obj<>endobj +2742 0 obj<>endobj +2743 0 obj<>endobj +2744 0 obj<>endobj +2745 0 obj<>endobj +2746 0 obj<>endobj +2747 0 obj<>endobj +2748 0 obj<>endobj +2749 0 obj<>endobj +2750 0 obj<>endobj +2751 0 obj<>endobj +2752 0 obj<>endobj +2753 0 obj<>endobj +2754 0 obj<>endobj +2755 0 obj<>endobj +2756 0 obj<>endobj +2757 0 obj<>endobj +2758 0 obj<>endobj +2759 0 obj<>endobj +2760 0 obj<>endobj +2761 0 obj<>endobj +2762 0 obj<>endobj +2763 0 obj<>endobj +2764 0 obj<>endobj +2765 0 obj<>endobj +2766 0 obj<>endobj +2767 0 obj<>endobj +2768 0 obj<>endobj +2769 0 obj<>endobj +2770 0 obj<>endobj +2771 0 obj<>endobj +2772 0 obj<>endobj +2773 0 obj<>endobj +2774 0 obj<>endobj +2775 0 obj<>endobj +2776 0 obj<>endobj +2777 0 obj<>endobj +2778 0 obj<>endobj +2779 0 obj<>endobj +2780 0 obj<>endobj +2781 0 obj<>endobj +2782 0 obj<>endobj +2783 0 obj<>endobj +2784 0 obj<>endobj +2785 0 obj<>endobj +2786 0 obj<>endobj +2787 0 obj<>endobj +2788 0 obj<>endobj +2789 0 obj<>endobj +2790 0 obj<>endobj +2791 0 obj<>endobj +2792 0 obj<>endobj +2793 0 obj<>endobj +2794 0 obj<>endobj +2795 0 obj<>endobj +2796 0 obj<>endobj +2797 0 obj<>endobj +2798 0 obj<>endobj +2799 0 obj<>endobj +2800 0 obj<>endobj +2801 0 obj<>endobj +2802 0 obj<>endobj +2803 0 obj<>endobj +2804 0 obj<>endobj +2805 0 obj<>endobj +2806 0 obj<>endobj +2807 0 obj<>endobj +2808 0 obj<>endobj +2809 0 obj<>endobj +2810 0 obj<>endobj +2811 0 obj<>endobj +2812 0 obj<>endobj +2813 0 obj<>endobj +2814 0 obj<>endobj +2815 0 obj<>endobj +2816 0 obj<>endobj +2817 0 obj<>endobj +2818 0 obj<>endobj +2819 0 obj<>endobj +2820 0 obj<>endobj +2821 0 obj<>endobj +2822 0 obj<>endobj +2823 0 obj<>endobj +2824 0 obj<>endobj +2825 0 obj<>endobj +2826 0 obj<>endobj +2827 0 obj<>endobj +2828 0 obj<>endobj +2829 0 obj<>endobj +2830 0 obj<>endobj +2831 0 obj<>endobj +2832 0 obj<>endobj +2833 0 obj<>endobj +2834 0 obj<>endobj +2835 0 obj<>endobj +2836 0 obj<>endobj +2837 0 obj<>endobj +2838 0 obj<>endobj +2839 0 obj<>endobj +2840 0 obj<>endobj +2841 0 obj<>endobj +2842 0 obj<>endobj +2843 0 obj<>endobj +2844 0 obj<>endobj +2845 0 obj<>endobj +2846 0 obj<>endobj +2847 0 obj<>endobj +2848 0 obj<>endobj +2849 0 obj<>endobj +2850 0 obj<>endobj +2851 0 obj<>endobj +2852 0 obj<>endobj +2853 0 obj<>endobj +2854 0 obj<>endobj +2855 0 obj<>endobj +2856 0 obj<>endobj +2857 0 obj<>endobj +2858 0 obj<>endobj +2859 0 obj<>endobj +2860 0 obj<>endobj +2861 0 obj<>endobj +2862 0 obj<>endobj +2863 0 obj<>endobj +2864 0 obj<>endobj +2865 0 obj<>endobj +2866 0 obj<>endobj +2867 0 obj<>endobj +2868 0 obj<>endobj +2869 0 obj<>endobj +2870 0 obj<>endobj +2871 0 obj<>endobj +2872 0 obj<>endobj +2873 0 obj<>endobj +2874 0 obj<>endobj +2875 0 obj<>endobj +2876 0 obj<>endobj +2877 0 obj<>endobj +2878 0 obj<>endobj +2879 0 obj<>endobj +2880 0 obj<>endobj +2881 0 obj<>endobj +2882 0 obj<>endobj +2883 0 obj<>endobj +2884 0 obj<>endobj +2885 0 obj<>endobj +2886 0 obj<>endobj +2887 0 obj<>endobj +2888 0 obj<>endobj +2889 0 obj<>endobj +2890 0 obj<>endobj +2891 0 obj<>endobj +2892 0 obj<>endobj +2893 0 obj<>endobj +2894 0 obj<>endobj +2895 0 obj<>endobj +2896 0 obj<>endobj +2897 0 obj<>endobj +2898 0 obj<>endobj +2899 0 obj<>endobj +2900 0 obj<>endobj +2901 0 obj<>endobj +2902 0 obj<>endobj +2903 0 obj<>endobj +2904 0 obj<>endobj +2905 0 obj<>endobj +2906 0 obj<>endobj +2907 0 obj<>endobj +2908 0 obj<>endobj +2909 0 obj<>endobj +2910 0 obj<>endobj +2911 0 obj<>endobj +2912 0 obj<>endobj +2913 0 obj<>endobj +2914 0 obj<>endobj +2915 0 obj<>endobj +2916 0 obj<>endobj +2917 0 obj<>endobj +2918 0 obj<>endobj +2919 0 obj<>endobj +2920 0 obj<>endobj +2921 0 obj<>endobj +2922 0 obj<>endobj +2923 0 obj<>endobj +2924 0 obj<>endobj +2925 0 obj<>endobj +2926 0 obj<>endobj +2927 0 obj<>endobj +2928 0 obj<>endobj +2929 0 obj<>endobj +2930 0 obj<>endobj +2931 0 obj<>endobj +2932 0 obj<>endobj +2933 0 obj<>endobj +2934 0 obj<>endobj +2935 0 obj<>endobj +2936 0 obj<>endobj +2937 0 obj<>endobj +2938 0 obj<>endobj +2939 0 obj<>endobj +2940 0 obj<>endobj +2941 0 obj<>endobj +2942 0 obj<>endobj +2943 0 obj<>endobj +2944 0 obj<>endobj +2945 0 obj<>endobj +2946 0 obj<>endobj +2947 0 obj<>endobj +2948 0 obj<>endobj +2949 0 obj<>endobj +2950 0 obj<>endobj +2951 0 obj<>endobj +2952 0 obj<>endobj +2953 0 obj<>endobj +2954 0 obj<>endobj +2955 0 obj<>endobj +2956 0 obj<>endobj +2957 0 obj<>endobj +2958 0 obj<>endobj +2959 0 obj<>endobj +2960 0 obj<>endobj +2961 0 obj<>endobj +2962 0 obj<>endobj +2963 0 obj<>endobj +2964 0 obj<>endobj +2965 0 obj<>endobj +2966 0 obj<>endobj +2967 0 obj<>endobj +2968 0 obj<>endobj +2969 0 obj<>endobj +2970 0 obj<>endobj +2971 0 obj<>endobj +2972 0 obj<>endobj +2973 0 obj<>endobj +2974 0 obj<>endobj +2975 0 obj<>endobj +2976 0 obj<>endobj +2977 0 obj<>endobj +2978 0 obj<>endobj +2979 0 obj<>endobj +2980 0 obj<>endobj +2981 0 obj<>endobj +2982 0 obj<>endobj +2983 0 obj<>endobj +2984 0 obj<>endobj +2985 0 obj<>endobj +2986 0 obj<>endobj +2987 0 obj<>endobj +2988 0 obj<>endobj +2989 0 obj<>endobj +2990 0 obj<>endobj +2991 0 obj<>endobj +2992 0 obj<>endobj +2993 0 obj<>endobj +2994 0 obj<>endobj +2995 0 obj<>endobj +2996 0 obj<>endobj +2997 0 obj<>endobj +2998 0 obj<>endobj +2999 0 obj<>endobj +3000 0 obj<>endobj +3001 0 obj<>endobj +3002 0 obj<>endobj +3003 0 obj<>endobj +3004 0 obj<>endobj +3005 0 obj<>endobj +3006 0 obj<>endobj +3007 0 obj<>endobj +3008 0 obj<>endobj +3009 0 obj<>endobj +3010 0 obj<>endobj +3011 0 obj<>endobj +3012 0 obj<>endobj +3013 0 obj<>endobj +3014 0 obj<>endobj +3015 0 obj<>endobj +3016 0 obj<>endobj +3017 0 obj<>endobj +3018 0 obj<>endobj +3019 0 obj<>endobj +3020 0 obj<>endobj +3021 0 obj<>endobj +3022 0 obj<>endobj +3023 0 obj<>endobj +3024 0 obj<>endobj +3025 0 obj<>endobj +3026 0 obj<>endobj +3027 0 obj<>endobj +3028 0 obj<>endobj +3029 0 obj<>endobj +3030 0 obj<>endobj +3031 0 obj<>endobj +3032 0 obj<>endobj +3033 0 obj<>endobj +3034 0 obj<>endobj +3035 0 obj<>endobj +3036 0 obj<>endobj +3037 0 obj<>endobj +3038 0 obj<>endobj +3039 0 obj<>endobj +3040 0 obj<>endobj +3041 0 obj<>endobj +3042 0 obj<>endobj +3043 0 obj<>endobj +3044 0 obj<>endobj +3045 0 obj<>endobj +3046 0 obj<>endobj +3047 0 obj<>endobj +3048 0 obj<>endobj +3049 0 obj<>endobj +3050 0 obj<>endobj +3051 0 obj<>endobj +3052 0 obj<>endobj +3053 0 obj<>endobj +3054 0 obj<>endobj +3055 0 obj<>endobj +3056 0 obj<>endobj +3057 0 obj<>endobj +3058 0 obj<>endobj +3059 0 obj<>endobj +3060 0 obj<>endobj +3061 0 obj<>endobj +3062 0 obj<>endobj +3063 0 obj<>endobj +3064 0 obj<>endobj +3065 0 obj<>endobj +3066 0 obj<>endobj +3067 0 obj<>endobj +3068 0 obj<>endobj +3069 0 obj<>endobj +3070 0 obj<>endobj +3071 0 obj<>endobj +3072 0 obj<>endobj +3073 0 obj<>endobj +3074 0 obj<>endobj +3075 0 obj<>endobj +3076 0 obj<>endobj +3077 0 obj<>endobj +3078 0 obj<>endobj +3079 0 obj<>endobj +3080 0 obj<>endobj +3081 0 obj<>endobj +3082 0 obj<>endobj +3083 0 obj<>endobj +3084 0 obj<>endobj +3085 0 obj<>endobj +3086 0 obj<>endobj +3087 0 obj<>endobj +3088 0 obj<>endobj +3089 0 obj<>endobj +3090 0 obj<>endobj +3091 0 obj<>endobj +3092 0 obj<>endobj +3093 0 obj<>endobj +3094 0 obj<>endobj +3095 0 obj<>endobj +3096 0 obj<>endobj +3097 0 obj<>endobj +3098 0 obj<>endobj +3099 0 obj<>endobj +3100 0 obj<>endobj +3101 0 obj<>endobj +3102 0 obj<>endobj +3103 0 obj<>endobj +3104 0 obj<>endobj +3105 0 obj<>endobj +3106 0 obj<>endobj +3107 0 obj<>endobj +3108 0 obj<>endobj +3109 0 obj<>endobj +3110 0 obj<>endobj +3111 0 obj<>endobj +3112 0 obj<>endobj +3113 0 obj<>endobj +3114 0 obj<>endobj +3115 0 obj<>endobj +3116 0 obj<>endobj +3117 0 obj<>endobj +3118 0 obj<>endobj +3119 0 obj<>endobj +3120 0 obj<>endobj +3121 0 obj<>endobj +3122 0 obj<>endobj +3123 0 obj<>endobj +3124 0 obj<>endobj +3125 0 obj<>endobj +3126 0 obj<>endobj +3127 0 obj<>endobj +3128 0 obj<>endobj +3129 0 obj<>endobj +3130 0 obj<>endobj +3131 0 obj<>endobj +3132 0 obj<>endobj +3133 0 obj<>endobj +3134 0 obj<>endobj +3135 0 obj<>endobj +3136 0 obj<>endobj +3137 0 obj<>endobj +3138 0 obj<>endobj +3139 0 obj<>endobj +3140 0 obj<>endobj +3141 0 obj<>endobj +3142 0 obj<>endobj +3143 0 obj<>endobj +3144 0 obj<>endobj +3145 0 obj<>endobj +3146 0 obj<>endobj +3147 0 obj<>endobj +3148 0 obj<>endobj +3149 0 obj<>endobj +3150 0 obj<>endobj +3151 0 obj<>endobj +3152 0 obj<>endobj +3153 0 obj<>endobj +3154 0 obj<>endobj +3155 0 obj<>endobj +3156 0 obj<>endobj +3157 0 obj<>endobj +3158 0 obj<>endobj +3159 0 obj<>endobj +3160 0 obj<>endobj +3161 0 obj<>endobj +3162 0 obj<>endobj +3163 0 obj<>endobj +3164 0 obj<>endobj +3165 0 obj<>endobj +3166 0 obj<>endobj +3167 0 obj<>endobj +3168 0 obj<>endobj +3169 0 obj<>endobj +3170 0 obj<>endobj +3171 0 obj<>endobj +3172 0 obj<>endobj +3173 0 obj<>endobj +3174 0 obj<>endobj +3175 0 obj<>endobj +3176 0 obj<>endobj +3177 0 obj<>endobj +3178 0 obj<>endobj +3179 0 obj<>endobj +3180 0 obj<>endobj +3181 0 obj<>endobj +3182 0 obj<>endobj +3183 0 obj<>endobj +3184 0 obj<>endobj +3185 0 obj<>endobj +3186 0 obj<>endobj +3187 0 obj<>endobj +3188 0 obj<>endobj +3189 0 obj<>endobj +3190 0 obj<>endobj +3191 0 obj<>endobj +3192 0 obj<>endobj +3193 0 obj<>endobj +3194 0 obj<>endobj +3195 0 obj<>endobj +3196 0 obj<>endobj +3197 0 obj<>endobj +3198 0 obj<>endobj +3199 0 obj<>endobj +3200 0 obj<>endobj +3201 0 obj<>endobj +3202 0 obj<>endobj +3203 0 obj<>endobj +3204 0 obj<>endobj +3205 0 obj<>endobj +3206 0 obj<>endobj +3207 0 obj<>endobj +3208 0 obj<>endobj +3209 0 obj<>endobj +3210 0 obj<>endobj +3211 0 obj<>endobj +3212 0 obj<>endobj +3213 0 obj<>endobj +3214 0 obj<>endobj +3215 0 obj<>endobj +3216 0 obj<>endobj +3217 0 obj<>endobj +3218 0 obj<>endobj +3219 0 obj<>endobj +3220 0 obj<>endobj +3221 0 obj<>endobj +3222 0 obj<>endobj +3223 0 obj<>endobj +3224 0 obj<>endobj +3225 0 obj<>endobj +3226 0 obj<>endobj +3227 0 obj<>endobj +3228 0 obj<>endobj +3229 0 obj<>endobj +3230 0 obj<>endobj +3231 0 obj<>endobj +3232 0 obj<>endobj +3233 0 obj<>endobj +3234 0 obj<>endobj +3235 0 obj<>endobj +3236 0 obj<>endobj +3237 0 obj<>endobj +3238 0 obj<>endobj +3239 0 obj<>endobj +3240 0 obj<>endobj +3241 0 obj<>endobj +3242 0 obj<>endobj +3243 0 obj<>endobj +3244 0 obj<>endobj +3245 0 obj<>endobj +3246 0 obj<>endobj +3247 0 obj<>endobj +3248 0 obj<>endobj +3249 0 obj<>endobj +3250 0 obj<>endobj +3251 0 obj<>endobj +3252 0 obj<>endobj +3253 0 obj<>endobj +3254 0 obj<>endobj +3255 0 obj<>endobj +3256 0 obj<>endobj +3257 0 obj<>endobj +3258 0 obj<>endobj +3259 0 obj<>endobj +3260 0 obj<>endobj +3261 0 obj<>endobj +3262 0 obj<>endobj +3263 0 obj<>endobj +3264 0 obj<>endobj +3265 0 obj<>endobj +3266 0 obj<>endobj +3267 0 obj<>endobj +3268 0 obj<>endobj +3269 0 obj<>endobj +3270 0 obj<>endobj +3271 0 obj<>endobj +3272 0 obj<>endobj +3273 0 obj<>endobj +3274 0 obj<>endobj +3275 0 obj<>endobj +3276 0 obj<>endobj +3277 0 obj<>endobj +3278 0 obj<>endobj +3279 0 obj<>endobj +3280 0 obj<>endobj +3281 0 obj<>endobj +3282 0 obj<>endobj +3283 0 obj<>endobj +3284 0 obj<>endobj +3285 0 obj<>endobj +3286 0 obj<>endobj +3287 0 obj<>endobj +3288 0 obj<>endobj +3289 0 obj<>endobj +3290 0 obj<>endobj +3291 0 obj<>endobj +3292 0 obj<>endobj +3293 0 obj<>endobj +3294 0 obj<>endobj +3295 0 obj<>endobj +3296 0 obj<>endobj +3297 0 obj<>endobj +3298 0 obj<>endobj +3299 0 obj<>endobj +3300 0 obj<>endobj +3301 0 obj<>endobj +3302 0 obj<>endobj +3303 0 obj<>endobj +3304 0 obj<>endobj +3305 0 obj<>endobj +3306 0 obj<>endobj +3307 0 obj<>endobj +3308 0 obj<>endobj +3309 0 obj<>endobj +3310 0 obj<>endobj +3311 0 obj<>endobj +3312 0 obj<>endobj +3313 0 obj<>endobj +3314 0 obj<>endobj +3315 0 obj<>endobj +3316 0 obj<>endobj +3317 0 obj<>endobj +3318 0 obj<>endobj +3319 0 obj<>endobj +3320 0 obj<>endobj +3321 0 obj<>endobj +3322 0 obj<>endobj +3323 0 obj<>endobj +3324 0 obj<>endobj +3325 0 obj<>endobj +3326 0 obj<>endobj +3327 0 obj<>endobj +3328 0 obj<>endobj +3329 0 obj<>endobj +3330 0 obj<>endobj +3331 0 obj<>endobj +3332 0 obj<>endobj +3333 0 obj<>endobj +3334 0 obj<>endobj +3335 0 obj<>endobj +3336 0 obj<>endobj +3337 0 obj<>endobj +3338 0 obj<>endobj +3339 0 obj<>endobj +3340 0 obj<>endobj +3341 0 obj<>endobj +3342 0 obj<>endobj +3343 0 obj<>endobj +3344 0 obj<>endobj +3345 0 obj<>endobj +3346 0 obj<>endobj +3347 0 obj<>endobj +3348 0 obj<>endobj +3349 0 obj<>endobj +3350 0 obj<>endobj +3351 0 obj<>endobj +3352 0 obj<>endobj +3353 0 obj<>endobj +3354 0 obj<>endobj +3355 0 obj<>endobj +3356 0 obj<>endobj +3357 0 obj<>endobj +3358 0 obj<>endobj +3359 0 obj<>endobj +3360 0 obj<>endobj +3361 0 obj<>endobj +3362 0 obj<>endobj +3363 0 obj<>endobj +3364 0 obj<>endobj +3365 0 obj<>endobj +3366 0 obj<>endobj +3367 0 obj<>endobj +3368 0 obj<>endobj +3369 0 obj<>endobj +3370 0 obj<>endobj +3371 0 obj<>endobj +3372 0 obj<>endobj +3373 0 obj<>endobj +3374 0 obj<>endobj +3375 0 obj<>endobj +3376 0 obj<>endobj +3377 0 obj<>endobj +3378 0 obj<>endobj +3379 0 obj<>endobj +3380 0 obj<>endobj +3381 0 obj<>endobj +3382 0 obj<>endobj +3383 0 obj<>endobj +3384 0 obj<>endobj +3385 0 obj<>endobj +3386 0 obj<>endobj +3387 0 obj<>endobj +3388 0 obj<>endobj +3389 0 obj<>endobj +3390 0 obj<>endobj +3391 0 obj<>endobj +3392 0 obj<>endobj +3393 0 obj<>endobj +3394 0 obj<>endobj +3395 0 obj<>endobj +3396 0 obj<>endobj +3397 0 obj<>endobj +3398 0 obj<>endobj +3399 0 obj<>endobj +3400 0 obj<>endobj +3401 0 obj<>endobj +3402 0 obj<>endobj +3403 0 obj<>endobj +3404 0 obj<>endobj +3405 0 obj<>endobj +3406 0 obj<>endobj +3407 0 obj<>endobj +3408 0 obj<>endobj +3409 0 obj<>endobj +3410 0 obj<>endobj +3411 0 obj<>endobj +3412 0 obj<>endobj +3413 0 obj<>endobj +3414 0 obj<>endobj +3415 0 obj<>endobj +3416 0 obj<>1<>2<>20<>]>>>>endobj +xref +0 3417 +0000000000 65535 f +0000000015 00000 n +0000000226 00000 n +0000001792 00000 n +0000001866 00000 n +0000001945 00000 n +0000002027 00000 n +0000002105 00000 n +0000002182 00000 n +0000002261 00000 n +0000002344 00000 n +0000002421 00000 n +0000002503 00000 n +0000002588 00000 n +0000002647 00000 n +0000002699 00000 n +0000002784 00000 n +0000002836 00000 n +0000002920 00000 n +0000002951 00000 n +0000003056 00000 n +0000003161 00000 n +0000003266 00000 n +0000003371 00000 n +0000003476 00000 n +0000003581 00000 n +0000003686 00000 n +0000003791 00000 n +0000003832 00000 n +0000003916 00000 n +0000003996 00000 n +0000004100 00000 n +0000004124 00000 n +0000004230 00000 n +0000004335 00000 n +0000004366 00000 n +0000004418 00000 n +0000004503 00000 n +0000004527 00000 n +0000004633 00000 n +0000004657 00000 n +0000004713 00000 n +0000004798 00000 n +0000004848 00000 n +0000004933 00000 n +0000004964 00000 n +0000005017 00000 n +0000005102 00000 n +0000005158 00000 n +0000005243 00000 n +0000005302 00000 n +0000005386 00000 n +0000005424 00000 n +0000005476 00000 n +0000005561 00000 n +0000005585 00000 n +0000005690 00000 n +0000005714 00000 n +0000005754 00000 n +0000005839 00000 n +0000005863 00000 n +0000005908 00000 n +0000005992 00000 n +0000006097 00000 n +0000006203 00000 n +0000006309 00000 n +0000006354 00000 n +0000006460 00000 n +0000006565 00000 n +0000006671 00000 n +0000006709 00000 n +0000006814 00000 n +0000006852 00000 n +0000006935 00000 n +0000006978 00000 n +0000007061 00000 n +0000007098 00000 n +0000007181 00000 n +0000007286 00000 n +0000007391 00000 n +0000007494 00000 n +0000007560 00000 n +0000007666 00000 n +0000007772 00000 n +0000007877 00000 n +0000007983 00000 n +0000008089 00000 n +0000008195 00000 n +0000008300 00000 n +0000008406 00000 n +0000008479 00000 n +0000008584 00000 n +0000008622 00000 n +0000008705 00000 n +0000008748 00000 n +0000008831 00000 n +0000008868 00000 n +0000008951 00000 n +0000009056 00000 n +0000009161 00000 n +0000009266 00000 n +0000009372 00000 n +0000009447 00000 n +0000009553 00000 n +0000009660 00000 n +0000009767 00000 n +0000009874 00000 n +0000009980 00000 n +0000010087 00000 n +0000010153 00000 n +0000010259 00000 n +0000010366 00000 n +0000010473 00000 n +0000010580 00000 n +0000010630 00000 n +0000010736 00000 n +0000010843 00000 n +0000010950 00000 n +0000010992 00000 n +0000011098 00000 n +0000011205 00000 n +0000011312 00000 n +0000011354 00000 n +0000011460 00000 n +0000011567 00000 n +0000011674 00000 n +0000011781 00000 n +0000011831 00000 n +0000011936 00000 n +0000011981 00000 n +0000012067 00000 n +0000012101 00000 n +0000012207 00000 n +0000012314 00000 n +0000012421 00000 n +0000012463 00000 n +0000012569 00000 n +0000012676 00000 n +0000012783 00000 n +0000012890 00000 n +0000012997 00000 n +0000013055 00000 n +0000013161 00000 n +0000013268 00000 n +0000013375 00000 n +0000013482 00000 n +0000013589 00000 n +0000013647 00000 n +0000013753 00000 n +0000013860 00000 n +0000013967 00000 n +0000014074 00000 n +0000014181 00000 n +0000014239 00000 n +0000014345 00000 n +0000014452 00000 n +0000014559 00000 n +0000014666 00000 n +0000014773 00000 n +0000014831 00000 n +0000014937 00000 n +0000015044 00000 n +0000015151 00000 n +0000015258 00000 n +0000015365 00000 n +0000015423 00000 n +0000015529 00000 n +0000015636 00000 n +0000015743 00000 n +0000015850 00000 n +0000015957 00000 n +0000016015 00000 n +0000016121 00000 n +0000016228 00000 n +0000016262 00000 n +0000016368 00000 n +0000016475 00000 n +0000016582 00000 n +0000016689 00000 n +0000016739 00000 n +0000016845 00000 n +0000016952 00000 n +0000017059 00000 n +0000017166 00000 n +0000017216 00000 n +0000017322 00000 n +0000017429 00000 n +0000017536 00000 n +0000017578 00000 n +0000017684 00000 n +0000017791 00000 n +0000017898 00000 n +0000017940 00000 n +0000018046 00000 n +0000018153 00000 n +0000018260 00000 n +0000018367 00000 n +0000018473 00000 n +0000018531 00000 n +0000018637 00000 n +0000018744 00000 n +0000018851 00000 n +0000018958 00000 n +0000019064 00000 n +0000019122 00000 n +0000019228 00000 n +0000019335 00000 n +0000019442 00000 n +0000019549 00000 n +0000019655 00000 n +0000019713 00000 n +0000019818 00000 n +0000019924 00000 n +0000020030 00000 n +0000020136 00000 n +0000020240 00000 n +0000020298 00000 n +0000020404 00000 n +0000020511 00000 n +0000020618 00000 n +0000020725 00000 n +0000020831 00000 n +0000020889 00000 n +0000020995 00000 n +0000021102 00000 n +0000021209 00000 n +0000021316 00000 n +0000021422 00000 n +0000021480 00000 n +0000021586 00000 n +0000021693 00000 n +0000021727 00000 n +0000021833 00000 n +0000021940 00000 n +0000021974 00000 n +0000022080 00000 n +0000022187 00000 n +0000022221 00000 n +0000022327 00000 n +0000022434 00000 n +0000022541 00000 n +0000022648 00000 n +0000022698 00000 n +0000022804 00000 n +0000022911 00000 n +0000023018 00000 n +0000023060 00000 n +0000023166 00000 n +0000023192 00000 n +0000023298 00000 n +0000023405 00000 n +0000023512 00000 n +0000023619 00000 n +0000023726 00000 n +0000023833 00000 n +0000023899 00000 n +0000024005 00000 n +0000024031 00000 n +0000024137 00000 n +0000024244 00000 n +0000024351 00000 n +0000024393 00000 n +0000024499 00000 n +0000024525 00000 n +0000024631 00000 n +0000024657 00000 n +0000024763 00000 n +0000024789 00000 n +0000024895 00000 n +0000025002 00000 n +0000025109 00000 n +0000025151 00000 n +0000025257 00000 n +0000025364 00000 n +0000025398 00000 n +0000025504 00000 n +0000025530 00000 n +0000025636 00000 n +0000025662 00000 n +0000025768 00000 n +0000025875 00000 n +0000025909 00000 n +0000026015 00000 n +0000026122 00000 n +0000026229 00000 n +0000026271 00000 n +0000026377 00000 n +0000026403 00000 n +0000026509 00000 n +0000026616 00000 n +0000026723 00000 n +0000026765 00000 n +0000026871 00000 n +0000026978 00000 n +0000027085 00000 n +0000027127 00000 n +0000027233 00000 n +0000027259 00000 n +0000027365 00000 n +0000027472 00000 n +0000027579 00000 n +0000027621 00000 n +0000027727 00000 n +0000027834 00000 n +0000027868 00000 n +0000027974 00000 n +0000028000 00000 n +0000028106 00000 n +0000028132 00000 n +0000028238 00000 n +0000028345 00000 n +0000028379 00000 n +0000028485 00000 n +0000028592 00000 n +0000028699 00000 n +0000028741 00000 n +0000028847 00000 n +0000028954 00000 n +0000029061 00000 n +0000029168 00000 n +0000029275 00000 n +0000029382 00000 n +0000029487 00000 n +0000029594 00000 n +0000029676 00000 n +0000029782 00000 n +0000029889 00000 n +0000029923 00000 n +0000030029 00000 n +0000030136 00000 n +0000030243 00000 n +0000030350 00000 n +0000030456 00000 n +0000030563 00000 n +0000030670 00000 n +0000030777 00000 n +0000030883 00000 n +0000030990 00000 n +0000031097 00000 n +0000031203 00000 n +0000031309 00000 n +0000031416 00000 n +0000031523 00000 n +0000031630 00000 n +0000031736 00000 n +0000031843 00000 n +0000031950 00000 n +0000032057 00000 n +0000032163 00000 n +0000032270 00000 n +0000032377 00000 n +0000032483 00000 n +0000032589 00000 n +0000032696 00000 n +0000032803 00000 n +0000032910 00000 n +0000033016 00000 n +0000033123 00000 n +0000033230 00000 n +0000033337 00000 n +0000033443 00000 n +0000033550 00000 n +0000033657 00000 n +0000033764 00000 n +0000033878 00000 n +0000033984 00000 n +0000034091 00000 n +0000034198 00000 n +0000034305 00000 n +0000034411 00000 n +0000034518 00000 n +0000034625 00000 n +0000034732 00000 n +0000034838 00000 n +0000034945 00000 n +0000035052 00000 n +0000035158 00000 n +0000035264 00000 n +0000035371 00000 n +0000035478 00000 n +0000035585 00000 n +0000035691 00000 n +0000035798 00000 n +0000035905 00000 n +0000036012 00000 n +0000036118 00000 n +0000036225 00000 n +0000036332 00000 n +0000036438 00000 n +0000036544 00000 n +0000036651 00000 n +0000036758 00000 n +0000036865 00000 n +0000036971 00000 n +0000037078 00000 n +0000037185 00000 n +0000037292 00000 n +0000037398 00000 n +0000037505 00000 n +0000037612 00000 n +0000037718 00000 n +0000037824 00000 n +0000037931 00000 n +0000038038 00000 n +0000038145 00000 n +0000038251 00000 n +0000038358 00000 n +0000038465 00000 n +0000038572 00000 n +0000038678 00000 n +0000038785 00000 n +0000038892 00000 n +0000038998 00000 n +0000039104 00000 n +0000039211 00000 n +0000039318 00000 n +0000039425 00000 n +0000039531 00000 n +0000039638 00000 n +0000039745 00000 n +0000039852 00000 n +0000039958 00000 n +0000040065 00000 n +0000040172 00000 n +0000040278 00000 n +0000040384 00000 n +0000040491 00000 n +0000040598 00000 n +0000040705 00000 n +0000040810 00000 n +0000040916 00000 n +0000041022 00000 n +0000041128 00000 n +0000041232 00000 n +0000041337 00000 n +0000041442 00000 n +0000041548 00000 n +0000041654 00000 n +0000041761 00000 n +0000041868 00000 n +0000041975 00000 n +0000042081 00000 n +0000042188 00000 n +0000042295 00000 n +0000042402 00000 n +0000042508 00000 n +0000042615 00000 n +0000042722 00000 n +0000042828 00000 n +0000042934 00000 n +0000043041 00000 n +0000043148 00000 n +0000043255 00000 n +0000043361 00000 n +0000043468 00000 n +0000043575 00000 n +0000043682 00000 n +0000043788 00000 n +0000043895 00000 n +0000044002 00000 n +0000044108 00000 n +0000044214 00000 n +0000044321 00000 n +0000044428 00000 n +0000044535 00000 n +0000044640 00000 n +0000044746 00000 n +0000044852 00000 n +0000044958 00000 n +0000045062 00000 n +0000045167 00000 n +0000045272 00000 n +0000045378 00000 n +0000045484 00000 n +0000045510 00000 n +0000045616 00000 n +0000045642 00000 n +0000045748 00000 n +0000045774 00000 n +0000045880 00000 n +0000045906 00000 n +0000046012 00000 n +0000046038 00000 n +0000046144 00000 n +0000046170 00000 n +0000046276 00000 n +0000046302 00000 n +0000046408 00000 n +0000046515 00000 n +0000046622 00000 n +0000046664 00000 n +0000046770 00000 n +0000046877 00000 n +0000046984 00000 n +0000047091 00000 n +0000047141 00000 n +0000047247 00000 n +0000047273 00000 n +0000047379 00000 n +0000047405 00000 n +0000047511 00000 n +0000047618 00000 n +0000047652 00000 n +0000047758 00000 n +0000047865 00000 n +0000047899 00000 n +0000048005 00000 n +0000048112 00000 n +0000048146 00000 n +0000048252 00000 n +0000048359 00000 n +0000048466 00000 n +0000048573 00000 n +0000048679 00000 n +0000048737 00000 n +0000048843 00000 n +0000048950 00000 n +0000049057 00000 n +0000049164 00000 n +0000049270 00000 n +0000049328 00000 n +0000049434 00000 n +0000049541 00000 n +0000049648 00000 n +0000049755 00000 n +0000049861 00000 n +0000049919 00000 n +0000050025 00000 n +0000050132 00000 n +0000050239 00000 n +0000050281 00000 n +0000050387 00000 n +0000050494 00000 n +0000050601 00000 n +0000050643 00000 n +0000050749 00000 n +0000050856 00000 n +0000050963 00000 n +0000051005 00000 n +0000051111 00000 n +0000051218 00000 n +0000051325 00000 n +0000051367 00000 n +0000051473 00000 n +0000051580 00000 n +0000051614 00000 n +0000051720 00000 n +0000051827 00000 n +0000051861 00000 n +0000051967 00000 n +0000052074 00000 n +0000052181 00000 n +0000052288 00000 n +0000052395 00000 n +0000052502 00000 n +0000052608 00000 n +0000052715 00000 n +0000052822 00000 n +0000052929 00000 n +0000053036 00000 n +0000053143 00000 n +0000053250 00000 n +0000053357 00000 n +0000053464 00000 n +0000053570 00000 n +0000053677 00000 n +0000053784 00000 n +0000053891 00000 n +0000053998 00000 n +0000054105 00000 n +0000054212 00000 n +0000054319 00000 n +0000054426 00000 n +0000054533 00000 n +0000054640 00000 n +0000054747 00000 n +0000054854 00000 n +0000054961 00000 n +0000055068 00000 n +0000055175 00000 n +0000055282 00000 n +0000055389 00000 n +0000055496 00000 n +0000055603 00000 n +0000055709 00000 n +0000055816 00000 n +0000055923 00000 n +0000056030 00000 n +0000056137 00000 n +0000056244 00000 n +0000056350 00000 n +0000056455 00000 n +0000056560 00000 n +0000056930 00000 n +0000057037 00000 n +0000057143 00000 n +0000057250 00000 n +0000057356 00000 n +0000057462 00000 n +0000057568 00000 n +0000057675 00000 n +0000057782 00000 n +0000057889 00000 n +0000057996 00000 n +0000058102 00000 n +0000058209 00000 n +0000058316 00000 n +0000058422 00000 n +0000058528 00000 n +0000058635 00000 n +0000058742 00000 n +0000058849 00000 n +0000058956 00000 n +0000059063 00000 n +0000059170 00000 n +0000059276 00000 n +0000059383 00000 n +0000059490 00000 n +0000059597 00000 n +0000059704 00000 n +0000059810 00000 n +0000059916 00000 n +0000060023 00000 n +0000060130 00000 n +0000060237 00000 n +0000060344 00000 n +0000060450 00000 n +0000060556 00000 n +0000060662 00000 n +0000060768 00000 n +0000060875 00000 n +0000060982 00000 n +0000061089 00000 n +0000061195 00000 n +0000061301 00000 n +0000061406 00000 n +0000061511 00000 n +0000061873 00000 n +0000061980 00000 n +0000062087 00000 n +0000062194 00000 n +0000062301 00000 n +0000062408 00000 n +0000062515 00000 n +0000062622 00000 n +0000062729 00000 n +0000062836 00000 n +0000062943 00000 n +0000063050 00000 n +0000063157 00000 n +0000063264 00000 n +0000063371 00000 n +0000063478 00000 n +0000063585 00000 n +0000063692 00000 n +0000063799 00000 n +0000063906 00000 n +0000064013 00000 n +0000064120 00000 n +0000064227 00000 n +0000064334 00000 n +0000064441 00000 n +0000064548 00000 n +0000064655 00000 n +0000064762 00000 n +0000064868 00000 n +0000064975 00000 n +0000065082 00000 n +0000065188 00000 n +0000065295 00000 n +0000065402 00000 n +0000065509 00000 n +0000065616 00000 n +0000065723 00000 n +0000065830 00000 n +0000065937 00000 n +0000066044 00000 n +0000066151 00000 n +0000066258 00000 n +0000066365 00000 n +0000066471 00000 n +0000066576 00000 n +0000066681 00000 n +0000067059 00000 n +0000067165 00000 n +0000067272 00000 n +0000067379 00000 n +0000067486 00000 n +0000067593 00000 n +0000067700 00000 n +0000067807 00000 n +0000067913 00000 n +0000068020 00000 n +0000068127 00000 n +0000068234 00000 n +0000068341 00000 n +0000068448 00000 n +0000068555 00000 n +0000068661 00000 n +0000068768 00000 n +0000068875 00000 n +0000068982 00000 n +0000069089 00000 n +0000069196 00000 n +0000069302 00000 n +0000069409 00000 n +0000069516 00000 n +0000069623 00000 n +0000069730 00000 n +0000069837 00000 n +0000069944 00000 n +0000070050 00000 n +0000070157 00000 n +0000070264 00000 n +0000070371 00000 n +0000070478 00000 n +0000070585 00000 n +0000070691 00000 n +0000070798 00000 n +0000070905 00000 n +0000071012 00000 n +0000071119 00000 n +0000071226 00000 n +0000071332 00000 n +0000071439 00000 n +0000071546 00000 n +0000071653 00000 n +0000071760 00000 n +0000071866 00000 n +0000071971 00000 n +0000072075 00000 n +0000072469 00000 n +0000072576 00000 n +0000072683 00000 n +0000072790 00000 n +0000072897 00000 n +0000073004 00000 n +0000073111 00000 n +0000073218 00000 n +0000073325 00000 n +0000073432 00000 n +0000073539 00000 n +0000073646 00000 n +0000073753 00000 n +0000073860 00000 n +0000073967 00000 n +0000074074 00000 n +0000074181 00000 n +0000074288 00000 n +0000074395 00000 n +0000074502 00000 n +0000074609 00000 n +0000074716 00000 n +0000074823 00000 n +0000074930 00000 n +0000075037 00000 n +0000075144 00000 n +0000075251 00000 n +0000075358 00000 n +0000075465 00000 n +0000075572 00000 n +0000075679 00000 n +0000075786 00000 n +0000075893 00000 n +0000076000 00000 n +0000076107 00000 n +0000076214 00000 n +0000076321 00000 n +0000076428 00000 n +0000076535 00000 n +0000076642 00000 n +0000076749 00000 n +0000076856 00000 n +0000076963 00000 n +0000077070 00000 n +0000077177 00000 n +0000077283 00000 n +0000077388 00000 n +0000077493 00000 n +0000077887 00000 n +0000077994 00000 n +0000078101 00000 n +0000078208 00000 n +0000078314 00000 n +0000078421 00000 n +0000078528 00000 n +0000078635 00000 n +0000078742 00000 n +0000078849 00000 n +0000078955 00000 n +0000079062 00000 n +0000079169 00000 n +0000079276 00000 n +0000079383 00000 n +0000079490 00000 n +0000079597 00000 n +0000079703 00000 n +0000079810 00000 n +0000079917 00000 n +0000080024 00000 n +0000080131 00000 n +0000080238 00000 n +0000080345 00000 n +0000080451 00000 n +0000080558 00000 n +0000080665 00000 n +0000080772 00000 n +0000080879 00000 n +0000080986 00000 n +0000081093 00000 n +0000081199 00000 n +0000081306 00000 n +0000081413 00000 n +0000081520 00000 n +0000081627 00000 n +0000081734 00000 n +0000081841 00000 n +0000081947 00000 n +0000082054 00000 n +0000082161 00000 n +0000082268 00000 n +0000082375 00000 n +0000082482 00000 n +0000082588 00000 n +0000082694 00000 n +0000082799 00000 n +0000082904 00000 n +0000083298 00000 n +0000083405 00000 n +0000083512 00000 n +0000083619 00000 n +0000083726 00000 n +0000083833 00000 n +0000083940 00000 n +0000084047 00000 n +0000084154 00000 n +0000084261 00000 n +0000084368 00000 n +0000084475 00000 n +0000084582 00000 n +0000084689 00000 n +0000084796 00000 n +0000084903 00000 n +0000085010 00000 n +0000085117 00000 n +0000085224 00000 n +0000085331 00000 n +0000085438 00000 n +0000085545 00000 n +0000085652 00000 n +0000085759 00000 n +0000085866 00000 n +0000085973 00000 n +0000086080 00000 n +0000086187 00000 n +0000086294 00000 n +0000086401 00000 n +0000086508 00000 n +0000086615 00000 n +0000086722 00000 n +0000086829 00000 n +0000086936 00000 n +0000087043 00000 n +0000087150 00000 n +0000087257 00000 n +0000087364 00000 n +0000087471 00000 n +0000087578 00000 n +0000087685 00000 n +0000087792 00000 n +0000087899 00000 n +0000088006 00000 n +0000088112 00000 n +0000088217 00000 n +0000088322 00000 n +0000088716 00000 n +0000088823 00000 n +0000088930 00000 n +0000089036 00000 n +0000089143 00000 n +0000089250 00000 n +0000089357 00000 n +0000089464 00000 n +0000089571 00000 n +0000089677 00000 n +0000089784 00000 n +0000089891 00000 n +0000089998 00000 n +0000090105 00000 n +0000090212 00000 n +0000090319 00000 n +0000090425 00000 n +0000090532 00000 n +0000090639 00000 n +0000090746 00000 n +0000090853 00000 n +0000090960 00000 n +0000091066 00000 n +0000091173 00000 n +0000091280 00000 n +0000091387 00000 n +0000091494 00000 n +0000091601 00000 n +0000091707 00000 n +0000091814 00000 n +0000091921 00000 n +0000092028 00000 n +0000092135 00000 n +0000092242 00000 n +0000092349 00000 n +0000092455 00000 n +0000092562 00000 n +0000092669 00000 n +0000092776 00000 n +0000092883 00000 n +0000092990 00000 n +0000093097 00000 n +0000093203 00000 n +0000093310 00000 n +0000093417 00000 n +0000093523 00000 n +0000093628 00000 n +0000093733 00000 n +0000094127 00000 n +0000094234 00000 n +0000094341 00000 n +0000094448 00000 n +0000094555 00000 n +0000094662 00000 n +0000094769 00000 n +0000094876 00000 n +0000094983 00000 n +0000095090 00000 n +0000095197 00000 n +0000095304 00000 n +0000095411 00000 n +0000095518 00000 n +0000095625 00000 n +0000095732 00000 n +0000095839 00000 n +0000095946 00000 n +0000096053 00000 n +0000096160 00000 n +0000096267 00000 n +0000096374 00000 n +0000096481 00000 n +0000096588 00000 n +0000096695 00000 n +0000096802 00000 n +0000096909 00000 n +0000097016 00000 n +0000097123 00000 n +0000097230 00000 n +0000097337 00000 n +0000097444 00000 n +0000097551 00000 n +0000097658 00000 n +0000097765 00000 n +0000097872 00000 n +0000097979 00000 n +0000098086 00000 n +0000098193 00000 n +0000098300 00000 n +0000098407 00000 n +0000098514 00000 n +0000098621 00000 n +0000098728 00000 n +0000098835 00000 n +0000098941 00000 n +0000099046 00000 n +0000099151 00000 n +0000099545 00000 n +0000099652 00000 n +0000099759 00000 n +0000099865 00000 n +0000099972 00000 n +0000100079 00000 n +0000100186 00000 n +0000100293 00000 n +0000100400 00000 n +0000100507 00000 n +0000100613 00000 n +0000100720 00000 n +0000100827 00000 n +0000100934 00000 n +0000101041 00000 n +0000101148 00000 n +0000101255 00000 n +0000101361 00000 n +0000101468 00000 n +0000101575 00000 n +0000101682 00000 n +0000101789 00000 n +0000101895 00000 n +0000102002 00000 n +0000102109 00000 n +0000102216 00000 n +0000102323 00000 n +0000102430 00000 n +0000102537 00000 n +0000102643 00000 n +0000102751 00000 n +0000102859 00000 n +0000102967 00000 n +0000103075 00000 n +0000103183 00000 n +0000103291 00000 n +0000103398 00000 n +0000103506 00000 n +0000103614 00000 n +0000103722 00000 n +0000103830 00000 n +0000103938 00000 n +0000104046 00000 n +0000104153 00000 n +0000104261 00000 n +0000104368 00000 n +0000104474 00000 n +0000104580 00000 n +0000104993 00000 n +0000105101 00000 n +0000105209 00000 n +0000105317 00000 n +0000105425 00000 n +0000105533 00000 n +0000105641 00000 n +0000105749 00000 n +0000105857 00000 n +0000105965 00000 n +0000106073 00000 n +0000106181 00000 n +0000106289 00000 n +0000106397 00000 n +0000106505 00000 n +0000106613 00000 n +0000106721 00000 n +0000106829 00000 n +0000106937 00000 n +0000107045 00000 n +0000107153 00000 n +0000107261 00000 n +0000107369 00000 n +0000107477 00000 n +0000107585 00000 n +0000107693 00000 n +0000107801 00000 n +0000107909 00000 n +0000108017 00000 n +0000108125 00000 n +0000108233 00000 n +0000108341 00000 n +0000108449 00000 n +0000108557 00000 n +0000108665 00000 n +0000108773 00000 n +0000108881 00000 n +0000108989 00000 n +0000109097 00000 n +0000109205 00000 n +0000109313 00000 n +0000109421 00000 n +0000109529 00000 n +0000109637 00000 n +0000109745 00000 n +0000109852 00000 n +0000109958 00000 n +0000110064 00000 n +0000110506 00000 n +0000110614 00000 n +0000110722 00000 n +0000110829 00000 n +0000110937 00000 n +0000111045 00000 n +0000111153 00000 n +0000111261 00000 n +0000111369 00000 n +0000111477 00000 n +0000111584 00000 n +0000111692 00000 n +0000111800 00000 n +0000111908 00000 n +0000112016 00000 n +0000112124 00000 n +0000112232 00000 n +0000112339 00000 n +0000112447 00000 n +0000112555 00000 n +0000112663 00000 n +0000112771 00000 n +0000112879 00000 n +0000112987 00000 n +0000113094 00000 n +0000113202 00000 n +0000113310 00000 n +0000113418 00000 n +0000113526 00000 n +0000113634 00000 n +0000113742 00000 n +0000113849 00000 n +0000113957 00000 n +0000114065 00000 n +0000114173 00000 n +0000114281 00000 n +0000114389 00000 n +0000114497 00000 n +0000114604 00000 n +0000114712 00000 n +0000114820 00000 n +0000114928 00000 n +0000115036 00000 n +0000115144 00000 n +0000115252 00000 n +0000115358 00000 n +0000115464 00000 n +0000115570 00000 n +0000116012 00000 n +0000116120 00000 n +0000116228 00000 n +0000116336 00000 n +0000116444 00000 n +0000116552 00000 n +0000116660 00000 n +0000116768 00000 n +0000116876 00000 n +0000116984 00000 n +0000117092 00000 n +0000117200 00000 n +0000117308 00000 n +0000117416 00000 n +0000117524 00000 n +0000117632 00000 n +0000117740 00000 n +0000117848 00000 n +0000117956 00000 n +0000118064 00000 n +0000118172 00000 n +0000118280 00000 n +0000118388 00000 n +0000118496 00000 n +0000118604 00000 n +0000118712 00000 n +0000118820 00000 n +0000118928 00000 n +0000119036 00000 n +0000119144 00000 n +0000119252 00000 n +0000119360 00000 n +0000119468 00000 n +0000119576 00000 n +0000119684 00000 n +0000119792 00000 n +0000119900 00000 n +0000120008 00000 n +0000120116 00000 n +0000120224 00000 n +0000120332 00000 n +0000120440 00000 n +0000120548 00000 n +0000120656 00000 n +0000120764 00000 n +0000120871 00000 n +0000120977 00000 n +0000121083 00000 n +0000121525 00000 n +0000121633 00000 n +0000121741 00000 n +0000121849 00000 n +0000121957 00000 n +0000122065 00000 n +0000122172 00000 n +0000122280 00000 n +0000122388 00000 n +0000122496 00000 n +0000122604 00000 n +0000122712 00000 n +0000122820 00000 n +0000122927 00000 n +0000123035 00000 n +0000123143 00000 n +0000123251 00000 n +0000123359 00000 n +0000123467 00000 n +0000123575 00000 n +0000123682 00000 n +0000123790 00000 n +0000123898 00000 n +0000124006 00000 n +0000124114 00000 n +0000124222 00000 n +0000124329 00000 n +0000124437 00000 n +0000124545 00000 n +0000124653 00000 n +0000124761 00000 n +0000124869 00000 n +0000124976 00000 n +0000125084 00000 n +0000125192 00000 n +0000125300 00000 n +0000125408 00000 n +0000125516 00000 n +0000125624 00000 n +0000125731 00000 n +0000125839 00000 n +0000125947 00000 n +0000126055 00000 n +0000126163 00000 n +0000126271 00000 n +0000126378 00000 n +0000126483 00000 n +0000126589 00000 n +0000127031 00000 n +0000127139 00000 n +0000127247 00000 n +0000127355 00000 n +0000127463 00000 n +0000127571 00000 n +0000127679 00000 n +0000127787 00000 n +0000127895 00000 n +0000128003 00000 n +0000128111 00000 n +0000128219 00000 n +0000128327 00000 n +0000128435 00000 n +0000128543 00000 n +0000128651 00000 n +0000128759 00000 n +0000128867 00000 n +0000128975 00000 n +0000129083 00000 n +0000129191 00000 n +0000129299 00000 n +0000129407 00000 n +0000129515 00000 n +0000129623 00000 n +0000129731 00000 n +0000129839 00000 n +0000129947 00000 n +0000130055 00000 n +0000130163 00000 n +0000130271 00000 n +0000130379 00000 n +0000130487 00000 n +0000130595 00000 n +0000130703 00000 n +0000130811 00000 n +0000130919 00000 n +0000131027 00000 n +0000131135 00000 n +0000131243 00000 n +0000131351 00000 n +0000131459 00000 n +0000131567 00000 n +0000131675 00000 n +0000131783 00000 n +0000131890 00000 n +0000131996 00000 n +0000132102 00000 n +0000132544 00000 n +0000132652 00000 n +0000132760 00000 n +0000132868 00000 n +0000132976 00000 n +0000133084 00000 n +0000133192 00000 n +0000133299 00000 n +0000133407 00000 n +0000133515 00000 n +0000133623 00000 n +0000133731 00000 n +0000133839 00000 n +0000133947 00000 n +0000134054 00000 n +0000134162 00000 n +0000134270 00000 n +0000134378 00000 n +0000134486 00000 n +0000134594 00000 n +0000134701 00000 n +0000134809 00000 n +0000134917 00000 n +0000135025 00000 n +0000135133 00000 n +0000135241 00000 n +0000135349 00000 n +0000135456 00000 n +0000135564 00000 n +0000135672 00000 n +0000135780 00000 n +0000135888 00000 n +0000135996 00000 n +0000136104 00000 n +0000136211 00000 n +0000136319 00000 n +0000136427 00000 n +0000136535 00000 n +0000136643 00000 n +0000136751 00000 n +0000136859 00000 n +0000136966 00000 n +0000137074 00000 n +0000137182 00000 n +0000137290 00000 n +0000137397 00000 n +0000137503 00000 n +0000137609 00000 n +0000138051 00000 n +0000138159 00000 n +0000138267 00000 n +0000138375 00000 n +0000138483 00000 n +0000138591 00000 n +0000138699 00000 n +0000138807 00000 n +0000138915 00000 n +0000139023 00000 n +0000139131 00000 n +0000139239 00000 n +0000139347 00000 n +0000139455 00000 n +0000139563 00000 n +0000139671 00000 n +0000139779 00000 n +0000139887 00000 n +0000139995 00000 n +0000140103 00000 n +0000140211 00000 n +0000140319 00000 n +0000140527 00000 n +0000140563 00000 n +0000140599 00000 n +0000153858 00000 n +0000153909 00000 n +0000153960 00000 n +0000154011 00000 n +0000154062 00000 n +0000154113 00000 n +0000154164 00000 n +0000154215 00000 n +0000154266 00000 n +0000154317 00000 n +0000154368 00000 n +0000154419 00000 n +0000154470 00000 n +0000154521 00000 n +0000154572 00000 n +0000154623 00000 n +0000154674 00000 n +0000154725 00000 n +0000154776 00000 n +0000154827 00000 n +0000154878 00000 n +0000154929 00000 n +0000154980 00000 n +0000155031 00000 n +0000155082 00000 n +0000155133 00000 n +0000155184 00000 n +0000155235 00000 n +0000155286 00000 n +0000155337 00000 n +0000155388 00000 n +0000155439 00000 n +0000155490 00000 n +0000155541 00000 n +0000155592 00000 n +0000155643 00000 n +0000155694 00000 n +0000155745 00000 n +0000155796 00000 n +0000155847 00000 n +0000155898 00000 n +0000155949 00000 n +0000156000 00000 n +0000156051 00000 n +0000156102 00000 n +0000156153 00000 n +0000156204 00000 n +0000156255 00000 n +0000156306 00000 n +0000156357 00000 n +0000156408 00000 n +0000156459 00000 n +0000156510 00000 n +0000156561 00000 n +0000156612 00000 n +0000156663 00000 n +0000156714 00000 n +0000156765 00000 n +0000156816 00000 n +0000156867 00000 n +0000156918 00000 n +0000156969 00000 n +0000157020 00000 n +0000157071 00000 n +0000157122 00000 n +0000157173 00000 n +0000157224 00000 n +0000157275 00000 n +0000157326 00000 n +0000157377 00000 n +0000157428 00000 n +0000157479 00000 n +0000157530 00000 n +0000157581 00000 n +0000157632 00000 n +0000157683 00000 n +0000157734 00000 n +0000157785 00000 n +0000157836 00000 n +0000157887 00000 n +0000157938 00000 n +0000157989 00000 n +0000158040 00000 n +0000158091 00000 n +0000158142 00000 n +0000158193 00000 n +0000158244 00000 n +0000158295 00000 n +0000158346 00000 n +0000158397 00000 n +0000158448 00000 n +0000158499 00000 n +0000158550 00000 n +0000158601 00000 n +0000158652 00000 n +0000158703 00000 n +0000158754 00000 n +0000158805 00000 n +0000158856 00000 n +0000158907 00000 n +0000158958 00000 n +0000159009 00000 n +0000159060 00000 n +0000159111 00000 n +0000159162 00000 n +0000159213 00000 n +0000159264 00000 n +0000159315 00000 n +0000159366 00000 n +0000159417 00000 n +0000159468 00000 n +0000159519 00000 n +0000159570 00000 n +0000159621 00000 n +0000159672 00000 n +0000159723 00000 n +0000159774 00000 n +0000159825 00000 n +0000159876 00000 n +0000159927 00000 n +0000159978 00000 n +0000160029 00000 n +0000160080 00000 n +0000160131 00000 n +0000160182 00000 n +0000160233 00000 n +0000160284 00000 n +0000160335 00000 n +0000160386 00000 n +0000160437 00000 n +0000160488 00000 n +0000160539 00000 n +0000160590 00000 n +0000160641 00000 n +0000160692 00000 n +0000160743 00000 n +0000160794 00000 n +0000160845 00000 n +0000160896 00000 n +0000160947 00000 n +0000160998 00000 n +0000161049 00000 n +0000161100 00000 n +0000161151 00000 n +0000161202 00000 n +0000161253 00000 n +0000161304 00000 n +0000161355 00000 n +0000161406 00000 n +0000161457 00000 n +0000161508 00000 n +0000161559 00000 n +0000161610 00000 n +0000161661 00000 n +0000161712 00000 n +0000161763 00000 n +0000161814 00000 n +0000161865 00000 n +0000161916 00000 n +0000161967 00000 n +0000162018 00000 n +0000162069 00000 n +0000162120 00000 n +0000162171 00000 n +0000162222 00000 n +0000162273 00000 n +0000162324 00000 n +0000162375 00000 n +0000162426 00000 n +0000162477 00000 n +0000162528 00000 n +0000162579 00000 n +0000162630 00000 n +0000162681 00000 n +0000162732 00000 n +0000162783 00000 n +0000162834 00000 n +0000162885 00000 n +0000162936 00000 n +0000162987 00000 n +0000163038 00000 n +0000163089 00000 n +0000163140 00000 n +0000163191 00000 n +0000163242 00000 n +0000163293 00000 n +0000163344 00000 n +0000163395 00000 n +0000163446 00000 n +0000163497 00000 n +0000163548 00000 n +0000163599 00000 n +0000163650 00000 n +0000163701 00000 n +0000163752 00000 n +0000163803 00000 n +0000163854 00000 n +0000163905 00000 n +0000163956 00000 n +0000164007 00000 n +0000164058 00000 n +0000164109 00000 n +0000164160 00000 n +0000164211 00000 n +0000164262 00000 n +0000164313 00000 n +0000164364 00000 n +0000164415 00000 n +0000164466 00000 n +0000164517 00000 n +0000164568 00000 n +0000164619 00000 n +0000164670 00000 n +0000164721 00000 n +0000164772 00000 n +0000164823 00000 n +0000164874 00000 n +0000164925 00000 n +0000164976 00000 n +0000165027 00000 n +0000165078 00000 n +0000165129 00000 n +0000165180 00000 n +0000165231 00000 n +0000165282 00000 n +0000165333 00000 n +0000165384 00000 n +0000165435 00000 n +0000165486 00000 n +0000165537 00000 n +0000165588 00000 n +0000165639 00000 n +0000165690 00000 n +0000165741 00000 n +0000165792 00000 n +0000165843 00000 n +0000165894 00000 n +0000165945 00000 n +0000165996 00000 n +0000166047 00000 n +0000166098 00000 n +0000166149 00000 n +0000166200 00000 n +0000166251 00000 n +0000166302 00000 n +0000166353 00000 n +0000166404 00000 n +0000166455 00000 n +0000166506 00000 n +0000166557 00000 n +0000166608 00000 n +0000166659 00000 n +0000166710 00000 n +0000166761 00000 n +0000166812 00000 n +0000166863 00000 n +0000166914 00000 n +0000166965 00000 n +0000167016 00000 n +0000167067 00000 n +0000167118 00000 n +0000167169 00000 n +0000167220 00000 n +0000167271 00000 n +0000167322 00000 n +0000167373 00000 n +0000167424 00000 n +0000167475 00000 n +0000167526 00000 n +0000167577 00000 n +0000167628 00000 n +0000167679 00000 n +0000167730 00000 n +0000167781 00000 n +0000167832 00000 n +0000167883 00000 n +0000167934 00000 n +0000167985 00000 n +0000168036 00000 n +0000168087 00000 n +0000168138 00000 n +0000168189 00000 n +0000168240 00000 n +0000168291 00000 n +0000168342 00000 n +0000168393 00000 n +0000168444 00000 n +0000168495 00000 n +0000168546 00000 n +0000168597 00000 n +0000168648 00000 n +0000168699 00000 n +0000168750 00000 n +0000168801 00000 n +0000168852 00000 n +0000168903 00000 n +0000168954 00000 n +0000169005 00000 n +0000169056 00000 n +0000169107 00000 n +0000169158 00000 n +0000169209 00000 n +0000169260 00000 n +0000169311 00000 n +0000169362 00000 n +0000169413 00000 n +0000169464 00000 n +0000169515 00000 n +0000169566 00000 n +0000169617 00000 n +0000169668 00000 n +0000169719 00000 n +0000169770 00000 n +0000169821 00000 n +0000169872 00000 n +0000169923 00000 n +0000169974 00000 n +0000170025 00000 n +0000170076 00000 n +0000170127 00000 n +0000170178 00000 n +0000170229 00000 n +0000170280 00000 n +0000170331 00000 n +0000170382 00000 n +0000170433 00000 n +0000170484 00000 n +0000170535 00000 n +0000170586 00000 n +0000170637 00000 n +0000170688 00000 n +0000170739 00000 n +0000170790 00000 n +0000170841 00000 n +0000170892 00000 n +0000170943 00000 n +0000170994 00000 n +0000171045 00000 n +0000171096 00000 n +0000171147 00000 n +0000171198 00000 n +0000171249 00000 n +0000171300 00000 n +0000171351 00000 n +0000171402 00000 n +0000171453 00000 n +0000171504 00000 n +0000171555 00000 n +0000171606 00000 n +0000171657 00000 n +0000171708 00000 n +0000171759 00000 n +0000171810 00000 n +0000171861 00000 n +0000171912 00000 n +0000171963 00000 n +0000172014 00000 n +0000172065 00000 n +0000172116 00000 n +0000172167 00000 n +0000172218 00000 n +0000172269 00000 n +0000172320 00000 n +0000172371 00000 n +0000172422 00000 n +0000172473 00000 n +0000172524 00000 n +0000172575 00000 n +0000172626 00000 n +0000172677 00000 n +0000172728 00000 n +0000172779 00000 n +0000172830 00000 n +0000172881 00000 n +0000172932 00000 n +0000172983 00000 n +0000173034 00000 n +0000173085 00000 n +0000173136 00000 n +0000173187 00000 n +0000173238 00000 n +0000173289 00000 n +0000173340 00000 n +0000173391 00000 n +0000173442 00000 n +0000173493 00000 n +0000173544 00000 n +0000173595 00000 n +0000173646 00000 n +0000173697 00000 n +0000173748 00000 n +0000173799 00000 n +0000173850 00000 n +0000173901 00000 n +0000173952 00000 n +0000174003 00000 n +0000174054 00000 n +0000174105 00000 n +0000174156 00000 n +0000174207 00000 n +0000174258 00000 n +0000174309 00000 n +0000174360 00000 n +0000174411 00000 n +0000174462 00000 n +0000174513 00000 n +0000174564 00000 n +0000174615 00000 n +0000174666 00000 n +0000174717 00000 n +0000174768 00000 n +0000174819 00000 n +0000174870 00000 n +0000174921 00000 n +0000174972 00000 n +0000175023 00000 n +0000175074 00000 n +0000175125 00000 n +0000175176 00000 n +0000175227 00000 n +0000175278 00000 n +0000175329 00000 n +0000175380 00000 n +0000175431 00000 n +0000175482 00000 n +0000175533 00000 n +0000175584 00000 n +0000175635 00000 n +0000175686 00000 n +0000175737 00000 n +0000175788 00000 n +0000175839 00000 n +0000175890 00000 n +0000175941 00000 n +0000175992 00000 n +0000176043 00000 n +0000176094 00000 n +0000176145 00000 n +0000176196 00000 n +0000176247 00000 n +0000176298 00000 n +0000176349 00000 n +0000176400 00000 n +0000176451 00000 n +0000176502 00000 n +0000176553 00000 n +0000176604 00000 n +0000176655 00000 n +0000176706 00000 n +0000176757 00000 n +0000176808 00000 n +0000176859 00000 n +0000176910 00000 n +0000176961 00000 n +0000177012 00000 n +0000177063 00000 n +0000177114 00000 n +0000177165 00000 n +0000177216 00000 n +0000177267 00000 n +0000177318 00000 n +0000177369 00000 n +0000177420 00000 n +0000177471 00000 n +0000177522 00000 n +0000177573 00000 n +0000177624 00000 n +0000177675 00000 n +0000177726 00000 n +0000177777 00000 n +0000177828 00000 n +0000177879 00000 n +0000177930 00000 n +0000177981 00000 n +0000178032 00000 n +0000178083 00000 n +0000178134 00000 n +0000178185 00000 n +0000178236 00000 n +0000178287 00000 n +0000178338 00000 n +0000178389 00000 n +0000178440 00000 n +0000178491 00000 n +0000178542 00000 n +0000178593 00000 n +0000178644 00000 n +0000178695 00000 n +0000178746 00000 n +0000178797 00000 n +0000178848 00000 n +0000178899 00000 n +0000178950 00000 n +0000179001 00000 n +0000179052 00000 n +0000179103 00000 n +0000179154 00000 n +0000179205 00000 n +0000179256 00000 n +0000179307 00000 n +0000179358 00000 n +0000179409 00000 n +0000179460 00000 n +0000179511 00000 n +0000179562 00000 n +0000179613 00000 n +0000179664 00000 n +0000179715 00000 n +0000179766 00000 n +0000179817 00000 n +0000179868 00000 n +0000179919 00000 n +0000179970 00000 n +0000180021 00000 n +0000180072 00000 n +0000180123 00000 n +0000180174 00000 n +0000180225 00000 n +0000180276 00000 n +0000180327 00000 n +0000180378 00000 n +0000180429 00000 n +0000180480 00000 n +0000180531 00000 n +0000180582 00000 n +0000180633 00000 n +0000180684 00000 n +0000180735 00000 n +0000180786 00000 n +0000180837 00000 n +0000180888 00000 n +0000180939 00000 n +0000180990 00000 n +0000181041 00000 n +0000181092 00000 n +0000181143 00000 n +0000181194 00000 n +0000181245 00000 n +0000181296 00000 n +0000181347 00000 n +0000181398 00000 n +0000181449 00000 n +0000181500 00000 n +0000181551 00000 n +0000181602 00000 n +0000181653 00000 n +0000181704 00000 n +0000181755 00000 n +0000181806 00000 n +0000181857 00000 n +0000181908 00000 n +0000181959 00000 n +0000182010 00000 n +0000182061 00000 n +0000182112 00000 n +0000182163 00000 n +0000182214 00000 n +0000182265 00000 n +0000182316 00000 n +0000182367 00000 n +0000182418 00000 n +0000182469 00000 n +0000182520 00000 n +0000182571 00000 n +0000182622 00000 n +0000182673 00000 n +0000182724 00000 n +0000182775 00000 n +0000182826 00000 n +0000182877 00000 n +0000182928 00000 n +0000182979 00000 n +0000183030 00000 n +0000183081 00000 n +0000183132 00000 n +0000183183 00000 n +0000183234 00000 n +0000183285 00000 n +0000183336 00000 n +0000183387 00000 n +0000183438 00000 n +0000183489 00000 n +0000183540 00000 n +0000183591 00000 n +0000183642 00000 n +0000183693 00000 n +0000183744 00000 n +0000183795 00000 n +0000183846 00000 n +0000183897 00000 n +0000183948 00000 n +0000183999 00000 n +0000184050 00000 n +0000184101 00000 n +0000184152 00000 n +0000184203 00000 n +0000184254 00000 n +0000184305 00000 n +0000184356 00000 n +0000184407 00000 n +0000184458 00000 n +0000184509 00000 n +0000184560 00000 n +0000184611 00000 n +0000184662 00000 n +0000184713 00000 n +0000184764 00000 n +0000184815 00000 n +0000184866 00000 n +0000184917 00000 n +0000184968 00000 n +0000185019 00000 n +0000185070 00000 n +0000185121 00000 n +0000185172 00000 n +0000185223 00000 n +0000185274 00000 n +0000185325 00000 n +0000185376 00000 n +0000185427 00000 n +0000185478 00000 n +0000185529 00000 n +0000185580 00000 n +0000185631 00000 n +0000185682 00000 n +0000185733 00000 n +0000185784 00000 n +0000185835 00000 n +0000185886 00000 n +0000185937 00000 n +0000185988 00000 n +0000186039 00000 n +0000186090 00000 n +0000186141 00000 n +0000186192 00000 n +0000186243 00000 n +0000186294 00000 n +0000186345 00000 n +0000186396 00000 n +0000186447 00000 n +0000186498 00000 n +0000186549 00000 n +0000186600 00000 n +0000186651 00000 n +0000186702 00000 n +0000186753 00000 n +0000186804 00000 n +0000186855 00000 n +0000186906 00000 n +0000186957 00000 n +0000187008 00000 n +0000187059 00000 n +0000187110 00000 n +0000187161 00000 n +0000187212 00000 n +0000187263 00000 n +0000187314 00000 n +0000187365 00000 n +0000187416 00000 n +0000187467 00000 n +0000187518 00000 n +0000187569 00000 n +0000187620 00000 n +0000187671 00000 n +0000187722 00000 n +0000187773 00000 n +0000187824 00000 n +0000187875 00000 n +0000187926 00000 n +0000187977 00000 n +0000188028 00000 n +0000188079 00000 n +0000188130 00000 n +0000188181 00000 n +0000188232 00000 n +0000188283 00000 n +0000188334 00000 n +0000188385 00000 n +0000188436 00000 n +0000188487 00000 n +0000188538 00000 n +0000188589 00000 n +0000188640 00000 n +0000188691 00000 n +0000188742 00000 n +0000188793 00000 n +0000188844 00000 n +0000188895 00000 n +0000188946 00000 n +0000188997 00000 n +0000189048 00000 n +0000189099 00000 n +0000189150 00000 n +0000189201 00000 n +0000189252 00000 n +0000189303 00000 n +0000189354 00000 n +0000189405 00000 n +0000189456 00000 n +0000189507 00000 n +0000189558 00000 n +0000189609 00000 n +0000189660 00000 n +0000189711 00000 n +0000189762 00000 n +0000189813 00000 n +0000189864 00000 n +0000189915 00000 n +0000189966 00000 n +0000190017 00000 n +0000190068 00000 n +0000190119 00000 n +0000190170 00000 n +0000190221 00000 n +0000190272 00000 n +0000190323 00000 n +0000190374 00000 n +0000190425 00000 n +0000190476 00000 n +0000190527 00000 n +0000190578 00000 n +0000190629 00000 n +0000190680 00000 n +0000190731 00000 n +0000190782 00000 n +0000190833 00000 n +0000190884 00000 n +0000190935 00000 n +0000190986 00000 n +0000191037 00000 n +0000191088 00000 n +0000191139 00000 n +0000191190 00000 n +0000191241 00000 n +0000191292 00000 n +0000191343 00000 n +0000191394 00000 n +0000191445 00000 n +0000191496 00000 n +0000191547 00000 n +0000191598 00000 n +0000191649 00000 n +0000191700 00000 n +0000191751 00000 n +0000191802 00000 n +0000191853 00000 n +0000191904 00000 n +0000191955 00000 n +0000192006 00000 n +0000192057 00000 n +0000192108 00000 n +0000192159 00000 n +0000192210 00000 n +0000192261 00000 n +0000192312 00000 n +0000192363 00000 n +0000192414 00000 n +0000192465 00000 n +0000192516 00000 n +0000192567 00000 n +0000192618 00000 n +0000192669 00000 n +0000192720 00000 n +0000192771 00000 n +0000192822 00000 n +0000192873 00000 n +0000194600 00000 n +0000194757 00000 n +0000201109 00000 n +0000201132 00000 n +0000201230 00000 n +0000201334 00000 n +0000201355 00000 n +0000201505 00000 n +0000202383 00000 n +0000202405 00000 n +0000202602 00000 n +0000203852 00000 n +0000203875 00000 n +0000204020 00000 n +0000204434 00000 n +0000204456 00000 n +0000204573 00000 n +0000204768 00000 n +0000204790 00000 n +0000204935 00000 n +0000205844 00000 n +0000205866 00000 n +0000206011 00000 n +0000207536 00000 n +0000207559 00000 n +0000207704 00000 n +0000208700 00000 n +0000208722 00000 n +0000208839 00000 n +0000209035 00000 n +0000209057 00000 n +0000209211 00000 n +0000209954 00000 n +0000209976 00000 n +0000210140 00000 n +0000211091 00000 n +0000211113 00000 n +0000211267 00000 n +0000212254 00000 n +0000212276 00000 n +0000212430 00000 n +0000213468 00000 n +0000213490 00000 n +0000213644 00000 n +0000214584 00000 n +0000214606 00000 n +0000214760 00000 n +0000215698 00000 n +0000215720 00000 n +0000215883 00000 n +0000217280 00000 n +0000217303 00000 n +0000217448 00000 n +0000218866 00000 n +0000218889 00000 n +0000219043 00000 n +0000220213 00000 n +0000220236 00000 n +0000220390 00000 n +0000221156 00000 n +0000221178 00000 n +0000221313 00000 n +0000221610 00000 n +0000221632 00000 n +0000221749 00000 n +0000221952 00000 n +0000221974 00000 n +0000222133 00000 n +0000222870 00000 n +0000222892 00000 n +0000223075 00000 n +0000224398 00000 n +0000224421 00000 n +0000224585 00000 n +0000225924 00000 n +0000225947 00000 n +0000226115 00000 n +0000227230 00000 n +0000227253 00000 n +0000227388 00000 n +0000227771 00000 n +0000227793 00000 n +0000227910 00000 n +0000228109 00000 n +0000228131 00000 n +0000228290 00000 n +0000229097 00000 n +0000229119 00000 n +0000229283 00000 n +0000230833 00000 n +0000230856 00000 n +0000231021 00000 n +0000232420 00000 n +0000232443 00000 n +0000232620 00000 n +0000233824 00000 n +0000233847 00000 n +0000233982 00000 n +0000234677 00000 n +0000234699 00000 n +0000234816 00000 n +0000235016 00000 n +0000235038 00000 n +0000235174 00000 n +0000235965 00000 n +0000235987 00000 n +0000236170 00000 n +0000237674 00000 n +0000237697 00000 n +0000237851 00000 n +0000239151 00000 n +0000239174 00000 n +0000239319 00000 n +0000239794 00000 n +0000239816 00000 n +0000239966 00000 n +0000240811 00000 n +0000240833 00000 n +0000241002 00000 n +0000242455 00000 n +0000242478 00000 n +0000242637 00000 n +0000243024 00000 n +0000243046 00000 n +0000243191 00000 n +0000244706 00000 n +0000244729 00000 n +0000244865 00000 n +0000246757 00000 n +0000246780 00000 n +0000246906 00000 n +0000248720 00000 n +0000248743 00000 n +0000248879 00000 n +0000250828 00000 n +0000250851 00000 n +0000250987 00000 n +0000251731 00000 n +0000251753 00000 n +0000251898 00000 n +0000253606 00000 n +0000253629 00000 n +0000253774 00000 n +0000255730 00000 n +0000255753 00000 n +0000255888 00000 n +0000257640 00000 n +0000257663 00000 n +0000257798 00000 n +0000259575 00000 n +0000259598 00000 n +0000259733 00000 n +0000261572 00000 n +0000261595 00000 n +0000261730 00000 n +0000263702 00000 n +0000263725 00000 n +0000263870 00000 n +0000264602 00000 n +0000264624 00000 n +0000264741 00000 n +0000264955 00000 n +0000264977 00000 n +0000265132 00000 n +0000265778 00000 n +0000265800 00000 n +0000265955 00000 n +0000266840 00000 n +0000266862 00000 n +0000267017 00000 n +0000268347 00000 n +0000268370 00000 n +0000268525 00000 n +0000269553 00000 n +0000269575 00000 n +0000269730 00000 n +0000270593 00000 n +0000270615 00000 n +0000270770 00000 n +0000271672 00000 n +0000271694 00000 n +0000271849 00000 n +0000273172 00000 n +0000273195 00000 n +0000273364 00000 n +0000274390 00000 n +0000274412 00000 n +0000274567 00000 n +0000275281 00000 n +0000275303 00000 n +0000275458 00000 n +0000276140 00000 n +0000276162 00000 n +0000276307 00000 n +0000277090 00000 n +0000277112 00000 n +0000277238 00000 n +0000278873 00000 n +0000278896 00000 n +0000279046 00000 n +0000279342 00000 n +0000279364 00000 n +0000279532 00000 n +0000280412 00000 n +0000280434 00000 n +0000280602 00000 n +0000281283 00000 n +0000281305 00000 n +0000281473 00000 n +0000282621 00000 n +0000282644 00000 n +0000282803 00000 n +0000283540 00000 n +0000283562 00000 n +0000283731 00000 n +0000284889 00000 n +0000284912 00000 n +0000285072 00000 n +0000285652 00000 n +0000285674 00000 n +0000285843 00000 n +0000286535 00000 n +0000286557 00000 n +0000286726 00000 n +0000287462 00000 n +0000287484 00000 n +0000287644 00000 n +0000288198 00000 n +0000288220 00000 n +0000288389 00000 n +0000289200 00000 n +0000289222 00000 n +0000289391 00000 n +0000290073 00000 n +0000290095 00000 n +0000290249 00000 n +0000290972 00000 n +0000290994 00000 n +0000291163 00000 n +0000291897 00000 n +0000291919 00000 n +0000292079 00000 n +0000292802 00000 n +0000292824 00000 n +0000292993 00000 n +0000293731 00000 n +0000293753 00000 n +0000293913 00000 n +0000294438 00000 n +0000294460 00000 n +0000294629 00000 n +0000295264 00000 n +0000295286 00000 n +0000295455 00000 n +0000296204 00000 n +0000296226 00000 n +0000296395 00000 n +0000297187 00000 n +0000297209 00000 n +0000297369 00000 n +0000297922 00000 n +0000297944 00000 n +0000298113 00000 n +0000298899 00000 n +0000298921 00000 n +0000299090 00000 n +0000299951 00000 n +0000299973 00000 n +0000300142 00000 n +0000301030 00000 n +0000301052 00000 n +0000301206 00000 n +0000302037 00000 n +0000302059 00000 n +0000302210 00000 n +0000302539 00000 n +0000302561 00000 n +0000302730 00000 n +0000303371 00000 n +0000303393 00000 n +0000303562 00000 n +0000304344 00000 n +0000304366 00000 n +0000304535 00000 n +0000305410 00000 n +0000305432 00000 n +0000305601 00000 n +0000306514 00000 n +0000306536 00000 n +0000306705 00000 n +0000307553 00000 n +0000307575 00000 n +0000307744 00000 n +0000308609 00000 n +0000308631 00000 n +0000308801 00000 n +0000309475 00000 n +0000309497 00000 n +0000309661 00000 n +0000310315 00000 n +0000310337 00000 n +0000310497 00000 n +0000311051 00000 n +0000311073 00000 n +0000311242 00000 n +0000311956 00000 n +0000311978 00000 n +0000312147 00000 n +0000312826 00000 n +0000312848 00000 n +0000313017 00000 n +0000313608 00000 n +0000313630 00000 n +0000313799 00000 n +0000314308 00000 n +0000314330 00000 n +0000314499 00000 n +0000315284 00000 n +0000315306 00000 n +0000315475 00000 n +0000316083 00000 n +0000316105 00000 n +0000316274 00000 n +0000316957 00000 n +0000316979 00000 n +0000317148 00000 n +0000317755 00000 n +0000317777 00000 n +0000317946 00000 n +0000318541 00000 n +0000318563 00000 n +0000318732 00000 n +0000319279 00000 n +0000319301 00000 n +0000319470 00000 n +0000320147 00000 n +0000320169 00000 n +0000320338 00000 n +0000321128 00000 n +0000321150 00000 n +0000321319 00000 n +0000321954 00000 n +0000321976 00000 n +0000322145 00000 n +0000322739 00000 n +0000322761 00000 n +0000322930 00000 n +0000323646 00000 n +0000323668 00000 n +0000323837 00000 n +0000324513 00000 n +0000324535 00000 n +0000324695 00000 n +0000325161 00000 n +0000325183 00000 n +0000325352 00000 n +0000326040 00000 n +0000326062 00000 n +0000326231 00000 n +0000326910 00000 n +0000326932 00000 n +0000327101 00000 n +0000327762 00000 n +0000327784 00000 n +0000327953 00000 n +0000328635 00000 n +0000328657 00000 n +0000328826 00000 n +0000329652 00000 n +0000329674 00000 n +0000329843 00000 n +0000330456 00000 n +0000330478 00000 n +0000330647 00000 n +0000331575 00000 n +0000331597 00000 n +0000331766 00000 n +0000332500 00000 n +0000332522 00000 n +0000332691 00000 n +0000333368 00000 n +0000333390 00000 n +0000333559 00000 n +0000334558 00000 n +0000334580 00000 n +0000334749 00000 n +0000335608 00000 n +0000335630 00000 n +0000335799 00000 n +0000336784 00000 n +0000336806 00000 n +0000336975 00000 n +0000338048 00000 n +0000338071 00000 n +0000338240 00000 n +0000339269 00000 n +0000339291 00000 n +0000339460 00000 n +0000340496 00000 n +0000340518 00000 n +0000340687 00000 n +0000341824 00000 n +0000341847 00000 n +0000342016 00000 n +0000343033 00000 n +0000343055 00000 n +0000343224 00000 n +0000344348 00000 n +0000344371 00000 n +0000344540 00000 n +0000345605 00000 n +0000345627 00000 n +0000345796 00000 n +0000346980 00000 n +0000347003 00000 n +0000347172 00000 n +0000348001 00000 n +0000348023 00000 n +0000348192 00000 n +0000349353 00000 n +0000349376 00000 n +0000349545 00000 n +0000350816 00000 n +0000350839 00000 n +0000351008 00000 n +0000351595 00000 n +0000351617 00000 n +0000351786 00000 n +0000352319 00000 n +0000352341 00000 n +0000352477 00000 n +0000352834 00000 n +0000352856 00000 n +0000352992 00000 n +0000353341 00000 n +0000353363 00000 n +0000353523 00000 n +0000353959 00000 n +0000353981 00000 n +0000354141 00000 n +0000354617 00000 n +0000354639 00000 n +0000354808 00000 n +0000355589 00000 n +0000355611 00000 n +0000355780 00000 n +0000356363 00000 n +0000356385 00000 n +0000356554 00000 n +0000357341 00000 n +0000357363 00000 n +0000357532 00000 n +0000358112 00000 n +0000358134 00000 n +0000358303 00000 n +0000358980 00000 n +0000359002 00000 n +0000359171 00000 n +0000359825 00000 n +0000359847 00000 n +0000360016 00000 n +0000360666 00000 n +0000360688 00000 n +0000360857 00000 n +0000361569 00000 n +0000361591 00000 n +0000361760 00000 n +0000362465 00000 n +0000362487 00000 n +0000362656 00000 n +0000363337 00000 n +0000363359 00000 n +0000363528 00000 n +0000364349 00000 n +0000364371 00000 n +0000364540 00000 n +0000365181 00000 n +0000365203 00000 n +0000365372 00000 n +0000366130 00000 n +0000366152 00000 n +0000366321 00000 n +0000367013 00000 n +0000367035 00000 n +0000367204 00000 n +0000367909 00000 n +0000367931 00000 n +0000368100 00000 n +0000368761 00000 n +0000368783 00000 n +0000368952 00000 n +0000369643 00000 n +0000369665 00000 n +0000369834 00000 n +0000370621 00000 n +0000370643 00000 n +0000370812 00000 n +0000371488 00000 n +0000371510 00000 n +0000371670 00000 n +0000374268 00000 n +0000374291 00000 n +0000374451 00000 n +0000377002 00000 n +0000377025 00000 n +0000377185 00000 n +0000379216 00000 n +0000379239 00000 n +0000379390 00000 n +0000380683 00000 n +0000380706 00000 n +0000380857 00000 n +0000382102 00000 n +0000382125 00000 n +0000382276 00000 n +0000383550 00000 n +0000383573 00000 n +0000383724 00000 n +0000384988 00000 n +0000385011 00000 n +0000385162 00000 n +0000386449 00000 n +0000386472 00000 n +0000386623 00000 n +0000387894 00000 n +0000387917 00000 n +0000388069 00000 n +0000389359 00000 n +0000389382 00000 n +0000389534 00000 n +0000390802 00000 n +0000390825 00000 n +0000390977 00000 n +0000392251 00000 n +0000392274 00000 n +0000392426 00000 n +0000393724 00000 n +0000393747 00000 n +0000393899 00000 n +0000395184 00000 n +0000395207 00000 n +0000395359 00000 n +0000396646 00000 n +0000396669 00000 n +0000396821 00000 n +0000398075 00000 n +0000398098 00000 n +0000398250 00000 n +0000399037 00000 n +0000399059 00000 n +0000399176 00000 n +0000399353 00000 n +0000399375 00000 n +0000399434 00000 n +0000399543 00000 n +0000399694 00000 n +0000399801 00000 n +0000399924 00000 n +0000400050 00000 n +0000400169 00000 n +0000400277 00000 n +0000400449 00000 n +0000400561 00000 n +0000400681 00000 n +0000400791 00000 n +0000400904 00000 n +0000401017 00000 n +0000401131 00000 n +0000401252 00000 n +0000401354 00000 n +0000401514 00000 n +0000401664 00000 n +0000401788 00000 n +0000401949 00000 n +0000402054 00000 n +0000402175 00000 n +0000402304 00000 n +0000402425 00000 n +0000402573 00000 n +0000402700 00000 n +0000402829 00000 n +0000402935 00000 n +0000403077 00000 n +0000403182 00000 n +0000403320 00000 n +0000403444 00000 n +0000403578 00000 n +0000403706 00000 n +0000403827 00000 n +0000403941 00000 n +0000404104 00000 n +0000404242 00000 n +0000404357 00000 n +0000404479 00000 n +0000404600 00000 n +0000404734 00000 n +0000404855 00000 n +0000404983 00000 n +0000405104 00000 n +0000405217 00000 n +0000405390 00000 n +0000405491 00000 n +0000405600 00000 n +0000405771 00000 n +0000405909 00000 n +0000406017 00000 n +0000406138 00000 n +0000406260 00000 n +0000406379 00000 n +0000406537 00000 n +0000406638 00000 n +0000406749 00000 n +0000406913 00000 n +0000407051 00000 n +0000407166 00000 n +0000407294 00000 n +0000407415 00000 n +0000407536 00000 n +0000407658 00000 n +0000407757 00000 n +0000407921 00000 n +0000408040 00000 n +0000408169 00000 n +0000408299 00000 n +0000408403 00000 n +0000408577 00000 n +0000408752 00000 n +0000408856 00000 n +0000408972 00000 n +0000409104 00000 n +0000409203 00000 n +0000409335 00000 n +0000409461 00000 n +0000409618 00000 n +0000409762 00000 n +0000409868 00000 n +0000409994 00000 n +0000410095 00000 n +0000410253 00000 n +0000410351 00000 n +0000410469 00000 n +0000410567 00000 n +0000410725 00000 n +0000410823 00000 n +0000410933 00000 n +0000411055 00000 n +0000411171 00000 n +0000411289 00000 n +0000411404 00000 n +0000411520 00000 n +0000411640 00000 n +0000411756 00000 n +0000411860 00000 n +0000412017 00000 n +0000412127 00000 n +0000412257 00000 n +0000412375 00000 n +0000412482 00000 n +0000412629 00000 n +0000412738 00000 n +0000412863 00000 n +0000412993 00000 n +0000413116 00000 n +0000413247 00000 n +0000413375 00000 n +0000413507 00000 n +0000413638 00000 n +0000413769 00000 n +0000413885 00000 n +0000414043 00000 n +0000414176 00000 n +0000414272 00000 n +0000414416 00000 n +0000414563 00000 n +0000414660 00000 n +0000414775 00000 n +0000414888 00000 n +0000415005 00000 n +0000415118 00000 n +0000415218 00000 n +0000415379 00000 n +0000415476 00000 n +0000415591 00000 n +0000415704 00000 n +0000415821 00000 n +0000415934 00000 n +0000416034 00000 n +0000416199 00000 n +0000416296 00000 n +0000416411 00000 n +0000416524 00000 n +0000416641 00000 n +0000416754 00000 n +0000416854 00000 n +0000417015 00000 n +0000417112 00000 n +0000417227 00000 n +0000417340 00000 n +0000417457 00000 n +0000417570 00000 n +0000417670 00000 n +0000417833 00000 n +0000417930 00000 n +0000418045 00000 n +0000418162 00000 n +0000418275 00000 n +0000418375 00000 n +0000418537 00000 n +0000418634 00000 n +0000418749 00000 n +0000418862 00000 n +0000418979 00000 n +0000419092 00000 n +0000419192 00000 n +0000419354 00000 n +0000419451 00000 n +0000419564 00000 n +0000419681 00000 n +0000419794 00000 n +0000419894 00000 n +0000420055 00000 n +0000420152 00000 n +0000420267 00000 n +0000420380 00000 n +0000420497 00000 n +0000420597 00000 n +0000420760 00000 n +0000420857 00000 n +0000420972 00000 n +0000421085 00000 n +0000421202 00000 n +0000421315 00000 n +0000421415 00000 n +0000421573 00000 n +0000421670 00000 n +0000421785 00000 n +0000421898 00000 n +0000422015 00000 n +0000422114 00000 n +0000422277 00000 n +0000422374 00000 n +0000422489 00000 n +0000422602 00000 n +0000422719 00000 n +0000422832 00000 n +0000422932 00000 n +0000423095 00000 n +0000423192 00000 n +0000423305 00000 n +0000423422 00000 n +0000423535 00000 n +0000423635 00000 n +0000423799 00000 n +0000423896 00000 n +0000424011 00000 n +0000424124 00000 n +0000424241 00000 n +0000424354 00000 n +0000424454 00000 n +0000424615 00000 n +0000424712 00000 n +0000424829 00000 n +0000424942 00000 n +0000425042 00000 n +0000425202 00000 n +0000425299 00000 n +0000425414 00000 n +0000425531 00000 n +0000425644 00000 n +0000425744 00000 n +0000425903 00000 n +0000426000 00000 n +0000426115 00000 n +0000426228 00000 n +0000426345 00000 n +0000426458 00000 n +0000426558 00000 n +0000426720 00000 n +0000426817 00000 n +0000426932 00000 n +0000427045 00000 n +0000427162 00000 n +0000427275 00000 n +0000427375 00000 n +0000427536 00000 n +0000427633 00000 n +0000427746 00000 n +0000427863 00000 n +0000427976 00000 n +0000428076 00000 n +0000428239 00000 n +0000428336 00000 n +0000428451 00000 n +0000428564 00000 n +0000428681 00000 n +0000428794 00000 n +0000428894 00000 n +0000429058 00000 n +0000429155 00000 n +0000429270 00000 n +0000429383 00000 n +0000429500 00000 n +0000429613 00000 n +0000429713 00000 n +0000429874 00000 n +0000429971 00000 n +0000430086 00000 n +0000430199 00000 n +0000430316 00000 n +0000430429 00000 n +0000430529 00000 n +0000430691 00000 n +0000430788 00000 n +0000430903 00000 n +0000431016 00000 n +0000431133 00000 n +0000431246 00000 n +0000431346 00000 n +0000431509 00000 n +0000431606 00000 n +0000431721 00000 n +0000431838 00000 n +0000431951 00000 n +0000432051 00000 n +0000432213 00000 n +0000432310 00000 n +0000432425 00000 n +0000432538 00000 n +0000432655 00000 n +0000432768 00000 n +0000432868 00000 n +0000433036 00000 n +0000433133 00000 n +0000433248 00000 n +0000433361 00000 n +0000433478 00000 n +0000433591 00000 n +0000433691 00000 n +0000433859 00000 n +0000433956 00000 n +0000434071 00000 n +0000434184 00000 n +0000434301 00000 n +0000434414 00000 n +0000434514 00000 n +0000434683 00000 n +0000434780 00000 n +0000434895 00000 n +0000435008 00000 n +0000435125 00000 n +0000435238 00000 n +0000435338 00000 n +0000435507 00000 n +0000435604 00000 n +0000435719 00000 n +0000435832 00000 n +0000435949 00000 n +0000436062 00000 n +0000436162 00000 n +0000436320 00000 n +0000436417 00000 n +0000436530 00000 n +0000436647 00000 n +0000436760 00000 n +0000436860 00000 n +0000437020 00000 n +0000437117 00000 n +0000437232 00000 n +0000437345 00000 n +0000437462 00000 n +0000437561 00000 n +0000437717 00000 n +0000437814 00000 n +0000437927 00000 n +0000438044 00000 n +0000438157 00000 n +0000438257 00000 n +0000438417 00000 n +0000438514 00000 n +0000438629 00000 n +0000438746 00000 n +0000438859 00000 n +0000438959 00000 n +0000439116 00000 n +0000439213 00000 n +0000439328 00000 n +0000439441 00000 n +0000439558 00000 n +0000439671 00000 n +0000439771 00000 n +0000439934 00000 n +0000440031 00000 n +0000440146 00000 n +0000440263 00000 n +0000440376 00000 n +0000440476 00000 n +0000440633 00000 n +0000440730 00000 n +0000440845 00000 n +0000440962 00000 n +0000441075 00000 n +0000441175 00000 n +0000441334 00000 n +0000441431 00000 n +0000441546 00000 n +0000441659 00000 n +0000441776 00000 n +0000441889 00000 n +0000441989 00000 n +0000442149 00000 n +0000442246 00000 n +0000442361 00000 n +0000442474 00000 n +0000442591 00000 n +0000442704 00000 n +0000442804 00000 n +0000442962 00000 n +0000443059 00000 n +0000443174 00000 n +0000443287 00000 n +0000443404 00000 n +0000443517 00000 n +0000443617 00000 n +0000443777 00000 n +0000443874 00000 n +0000443989 00000 n +0000444102 00000 n +0000444219 00000 n +0000444332 00000 n +0000444432 00000 n +0000444589 00000 n +0000444686 00000 n +0000444801 00000 n +0000444914 00000 n +0000445031 00000 n +0000445144 00000 n +0000445244 00000 n +0000445401 00000 n +0000445498 00000 n +0000445613 00000 n +0000445730 00000 n +0000445843 00000 n +0000445943 00000 n +0000446098 00000 n +0000446195 00000 n +0000446310 00000 n +0000446423 00000 n +0000446540 00000 n +0000446653 00000 n +0000446753 00000 n +0000446909 00000 n +0000447006 00000 n +0000447121 00000 n +0000447234 00000 n +0000447351 00000 n +0000447464 00000 n +0000447564 00000 n +0000447729 00000 n +0000447826 00000 n +0000447941 00000 n +0000448054 00000 n +0000448171 00000 n +0000448284 00000 n +0000448384 00000 n +0000448547 00000 n +0000448644 00000 n +0000448759 00000 n +0000448872 00000 n +0000448989 00000 n +0000449102 00000 n +0000449202 00000 n +0000449362 00000 n +0000449459 00000 n +0000449574 00000 n +0000449687 00000 n +0000449804 00000 n +0000449917 00000 n +0000450017 00000 n +0000450173 00000 n +0000450270 00000 n +0000450385 00000 n +0000450498 00000 n +0000450615 00000 n +0000450728 00000 n +0000450828 00000 n +0000450990 00000 n +0000451087 00000 n +0000451204 00000 n +0000451317 00000 n +0000451417 00000 n +0000451576 00000 n +0000451673 00000 n +0000451788 00000 n +0000451901 00000 n +0000452018 00000 n +0000452131 00000 n +0000452231 00000 n +0000452387 00000 n +0000452484 00000 n +0000452599 00000 n +0000452712 00000 n +0000452829 00000 n +0000452942 00000 n +0000453042 00000 n +0000453200 00000 n +0000453297 00000 n +0000453412 00000 n +0000453525 00000 n +0000453642 00000 n +0000453755 00000 n +0000453855 00000 n +0000454010 00000 n +0000454107 00000 n +0000454222 00000 n +0000454335 00000 n +0000454452 00000 n +0000454565 00000 n +0000454665 00000 n +0000454821 00000 n +0000454918 00000 n +0000455033 00000 n +0000455146 00000 n +0000455263 00000 n +0000455376 00000 n +0000455476 00000 n +0000455637 00000 n +0000455734 00000 n +0000455849 00000 n +0000455962 00000 n +0000456079 00000 n +0000456192 00000 n +0000456292 00000 n +0000456452 00000 n +0000456549 00000 n +0000456664 00000 n +0000456781 00000 n +0000456894 00000 n +0000456994 00000 n +0000457154 00000 n +0000457251 00000 n +0000457366 00000 n +0000457483 00000 n +0000457596 00000 n +0000457696 00000 n +0000457853 00000 n +0000457950 00000 n +0000458065 00000 n +0000458178 00000 n +0000458295 00000 n +0000458408 00000 n +0000458508 00000 n +0000458666 00000 n +0000458763 00000 n +0000458878 00000 n +0000458991 00000 n +0000459108 00000 n +0000459221 00000 n +0000459321 00000 n +0000459478 00000 n +0000459575 00000 n +0000459690 00000 n +0000459803 00000 n +0000459920 00000 n +0000460033 00000 n +0000460133 00000 n +0000460294 00000 n +0000460391 00000 n +0000460506 00000 n +0000460619 00000 n +0000460736 00000 n +0000460849 00000 n +0000460949 00000 n +0000461111 00000 n +0000461208 00000 n +0000461323 00000 n +0000461436 00000 n +0000461553 00000 n +0000461666 00000 n +0000461766 00000 n +0000461924 00000 n +0000462021 00000 n +0000462136 00000 n +0000462249 00000 n +0000462366 00000 n +0000462479 00000 n +0000462579 00000 n +0000462740 00000 n +0000462837 00000 n +0000462952 00000 n +0000463065 00000 n +0000463182 00000 n +0000463295 00000 n +0000463395 00000 n +0000463557 00000 n +0000463654 00000 n +0000463769 00000 n +0000463882 00000 n +0000463999 00000 n +0000464112 00000 n +0000464212 00000 n +0000464371 00000 n +0000464468 00000 n +0000464583 00000 n +0000464696 00000 n +0000464813 00000 n +0000464926 00000 n +0000465026 00000 n +0000465186 00000 n +0000465283 00000 n +0000465398 00000 n +0000465511 00000 n +0000465628 00000 n +0000465741 00000 n +0000465841 00000 n +0000466005 00000 n +0000466102 00000 n +0000466217 00000 n +0000466330 00000 n +0000466447 00000 n +0000466560 00000 n +0000466660 00000 n +0000466825 00000 n +0000466922 00000 n +0000467037 00000 n +0000467150 00000 n +0000467267 00000 n +0000467380 00000 n +0000467480 00000 n +0000467643 00000 n +0000467740 00000 n +0000467855 00000 n +0000467968 00000 n +0000468085 00000 n +0000468198 00000 n +0000468298 00000 n +0000468458 00000 n +0000468555 00000 n +0000468670 00000 n +0000468783 00000 n +0000468900 00000 n +0000469013 00000 n +0000469113 00000 n +0000469274 00000 n +0000469371 00000 n +0000469486 00000 n +0000469599 00000 n +0000469716 00000 n +0000469829 00000 n +0000469929 00000 n +0000470090 00000 n +0000470187 00000 n +0000470302 00000 n +0000470415 00000 n +0000470532 00000 n +0000470645 00000 n +0000470745 00000 n +0000470902 00000 n +0000470999 00000 n +0000471114 00000 n +0000471231 00000 n +0000471344 00000 n +0000471444 00000 n +0000471608 00000 n +0000471705 00000 n +0000471820 00000 n +0000471933 00000 n +0000472050 00000 n +0000472163 00000 n +0000472263 00000 n +0000472420 00000 n +0000472517 00000 n +0000472632 00000 n +0000472745 00000 n +0000472862 00000 n +0000472975 00000 n +0000473075 00000 n +0000473229 00000 n +0000473326 00000 n +0000473439 00000 n +0000473556 00000 n +0000473669 00000 n +0000473769 00000 n +0000473924 00000 n +0000474021 00000 n +0000474134 00000 n +0000474251 00000 n +0000474364 00000 n +0000474464 00000 n +0000474619 00000 n +0000474716 00000 n +0000474831 00000 n +0000474944 00000 n +0000475061 00000 n +0000475174 00000 n +0000475274 00000 n +0000475435 00000 n +0000475532 00000 n +0000475647 00000 n +0000475760 00000 n +0000475877 00000 n +0000475990 00000 n +0000476090 00000 n +0000476246 00000 n +0000476343 00000 n +0000476458 00000 n +0000476571 00000 n +0000476688 00000 n +0000476801 00000 n +0000476901 00000 n +0000477057 00000 n +0000477154 00000 n +0000477269 00000 n +0000477386 00000 n +0000477499 00000 n +0000477599 00000 n +0000477759 00000 n +0000477856 00000 n +0000477971 00000 n +0000478084 00000 n +0000478201 00000 n +0000478314 00000 n +0000478414 00000 n +0000478569 00000 n +0000478666 00000 n +0000478781 00000 n +0000478894 00000 n +0000479011 00000 n +0000479124 00000 n +0000479224 00000 n +0000479381 00000 n +0000479478 00000 n +0000479593 00000 n +0000479706 00000 n +0000479823 00000 n +0000479936 00000 n +0000480036 00000 n +0000480197 00000 n +0000480294 00000 n +0000480409 00000 n +0000480522 00000 n +0000480639 00000 n +0000480752 00000 n +0000480852 00000 n +0000481019 00000 n +0000481116 00000 n +0000481231 00000 n +0000481344 00000 n +0000481461 00000 n +0000481574 00000 n +0000481674 00000 n +0000481835 00000 n +0000481932 00000 n +0000482047 00000 n +0000482160 00000 n +0000482277 00000 n +0000482390 00000 n +0000482490 00000 n +0000482649 00000 n +0000482746 00000 n +0000482861 00000 n +0000482974 00000 n +0000483091 00000 n +0000483204 00000 n +0000483304 00000 n +0000483467 00000 n +0000483564 00000 n +0000483679 00000 n +0000483796 00000 n +0000483909 00000 n +0000484009 00000 n +0000484170 00000 n +0000484267 00000 n +0000484382 00000 n +0000484495 00000 n +0000484612 00000 n +0000484725 00000 n +0000484825 00000 n +0000484980 00000 n +0000485077 00000 n +0000485192 00000 n +0000485305 00000 n +0000485422 00000 n +0000485535 00000 n +0000485635 00000 n +0000485792 00000 n +0000485889 00000 n +0000486004 00000 n +0000486117 00000 n +0000486234 00000 n +0000486347 00000 n +0000486447 00000 n +0000486606 00000 n +0000486703 00000 n +0000486818 00000 n +0000486931 00000 n +0000487048 00000 n +0000487161 00000 n +0000487261 00000 n +0000487422 00000 n +0000487519 00000 n +0000487634 00000 n +0000487747 00000 n +0000487864 00000 n +0000487977 00000 n +0000488077 00000 n +0000488236 00000 n +0000488333 00000 n +0000488448 00000 n +0000488561 00000 n +0000488678 00000 n +0000488791 00000 n +0000488891 00000 n +0000489037 00000 n +0000489134 00000 n +0000489249 00000 n +0000489362 00000 n +0000489479 00000 n +0000489592 00000 n +0000489692 00000 n +trailer +<]>> +startxref +489926 +%%EOF diff --git a/doc/spm.shtml b/doc/spm.shtml new file mode 100644 index 0000000000..942660f156 --- /dev/null +++ b/doc/spm.shtml @@ -0,0 +1,8051 @@ + + + + + + CUPS Software Programmers Manual + + + +

Preface

+ +

This software programmers manual provides software programming +information for the Common UNIX Printing System ("CUPS") Version 1.1.1. + + + + +

Document Overview

+ +

This software programmers manual is organized into the following sections: + +

+ +

Notation Conventions

+ +

Various font and syntax conventions are used in this guide. Examples and +their meanings and uses are explained below: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Example   Description
 
lpstat
+ lpstat(1)
   The names of commands; the first mention of a command or + function in a chapter is followed by a manual page section + number.
 
/var
+ /usr/share/cups/data/testprint.ps
   File and directory names.
 
Request ID is Printer-123   Screen output.
 
lp -d printer filename ENTER   Literal user input; special keys like ENTER are + in ALL CAPS.
 
12.3   Numbers in the text are written using the period (.) to indicate + the decimal point.
+ + +

Abbreviations

+ +The following abbreviations are used throughout this manual: + +
    +
    + +
    kb +
    Kilobytes, or 1024 bytes
      + +
    Mb +
    Megabytes, or 1048576 bytes
      + +
    Gb +
    Gigabytes, or 1073741824 bytes
      + +
    +
+ +

Other References

+ +
    +
    + +
    CUPS Software Administrators Manual + +
    An administration guide for the CUPS software.
      + +
    CUPS Software Users Manual + +
    An end-user guide for using the CUPS software.
      + +
    +
+ + + + + +

2 - The CUPS API

+ +

This chapter describes the CUPS Application Programmers Interface ("API"). + +

The CUPS API Library

+ +

The CUPS library provides a whole collection of interfaces needed to +support the internal needs of the CUPS software as well as the needs of +applications, filters, printer drivers, and backends. + +

Unlike the rest of CUPS, the CUPS API library is provided under the +GNU Library General Public License. This means that you can use the +CUPS API library in both proprietary and open-source programs. + +

Programs that use the CUPS API library typically will include the +<cups/cups.h> header file: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +jobid = cupsPrintFile("myprinter", "filename.ps", "title",
    +                      num_options, options);
    +
+ +

Use the -lcups compiler option when linking to the CUPS API +library: + +

    +cc -o program program.c -lcups ENTER
    +
+ +

Additional options and libraries may be required depending on the +operating system and the location of the CUPS API library. + +

Detecting the CUPS API Library in GNU Autoconf

+ +

GNU autoconf is a popular configuration tool used by many programs. +Add the following lines to your configure.in file to check +for the CUPS API library in your configuration script: + +

    +AC_CHECK_LIB(socket,socket,
    +if test "$uname" != "IRIX"; then
    +	LIBS="-lsocket $LIBS"
    +else
    +	echo "Not using -lsocket since you are running IRIX."
    +fi)
    +AC_CHECK_LIB(nsl,gethostbyaddr,
    +if test "$uname" != "IRIX"; then
    +	LIBS="-lnsl $LIBS"
    +else
    +	echo "Not using -lnsl since you are running IRIX."
    +fi)
    +
    +AC_CHECK_LIB(cups,httpConnect)
    +
+ +

Printing Services

+ +

The CUPS API library provides some basic printing services for applications +that need to print files. + +

Include Files

+ +

The include file used by all of these functions is +<cups/cups.h>: + +

    +#include <cups/cups.h>
    +
+ +

Printing a File

+ +

The CUPS API provides two functions for printing files. The first is +cupsPrintFile which prints a single named file: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +int jobid;
    +
    +...
    +
    +jobid = cupsPrintFile("name", "filename", "title", 0, NULL);
    +
+ +

The name string is the name of the printer or class to +print to. The filename string is the name of the file to +print. The title string is the name of the print job, e.g. +"Acme Word Document". + +

The return value is a unique ID number for the print job or 0 if there +was an error. + +

Printing Multiple Files

+ +

The second printing function is cupsPrintFiles: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +int        jobid;
    +int        num_files;
    +const char *files[100];
    +...
    +
    +jobid = cupsPrintFiles("name", num_files, files, "title", 0, NULL);
    +
+ +

Instead of passing a filename string as with cupsPrintFile(), +you pass a file count (num_files) and filename pointer array +(files) for each file that you want to print. + +

As with cupsPrintFile(), the return value is a unique ID for +the print job. + +

Cancelling Jobs

+ +

The cupsCancelJob() function cancels a queued print job: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +int jobid;
    +int status;
    +...
    +
    +status = cupsCancelJob("name", jobid);
    +
+ +

The name string specifies the destination and is used +to determine the server to send the request to. The jobid +value is the integer returned from a previous cupsPrintFile() +or cupsPrintFiles() call. + +

cupsCancelJob() returns 1 if the job was +successfully cancelled and 0 if there was an error. + +

Getting the Available Printers and Classes

+ +

The cupsGetDests() function can be used to get a list +of the available printers, classes, and instances that a user has defined: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +int         num_dests;
    +cups_dest_t *dests;
    +
    +...
    +
    +num_dests = cupsGetDests(&dests);
    +
+ +

Each destination is stored in a cups_dest_t structure which +defines the printer or class name, the instance name (if any), if it is the +default destination, and the default options the user has defined for the +destination: + +

    +typedef struct               /**** Destination ****/
    +{
    +  char          *name,       /* Printer or class name */
    +                *instance;   /* Local instance name or NULL */
    +  int           is_default;  /* Is this printer the default? */
    +  int           num_options; /* Number of options */
    +  cups_option_t *options;    /* Options */
    +} cups_dest_t;
    +
+ +

The destinations are sorted by name and instance for your convenience. +Once you have the list of available destinations, you can lookup a specific +destination using the cupsGetDest() function: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +int         num_dests;
    +cups_dest_t *dests;
    +cups_dest_t *mydest;
    +
    +...
    +
    +mydest = cupsGetDest("name", "instance", num_dests, dests);
    +
+ +

The name string is the printer or class name. You can pass +a value of NULL to get the default destination. + +

The instance string is the user-defined instance name. Pass +NULL to select the default instance, e.g. "name" instead of +"name/instance". + +

Printing with Options

+ +

All of the previous printing examples have passed 0 and +NULL for the last two arguments to the cupsPrintFile() +and cupsPrintFiles() functions. These last two arguments are the +number of options and a pointer to the option array: + +

    +int cupsPrintFile(const char *name, const char *filename, const char *title,
    +                  int num_options, cups_option_t *options);
    +int cupsPrintFiles(const char *name, int num_files, const char **files,
    +                   const char *title, int num_options,
    +		   cups_option_t *options);
    +
+ +

The cups_option_t structure holds each option and its value. +These are converted as needed and passed to the CUPS server when printing a +file. + +

The simplest way of handling options is to use the num_options +and options members of the cups_dest_t +structure described earlier: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +int         jobid;
    +int         num_dests;
    +cups_dest_t *dests;
    +cups_dest_t *mydest;
    +
    +...
    +
    +mydest = cupsGetDest("name", "instance", num_dests, dests);
    +
    +jobid  = cupsPrintFile(mydest->name, "filename", "title",
    +                       mydest->num_options, mydest->options);
    +
+ +

This effectively uses the options a user has previous selected without a +lot of code. + +

Setting Printer Options

+ +

Options can also be set by your program using the cupsAddOption() +function: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +int           num_options;
    +cups_option_t *options;
    +
    +...
    +
    +num_options = 0;
    +options     = NULL;
    +
    +...
    +
    +num_options = cupsAddOption("name", "value", num_options, &options);
    +num_options = cupsAddOption("name", "value", num_options, &options);
    +num_options = cupsAddOption("name", "value", num_options, &options);
    +num_options = cupsAddOption("name", "value", num_options, &options);
    +
+ +

The name string is the name of the option, and the +value string is the value for that option. + +

Each call to cupsAddOption() returns the new number of +options. Since adding two options with the same name overwrites the +first value with the second, do not assume that calling +cupsAddOptions() 20 times will result in 20 options. + +

Call cupsFreeOptions once you are done using the options: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +int           num_options;
    +cups_option_t *options;
    +
    +...
    +
    +cupsFreeOptions(num_options, options);
    +
+ +

Getting Errors

+ +

If any of the CUPS API printing functions returns an error, the reason for +that error can be found by calling cupsLastError() and +cupsErrorString(). cupsLastError() returns the +last IPP error code that was encountered. cupsErrorString() +converts the error code to a localized message string suitable for +presentation to the user: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +int jobid;
    +
    +...
    +
    +if (jobid == 0)
    +  puts(cupsErrorString(cupsLastError()));
    +
+ +

PPD Services

+ +

CUPS includes functions to access and manipulate PostScript Printer +Description ("PPD") files that are used with the printer drivers in CUPS. + +

Each PPD file enumerates the available features provided by a +printer, including conflict information for specific options (e.g. +can't duplex output on envelopes.) + +

Include Files

+ +

Include the <cups/ppd.h> header file to use the PPD +functions: + +

    +#include <cups/ppd.h>
    +
+ +

This header file is also included by the +<cups/cups.h> header file. + +

Getting a PPD File for a Printer

+ +

The cupsGetPPD() function retrieves the PPD file for the +named printer or class: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +const char *filename;
    +
    +filename = cupsGetPPD("name");
    +
+ +

The name string is the name of the printer or class, including +the remote server name as appropriate (e.g. "printer@server".) + +

The return value is a pointer to a filename in static storage; this value +is overwritten with each call to cupsGetPPD(). If the printer +or class does not exist, a NULL pointer will be returned. + +

Loading a PPD File

+ +

The ppdOpenFile() function "opens" a PPD file and loads it +into memory: + +

    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +
    +ppd = ppdOpenFile("filename");
    +
+ +

The filename string is the name of the file to load, such as +the value returned by the cupsGetPPD() function. + +

The return value is a pointer to a structure describing the contents of the +PPD file or NULL if the PPD file could not be read. + +

Freeing PPD File Information

+ +

Once you are done using a PPD file, call the ppdClose() function +to free all memory that has been used: + +

    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +
    +...
    +
    +ppdClose(ppd);
    +
+ +

The PPD File Structure

+ +

Each PPD file contains a number of capability attributes, printer options, +and conflict definitions. The page size options also include the physical +margins for the printer and the minimum and maximum sizes for the printer. +All of this information is stored in the ppd_file_t structure. + +

Capabilities

+ +

Each PPD file contains a number of informational attributes that +describe the capabilities of the printer. These are provided in the +ppd_file_t structure in the following members: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MemberTypeDescription
accurate_screensint1 = supports accurate screens
color_deviceint1 = color device
colorspaceppd_cs_tDefault colorspace: PPD_CS_CMYK, PPD_CS_CMY, PPD_CS_GRAY, + PPD_CS_RGB, PPD_CS_RGBK, PPD_CS_N
contone_onlyint1 = printer is continuous tone only
num_emulations
+ emulations
int
+ ppd_emul_t *
Emulations supported by the printer
flip_duplexint1 = need to flip odd pages when duplexing
num_fonts
+ fonts
int
+ char **
The fonts available on the printer.
jcl_begin
+ jcl_ps
+ jcl_end
char *Job Control Language commands for PostScript output
landscapeintLandscape orientation, -90 or 90 degrees
lang_encodingchar *The character used for the option strings
lang_versionchar *The language used for the options strings (English, French, etc.)
language_levelintPostScript language level, 1 to 3
manual_copiesint1 = Copies are done manually
model_numberintDriver-specific model number.
patcheschar *Patch commands to send to the printer
manufacturerchar *The Manufacturer attribute from the PPD file, if any
modelnamechar *The ModelName attribute from the PPD file
nicknamechar *The NickName attribute from the PPD file, if any
productchar *The Product attribute from the PPD file, if any
shortnicknamechar *The ShortNickName attribute from the PPD file, if any
throughputintNumber of pages per minute
ttrasterizerchar *The TruType font rasterizer (Type42)
variable_sizesint1 = supports variable sizes
+ +

Options and Groups

+ +

PPD files support multiple options, which are stored in +ppd_option_t and ppd_choice_t structures by +the PPD functions. + +

Each option in turn is associated with a group +stored in the ppd_group_t structure. Groups can be +specified in the PPD file; if an option is not associated with a group +then it is put in a "General" or "Extra" group depending on the option. + +

Groups can also have sub-groups; CUPS currently limits the depth of +sub-groups to 1 level to reduce programming complexity. + +

Conflicts

+ +

PPD files support specification of conflict conditions between +different options. Conflicts are stored in ppd_conflict_t +structures which specify the options that conflict with each other. + +

Page Sizes

+ +

PPD files specify all of the available pages sizes and the physical +margins associated with them. These sizes are stored in +ppd_size_t structures and are available in the +num_sizes and sizes members of the +ppd_file_t structure. You can lookup a particular page size +with the ppdPageWidth(), ppdPageLength(), and +ppdPageSize() functions: + +

    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +ppd_size_t *size;
    +float      width;
    +float      length;
    +
    +...
    +
    +size   = ppdPageSize(ppd, "size");
    +width  = ppdPageWidth(ppd, "size");
    +length = ppdPageLength(ppd, "size");
    +
+ +

The size string is the named page size option. The +width and length are in points; there are 72 points per inch. The +ppd_size_t structure contains the width, length, and +margin information: + +

    +typedef struct    /**** Page Sizes ****/
    +{
    +  int   marked;   /* Page size selected? */
    +  char  name[41]; /* Media size option */
    +  float width,    /* Width of media in points */
    +        length,   /* Length of media in points */
    +        left,     /* Left printable margin in points */
    +        bottom,   /* Bottom printable margin in points */
    +        right,    /* Right printable margin in points */
    +        top;      /* Top printable margin in points */
    +} ppd_size_t;
    +
+ +

Custom Page Sizes

+ +

Besides the standard page sizes listed in a PPD file, some printers +support variable or custom page sizes. If variables_sizes +is non-zero, the custom_min, custom_max, and +custom_margins members of the ppd_file_t +structure define the limits of the variable sizes. + +

To get the resulting media size, use a page size string of +Custom.widthxlength, where width +and length are integer values in points: + +

    +Custom.612x792   [8.5 inches wide, 11 inches long]
    +Custom.1224x792  [17 inches wide, 11 inches long]
    +
+ +

Marking Options

+ +

Before marking any user-defined options, call the ppdMarkDefaults() +function to mark the default options from the PPD file: + +

    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +
    +...
    +
    +ppdMarkDefaults(ppd);
    +
+ +

Then call the ppdMarkOption() function to mark individual +options: + +

    +#include <cups/ppd.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +int        conflicts;
    +
    +...
    +
    +conflicts = ppdMarkOption(ppd, "name", "value");
    +
+ +

The name and value strings choose a +particular option and choice, respectively. The return value is 0 +if there are not conflicts created by the selection. + +

CUPS also provides a convenience function for marking all options +in the cups_option_t structure: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +ppd_file_t    *ppd;
    +int           num_options;
    +cups_option_t *options;
    +int           conflicts;
    +
    +...
    +
    +conflicts = cupsMarkOptions(ppd, num_options, options);
    +
+ +

The cupsMarkOptions() function also handles mapping the +IPP job template attributes to PPD options. The return value is the number +of conflicts present. + +

Checking for Conflicts

+ +

The ppdMarkOption() and cupsMarkOptions() +functions return the number of conflicts with the currently marked options. + +

Call the ppdConflicts() function to get the number of +conflicts after you have marked all of the options: + +

    +#include <cups/cups.h>
    +
    +...
    +
    +ppd_file_t *ppd;
    +int        conflicts;
    +
    +...
    +
    +conflicts = ppdConflicts(ppd);
    +
+ +

The return value is the number of conflicting options, or 0 if there +are no conflicts. + + +

3 - Writing Filters

+ +

This chapter describes how to write a file filter for CUPS. + +

Overview

+ +

File filters are programs that convert from one or more MIME types to +another type. Filters use a common command-line and environment interface +that allows them to be joined as needed to print files to any type of +printer. + +

Security Considerations

+ +

Filters are normally run as a non-priviledged user, so the major +security consideration is resource utilization - filters should not +depend on unlimited amounts of memory and disk space. + +

Users and Groups

+ +

The default CUPS configuration runs filters as user "lp" and group "other". + +

Temporary Files

+ +

Temporary files should be created in the directory specified by the +"TMPDIR" environment variable. The +cupsTempFile() function can be +used to safely choose temporary files in this directory. + +

Sending Messages to the User

+ +

The CUPS scheduler collects messages sent to the standard error file +by the filter. These messages are relayed to the user based upon the +scheduler LogLevel directive. + +

The type of message is determined by an initial prefix sent on each +line: + +

    + +
  • DEBUG: - a debug message + +
  • INFO: - an informational message + +
  • WARNING: - a warning message + +
  • ERROR: - an error message + +
  • PAGE: - a page accounting message + +
+ +

If the line of text does not begin with any of the above prefixes, it +is treated as a debug message. Text following the prefix is copied to the +printer-state-message attribute for the printer, and also +added to the error_log unless it is an informational or page +accounting message. + +

Page Accounting

+ +

Page accounting messages are used to inform the server when one or more +pages are printed. Each line has the form: + +

    +PAGE: page-number copy-count
    +
+ +

The page-number field is the current page number, starting at 1. +The copy-count field specifies the number of copies of that page +that was produced. + +

Page account messages are added to the page_log file and +cause the job-sheets-completed attribute to be updated for +the job. + +

Command-Line Arguments

+ +

Every filter accepts exactly 6 or 7 command-line arguments: + +

    +printer job user title copies options [filename]
    +
    + +
  • printer - The name of the printer queue (normally + this is the name of the program being run) + +
  • job - The numeric job ID for the job being + printed + +
  • user - The string from the + originating-user-name attribute + +
  • title - The string from the + job-name attribute + +
  • copies - The numeric value from the + number-copies attribute + +
  • options - String representations of the + job template attributes, separated by spaces. Boolean attributes + are provided as "name" for true values and "noname" for false + values. All other attributes are provided as "name=value" for + single-valued attributes and "name=value1,value2,...,valueN" for + set attributes + +
  • filename - The request file + +
+ +

The filename argument is only provided to the first filter in the +chain; all filters must be prepared to read the print file from +the standard input if the filename argument is omitted. + +

Copy Generation

+ +

The copies argument specifies the number of copies to produce +of the input file. In general, you should only generate copies if the +filename argument is supplied. The only exception to this are +filters that produce device-independent PostScript output (without any +printer commands from the printer's PPD file), since the PostScript +filter pstops is responsible for copy generation. + +

Environment Variables

+ +

Every filter receives a fixed set of environment variables that can +be used by the filter: + +

    + +
  • CHARSET - The character set used by the client for + this print file + +
  • CONTENT_TYPE - The original document type, such as + "application/postscript" + +
  • CUPS_DATADIR - The location of CUPS data files + +
  • CUPS_SERVERROOT - The location of CUPS configuration + files + +
  • DEVICE_URI - The output device URI + +
  • LANG - The language used by the client for + this print file + +
  • PATH - The execution path exported to the filter + +
  • PPD - The full filename of the printer's PPD file + +
  • PRINTER - The name of the printer queue + +
  • RIP_CACHE - The maximum amount of memory each filter + should use + +
  • SOFTWARE - The name of the CUPS software, typically + "CUPS/1.1" + +
  • TZ - The local timezone + +
  • USER - The name of the current user + +
+ +

Dissecting the HP-GL/2 Filter

+ +

The HP-GL/2 filter (hpgltops) provided with CUPS is a +complex program that converts HP-GL/2 files into device-independent PostScript +output. Since it produces device-independent PostScript output, it does not +need to handle copy generation or writing printer options from the printer's +PPD file. + +

Initializing the Filter

+ +

The first task of any filter is to ensure that the correct number of +command-line arguments are present: + +

    +if (argc < 6 || argc > 7)
    +{
    +  fputs("ERROR: hpgltops job-id user title copies options [file]\n", stderr);
    +  return (1);
    +}
    +
+ +

After this you open the print file or read from the standard input +as needed: + +

    +FILE *fp;
    +
    +/*
    + * If we have 7 arguments, print the file named on the command-line.
    + * Otherwise, send stdin instead...
    + */
    +
    +if (argc == 6)
    +  fp = stdin;
    +else
    +{
    + /*
    +  * Try to open the print file...
    +  */
    +
    +  if ((fp = fopen(argv[6], "rb")) == NULL)
    +  {
    +    perror("ERROR: unable to open print file - ");
    +    return (1);
    +  }
    +}
    +
+ +

Once the print file has been opened, options can be processed using +the cupsParseOptions() and +cupsGetOption() functions: + +

    +int           num_options;
    +cups_option_t *options;
    +const char    *val;
    +
    +/*
    + * Process command-line options and write the prolog...
    + */
    +
    +options     = NULL;
    +num_options = cupsParseOptions(argv[5], 0, &options);
    +
    +if ((val = cupsGetOption("blackplot", num_options, options)) != NULL)
    +  shading = 0;
    +
    +if ((val = cupsGetOption("fitplot", num_options, options)) != NULL)
    +  FitPlot = 1;
    +
    +if ((val = cupsGetOption("penwidth", num_options, options)) != NULL)
    +  PenWidth = (float)atoi(val) * 0.001f;
    +
+ +

After the options have been processed, the filter writes PostScript code +to the standard output based on the print file, closes the print file (as +needed), and returns 0 to the scheduler. + +

PostScript Output

+ +

Filters that produce PostScript output must generate output conforming +to the Adobe Document Structuring Conventions, 3.0. In general this means +the beginning of each file must begin with: + +

    +%!PS-Adobe-3.0
    +%%BoundingBox: left bottom right top
    +%%Pages: (atend)
    +%%EndComments
    +
+ +

The left, bottom, right, and top values +are integers in points from the lower-lefthand corner of the page. + +

Pages must be surrounded by: + +

    +%%Page: number number
    +gsave
    +...
    +grestore
    +showpage
    +
+ +

And the end of each file must contain: + +

    +%%Trailer
    +%%Pages: number-pages
    +%%EOF
    +
+ +

These comments allow the PostScript filter to correctly perform page +accounting, copy generation, N-up printing, and so forth. + +

4 - Writing Printer Drivers

+ +

This chapter discusses how to write a printer driver, which is a +special filter program that converts CUPS raster data into the +appropriate commands and data required for a printer. + +

Overview

+ +

Raster printers utilitize PPD files that specify one or more +device-specific filters that handle converting print files for the +printer. The simplest raster printer drivers provide a single filter +that converts CUPS raster data to the printer's native format. + +

CUPS Raster Data

+ +

CUPS raster data (application/vnd.cups-raster) consists of +a stream of raster page descriptions produced by one of the RIP filters, +such as pstoraster or imagetoraster. + +

Each page of data begins with a page dictionary structure called +cups_raster_header_t. This +structure contains the colorspace, bits per color, media size, media type, +hardware resolution, and so forth. + +

After the page dictionary comes the page data which is a full-resolution, +uncompressed bitmap representing the page in the printer's output colorspace. + +

Page Accounting

+ +

Printer drivers must handle all page accounting. This means they must +send "PAGE:" messages to the standard error file for each page (and in many +cases, copy) sent to the printer. + +

Color Management

+ +

Printer drivers can implement their color management via the +cupsColorProfile attributes in the PPD file or internally +in the driver from a device-independent colorspace. In general, color +management performed by the RIP filters is more efficient than that +performed inside printer drivers. + +

For example, the pstoraster filter often only has to +perform a color conversion once each time the color is used for +multiple output pixels, while the raster filter must convert every +pixel on the page. + +

Device and Bitmap Variables

+ +

Besides the standard PostScript page device dictionary variables defined +in the Adobe PostScript Level 3 reference manual, the CUPS filters support +additional variables that are passed in the page device dictionary header for +the page and in some cases control the type of raster data that is generated: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
VariableTypeDescription
cupsWidthread-only integerWidth of bitmap in pixels
cupsHeightread-only integer Height of bitmap in pixels
cupsMediaTyperead-write integerDevice-specific media type code
cupsBitsPerColorread-write integerNumber of bits per color; 1, 2, 4, and 8 are currently + supported
cupsBitsPerPixelread-only integer Number of bits per pixel; 1 to 32
cupsBytesPerLineread-only integerNumber of bytes per line of raster graphics
cupsColorOrderread-write enumThe order of color values in the bitmap: +
    +
  • CUPS_ORDER_CHUNKED - CMYK CMYK CMYK +
  • CUPS_ORDER_BANDED - CCC MMM YYY KKK +
  • CUPS_ORDER_PLANAR - CCC ... MMM ... YYY ... KKK ... +
+
cupsColorSpaceread-write enumThe colorspace of the bitmap: +
    +
  • CUPS_CSPACE_W - White (luminance) +
  • CUPS_CSPACE_RGB - Red, green, blue +
  • CUPS_CSPACE_RGBA - Red, green, blue, alpha +
  • CUPS_CSPACE_K - Black +
  • CUPS_CSPACE_CMY - Cyan, magenta, yellow +
  • CUPS_CSPACE_YMC - Yellow, magenta, cyan +
  • CUPS_CSPACE_CMYK - Cyan, magenta, yellow, black +
  • CUPS_CSPACE_YMCK - Yellow, magenta, cyan, black +
  • CUPS_CSPACE_KCMY - Black, cyan, magenta, yellow +
  • CUPS_CSPACE_KCMYcm - Black, cyan, magenta, yellow, + light cyan, light magenta +
  • CUPS_CSPACE_GMCK - Metallic yellow (gold), metallic magenta, + metallic cyan, black +
  • CUPS_CSPACE_GMCS - Metallic yellow (gold), metallic magenta, + metallic cyan, metallic grey (silver) +
  • CUPS_CSPACE_WHITE - White pigment (black as white pigment) +
  • CUPS_CSPACE_GOLD - Gold foil (black as gold foil) +
  • CUPS_CSPACE_SILVER - Silver foil (black as silver foil) +
+
cupsCompressionread-write integerDevice-specific compression type code
cupsRowCountread-write integerDevice-specific row count value
cupsRowFeedread-write integerDevice-specific row feed value
cupsRowStepread-write integerDevice-specific row step value
+ +

Bitmaps with a colorspace of CUPS_CSPACE_KCMYcm and more than 1 bit per +color are transmitted to the raster driver in KCMY colorspace; the driver +is responsible for producing the correct separation of normal and light +cyan and magenta inks. + +

Dissecting the HP-PCL Driver

+ +

The HP-PCL driver provided with CUPS (rastertohp) converts +bitmap data from the raster filters into HP-PCL commands for most +PCL-compatible printers. The actual format of the raster data is controlled +by the PPD file being used - deskjet.ppd or laserjet.ppd. + +

PPD Files

+ +

PPD files play an important part of all raster printer drivers. Options +defined in the PPD file contain PostScript commands that control the raster +data that is sent to the printer driver. + +

A typical CUPS printer driver will include ColorModel, +InputSlot, PageSize, PageRegion, +and Resolution options. Each option is shown using the +standard PPD format: + +

    +*OpenUI *PageSize/Media Size: PickOne
    +*OrderDependency: 10 AnySetup *PageSize
    +*DefaultPageSize: Letter
    +*PageSize Letter/US Letter: "<<
    +/PageSize [612 792]
    +/ImagingBBox null
    +>> setpagedevice"
    +*End
    +*PageSize Legal/US Legal: "<<
    +/PageSize [612 1008]
    +/ImagingBBox null
    +>> setpagedevice"
    +*End
    +*PageSize A4/A4: "<<
    +/PageSize [595 842]
    +/ImagingBBox null
    +>> setpagedevice"
    +*End
    +*CloseUI: *PageSize
    +
+ +

The OpenUI keyword specifies the new option. The first +name is the option with an asterisk (*) in front of it. The first name is +usually followed by a slash (/) and a human-readable version of the +option name. + +

Every option must have a default value, specified using the +DefaultOption keyword. + +

Each option begins with the option name followed by the computer and +human-readable values. The PostScript commands follow these inside double +quotes. PostScript commands can be provided on a single line: + +

    +*PageSize A4/A4: "<</PageSize[595 842]/ImagingBBox null>> setpagedevice"
    +
+ +

or broken down on separate lines using the End keyword to +terminate them: + +

    +*PageSize A4/A4: "<<
    +/PageSize [595 842]
    +/ImagingBBox null
    +>> setpagedevice"
    +*End
    +
+ +

The choice of the two formats is usually esthetic. However, each line in +a PPD file must not exceed 255 characters, so if your PostScript commands are +long you may need to break them up on separate lines. + +

Reading Raster Data

+ +

As with any filter, your printer driver should handle raster data from +a filename specified on the command-line or from the standard input. The +cupsRasterOpen() function opens +a raster stream for printing: + +

    +int           fd;   /* File descriptor */
    +cups_raster_t *ras; /* Raster stream for printing */
    +
    +
    +/*
    + * Check for valid arguments...
    + */
    +
    +if (argc < 6 || argc > 7)
    +{
    + /*
    +  * We don't have the correct number of arguments; write an error message
    +  * and return.
    +  */
    +
    +  fputs("ERROR: rastertopcl job-id user title copies options [file]\n", stderr);
    +  return (1);
    +}
    +
    +/*
    + * Open the page stream...
    + */
    +
    +if (argc == 7)
    +{
    +  if ((fd = open(argv[6], O_RDONLY)) == -1)
    +  {
    +    perror("ERROR: Unable to open raster file - ");
    +    sleep(1);
    +    return (1);
    +  }
    +}
    +else
    +  fd = 0;
    +
    +ras = cupsRasterOpen(fd, CUPS_RASTER_READ);
    +
+ +

Once you have opened the raster stream you just need to read each +page and print it: + +

    +cups_raster_header_t header;
    +int                  y;
    +unsigned char        data[8192];
    +
    +while (cupsRasterReadHeader(ras, &header))
    +{
    +  ... initialize the printer ...
    +  for (y = header.cupsHeight; y > 0; y ++)
    +  {
    +    cupsRasterReadPixels(ras, data, header.cupsBytesPerLine);
    +    ... send raster line to printer ...
    +  }
    +}
    +
+ +

After you have processed all pages, close the raster stream and +return: + +

    +cupsRasterClose(ras);
    +
    +return (0);
    +
+ +

5 - Writing Backends

+ +

This chapter describes how to write a backend for CUPS. Backends +communicate directly with printers and allow printer drivers and +filters to send data using any type of connection transparently. + +

Overview

+ +

Backends are special filters that communicate with printers directly. +They are treated slightly differently than filters, however, and have some +unique requirements. + +

Security Considerations

+ +

Backends are run as the root user, so special care must be taken to +avoid potential security violations. In particular, remember that a backend +will be able to manipulate disk files, devices, and other resources that +potentially could damage a system or printer. + +

Command-Line Arguments

+ +

Besides the standard filter arguments, backends are also run with no +arguments to get a list of available devices. This discovery process is +described later in this chapter. + +

Copy Generation

+ +

Like filters, backends should send multiple copies of the print file only +if a filename is supplied on the command-line. Otherwise the backend should +assume that the upstream filter has already added the necessary commands or +data to produce the multiple copies. + +

Page Accounting

+ +

Backend filters generally do not do page accounting, however they should +at a minimum produce a single page message for each copy that is produced +when a filename is present on the command-line. This is because the user +selected "raw" printing and no other accounting information is possible. + +

Exclusive Access

+ +

Backends that talk to local character or block devices should open the +device file in exclusive mode (O_EXCL) to cooperate with other +printers defined for the same device. + +

Retries

+ +

All backends must retry connections to the device. This +includes backends that talk to local character or block devices, as the +user may define more than one printer queue pointing at the same +physical device. + +

To prevent excess CPU utilitization, the backend should go to sleep +for an amount of time between retries; the CUPS-supplied backends retry +once every 30 seconds. + +

Dissecting the Serial Port Backend

+ +

The serial port backend provides support for serial printers. Since +it does everything a good backend needs to do, it provides an excellent +example of what to do. + +

Supporting Device Discovery

+ +

As previously noted, backends are special filter programs that talk +to printer devices. Another task a backend must perform is to list the +available devices it supports. The backend lists the available devices +when no additioanl arguments are supplied on the command-line (i.e. +just the command name...) + +

The serial backend lists devices by looking at serial port files in the +/dev directory, by consulting a hardware inventory (IRIX), and +in some cases by trying to open the ports to see if they actually exist. + +

Once it finds a serial port it writes a single line for each port to +the standard error file. Each line looks like this: + +

    +serial serial:/dev/ttyS0?baud=115200 "Unknown" "Serial Port 1"
    +
+ +

The first word "serial" is the device class; this identifies the +class of device which can be used to categorize it in user interfaces. CUPS +currently recognizes the following classes: + +

    + +
  • "file" - a disk file. + +
  • "direct" - a parallel or fixed-rate serial data port, + currently used for Centronics, IEEE-1284, and USB printer + ports. + +
  • "serial" - a variable-rate serial port. + +
  • "network" - a network connection, typically via AppSocket, + HTTP, IPP, LPD, or SMB/CIFS protocols. + +
+ +

After the device class is the device URI, in this case +"serial:/dev/ttyS0?baud=115200". This is the URI that should be used by +the user to select this port. For serial ports, the "baud=115200" +specifies the maximum baud rate supported by the port - the actual +value will vary based on the speed the user selects for the printer. + +

The last two strings are the model and description for the port. The +"Unknown" string means that the printer model is unknown - some devices +are able to provide a make and model such as "HP DeskJet" that allows +users and software to choose an appropriate printer driver more easily. +Both the model and description must be enclosed inside double quotes. + +

Opening the Serial Port

+ +

As noted previously, all backends should open device files in exclusive +mode, and retry as needed until the port is available. The serial port does +this using a do-while loop: + +

    +do
    +{
    +  if ((fd = open(resource, O_WRONLY | O_NOCTTY | O_EXCL)) == -1)
    +  {
    +    if (errno == EBUSY)
    +    {
    +      fputs("INFO: Serial port busy; will retry in 30 seconds...\n", stderr);
    +      sleep(30);
    +    }
    +    else
    +    {
    +      perror("ERROR: Unable to open serial port device file");
    +      return (1);
    +    }
    +  }
    +}
    +while (fd < 0);
    +
+ +

If the port is busy or in use by another process, the backend will +go to sleep for 30 seconds and try again. If another error is detected +a message is sent to the user and the backend aborts the print job +until the problem can be corrected. + +

Writing Data to the Port

+ +

Network and character devices pose an interesting problem when writing +data to the port - they may not be able to write all of the bytes in your +buffer before returning. To work around this problem you must loop until +all bytes have been written: + +

    +while (nbytes > 0)
    +{
    +  if ((wbytes = write(fd, bufptr, nbytes)) < 0)
    +    if (errno == ENOTTY)
    +      wbytes = write(fd, bufptr, nbytes);
    +
    +  if (wbytes < 0)
    +  {
    +    perror("ERROR: Unable to send print file to printer");
    +    break;
    +  }
    +
    +  nbytes -= wbytes;
    +  bufptr += wbytes;
    +}
    +
+ +

The check for the ENOTTY error is needed on some platforms +to clear an error from a previous ioctl() call. + +

Finishing Up

+ +

Once you have sent the print file, return 0 if the file printed +successfully or 1 if it did not. This will allow the scheduler to stop +the print job if there is a device error, preserving the print job for +later printing once the problem has been corrected. + +

A - Software License Agreement

+ + + + +

B - Constants

+ +

This appendix lists all of the constants that are defined by the CUPS +API. + +

CUPS Constants

+ +

Version Number

+ +

The CUPS_VERSION constant is a floating-point number +representing the API version number. The current version number is +1.0100 which represents CUPS version 1.1.0. + +

Printer Capabilities

+ +

The CUPS_PRINTER constants represent capability bits for +printers and classes: + +

    + +
  • CUPS_PRINTER_LOCAL - Is a local printer or class. + +
  • CUPS_PRINTER_REMOTE - Is a remote printer or class. + +
  • CUPS_PRINTER_CLASS - Is a class. + +
  • CUPS_PRINTER_BW - Printer prints in black and white. + +
  • CUPS_PRINTER_COLOR - Printer prints in color. + +
  • CUPS_PRINTER_DUPLEX - Printer can print double-sided. + +
  • CUPS_PRINTER_STAPLE - Printer can staple output. + +
  • CUPS_PRINTER_COPIES - Printer can produce multiple + copies on its own. + +
  • CUPS_PRINTER_COLLATE - Printer can collate copies. + +
  • CUPS_PRINTER_PUNCH - Printer can punch holes in output. + +
  • CUPS_PRINTER_COVER - Printer can put covers on output. + +
  • CUPS_PRINTER_BIND - Printer can bind output. + +
  • CUPS_PRINTER_SORT - Printer can sort output. + +
  • CUPS_PRINTER_SMALL - Printer can print on media up + to 9x14 inches. + +
  • CUPS_PRINTER_MEDIUM - Printer can print on media + from 9x14 to 18x24 inches. + +
  • CUPS_PRINTER_LARGE - Printer can print on media + larger than 18x24 inches. + +
  • CUPS_PRINTER_VARIABLE - Printer can print on + variable or custom media sizes. + +
  • CUPS_PRINTER_IMPLICIT - Is an implicit class. + +
  • CUPS_PRINTER_OPTIONS - All of the printer capability + and option bits. + +
+ +

Encodings

+ +

CUPS defines the following character set encoding constants: + +

    + +
  • CUPS_US_ASCII - US ASCII character set. + +
  • CUPS_UTF_8 - UTF-8 encoding of Unicode. + +
  • CUPS_ISO8859_1 - ISO-8859-1 character set. + +
  • CUPS_ISO8859_2 - ISO-8859-2 character set. + +
  • CUPS_ISO8859_3 - ISO-8859-3 character set. + +
  • CUPS_ISO8859_4 - ISO-8859-4 character set. + +
  • CUPS_ISO8859_5 - ISO-8859-5 character set. + +
  • CUPS_ISO8859_6 - ISO-8859-6 character set. + +
  • CUPS_ISO8859_7 - ISO-8859-7 character set. + +
  • CUPS_ISO8859_8 - ISO-8859-8 character set. + +
  • CUPS_ISO8859_9 - ISO-8859-9 character set. + +
  • CUPS_ISO8859_10 - ISO-8859-10 character set. + +
  • CUPS_ISO8859_13 - ISO-8859-13 character set. + +
  • CUPS_ISO8859_14 - ISO-8859-14 character set. + +
  • CUPS_ISO8859_15 - ISO-8859-15 character set. + +
  • CUPS_WINDOWS_874 - Windows code page 874. + +
  • CUPS_WINDOWS_1250 - Windows code page 1250. + +
  • CUPS_WINDOWS_1251 - Windows code page 1251. + +
  • CUPS_WINDOWS_1252 - Windows code page 1252. + +
  • CUPS_WINDOWS_1253 - Windows code page 1253. + +
  • CUPS_WINDOWS_1254 - Windows code page 1254. + +
  • CUPS_WINDOWS_1255 - Windows code page 1255. + +
  • CUPS_WINDOWS_1256 - Windows code page 1256. + +
  • CUPS_WINDOWS_1257 - Windows code page 1257. + +
  • CUPS_WINDOWS_1258 - Windows code page 1258. + +
+ +

HTTP Constants

+ +

Limits

+ +

The following constants define the limits for strings: + +

    + +
  • HTTP_MAX_BUFFER - Size of socket buffer. + +
  • HTTP_MAX_HOST - Maximum length of hostname. + +
  • HTTP_MAX_URI - Maximum length of URI. + +
  • HTTP_MAX_VALUE - Maximum length of field values. + +
+ +

Status Codes

+ +

The following status codes can be returned by httpUpdate(): + +

    + +
  • HTTP_ERROR - A network error occurred + +
  • HTTP_CONTINUE - Continue response from HTTP proxy + +
  • HTTP_OK - OPTIONS/GET/HEAD/POST/TRACE command was successful + +
  • HTTP_CREATED - PUT command was successful + +
  • HTTP_ACCEPTED - DELETE command was successful + +
  • HTTP_NOT_AUTHORITATIVE - Information isn't authoritative + +
  • HTTP_NO_CONTENT - Successful command + +
  • HTTP_RESET_CONTENT - Content was reset/recreated + +
  • HTTP_PARTIAL_CONTENT - Only a partial file was recieved/sent + +
  • HTTP_MULTIPLE_CHOICES - Multiple files match request + +
  • HTTP_MOVED_PERMANENTLY - Document has moved permanently + +
  • HTTP_MOVED_TEMPORARILY - Document has moved temporarily + +
  • HTTP_SEE_OTHER - See this other link... + +
  • HTTP_NOT_MODIFIED - File not modified + +
  • HTTP_USE_PROXY - Must use a proxy to access this URI + +
  • HTTP_BAD_REQUEST - Bad request + +
  • HTTP_UNAUTHORIZED - Unauthorized to access host + +
  • HTTP_PAYMENT_REQUIRED - Payment required + +
  • HTTP_FORBIDDEN - Forbidden to access this URI + +
  • HTTP_NOT_FOUND - URI was not found + +
  • HTTP_METHOD_NOT_ALLOWED - Method is not allowed + +
  • HTTP_NOT_ACCEPTABLE - Not Acceptable + +
  • HTTP_PROXY_AUTHENTICATION - Proxy Authentication is Required + +
  • HTTP_REQUEST_TIMEOUT - Request timed out + +
  • HTTP_CONFLICT - Request is self-conflicting + +
  • HTTP_GONE - Server has gone away + +
  • HTTP_LENGTH_REQUIRED - A content length or encoding is required + +
  • HTTP_PRECONDITION - Precondition failed + +
  • HTTP_REQUEST_TOO_LARGE - Request entity too large + +
  • HTTP_URI_TOO_LONG - URI too long + +
  • HTTP_UNSUPPORTED_MEDIATYPE - The requested media type is unsupported + +
  • HTTP_SERVER_ERROR - Internal server error + +
  • HTTP_NOT_IMPLEMENTED - Feature not implemented + +
  • HTTP_BAD_GATEWAY - Bad gateway + +
  • HTTP_SERVICE_UNAVAILABLE - Service is unavailable + +
  • HTTP_GATEWAY_TIMEOUT - Gateway connection timed out + +
  • HTTP_NOT_SUPPORTED - HTTP version not supported + +
+ +

Fields

+ +

The following fields are indices for each of the standard HTTP fields in +HTTP 1/1: + +

    + +
  • HTTP_FIELD_ACCEPT_LANGUAGE - Accept-Language + +
  • HTTP_FIELD_ACCEPT_RANGES - Accept-Ranges + +
  • HTTP_FIELD_AUTHORIZATION - Authorization + +
  • HTTP_FIELD_CONNECTION - Connection + +
  • HTTP_FIELD_CONTENT_ENCODING - Content-Encoding + +
  • HTTP_FIELD_CONTENT_LANGUAGE - Content-Language + +
  • HTTP_FIELD_CONTENT_LENGTH - Content-Length + +
  • HTTP_FIELD_CONTENT_LOCATION - Content-Location + +
  • HTTP_FIELD_CONTENT_MD5 - Content-MD5 + +
  • HTTP_FIELD_CONTENT_RANGE - Content-Range + +
  • HTTP_FIELD_CONTENT_TYPE - Content-Type + +
  • HTTP_FIELD_CONTENT_VERSION - Content-Version + +
  • HTTP_FIELD_DATE - Date + +
  • HTTP_FIELD_HOST - Host + +
  • HTTP_FIELD_IF_MODIFIED_SINCE - If-Modified-Since + +
  • HTTP_FIELD_IF_UNMODIFIED_SINCE - If-Unmodified-Since + +
  • HTTP_FIELD_KEEP_ALIVE - Keep-Alive + +
  • HTTP_FIELD_LAST_MODIFIED - Last-Modified + +
  • HTTP_FIELD_LINK - Link + +
  • HTTP_FIELD_LOCATION - Location + +
  • HTTP_FIELD_RANGE - Range + +
  • HTTP_FIELD_REFERER - Referer + +
  • HTTP_FIELD_RETRY_AFTER - Retry-After + +
  • HTTP_FIELD_TRANSFER_ENCODING - Transfer-Encoding + +
  • HTTP_FIELD_UPGRADE - Upgrade + +
  • HTTP_FIELD_USER_AGENT - User-Agent + +
  • HTTP_FIELD_WWW_AUTHENTICATE - WWW-Authenticate + + +
+ +

IPP Constants

+ +

Limits

+ +

The following constants define array limits for IPP data: + +

    + +
  • IPP_MAX_NAME - Maximum length of an attribute name + +
  • IPP_MAX_VALUES - Maximum number of set-of values + that can be read in a request. + +
+ +

Tags

+ +
    + +
  • IPP_TAG_ZERO - Wildcard tag value for searches; also + used to separate groups of attributes + +
  • IPP_TAG_OPERATION - Tag for values of type operation + +
  • IPP_TAG_JOB - Tag for values of type job + +
  • IPP_TAG_END - Tag for values of type end + +
  • IPP_TAG_PRINTER - Tag for values of type printer + +
  • IPP_TAG_UNSUPPORTED_GROUP - Tag for values of type unsupported_group + +
  • IPP_TAG_UNSUPPORTED_VALUE - Tag for values of type unsupported_value + +
  • IPP_TAG_DEFAULT - Tag for values of type default + +
  • IPP_TAG_UNKNOWN - Tag for values of type unknown + +
  • IPP_TAG_NOVALUE - Tag for values of type novalue + +
  • IPP_TAG_NOTSETTABLE - Tag for values of type notsettable + +
  • IPP_TAG_DELETEATTR - Tag for values of type deleteattr + +
  • IPP_TAG_ANYVALUE - Tag for values of type anyvalue + +
  • IPP_TAG_INTEGER - Tag for values of type integer + +
  • IPP_TAG_BOOLEAN - Tag for values of type boolean + +
  • IPP_TAG_ENUM - Tag for values of type enum + +
  • IPP_TAG_STRING - Tag for values of type string + +
  • IPP_TAG_DATE - Tag for values of type date + +
  • IPP_TAG_RESOLUTION - Tag for values of type resolution + +
  • IPP_TAG_RANGE - Tag for values of type range + +
  • IPP_TAG_COLLECTION - Tag for values of type collection + +
  • IPP_TAG_TEXTLANG - Tag for values of type textlang + +
  • IPP_TAG_NAMELANG - Tag for values of type namelang + +
  • IPP_TAG_TEXT - Tag for values of type text + +
  • IPP_TAG_NAME - Tag for values of type name + +
  • IPP_TAG_KEYWORD - Tag for values of type keyword + +
  • IPP_TAG_URI - Tag for values of type uri + +
  • IPP_TAG_URISCHEME - Tag for values of type urischeme + +
  • IPP_TAG_CHARSET - Tag for values of type charset + +
  • IPP_TAG_LANGUAGE - Tag for values of type language + +
  • IPP_TAG_MIMETYPE - Tag for values of type mimetype + +
+ +

Resolution Units

+ +

The IPP_RES_PER_INCH and IPP_RES_PER_CM constants +specify dots per inch and dots per centimeter, respectively. + +

Finishings

+ +

The finishing values specify special finishing operations to be +performed on the job. + +

    + +
  • IPP_FINISH_NONE - Do no finishing + +
  • IPP_FINISH_STAPLE - Staple the job + +
  • IPP_FINISH_PUNCH - Punch the job + +
  • IPP_FINISH_COVER - Cover the job + +
  • IPP_FINISH_BIND - Bind the job + +
+ +

Orientations

+ +

The orientation values specify the orientation of the job. + +

    + +
  • IPP_PORTRAIT - No rotation + +
  • IPP_LANDSCAPE - 90 degrees counter-clockwise + +
  • IPP_REVERSE_LANDSCAPE - 90 degrees clockwise + +
  • IPP_REVERSE_PORTRAIT - 180 degrees + +
+ +

Qualities

+ +

The quality values specify the desired quality of the print. +

    + +
  • IPP_QUALITY_DRAFT - Draft quality + +
  • IPP_QUALITY_NORMAL - Normal quality + +
  • IPP_QUALITY_HIGH - High quality + +
+ +

Job States

+ +

The job state values are used to represent the current job state. + +

    + +
  • IPP_JOB_PENDING - Job is pending + +
  • IPP_JOB_HELD - Job is held + +
  • IPP_JOB_PROCESSING - Job is processing + +
  • IPP_JOB_STOPPED - Job is stopped + +
  • IPP_JOB_CANCELLED - Job is cancelled + +
  • IPP_JOB_ABORTED - Job is aborted + +
  • IPP_JOB_COMPLETED - Job is completed + +
+ +

Printer States

+ +

The printer state values are used to represent the current printer +state. + +

    + +
  • IPP_PRINTER_IDLE - Printer is idle + +
  • IPP_PRINTER_PROCESSING - Printer is processing + +
  • IPP_PRINTER_STOPPED - Printer is stopped + +
+ +

Operations

+ +

The operation values represent the available IPP operations. + +

    + +
  • IPP_PRINT_JOB - Print a file + +
  • IPP_PRINT_URI - Print a URI + +
  • IPP_VALIDATE_JOB - Validate job attributes + +
  • IPP_CREATE_JOB - Create a new job + +
  • IPP_SEND_DOCUMENT - Send a document to a job + +
  • IPP_SEND_URI - Send a URI to a job + +
  • IPP_CANCEL_JOB - Cancel a job + +
  • IPP_GET_JOB_ATTRIBUTES - Get job attributes + +
  • IPP_GET_JOBS - Get a list of all jobs + +
  • IPP_GET_PRINTER_ATTRIBUTES - Get printer attributes + +
  • IPP_HOLD_JOB - Hold a pending job + +
  • IPP_RELEASE_JOB - Release a held job + +
  • IPP_RESTART_JOB - Restart a completed job + +
  • IPP_PAUSE_PRINTER - Pause a printer + +
  • IPP_RESUME_PRINTER - Restart a paused printer + +
  • IPP_PURGE_JOBS - Purge jobs from the queue + +
  • IPP_SET_PRINTER_ATTRIBUTES - Set printer attributes + +
  • IPP_SET_JOB_ATTRIBUTES - Set job attributes + +
  • IPP_GET_PRINTER_SUPPORTED_VALUES - Get printer supported values + +
  • CUPS_GET_DEFAULT - Get the default destination + +
  • CUPS_GET_PRINTERS - Get a list of all printers + +
  • CUPS_ADD_PRINTER - Add or modify a printer + +
  • CUPS_DELETE_PRINTER - Delete a printer + +
  • CUPS_GET_CLASSES - Get a list of all classes + +
  • CUPS_ADD_CLASS - Add or modify a class + +
  • CUPS_DELETE_CLASS - Delete a class + +
  • CUPS_ACCEPT_JOBS - Accept jobs on a printer or class + +
  • CUPS_REJECT_JOBS - Reject jobs on a printer or class + +
  • CUPS_SET_DEFAULT - Set the default destination + +
  • CUPS_GET_DEVICES - Get a list of all devices + +
  • CUPS_GET_PPDS - Get a list of all PPDs + +
  • CUPS_MOVE_JOB - Move a job to a new destination + +
+ +

Status Codes

+ +

Status codes are returned by all IPP requests. + +

    + +
  • IPP_OK - Request completed with no errors + +
  • IPP_OK_SUBST - Request completed but some attribute + values were substituted + +
  • IPP_OK_CONFLICT - Request completed but some attributes + conflicted + +
  • IPP_BAD_REQUEST - The request was bad + +
  • IPP_FORBIDDEN - You don't have access to the resource + +
  • IPP_NOT_AUTHENTICATED - You are not authenticated for + the resource + +
  • IPP_NOT_AUTHORIZED - You not authorized to access + the resource + +
  • IPP_NOT_POSSIBLE - The requested operation cannot be + completed + +
  • IPP_TIMEOUT - A timeout occurred + +
  • IPP_NOT_FOUND - The resource was not found + +
  • IPP_GONE - The resource has gone away + +
  • IPP_REQUEST_ENTITY - The request was too large + +
  • IPP_REQUEST_VALUE - The request contained a value + that was unknown to the server + +
  • IPP_DOCUMENT_FORMAT - The document format is not + supported by the server + +
  • IPP_ATTRIBUTES - Required attributes are missing + +
  • IPP_URI_SCHEME - The URI scheme is not supported + +
  • IPP_CHARSET - The charset is not supported + +
  • IPP_CONFLICT - One or more attributes conflict + +
  • IPP_COMPRESSION_NOT_SUPPORTED - The specified + compression is not supported + +
  • IPP_COMPRESSION_ERROR - The compressed data + contained an error + +
  • IPP_DOCUMENT_FORMAT_ERROR - The document data + contained an error in it + +
  • IPP_DOCUMENT_ACCESS_ERROR - The remote document + could not be accessed + +
  • IPP_INTERNAL_ERROR - The server encountered an + internal error + +
  • IPP_OPERATION_NOT_SUPPORTED - The requested operation + is not supported + +
  • IPP_SERVICE_UNAVAILABLE - The requested service + is unavailable + +
  • IPP_VERSION_NOT_SUPPORTED - The IPP request + version is not supported + +
  • IPP_DEVICE_ERROR - The output device encountered + an error + +
  • IPP_TEMPORARY_ERROR - A temporary error occurred + +
  • IPP_NOT_ACCEPTING - The destination is not accepting + jobs + +
  • IPP_PRINTER_BUSY - The destination is busy + +
  • IPP_ERROR_JOB_CANCELLED - The requested job has been + cancelled + +
  • IPP_MULTIPLE_JOBS_NOT_SUPPORTED - The server + does not support multiple jobs + +
+ +

PPD Constants

+ +

PPD Format Version

+ +

The PPD_VERSION constant defines a floating point number +representing the newest format version that is supported by CUPS, currently +4.3. + +

PPD User-Interface Types

+ +

Each printer option has a type associated with it: + +

    + +
  • PPD_UI_BOOLEAN - The user can turn this option on or off + +
  • PPD_UI_PICKONE - The user can choose one option value + to use. + +
  • PPD_UI_PICKMANY - The user can choose zero or more + option values. + +
+ +

PPD Sections

+ +

Some options must be output before others, or in different sections of +the output document. The ppd_section_t enumeration defines +which section the option must be output in: + +

    + +
  • PPD_ORDER_ANY - The option can be output in any of + the document, page, or prolog sections of the document + +
  • PPD_ORDER_DOCUMENT - The option must be output in + the DocumentSetup section of the document + +
  • PPD_ORDER_EXIT - The option must be output before + the document + +
  • PPD_ORDER_JCL - The option must be output in the + job control section of the document + +
  • PPD_ORDER_PAGE - The option must be output in the + PageSetup section of the document + +
  • PPD_ORDER_PROLOG - The option must be output in the + Prolog section of the document + +
+ +

PPD Colorspaces

+ +

Each printer has a default colorspace: + +

    + +
  • PPD_CS_CMYK - The printer uses CMYK colors by default + +
  • PPD_CS_CMY - The printer uses CMY colors by default + +
  • PPD_CS_GRAY - The printer uses grayscale by default + +
  • PPD_CS_RGB - The printer uses RGB colors by default + +
  • PPD_CS_RGBK - The printer uses RGBK colors by default + +
  • PPD_CS_N - The printer uses a DeviceN colorspace + by default + +
+ +

Raster Constants

+ +

Raster Sync Words

+ +

The CUPS_RASTER_SYNC and CUPS_RASTER_REVSYNC +constants define the standard sync words at the beginning of each CUPS +raster file. + +

Raster Stream Modes

+ +

The CUPS_RASTER_READ and CUPS_RASTER_WRITE +constants are used with the +cupsRasterOpen() function to +specify a stream for reading or writing. + +

Raster Boolean Constants

+ +

The CUPS_FALSE and CUPS_TRUE constants +represent boolean values in the page header. + +

Raster Jog Values

+ +

The cups_jog_t enumeration defines constants for the +Jog page device dictionary variable: + +

    + +
  • CUPS_JOG_NONE - Do no jogging + +
  • CUPS_JOG_FILE - Jog pages after each file + +
  • CUPS_JOG_JOB - Jog pages after each job + +
  • CUPS_JOG_SET - Jog pages after each set of jobs + +
+ +

Raster Orientation Values

+ +

The cups_orient_t enumeration defines constants for the +Orientation page device dictionary variable: + +

    + +
  • CUPS_ORIENT_0 - Portrait orientation + +
  • CUPS_ORIENT_90 - Landscape orientation + +
  • CUPS_ORIENT_180 - Reverse-portrait orientation + +
  • CUPS_ORIENT_270 - Reverse-landscape orientation + +
+ +

Raster CutMedia Values

+ +

The cups_cut_t enumeration defines constants for the +CutMedia page device dictionary variable: + +

    + +
  • CUPS_CUT_NONE - Do no jogging + +
  • CUPS_CUT_FILE - Cut pages after each file + +
  • CUPS_CUT_JOB - Cut pages after each job + +
  • CUPS_CUT_SET - Cut pages after each set of jobs + +
  • CUPS_CUT_PAGE - Cut each page + +
+ +

Raster AdvanceMedia Values

+ +

The cups_advance_t enumeration defines constants for the +AdvanceMedia page device dictionary variable: + +

    + +
  • CUPS_ADVANCE_NONE - Do no jogging + +
  • CUPS_ADVANCE_FILE - Advance media after each file + +
  • CUPS_ADVANCE_JOB - Advance media after each job + +
  • CUPS_ADVANCE_SET - Advance media after each set of jobs + +
  • CUPS_ADVANCE_PAGE - Advance media for each page + +
+ +

Raster LeadingEdge Values

+ +

The cups_edge_t enumeration defines constants for the +LeadingEdge page device dictionary variable: + +

    + +
  • CUPS_EDGE_TOP - The top of the media is the leading + edge + +
  • CUPS_EDGE_RIGHT - The right of the media is the leading + edge + +
  • CUPS_EDGE_BOTTOM - The bottom of the media is the + leading edge + +
  • CUPS_EDGE_LEFT - The left of the media is the leading + edge + +
+ +

Raster Color Order Values

+ +

The cups_order_t enumeration defines the possible color +value orderings: + +

    + +
  • CUPS_ORDER_CHUNKED - CMYK CMYK CMYK + +
  • CUPS_ORDER_BANDED - CCC MMM YYY KKK + +
  • CUPS_ORDER_PLANAR - CCC ... MMM ... YYY ... KKK ... + +
+ +

Raster Colorspace Values

+ +

The cups_cspace_t enumeration defines the possible colorspaces: + +

    + +
  • CUPS_CSPACE_W - White (luminance) + +
  • CUPS_CSPACE_RGB - Red, green, blue + +
  • CUPS_CSPACE_RGBA - Red, green, blue, alpha + +
  • CUPS_CSPACE_K - Black + +
  • CUPS_CSPACE_CMY - Cyan, magenta, yellow + +
  • CUPS_CSPACE_YMC - Yellow, magenta, cyan + +
  • CUPS_CSPACE_CMYK - Cyan, magenta, yellow, black + +
  • CUPS_CSPACE_YMCK - Yellow, magenta, cyan, black + +
  • CUPS_CSPACE_KCMY - Black, cyan, magenta, yellow + +
  • CUPS_CSPACE_KCMYcm - Black, cyan, magenta, yellow, + light cyan, light magenta + +
  • CUPS_CSPACE_GMCK - Metallic yellow (gold), metallic magenta, + metallic cyan, black + +
  • CUPS_CSPACE_GMCS - Metallic yellow (gold), metallic magenta, + metallic cyan, metallic grey (silver) + +
  • CUPS_CSPACE_WHITE - White pigment (black as white pigment) + +
  • CUPS_CSPACE_GOLD - Gold foil (black as gold foil) + +
  • CUPS_CSPACE_SILVER - Silver foil (black as silver foil) + +
+ +

C - Structures

+ +

This appendix describes all of the structures that are defined by the CUPS +API. + +

Raster Structures

+ +

Raster Page Header

+ +

The raster page header consists of the PostScript page device dictionary +for the page: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
MemberTypeDescription
MediaClasschar[64]The media class name
MediaColorchar[64]The media color name
MediaTypechar[64]The media type name
OutputTypechar[64]The output type name
AdvanceDistanceunsignedThe distance to advance the media in points
AdvanceMediacups_adv_tWhen to advance the media
Collatecups_bool_tWhether or not to produce collated copies
CutMediacups_cut_tWhen to cut the media
Duplexcups_bool_tWhether or not to print on both sides of the paper
HWResolutionunsigned[2]The resolution of the page image in pixels per inch; the + HWResolution[0] represents the horizontal resolution and + HWResolution[1] represents the vertical resolution
ImagingBoundingBoxunsigned[4]The bounding box for the page in points; the elements + represent the left, bottom, right, and top coordinates of the + imaged area (if 0 then the whole page is imaged)
InsertSheetcups_bool_tWhether or not to insert a sheet before this page
Jogcups_jog_tWhen to jog copies of the page
LeadingEdgecups_edge_tThe leading edge of the page
Marginsunsigned[2]The lower-lefthand margin of the page in points
ManualFeedcups_bool_tWhether or not to manually feed the page
MediaPositionunsignedThe input slot number to use
MediaWeightunsignedThe weight of the output media in grams/m2
MirrorPrintcups_bool_tWhether or not to mirror the print
NegativePrintcups_bool_tWhether or not to invert the print
NumCopiesunsignedThe number of copies to produce
Orientationcups_orient_tThe orientation of the page image
OutputFaceUpcups_bool_tWhether or not to output the page face up
PageSizeunsigned[2]The width and height of the page in points
Separationscups_bool_tWhether or not to output separations
TraySwitchcups_bool_tWhether or not to automatically switch trays for the requested + media size/type
Tumblecups_bool_tWhether or not to rotate the back side of the page
cupsWidthunsignedThe width of the page image in pixels
cupsHeightunsignedThe height of the page image in pixels
cupsMediaTypeunsignedThe device-specific media type code
cupsBitsPerColorunsignedThe number of bits per color
cupsBitsPerPixelunsignedThe number of bits per pixel
cupsBytesPerLineunsignedThe number of bytes per line of image data
cupsColorOrdercups_order_tThe order of color values
cupsColorSpacecups_cspace_tThe type of color values
cupsCompressionunsignedThe device-specific compression code
cupsRowCountunsignedThe device-specific row count
cupsRowFeedunsignedThe device-specific row feed
cupsRowStepunsignedThe device-specific row step
+ +

D - Functions

+ +

This appendix provides a reference for all of the CUPS API functions. + +

cupsAddOption()

+ +

Usage

+ +
+int
+cupsAddOption(const char *name,
+              const char *value,
+              int num_options,
+	      cups_option_t **options);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
nameThe name of the option.
valueThe value of the option.
num_optionsNumber of options currently in the array.
optionsPointer to the options array.
+ +

Returns

+ +

The new number of options. + +

Description

+ +

cupsAddOption() adds an option to the specified array. + +

Example

+ +
+#include <cups.h>
+
+...
+
+/* Declare the options array */
+int           num_options;
+cups_option_t *options;
+
+/* Initialize the options array */
+num_options = 0;
+options     = (cups_option_t *)0;
+
+/* Add options using cupsAddOption() */
+num_options = cupsAddOption("media", "letter", num_options, &options);
+num_options = cupsAddOption("resolution", "300dpi", num_options, &options);
+
+ +

See Also

+ +cupsFreeOptions(), +cupsGetOption(), +cupsParseOptions() + +

cupsCancelJob()

+ +

Usage

+ +
+int
+cupsCancelJob(const char *dest,
+              int job);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
destPrinter or class name
jobJob ID
+ +

Returns

+ +

1 on success, 0 on failure. On failure the error can be found by calling +cupsLastError(). + +

Description

+ +

cupsCancelJob() cancels the specifies job. + +

Example

+ +
+#include <cups.h>
+
+cupsCancelJob("LaserJet", 1);
+
+ +

See Also

+ +

+cupsLastError(), +cupsPrintFile() + +

cupsDoFileRequest()

+ +

Usage

+ +
+ipp_t *
+cupsDoFileRequest(http_t *http,
+                  ipp_t *request,
+                  const char *resource,
+		  const char *filename);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
httpHTTP connection to server.
requestIPP request data.
resourceHTTP resource name for POST.
filenameFile to send with POST request (NULL pointer if none.)
+ +

Returns

+ +

IPP response data or NULL if the request fails. On failure +the error can be found by calling +cupsLastError(). + +

Description

+ +

cupsDoFileRequest() does a HTTP POST request and provides the +IPP request and optionally the contents of a file to the IPP server. It also +handles resubmitting the request and performing password authentication as +needed. + +

Example

+ +
+#include <cups.h>
+
+http_t      *http;
+cups_lang_t *language;
+ipp_t       *request;
+ipp_t       *response;
+
+...
+
+/* Get the default language */
+language = cupsLangDefault();
+
+/* Create a new IPP request */
+request  = ippNew();
+
+request->request.op.operation_id = IPP_PRINT_FILE;
+request->request.op.request_id   = 1;
+
+/* Add required attributes */
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+             "attributes-charset", NULL, cupsLangEncoding(language));
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+             "attributes-natural-language", NULL,
+             language != NULL ? language->language : "C");
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+             NULL, "ipp://hostname/resource");
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name",
+             NULL, cupsUser());
+
+/* Do the request... */
+response = cupsDoFileRequest(http, request, "/resource", "filename.txt");
+
+ +

See Also

+ +

+cupsLangDefault(), +cupsLangEncoding(), +cupsUser(), +httpConnect(), +ippAddString(), +ippNew() + +

cupsDoRequest()

+ +

Usage

+ +
+ipp_t *
+cupsDoRequest(http_t *http,
+              ipp_t *request,
+              const char *resource);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
httpHTTP connection to server.
requestIPP request data.
resourceHTTP resource name for POST.
+ +

Returns

+ +

IPP response data or NULL if the request fails. On failure +the error can be found by calling +cupsLastError(). + +

Description

+ +

cupsDoRequest() does a HTTP POST request and provides +the IPP request to the IPP server. It also handles resubmitting the +request and performing password authentication as needed. + +

Example

+ +
+#include <cups.h>
+
+http_t      *http;
+cups_lang_t *language;
+ipp_t       *request;
+ipp_t       *response;
+
+...
+
+/* Get the default language */
+language = cupsLangDefault();
+
+/* Create a new IPP request */
+request  = ippNew();
+
+request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+request->request.op.request_id   = 1;
+
+/* Add required attributes */
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+             "attributes-charset", NULL, cupsLangEncoding(language));
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+             "attributes-natural-language", NULL,
+             language != NULL ? language->language : "C");
+
+ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+             NULL, "ipp://hostname/resource");
+
+/* Do the request... */
+response = cupsDoRequest(http, request, "/resource");
+
+ +

See Also

+ +

+cupsLangDefault(), +cupsLangEncoding(), +cupsUser(), +httpConnect(), +ippAddString(), +ippNew() + +

cupsFreeOptions()

+ +

Usage

+ +
+void
+cupsFreeOptions(int num_options,
+                cups_option_t *options);
+
+

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
num_optionsNumber of options in array.
optionsPointer to options array.
+ +

Description

+ +

cupsFreeOptions() frees all memory associated with the +option array specified. + +

Example

+ +
+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+
+...
+
+cupsFreeOptions(num_options, options);
+
+ +

See Also

+ +

+cupsAddOption(), +cupsGetOption(), +cupsMarkOptions(), +cupsParseOptions() + +

cupsGetClasses()

+ +

Usage

+ +
+int
+cupsGetClasses(char ***classes);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
classesPointer to character pointer array.
+ +

Returns

+ +

The number of printer classes available. + +

Description

+ +

cupsGetClasses() gets a list of the available printer classes. +The returned array should be freed using the free() when it is +no longer needed. + +

Example

+ +
+#include <cups/cups.h>
+
+int  i;
+int  num_classes;
+char **classes;
+
+...
+
+num_classes = cupsGetClasses(&classes);
+
+...
+
+if (num_classes > 0)
+{
+  for (i = 0; i < num_classes; i ++)
+    free(classes[i]);
+
+  free(classes);
+}
+
+ +

See Also

+ +

+cupsGetDefault(), +cupsGetPrinters() + +

cupsGetDefault()

+ +

Usage

+ +
+const char *
+cupsGetDefault(void);
+
+ +

Returns

+ +

A pointer to the default destination. + +

Description

+ +

cupsGetDefault() gets the default destination printer or class. +The default destination is stored in a static string and will be overwritten +(usually with the same value) after each call. + +

Example

+ +
+#include <cups/cups.h>
+
+printf("The default destination is %s\n", cupsGetDefault());
+
+ +

See Also

+ +

+cupsGetClasses(), +cupsGetPrinters() + +

cupsGetOption()

+ +

Usage

+ +
+const char *
+cupsGetOption(const char *name,
+              int num_options,
+              cups_option_t *options);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
nameThe name of the option.
num_optionsThe number of options in the array.
optionsThe options array.
+ +

Returns

+ +

A pointer to the option values or NULL if the option is +not defined. + +

Description

+ +

cupsGetOption() returns the first occurrence of the +named option. If the option is not included in the options array then a +NULL pointer is returned. + +

+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+const char    *media;
+
+...
+
+media = cupsGetOption("media", num_options, options);
+
+ +

See Also

+ +

+cupsAddOption(), +cupsFreeOptions(), +cupsMarkOptions(), +cupsParseOptions() + +

cupsGetPassword()

+ +

Usage

+ +
+const char *
+cupsGetPassword(const char *prompt);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
promptThe prompt to display to the user.
+ +

Returns

+ +

A pointer to the password that was entered or NULL if no +password was entered. + +

Description

+ +

cupsGetPassword() displays the prompt string and asks the user +for a password. The password text is not echoed to the user. + +

Example

+ +
+#include <cups/cups.h>
+
+char *password;
+
+...
+
+password = cupsGetPassword("Please enter a password:");
+
+ +

See Also

+ +

+cupsServer(), +cupsUser() + +

cupsGetPPD()

+ +

Usage

+ +
+const char *
+cupsGetPPD(const char *printer);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
printerThe name of the printer.
+ +

Returns

+ +

The name of a temporary file containing the PPD file or NULL +if the printer cannot be located or does not have a PPD file. + +

Description

+ +

cupsGetPPD() gets a copy of the PPD file for the named printer. +The printer name can be of the form "printer" or "printer@hostname". + +

You should remove (unlink) the PPD file after you are done using it. The +filename is stored in a static buffer and will be overwritten with each call +to cupsGetPPD(). + +

Example

+ +
+#include <cups/cups.h>
+
+char *ppd;
+
+...
+
+ppd = cupsGetPPD("printer@hostname");
+
+...
+
+unlink(ppd);
+
+ +

cupsGetPrinters()

+ +

Usage

+ +
+int
+cupsGetPrinters(char ***printers);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
printersPointer to character pointer array.
+ +

Returns

+ +

The number of printer printers available. + +

Description

+ +

cupsGetPrinters() gets a list of the available printers. +The returned array should be freed using the free() when it is +no longer needed. + +

Example

+ +
+#include <cups/cups.h>
+
+int  i;
+int  num_printers;
+char **printers;
+
+...
+
+num_printers = cupsGetPrinters(&printers);
+
+...
+
+if (num_printers > 0)
+{
+  for (i = 0; i < num_printers; i ++)
+    free(printers[i]);
+
+  free(printers);
+}
+
+ +

See Also

+ +

+cupsGetClasses(), +cupsGetDefault() + +

cupsLangDefault()

+ +

Usage

+ +
+const char *
+cupsLangDefault(void);
+
+ +

Returns

+ +

A pointer to the default language structure. + +

Description

+ +

cupsLangDefault() returns a language structure for the default +language. The default language is defined by the LANG environment +variable. If the specified language cannot be located then the POSIX (English) +locale is used. + +

Call cupsLangFree() to free any memory associated with the +language structure when you are done. + +

Example

+ +
+#include <cups/language.h>
+
+cups_lang_t *language;
+...
+
+language = cupsLangDefault();
+
+...
+
+cupsLangFree(language);
+
+ +

See Also

+ +

+cupsLangEncoding(), +cupsLangFlush(), +cupsLangFree(), +cupsLangGet(), +cupsLangString() + +

cupsLangEncoding()

+ +

Usage

+ +
+char *
+cupsLangEncoding(cups_lang_t *language);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
languageThe language structure.
+ +

Returns

+ +

A pointer to the encoding string. + +

Description

+ +

cupsLangEncoding() returns the language encoding used for the +specified language, e.g. "iso-8859-1", "utf-8", etc. + +

Example

+ +
+#include <cups/language.h>
+
+cups_lang_t *language;
+char        *encoding;
+...
+
+language = cupsLangDefault();
+encoding = cupsLangEncoding(language);
+...
+
+cupsLangFree(language);
+
+ +

See Also

+ +

+cupsLangDefault(), +cupsLangFlush(), +cupsLangFree(), +cupsLangGet(), +cupsLangString() + +

cupsLangFlush()

+ +

Usage

+ +
+void
+cupsLangFlush(void);
+
+ +

Description

+ +

cupsLangFlush() frees all language structures that have been +allocated. + +

Example

+ +
+#include <cups/language.h>
+
+...
+
+cupsLangFlush();
+
+ +

See Also

+ +

+cupsLangDefault(), +cupsLangEncoding(), +cupsLangFree(), +cupsLangGet(), +cupsLangString() + +

cupsLangFree()

+ +

Usage

+ +
+void
+cupsLangFree(cups_lang_t *language);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
languageThe language structure to free.
+ +

Description

+ +

cupsLangFree() frees the specified language structure. + +

Example

+ +
+#include <cups/language.h>
+
+cups_lang_t *language;
+...
+
+cupsLangFree(language);
+
+ +

See Also

+ +

+cupsLangDefault(), +cupsLangEncoding(), +cupsLangFlush(), +cupsLangGet(), +cupsLangString() + +

cupsLangGet()

+ +

Usage

+ +
+cups_lang_t *
+cupsLangGet(const char *name);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
nameThe name of the locale.
+ +

Returns

+ +

A pointer to a language structure. + +

Description

+ +

cupsLangGet() returns a language structure for the specified +locale. If the locale is not defined then the POSIX (English) locale is +substituted. + +

Example

+ +
+#include <cups/language.h>
+
+cups_lang_t *language;
+
+...
+
+language = cupsLangGet("fr");
+
+...
+
+cupsLangFree(language);
+
+ +

See Also

+ +

+cupsLangDefault(), +cupsLangEncoding(), +cupsLangFlush(), +cupsLangFree(), +cupsLangString() + +

cupsLangString()

+ +

Usage

+ +
+char *
+cupsLangString(cups_lang_t *language,
+               int         message);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
languageThe language to query.
messageThe message number.
+ +

Returns

+ +

A pointer to the message string or NULL if the message is +not defined. + +

Description

+ +

cupsLangString() returns a pointer to the specified message +string in the specified language. + +

Example

+ +
+#include <cups/language.h>
+
+cups_lang_t *language;
+char        *s;
+...
+
+language = cupsLangGet("fr");
+
+s = cupsLangString(language, CUPS_MSG_YES);
+
+...
+
+cupsLangFree(language);
+
+ +

See Also

+ +

+cupsLangDefault(), +cupsLangEncoding(), +cupsLangFlush(), +cupsLangFree(), +cupsLangGet() + +

cupsLastError()

+ +

Usage

+ +
+ipp_status_t
+cupsLastError(void);
+
+ +

Returns

+ +

An enumeration containing the last IPP error. + +

Description

+ +

cupsLastError() returns the last IPP error that occurred. +If no error occurred then it will return IPP_OK or +IPP_OK_CONFLICT. + +

Example

+ +
+#include <cups/cups.h>
+
+ipp_status_t status;
+
+...
+
+status = cupsLastError();
+
+ +

See Also

+ +

+cupsCancelJob(), +cupsPrintFile() + +

cupsMarkOptions()

+ +

Usage

+ +
+int
+cupsMarkOptions(ppd_file_t *ppd,
+                int num_options,
+                cups_option_t *options);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file to mark.
num_optionsThe number of options in the options array.
optionsA pointer to the options array.
+ +

Returns

+ +

The number of conflicts found. + +

Description

+ +

cupsMarkOptions() marks options in the PPD file. It also +handles mapping of IPP option names and values to PPD option names. + +

Example

+ +
+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+ppd_file_t    *ppd;
+
+...
+
+cupsMarkOptions(ppd, num_options, options);
+
+ +

See Also

+ +

+cupsAddOption(), +cupsFreeOptions(), +cupsGetOption(), +cupsParseOptions() + +

cupsParseOptions()

+ +

Usage

+ +
+int
+cupsParseOptions(const char *arg,
+                 int num_options,
+                 cups_option_t **options);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
argThe string containing one or more options.
num_optionsThe number of options in the options array.
optionsA pointer to the options array pointer.
+ +

Returns

+ +

The new number of options in the array. + +

Description

+ +

cupsParseOptions() parses the specifies string for one +or more options of the form "name=value", "name", or "noname". It can +be called multiple times to combine the options from several strings. + +

Example

+ +
+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+
+...
+
+num_options = 0;
+options     = (cups_option_t *)0;
+num_options = cupsParseOptions(argv[5], num_options, &options);
+
+ +

See Also

+ +

+cupsAddOption(), +cupsFreeOptions(), +cupsGetOption(), +cupsMarkOptions() + +

cupsPrintFile()

+ +

Usage

+ +
+int
+cupsPrintFile(const char    *printer,
+              const char    *filename,
+              const char    *title,
+	      int           num_options,
+	      cups_option_t *options);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
printerThe printer or class to print to.
filenameThe file to print.
titleThe job title.
num_optionsThe number of options in the options array.
optionsA pointer to the options array.
+ +

Returns

+ +

The new job ID number or 0 on error. + +

Description

+ +

cupsPrintFile() sends a file to the specified printer or +class for printing. If the job cannot be printed the error code can be +found by calling cupsLastError(). + +

Example

+ +
+#include <cups/cups.h>
+
+int           num_options;
+cups_option_t *options;
+int           jobid;
+
+...
+
+jobid = cupsPrintFile("printer@hostname", "filename.ps", "Job Title",
+                      num_options, options);
+
+ +

See Also

+ +

+cupsCancelJob(), +cupsLastError(), +cupsPrintFiles() + +

cupsPrintFiles()

+ +

Usage

+ +
+int
+cupsPrintFiles(const char    *printer,
+               int           num_files,
+               const char    **files,
+               const char    *title,
+	       int           num_options,
+	       cups_option_t *options);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
printerThe printer or class to print to.
num_filesThe number of files to print.
filesThe files to print.
titleThe job title.
num_optionsThe number of options in the options array.
optionsA pointer to the options array.
+ +

Returns

+ +

The new job ID number or 0 on error. + +

Description

+ +

cupsPrintFiles() sends multiple files to the specified +printer or class for printing. If the job cannot be printed the error +code can be found by calling cupsLastError(). + +

Example

+ +
+#include <cups/cups.h>
+
+int           num_files;
+const char    *files[100];
+int           num_options;
+cups_option_t *options;
+int           jobid;
+
+...
+
+jobid = cupsPrintFiles("printer@hostname", num_files, files,
+                       "Job Title", num_options, options);
+
+ +

See Also

+ +

+cupsCancelJob(), +cupsLastError(), +cupsPrintFile() + +

cupsRasterClose()

+ +

Usage

+ +
+void
+cupsRasterClose(cups_raster_t *ras);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
rasThe raster stream to close.
+ +

Description

+ +

cupsRasterClose() closes the specified raster stream. + +

Example

+ +
+#include <cups/raster.h>
+
+cups_raster_t *ras;
+
+...
+
+cupsRasterClose(ras);
+
+ +

See Also

+ +

+cupsRasterOpen(), +cupsRasterReadHeader(), +cupsRasterReadPixels(), +cupsRasterWriteHeader(), +cupsRasterWritePixels() + + +

cupsRasterOpen()

+ +

Usage

+ +
+cups_raster_t *
+cupsRasterOpen(int fd,
+               cups_mode_t mode);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
fdThe file descriptor to use.
modeThe mode to use; CUPS_RASTER_READ or + CUPS_RASTER_WRITE.
+ +

Returns

+ +

A pointer to a raster stream or NULL if there was an error. + +

Description

+ +

cupsRasterOpen() opens a raster stream for reading or writing. + +

Example

+ +
+#include <cups/raster.h>
+
+cups_raster_t *ras;
+
+...
+
+ras = cupsRasterOpen(0, CUPS_RASTER_READ);
+
+ +

See Also

+ +

+cupsRasterClose(), +cupsRasterReadHeader(), +cupsRasterReadPixels(), +cupsRasterWriteHeader(), +cupsRasterWritePixels() + +

cupsRasterReadHeader()

+ +

Usage

+ +
+unsigned
+cupsRasterReadHeader(cups_raster_t *ras,
+                     cups_page_header_t *header);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
rasThe raster stream to read from.
headerA pointer to a page header structure to read into.
+ +

Returns

+ +

1 on success, 0 on EOF or error. + +

Description

+ +

cupsRasterReadHeader() reads a page header from the specified +raster stream. + +

Example

+ +
+#include <cups/raster.h>
+
+int                  line;
+cups_raster_t        *ras;
+cups_raster_header_t header;
+unsigned char        pixels[8192];
+...
+
+while (cupsRasterReadHeader(ras, &header))
+{
+  ...
+
+  for (line = 0; line < header.cupsHeight; line ++)
+  {
+    cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
+
+    ...
+  }
+}
+
+ +

See Also

+ +

+cupsRasterClose(), +cupsRasterOpen(), +cupsRasterReadPixels(), +cupsRasterWriteHeader(), +cupsRasterWritePixels() + +

cupsRasterReadPixels()

+ +

Usage

+ +
+unsigned
+cupsRasterReadPixels(cups_raster_t *ras,
+                     unsigned char *pixels,
+		     unsigned length);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
rasThe raster stream to read from.
pixelsThe pointer to a pixel buffer.
lengthThe number of bytes of pixel data to read.
+ +

Returns

+ +

The number of bytes read or 0 on EOF or error. + +

Description

+ +

cupsRasterReadPixels() reads pixel data from the specified +raster stream. + +

Example

+ +
+#include <cups/raster.h>
+
+int                  line;
+cups_raster_t        *ras;
+cups_raster_header_t header;
+unsigned char        pixels[8192];
+...
+
+while (cupsRasterReadHeader(ras, &header))
+{
+  ...
+
+  for (line = 0; line < header.cupsHeight; line ++)
+  {
+    cupsRasterReadPixels(ras, pixels, header.cupsBytesPerLine);
+
+    ...
+  }
+}
+
+ +

See Also

+ +

+cupsRasterClose(), +cupsRasterOpen(), +cupsRasterReadHeader(), +cupsRasterWriteHeader(), +cupsRasterWritePixels() + +

cupsRasterWriteHeader()

+ +

Usage

+ +
+unsigned
+cupsRasterWriteHeader(cups_raster_t *ras,
+                      cups_page_header_t *header);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
rasThe raster stream to write to.
headerA pointer to the page header to write.
+ +

Returns

+ +

1 on success, 0 on error. + +

Description

+ +

cupsRasterWriteHeader() writes the specified page header to +a raster stream. + +

Example

+ +
+#include <cups/raster.h>
+
+int                  line;
+cups_raster_t        *ras;
+cups_raster_header_t header;
+unsigned char        pixels[8192];
+...
+
+cupsRasterWriteHeader(ras, &header);
+
+for (line = 0; line < header.cupsHeight; line ++)
+{
+  ...
+
+  cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
+}
+
+ +

See Also

+ +

+cupsRasterClose(), +cupsRasterOpen(), +cupsRasterReadHeader(), +cupsRasterReadPixels(), +cupsRasterWritePixels() + +

cupsRasterWritePixels()

+ +

Usage

+ +
+unsigned
+cupsRasterWritePixels(cups_raster_t *ras,
+                      unsigned char *pixels,
+		      unsigned length);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
rasThe raster stream to write to.
pixelsThe pixel data to write.
lengthThe number of bytes to write.
+ +

Returns

+ +

The number of bytes written. + +

Description

+ +

cupsRasterWritePixels() writes the specified pixel data to a +raster stream. + +

Example

+ +
+#include <cups/raster.h>
+
+int                  line;
+cups_raster_t        *ras;
+cups_raster_header_t header;
+unsigned char        pixels[8192];
+...
+
+cupsRasterWriteHeader(ras, &header);
+
+for (line = 0; line < header.cupsHeight; line ++)
+{
+  ...
+
+  cupsRasterWritePixels(ras, pixels, header.cupsBytesPerLine);
+}
+
+ +

See Also

+ +

+cupsRasterClose(), +cupsRasterOpen(), +cupsRasterReadHeader(), +cupsRasterReadPixels(), +cupsRasterWriteHeader() + +

cupsServer()

+ +

Usage

+ +
+const char *
+cupsServer(void);
+
+ +

Returns

+ +

A pointer to the default server name. + +

Description

+ +

cupsServer() returns a pointer to the default server name. +The server name is stored in a static location and will be overwritten with +every call to cupsServer() + +

The default server is determined from the following locations: + +

    + +
  1. The CUPS_SERVER environment variable, + +
  2. The ServerName directive in the + client.conf file, + +
  3. The default host, "localhost". + +
+ +

Example

+ +
+#include <cups/cups.h>
+
+const char *server;
+
+server = cupsServer();
+
+ +

See Also

+ +

+cupsGetPassword(), +cupsUser() + +

cupsTempFile()

+ +

Usage

+ +
+char *
+cupsTempFile(char *filename,
+             int length);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
filenameThe character string to hold the temporary filename.
lengthThe size of the filename string in bytes.
+ +

Returns

+ +

A pointer to filename. + +

Description

+ +

cupsTempFile() generates a temporary filename for the +/var/tmp directory or the directory specified by the +TMPDIR environment variable. + +

Example

+ +
+#include <cups/cups.h>
+
+char filename[256];
+
+cupsTempFile(filename, sizeof(filename));
+
+ +

cupsUser()

+ +

Usage

+ +
+const char *
+cupsUser(void);
+
+ +

Returns

+ +

A pointer to the current username or NULL if the user ID is +undefined. + +

Description

+ +

cupsUser() returns the name associated with the current +user ID as reported by the getuid() system call. + +

Example

+ +
+#include <cups/cups.h>
+
+const char *user;
+
+user = cupsUser();
+
+ +

See Also

+ +

+cupsGetPassword(), +cupsServer() + +

httpBlocking()

+ +

Usage

+ +
+void httpBlocking(http_t *http, int blocking)
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
blocking0 if the connection should be non-blocking, 1 if it should + be blocking
+ +

Description

+ +

The httpBlocking() function sets the blocking mode for the +HTTP connection. By default HTTP connections will block (stop) the client +program until data is available or can be sent to the server. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+http = httpConnect("server", port);
+httpBlocking(http, 0);
+
+ +

See Also

+ +httpCheck(), +httpConnect() + +

httpCheck()

+ +

Usage

+ +
+int httpCheck(http_t *http);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
httpThe HTTP connection
+ +

Returns

+ +

0 if there is no data pending, 1 otherwise. + +

Description

+ +

The httpCheck() function checks to see if there is any data +pending on an HTTP connection. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+if (httpCheck(http))
+{
+  ... do something ...
+}
+
+ +

See Also

+ +httpBlocking(), +httpConnect(), +httpGets(), +httpRead() + + +

httpClearFields()

+ +

Usage

+ +
+void httpClearFields(http_t *http)
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
httpThe HTTP connection
+ +

Description

+ +

The httpClearFields() function clears all HTTP request fields +for the HTTP connection. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpClearFields(http);
+
+ +

See Also

+ +httpConnect(), +httpGetField(), +httpSetField() + +

httpClose()

+ +

Usage

+ +
+void httpClose(http_t *http);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
httpThe HTTP connection
+ +

Description

+ +

The httpClose() function closes an active HTTP connection. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpClose(http);
+
+ +

See Also

+ +httpConnect() + +

httpConnect()

+ +

Usage

+ +
+http_t *httpConnect(const char *hostname, int port);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
hostnameThe name or IP address of the server to connect to
portThe port number to use
+ +

Returns

+ +

A pointer to a HTTP connection structure or NULL if the connection could +not be made. + +

Description

+ +

The httpConnect() function opens a HTTP connection to the +specified server and port. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+http = httpConnect(cupsServer(), ippPort());
+
+ +

See Also

+ +httpClose(), +httpGet(), +httpGets(), +httpPost(), +httpRead(), +httpWrite() + + +

httpDecode64()

+ +

Usage

+ +
+char *httpDecode64(char *out, const char *in);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
outThe output string
inThe input string
+ +

Returns

+ +

A pointer to the decoded string. + +

Description

+ +

The httpDecode64() function decodes a base-64 encoded string +to the original string. + +

Example

+ +
+#include <cups/http.h>
+
+char encoded_string[255];
+char original_string[255];
+
+httpDecode64(original_string, encoded_string);
+
+ +

See Also

+ +httpEncode64() + +

httpDelete()

+ +

Usage

+ +
+int httpDelete(http_t *http, const char *uri);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to delete
+ +

Returns

+ +

0 on success, non-zero on failure. + +

Description

+ +

The httpDelete() function sends a HTTP DELETE request to +the server. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpDelete(http, "/some/uri");
+
+ +

See Also

+ +httpConnect(), +httpSetField(), +httpUpdate() + +

httpEncode64()

+ +

Usage

+ +
+char *httpEncode64(char *out, const char *in);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
outThe output string
inThe input string
+ +

Returns

+ +

A pointer to the encoded string. + +

Description

+ +

The httpEncode64() function decodes a base-64 encoded string +to the original string. + +

Example

+ +
+#include <cups/http.h>
+
+char encoded_string[255];
+char original_string[255];
+
+httpEncode64(encoded_string, original_string);
+
+ +

See Also

+ +httpDecode64() + +

httpError()

+ +

Usage

+ +
+int httpError(http_t *http);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
httpThe HTTP connection
+ +

Returns

+ +

The last error that occurred or 0 if no error has occurred. + +

Description

+ +

The httpError() function returns the last error that occurred +on the HTTP connection. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+if (httpError(http))
+{
+  ... show an error message ...
+}
+
+ +

See Also

+ +httpConnect() + +

httpFlush()

+ +

Usage

+ +
+void httpFlush(http_t *http);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
httpThe HTTP connection
+ +

Description

+ +

The httpFlush() function flushes any remaining data left from +a GET or POST operation. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpFlush(http);
+
+ +

See Also

+ +httpConnect(), + +

httpGet()

+ +

Usage

+ +
+int httpGet(http_t *http, const char *uri);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to get
+ +

Returns

+ +

0 on success, non-zero on failure. + +

Description

+ +

The httpGet() function sends a HTTP GET request to the +server. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpGet(http, "/some/uri");
+
+ +

See Also

+ +httpConnect(), +httpSetField(), +httpUpdate() + + +

httpGets()

+ +

Usage

+ +
+char *httpGets(char *line, int length, http_t *http)
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
lineThe string to fill with a line from the HTTP connection
lengthThe maximum length of the string
httpThe HTTP connection
+ +

Returns

+ +

A pointer to the string or NULL if no line could be retrieved. + +

Description

+ +

The httpGets() function is used to read a request line from +the HTTP connection. It is not normally used by a client program. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+char line[1024];
+
+if (httpGets(line, sizeof(line), http))
+{
+  ... process the line ...
+}
+
+ +

See Also

+ +httpConnect(), +httpUpdate() + +

httpGetDateString()

+ +

Usage

+ +
+const char *httpGetDateString(time_t time)
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
timeThe UNIX date/time value
+ +

Returns

+ +

A pointer to a static string containing the HTTP date/time string for +the specified UNIX time value. + +

Description

+ +

The httpGetDateString() function generates a date/time string +suitable for HTTP requests from a UNIX time value. + +

Example

+ +
+#include <cups/http.h>
+
+puts(httpGetDateString(time(NULL)));
+
+ +

See Also

+ +httpGetDateTime() + + +

httpGetDateTime()

+ +

Usage

+ +
+time_t httpGetDateTime(const char *date)
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
dateThe HTTP date/time string
+ +

Returns

+ +

A UNIX time value. + +

Description

+ +

The httpGetDateTime() function converts a HTTP +date/time string to a UNIX time value. + +

Example

+ +
+#include <cups/http.h>
+
+printf("%d\n", httpGetDateTime("Fri, 30 June 2000 12:34:56 GMT"));
+
+ +

See Also

+ +httpGetDateString() + + +

httpGetField()

+ +

Usage

+ +
+const char *httpGetField(http_t *http, http_field_t field);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
fieldThe HTTP field
+ +

Returns

+ +

A pointer to the field value string. + +

Description

+ +

The httpGetField() function returns the current value for +the specified HTTP field. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpGet(http, "/some/uri");
+while (httpUpdate(http) == HTTP_CONTINUE);
+
+puts(httpGetField(http, HTTP_FIELD_CONTENT_TYPE));
+
+ +

See Also

+ +httpConnect(), +httpSetField() + + +

httpHead()

+ +

Usage

+ +
+int httpHead(http_t *http, const char *uri);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to head
+ +

Returns

+ +

0 on success, non-zero on failure. + +

Description

+ +

The httpHead() function sends a HTTP HEAD request to the +server. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpHead(http, "/some/uri");
+
+ +

See Also

+ +httpConnect(), +httpSetField(), +httpUpdate() + + +

httpInitialize()

+ +

Usage

+ +
+void httpInitialize(void);
+
+ +

Description

+ +

The httpInitialize() function initializes the networking +code as needed by the underlying platform. It is called automatically by +the httpConnect() function. + +

Example

+ +
+#include <cups/http.h>
+
+httpInitialize();
+
+ +

See Also

+ +httpConnect() + +

httpOptions()

+ +

Usage

+ +
+int httpOptions(http_t *http, const char *uri);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to check for options
+ +

Returns

+ +

0 on success, non-zero on failure. + +

Description

+ +

The httpOptions() function sends a HTTP OPTIONS request to the +server. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpOptions(http, "/some/uri");
+
+ +

See Also

+ +httpConnect(), +httpSetField(), +httpUpdate() + + +

httpPost()

+ +

Usage

+ +
+int httpPost(http_t *http, const char *uri);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to post to
+ +

Returns

+ +

0 on success, non-zero on failure. + +

Description

+ +

The httpPost() function sends a HTTP POST request to the +server. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpPost(http, "/some/uri");
+
+ +

See Also

+ +httpConnect(), +httpSetField(), +httpUpdate() + + +

httpPrintf()

+ +

Usage

+ +
+int httpPrintf(http_t *http, const char *format, ...);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
formatA printf-style format string
+ +

Returns

+ +

The number of bytes written. + +

Description

+ +

The httpPrintf() function sends a formatted string to the +HTTP connection. It is normally only used by the CUPS API and scheduler. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpPrintf(http, "GET / HTTP/1.1 \r\n");
+
+ +

See Also

+ +httpConnect() + +

httpPut()

+ +

Usage

+ +
+int httpPut(http_t *http, const char *uri);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to put
+ +

Returns

+ +

0 on success, non-zero on failure. + +

Description

+ +

The httpPut() function sends a HTTP PUT request to the +server. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpDelete(http, "/some/uri");
+
+ +

See Also

+ +httpConnect(), +httpSetField(), +httpUpdate() + + +

httpRead()

+ +

Usage

+ +
+int httpRead(http_t *http, char *buffer, int length);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
bufferThe buffer to read into
lengthThe number of bytes to read
+ +

Returns

+ +

The number of bytes read or -1 on error. + +

Description

+ +

The httpRead() function reads data from the HTTP connection, +possibly the result of a GET or POST request. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+char buffer[1024];
+int  bytes;
+
+httpGet(http, "/");
+while (httpUpdate(http) != HTTP_CONTINUE);
+while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
+{
+  buffer[bytes] = '\0';
+  fputs(buffer, stdout);
+}
+
+ +

See Also

+ +httpConnect(), +httpWrite() + +

httpReconnect()

+ +

Usage

+ +
+int httpReconnect(http_t *http);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
httpThe HTTP connection
+ +

Returns

+ +

0 on success, non-zero on failure. + +

Description

+ +

The httpReconnect() function reconnects to the HTTP server. +This is usually done automatically if the HTTP functions detect that the +server connection has terminated. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpReconnect(http);
+
+ +

See Also

+ +httpConnect() + +

httpSeparate()

+ +

Usage

+ +
+void httpSeparate(const char *uri, char *method,
+                  char *username, char *host, int *port,
+                  char *resource);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
uriThe URI to separate
methodThe method (scheme) of the URI
usernameThe username (and password) portion of the URI, if any
hostThe hostname portion of the URI, if any
portThe port number for the URI, either as specified or as + default for the method/scheme
resourceThe resource string, usually a filename on the server
+ +

Description

+ +

The httpSeparate() function separates the specified URI into +its component parts. The method, username, hostname, and resource strings should +be at least HTTP_MAX_URI characters long to avoid potential +buffer overflow problems. + +

Example

+ +
+char uri[HTTP_MAX_URI];
+char method[HTTP_MAX_URI];
+char username[HTTP_MAX_URI];
+char host[HTTP_MAX_URI];
+char resource[HTTP_MAX_URI];
+int port;
+
+httpSeparate(uri, method, username, host, &port, resource);
+
+ +

See Also

+ +httpConnect() + +

httpSetField()

+ +

Usage

+ +
+void httpSetField(http_t *http, http_field_t field, const char *value);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
fieldThe HTTP field
valueThe string value for the field
+ +

Description

+ +

The httpSetField() function sets the current value for +the specified HTTP field. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpSetField(http, HTTP_FIELD_AUTHORIZATION, "Basic dfdr34453454325"));
+httpGet(http, "/some/uri");
+while (httpUpdate(http) == HTTP_CONTINUE);
+
+ +

See Also

+ +httpConnect(), +httpGetField() + + +

httpTrace()

+ +

Usage

+ +
+int httpTrace(http_t *http, const char *uri);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
uriThe URI to trace
+ +

Returns

+ +

0 on success, non-zero on failure. + +

Description

+ +

The httpTrace() function sends a HTTP TRACE request to the +server. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+
+httpTrace(http, "/some/uri");
+
+ +

See Also

+ +httpConnect(), +httpSetField(), +httpUpdate() + + +

httpUpdate()

+ +

Usage

+ +
+http_status_t httpUpdate(http_t *http);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
httpThe HTTP connection
+ +

Returns

+ +

The HTTP status of the current request. + +

Description

+ +

The httpUpdate() function updates the current request status. +It is used after any DELETE, GET, HEAD, OPTIONS, POST, PUT, or TRACE +request to finalize the HTTP request and retrieve the request status. + +

Since proxies and the current blocking mode can cause the request to +take longer, programs should continue calling httpUpdate() +until the return status is not the constant value HTTP_CONTINUE. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+http_status_t status;
+
+httpGet(http, "/some/uri");
+while ((status = httpUpdate(http)) == HTTP_CONTINUE);
+printf("Request status is %d\n", status);
+
+ +

See Also

+ +httpConnect(), +httpDelete(), +httpGet(), +httpHead(), +httpOptions(), +httpPost(), +httpPut(), +httpTrace() + +

httpWrite()

+ +

Usage

+ +
+int httpWrite(http_t *http, char *buffer, int length);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
bufferThe buffer to read into
lengthThe number of bytes to read
+ +

Returns

+ +

The number of bytes read or -1 on error. + +

Description

+ +

The httpWrite() function reads data from the HTTP connection, +possibly the result of a GET or POST request. + +

Example

+ +
+#include <cups/http.h>
+
+http_t *http;
+FILE *fp;
+char buffer[1024];
+int  bytes;
+
+httpPost(http, "/");
+
+while ((bytes = fread(buffer, 1, sizeof(buffer), fp)) > 0)
+  httpWrite(http, buffer, bytes);
+
+while (httpUpdate(http) != HTTP_CONTINUE);
+
+while ((bytes = httpRead(http, buffer, sizeof(buffer) - 1)) > 0)
+{
+  buffer[bytes] = '\0';
+  fputs(buffer, stdout);
+}
+
+ +

See Also

+ +httpConnect(), +httpRead() + +

ippAddBoolean()

+ +

Usage

+ +
+ipp_attribute_t *ippAddBoolean(ipp_t *ipp, ipp_tag_t group,
+                               const char *name, char value);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
valueThe boolean value
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddBoolean() function adds a single boolean attribute +value to the specified IPP request. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, "my-jobs", 1);
+
+ +

See Also

+ +ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddBooleans()

+ +

Usage

+ +
+ipp_attribute_t *ippAddBooleans(ipp_t *ipp, ipp_tag_t group,
+                                const char *name, int num_values,
+                                const char *values);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
num_valuesThe number of values
valuesThe boolean values
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddBooleans() function adds one or more boolean +attribute values to the specified IPP request. If the +values pointer is NULL then an array of +num_values false values is created. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+char values[10];
+
+ippAddBooleans(ipp, IPP_TAG_OPERATION, "some-attribute", 10, values);
+
+ +

See Also

+ +ippAddBoolean(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddDate()

+ +

Usage

+ +
+ipp_attribute_t *ippAddDate(ipp_t *ipp, ipp_tag_t group,
+                            const char *name, ipp_uchar_t *value);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
valueThe date value
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddDate() function adds a single date-time attribute +value to the specified IPP request. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddDate(ipp, IPP_TAG_OPERATION, "some-attribute", 
+           ippTimeToDate(time(NULL));
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddInteger(), +ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings(), +ippTimeToDate() + + +

ippAddInteger()

+ +

Usage

+ +
+ipp_attribute_t *ippAddInteger(ipp_t *ipp, ipp_tag_t group,
+                               ipp_tag_t tag, const char *name,
+                               int value);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
tagThe type of integer value (IPP_TAG_INTEGER or IPP_TAG_ENUM)
nameThe name of attribute
valueThe integer value
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddInteger() function adds a single integer attribute +value to the specified IPP request. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddInteger(ipp, IPP_TAG_OPERATION, "limit", 100);
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddIntegers()

+ +

Usage

+ +
+ipp_attribute_t *ippAddIntegers(ipp_t *ipp, ipp_tag_t group,
+                                ipp_tag_t tag, const char *name,
+                                int num_values, const int *values);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
tagThe type of integer value (IPP_TAG_INTEGER or IPP_TAG_ENUM)
nameThe name of attribute
num_valuesThe number of values
valuesThe integer values
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddIntegers() function adds one or more integer +attribute values to the specified IPP request. If the +values pointer is NULL then an array of +num_values 0 values is created. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+int values[100];
+
+ippAddIntegers(ipp, IPP_TAG_OPERATION, "some-attribute", 100, values);
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddRange()

+ +

Usage

+ +
+ipp_attribute_t *ippAddRange(ipp_t *ipp, ipp_tag_t group,
+                             const char *name, int low,
+                             int high);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
lowThe lower value
highThe higher value
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddRange() function adds a single range attribute +value to the specified IPP request. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddRange(ipp, IPP_TAG_OPERATION, "page-ranges", 1, 10);
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddRanges()

+ +

Usage

+ +
+ipp_attribute_t *ippAddRanges(ipp_t *ipp, ipp_tag_t group,
+                              const char *name, int num_values,
+                              const int *lows, const int *highs);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
num_valuesThe number of range values
lowsThe lower values
highsThe higher values
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddRanges() function adds one or more range +attribute values to the specified IPP request. If the +values pointer is NULL then an array of +num_values 0,0 ranges is created. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+int lows[2];
+int highs[2];
+
+ippAddRanges(ipp, IPP_TAG_OPERATION, "page-ranges", 2, lows, highs);
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), +ippAddRange(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddResolution()

+ +

Usage

+ +
+ipp_attribute_t *ippAddResolution(ipp_t *ipp, ipp_tag_t group,
+                                  const char *name, int xres,
+                                  int yres, ipp_res_t units);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
xresThe horizontal resolution
yresThe vertical resolution
unitsThe resolution units
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddResolution() function adds a single resolution attribute +value to the specified IPP request. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolution",
+              720, 720, IPP_RES_PER_INCH);
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddResolutions()

+ +

Usage

+ +
+ipp_attribute_t *ippAddResolutions(ipp_t *ipp, ipp_tag_t group,
+                                   const char *name, int num_values,
+                                   const int *xres, const int *yres,
+                                   const ipp_res_t *units);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
nameThe name of attribute
num_valuesThe number of resolution values
xresThe horizontal resolutions
yresThe vertical resolutions
unitsThe resolution units
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddResolutions() function adds one or more +resolution attribute values to the specified IPP request. If the +values pointer is NULL then an array of +num_values 0,0 resolutions is created. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+int xres[5];
+int yres[5];
+ipp_res_t units[5];
+
+ippAddBoolean(ipp, IPP_TAG_OPERATION, "printer-resolutions-supported",
+              5, xres, yres, units);
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddSeparator(), +ippAddString(), +ippAddStrings() + + +

ippAddSeparator()

+ +

Usage

+ +
+ipp_attribute_t *ippAddSeparator(ipp_t *ipp);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
ippThe IPP request
+ +

Returns

+ +

A pointer to the new separator or NULL if the separator could not be +created. + +

Description

+ +

The ippAddSeparator() function adds a group separator +to the specified IPP request. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddSeparator(ipp);
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddString(), +ippAddStrings() + + +

ippAddString()

+ +

Usage

+ +
+ipp_attribute_t *ippAddString(ipp_t *ipp, ipp_tag_t group,
+                              ipp_tag_t tag, const char *name,
+                              const char *charset, const char *value);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
tagThe type of string value
nameThe name of attribute
charsetThe character set for the string
valueThe string value
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddString() function adds a single string attribute +value to the specified IPP request. For IPP_TAG_NAMELANG and +IPP_TAG_TEXTLANG strings, the charset value is provided with +the string to identify the string encoding used. Otherwise the charset value +is ignored. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippAddString(ipp, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name",
+             NULL, "abc123");
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddStrings() + + +

ippAddStrings()

+ +

Usage

+ +
+ipp_attribute_t *ippAddStrings(ipp_t *ipp, ipp_tag_t group,
+                               ipp_tag_t tag, const char *name,
+                               int num_values, const char *charset,
+                               const char **values);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ArgumentDescription
ippThe IPP request
groupThe IPP group
tagThe type of string value
nameThe name of attribute
num_valuesThe number of strings
charsetThe character set for the strings
valuesThe string values
+ +

Returns

+ +

A pointer to the new attribute or NULL if the attribute could not be +created. + +

Description

+ +

The ippAddStrings() function adds one or more string +attribute values to the specified IPP request. For +IPP_TAG_NAMELANG and IPP_TAG_TEXTLANG +strings, the charset value is provided with the strings to identify the +string encoding used. Otherwise the charset value is ignored. If the +values pointer is NULL then an array of +num_values NULL strings is created. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+char *values[2] = { "one", "two" };
+
+ippAddStrings(ipp, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "attr-name",
+              2, NULL, values);
+
+ +

See Also

+ +ippAddBoolean(), +ippAddBooleans(), +ippAddDate(), +ippAddInteger(), +ippAddIntegers(), +ippAddRange(), +ippAddRanges(), +ippAddResolution(), +ippAddResolutions(), +ippAddSeparator(), +ippAddString() + + +

ippDateToTime()

+ +

Usage

+ +
+time_t ippDateToTime(const ipp_uchar_t date[11]);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
dateThe IPP date-time value
+ +

Returns

+ +

A UNIX time value. + +

Description

+ +

The ippDateToTime() function converts an IPP date-time value +to a UNIX time value. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_uchar_t date[11];
+
+printf("UNIX time is %d\n", ippDateToTime(date));
+
+ +

See Also

+ +ippTimeToDate() + + +

ippDelete()

+ +

Usage

+ +
+void ippDelete(ipp_t *ipp);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
ippThe IPP request or response
+ +

Description

+ +

The ippDelete() function deletes all memory used by an IPP +request or response. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ippDelete(ipp);
+
+ +

See Also

+ +ippNew() + + +

ippFindAttribute()

+ +

Usage

+ +
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
+ +

Returns

+ +

Description

+ +

Example

+ +
+
+ +

See Also

+ + +

ippLength()

+ +

Usage

+ +
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
+ +

Returns

+ +

Description

+ +

Example

+ +
+
+ +

See Also

+ + +

ippNew()

+ +

Usage

+ +
+ipp_t *ippNew(void);
+
+ +

Returns

+ +

A pointer to a new IPP request or response. + +

Description

+ +

The ippNew() function creates a new IPP request or response. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_t *ipp;
+
+ipp = ippNew();
+
+ +

See Also

+ +ippDelete() + + +

ippPort()

+ +

Usage

+ +
+int ippPort(void);
+
+ +

Returns

+ +

The default TCP/IP port number for IPP requests. + +

Description

+ +

The ippPort() function returns the default IPP port number +for requests. + +

Example

+ +
+#include <cups/http.h>
+#include <cups/ipp.h>
+
+http_t *http;
+
+http = httpConnect(cupsServer(), ippPort());
+
+ +

See Also

+ +cupsServer() + + +

ippRead()

+ +

Usage

+ +
+ipp_state_t ippRead(http_t *http, ipp_t *ipp);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
ippThe IPP request or response
+ +

Returns

+ +

The current read state. + +

Description

+ +

The ippRead() function reads IPP attributes from the specified +HTTP connection. Programs should continue calling ippRead() until +IPP_ERROR or IPP_DATA is returned. + +

Example

+ +
+#include <cups/http.h>
+#include <cups/ipp.h>
+
+http_t *http;
+ipp_t *ipp;
+ipp_state_t status;
+
+ipp = ippNew();
+
+while ((status = ippRead(http, ipp)) != IPP_ERROR)
+  if (status == IPP_DATA)
+    break;
+
+if (status == IPP_DATA)
+{
+  ... read additional non-IPP data using httpRead() ...
+}
+
+ +

See Also

+ +ippWrite() + + +

ippTimeToDate()

+ +

Usage

+ +
+ipp_uchar_t *ippTimeToDate(time_t time);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
timeThe UNIX time value
+ +

Returns

+ +

A static pointer to an IPP date-time value. + +

Description

+ +

The ippTimeToDate() function converts a UNIX time to an IPP +date-time value. + +

Example

+ +
+#include <cups/ipp.h>
+
+ipp_uchar_t *date;
+
+date = ippTimeToDate(time(NULL));
+
+ +

See Also

+ +ippDateToTime() + + +

ippWrite()

+ +

Usage

+ +
+ipp_state_t ippWrite(http_t *http, ipp_t *ipp);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
httpThe HTTP connection
ippThe IPP request or response
+ +

Returns

+ +

The current write state. + +

Description

+ +

The ippWrite() function writes IPP attributes to the specified +HTTP connection. Programs should continue calling ippWrite() until +IPP_ERROR or IPP_DATA is returned. + +

Example

+ +
+#include <cups/http.h>
+#include <cups/ipp.h>
+
+http_t *http;
+ipp_t *ipp;
+ipp_state_t status;
+
+ipp = ippNew();
+... add attributes ...
+
+while ((status = ippWrite(http, ipp)) != IPP_ERROR)
+  if (status == IPP_DATA)
+    break;
+
+if (status == IPP_DATA)
+{
+  ... read additional non-IPP data using httpWrite() ...
+}
+
+ +

See Also

+ +ippRead() + + +

ppdClose()

+ +

Usage

+ +
+void ppdClose(ppd_file_t *ppd);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
ppdThe PPD file
+ +

Description

+ +

The ppdClose() function frees all memory associated with the +PPD file. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdClose(ppd);
+
+ +

See Also

+ +ppdOpen(), +ppdOpenFd(), +ppdOpenFile() + + +

ppdConflicts()

+ +

Usage

+ +
+int ppdConflicts(ppd_file_t *ppd);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
ppdThe PPD file
+ +

Returns

+ +

The number of option conflicts in the file. + +

Description

+ +

The ppdConflicts() function returns the number of conflicts +with the currently selected options. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("%d conflicts\n", ppdConflicts(ppd));
+
+ +

See Also

+ +cupsMarkOptions(), +ppdIsMarked(), +ppdMarkDefaults(), +ppdMarkOption() + + +

ppdEmit()

+ +

Usage

+ +
+int ppdEmit(ppd_file_t *ppd, FILE *file, ppd_section_t section);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file
fileThe file to write to
sectionThe option section to write
+ +

Returns

+ +

0 on success, -1 on error. + +

Description

+ +

The ppdEmit() function sends printer-specific option +commands to the specified file. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdEmit(ppd, stdout, PPD_ORDER_PAGE);
+
+ +

See Also

+ +ppdEmitFd() + + +

ppdEmitFd()

+ +

Usage

+ +
+int ppdEmitFd(ppd_file_t *ppd, int fd, ppd_section_t section);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file
fdThe file descriptor to write to
sectionThe option section to write
+ +

Returns

+ +

0 on success, -1 on error. + +

Description

+ +

The ppdEmitFd() function sends printer-specific option +commands to the specified file descriptor. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdEmitFd(ppd, 1, PPD_ORDER_PAGE);
+
+ +

See Also

+ +ppdEmit() + + +

ppdFindChoice()

+ +

Usage

+ +
+ppd_choice_t *ppdFindChoice(ppd_option_t *option, const char *choice);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
optionA pointer to the option
choiceThe name of the choice
+ +

Returns

+ +

A pointer to the choice data or NULL if the choice does not exist. + +

Description

+ +

The ppdFindChoice() function returns a pointer to the choice +data for the specified option. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_option_t *option;
+ppd_choice_t *choice;
+
+option = ppdFindOption(ppd, "PageSize");
+choice = ppdFindChoice(option, "Letter");
+
+ +

See Also

+ +ppdFindMarkedChoice(), +ppdFindOption() + + +

ppdFindMarkedChoice()

+ +

Usage

+ +
+ppd_choice_t *ppdFindMarkedChoice(ppd_file_t *ppd, const char *keyword);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file
keywordThe name of the option
+ +

Returns

+ +

A pointer to the choice data or NULL if the choice does not exist or +is not marked. + +

Description

+ +

The ppdFindMarkedChoice() function returns a pointer to +the marked choice data for the specified option. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_choice_t *choice;
+
+choice = ppdFindMarkedChoice(ppd, "PageSize");
+
+ +

See Also

+ +ppdFindChoice(), +ppdFindOption() + + +

ppdFindOption()

+ +

Usage

+ +
+ppd_option_t *ppdFindOption(ppd_file_t *ppd, const char *keyword);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file
keywordThe name of the option
+ +

Returns

+ +

A pointer to the option data or NULL if the option does not exist. + +

Description

+ +

The ppdFindOption() function returns a pointer to the option +data for the specified option. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_option_t *option;
+
+option = ppdFindOption(ppd, "PageSize");
+
+ +

See Also

+ +ppdFindChoice(), +ppdFindMarkedChoice() + + +

ppdIsMarked()

+ +

Usage

+ +
+int ppdIsMarked(ppd_file_t *ppd, const char *keyword, char char *choice);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file
keywordThe name of the option
choiceThe name of the option choice
+ +

Returns

+ +

1 if the choice is marked, 0 otherwise. + +

Description

+ +

The ppdIsMarked() function returns whether or not the +specified option choice is marked. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("Letter size %s selected.\n",
+       ppdIsMarked(ppd, "PageSize", "Letter") ? "is" : "is not");
+
+ +

See Also

+ +cupsMarkOptions(), +ppdConflicts(), +ppdIsMarked(), +ppdMarkDefaults(), +ppdMarkOption() + + +

ppdMarkDefaults()

+ +

Usage

+ +
+void ppdMarkDefaults(ppd_file_t *ppd);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
ppdThe PPD file
+ +

Description

+ +

The ppdMarkDefaults() function marks all of the default +choices in the PPD file. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdMarkDefaults(ppd);
+
+ +

See Also

+ +cupsMarkOptions(), +ppdConflicts(), +ppdIsMarked(), +ppdMarkDefaults(), +ppdMarkOption() + + +

ppdMarkOption()

+ +

Usage

+ +
+int ppdMarkOption(ppd_file_t *ppd, const char *keyword, const char *choice);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file
keywordThe name of the option
choiceThe name of the choice
+ +

Returns

+ +

The number of conflicts in the PPD file. + +

Description

+ +

The ppdMarkOption() function marks the specified option +choice. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppdMarkOption(ppd, "PageSize", "Letter");
+
+ +

See Also

+ +cupsMarkOptions(), +ppdConflicts(), +ppdIsMarked(), +ppdMarkDefaults(), +ppdMarkOption() + + +

ppdOpen()

+ +

Usage

+ +
+ppd_file_t *ppdOpen(FILE *file);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
fileThe file to read from
+ +

Returns

+ +

A pointer to a PPD file structure or NULL if the PPD file could not be +read. + +

Description

+ +

The ppdOpen() function reads a PPD file from the specified +file into memory. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+FILE *file;
+
+file = fopen("filename.ppd", "rb");
+ppd = ppdOpen(file);
+fclose(file);
+
+ +

See Also

+ +ppdClose(), +ppdOpenFd(), +ppdOpenFile() + + +

ppdOpenFd()

+ +

Usage

+ +
+ppd_file_t *ppdOpenFd(int fd);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
fdThe file descriptor to read from
+ +

Returns

+ +

A pointer to a PPD file structure or NULL if the PPD file could not be +read. + +

Description

+ +

The ppdOpenFd() function reads a PPD file from the specified +file descriptor into memory. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+int        fd;
+
+fd = open("filename.ppd", O_RDONLY);
+ppd = ppdOpenFd(fd);
+close(fd);
+
+ +

See Also

+ +ppdClose(), +ppdOpen(), +ppdOpenFile() + + +

ppdOpenFile()

+ +

Usage

+ +
+ppd_file_t *ppdOpenFile(const char *filename);
+
+ +

Arguments

+ +
+ + + + + + + + +
ArgumentDescription
filenameThe name of the file to read from
+ +

Returns

+ +

A pointer to a PPD file structure or NULL if the PPD file could not be +read. + +

Description

+ +

The ppdOpenFile() function reads a PPD file from the named +file into memory. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+ppd = ppdOpenFile("filename.ppd");
+
+ +

See Also

+ +ppdClose(), +ppdOpen(), +ppdOpenFd() + + +

ppdPageLength()

+ +

Usage

+ +
+float ppdPageLength(ppd_file_t *ppd, const char *name);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file
nameThe name of the page size
+ +

Returns

+ +

The length of the specified page size in points or 0 if the page size +does not exist. + +

Description

+ +

The ppdPageLength() function returns the page length of the +specified page size. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("Length = %.0f\n", ppdPageLength(ppd, "Letter"));
+
+ +

See Also

+ +ppdPageLength(), +ppdPageSize(), +ppdPageWidth() + + +

ppdPageSize()

+ +

Usage

+ +
+ppd_size_t *ppdPageSize(ppd_file_t *ppd, const char *name);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file
nameThe name of the page size
+ +

Returns

+ +

A pointer to the page size record of the specified page size in +points or NULL if the page size does not exist. + +

Description

+ +

The ppdPageSize() function returns the page size record for the +specified page size. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+ppd_size_t *size;
+
+size = ppdPageSize(ppd, "Letter");
+if (size != NULL)
+{
+  printf(" Width = %.0f\n", size->width);
+  printf("Length = %.0f\n", size->length);
+  printf("  Left = %.0f\n", size->left);
+  printf(" Right = %.0f\n", size->right);
+  printf("Bottom = %.0f\n", size->bottom);
+  printf("   Top = %.0f\n", size->top);
+}
+
+ +

See Also

+ +ppdPageLength(), +ppdPageWidth() + + +

ppdPageWidth()

+ +

Usage

+ +
+float ppdPageWidth(ppd_file_t *ppd, const char *name);
+
+ +

Arguments

+ +
+ + + + + + + + + + + + +
ArgumentDescription
ppdThe PPD file
nameThe name of the page size
+ +

Returns

+ +

The width of the specified page size in points or 0 if the page size +does not exist. + +

Description

+ +

The ppdPageWidth() function returns the page width of the +specified page size. + +

Example

+ +
+#include <cups/ppd.h>
+
+ppd_file_t *ppd;
+
+printf("Width = %.0f\n", ppdPageWidth(ppd, "Letter"));
+
+ +

See Also

+ +ppdPageLength(), +ppdPageSize() + + + + diff --git a/doc/ssr.html b/doc/ssr.html new file mode 100644 index 0000000000..bd6e6bd2a9 --- /dev/null +++ b/doc/ssr.html @@ -0,0 +1,270 @@ + + + + CUPS Software Security Report + + + + + + + +

+

CUPS Software Security Report


+CUPS-SSR-1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
1 Scope + +2 References + +3 Local Access Risks + +4 Remote Access Risks + +A Glossary + +
+

1 Scope

+

1.1 Identification

+

This software security report provides an analysis of possible +security concerns for the Common UNIX Printing System ("CUPS") Version +1.1.

+

1.2 System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+

1.3 Document Overview

+

This software security report is organized into the following +sections:

+
    +
  • 1 - Scope
  • +
  • 2 - References
  • +
  • 3 - Local Access Risks
  • +
  • 4 - Remote Access Risks
  • +
  • A - Glossary
  • +
+

2 References

+

2.1 CUPS Documentation

+

The following CUPS documentation is referenced by this document:

+
    +
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • +
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • +
  • CUPS-IPP-1.1: CUPS Implmentation of IPP
  • +
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • +
  • CUPS-SDD-1.1: CUPS Software Design Description
  • +
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual
  • +
  • CUPS-SSR-1.1: CUPS Software Security Report
  • +
  • CUPS-STP-1.1: CUPS Software Test Plan
  • +
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • +
  • CUPS-SVD-1.1.x: CUPS Software Version Description
  • +
+

2.2 Other Documents

+

The following non-CUPS documents are referenced by this document:

+ +

3 Local Access Risks

+

Local access risks are those that can be exploited only with a +local user account. This section does not address issues related to +dissemination of the root password or other security issues associated +with the UNIX operating system.

+

3.1 Security Breaches

+

There is one known security vulnerability with local access:

+
    +
  1. Device URIs are passed to backend filters in argv[0] and in an +environment variable. Since device URIs can contain usernames and +passwords it may be possible for a local user to gain access to a +remote resource.
  2. +

    We recommend that any password-protected accounts used for remote +printing have limited access priviledges so that the possible damages +can be minimized.

    +

    The device URI is "sanitized" (the username and password are + removed) when sent to an IPP client so that a remote user cannot +exploit this vulnerability.

    +
+

4 Remote Access Risks

+

Remote access risks are those that can be exploited without a local +user account and/or from a remote system. This section does not address +issues related to network or firewall security.

+

4.1 Denial of Service Attacks

+

Like all Internet services, the CUPS server is vulnerable to denial +of service attacks, including:

+
    +
  1. Establishing multiple connections to the server until the server + will accept no more.
  2. +

    This cannot be protected against by the current software. It is +possible that future versions of the CUPS software could be configured +to limit the number of connections allowed from a single host, however +that still would not prevent a distributed attack.

    +
  3. Repeatedly opening and closing connections to the server as fast + as possible.
  4. +

    There is no easy way of protecting against this in the CUPS + software. If the attack is coming from outside the local network it +might be possible to filter such an attack, however once the +connection request has been received by the server it must at least +accept the connection to find out who is connecting.

    +
  5. Flooding the network with broadcast packets on port 631.
  6. +

    It might be possible to disable browsing if this condition is +detected by the CUPS software, however if there are large numbers of +printers available on the network such an algorithm might think that +an attack was occurring when instead a valid update was being +received.

    +
  7. Sending partial IPP requests; specifically, sending part of an + attribute value and then stopping transmission.
  8. +

    The current code is structured to read and write the IPP request +data on-the-fly, so there is no easy way to protect against this for +large attribute values.

    +
  9. Sending large/long print jobs to printers, preventing other users + from printing.
  10. +

    There are limited facilities for protecting against large print + jobs (the MaxRequestSize attribute), however this will + not protect printers from malicious users and print files that + generate hundreds or thousands of pages. In general, we recommend + restricting printer access to known hosts or networks, and adding + user-level access control as needed for expensive printers.

    +
+

4.2 Security Breaches

+

The current CUPS server supports Basic, Digest, and local +certificate authentication:

+
    +
  1. Basic authentication essentially places the clear text of the +username and password on the network. Since CUPS uses the UNIX +username and password account information, the authentication +information could be used to gain access to accounts (possibly +priviledged accounts) on the server.
  2. +
  3. Digest authentication uses an MD5 checksum of the username, + password, and domain ("CUPS"), so the original username and password +is not sent over the network. However, the current implementation does +not authenticate the entire message and uses the client's IP address +for the nonce value, making it possible to launch "man in the middle" +and replay attacks from the same client. The next minor release of +CUPS will support Digest authentication of the entire message body, +effectively stopping these methods of attack.
  4. +
  5. Local certificate authentication passes 128-bit "certificates" +that identify an authenticated user. Certificates are created +on-the-fly from random data and stored in files under +/etc/cups/certs. They have restricted read permissions: root + +system for the root certificate, and lp + system for CGI certificates. +Because certificates are only available on the local system, the CUPS + server does not accept local authentication unless the client is +connected to the localhost address (127.0.0.1.)
  6. +
+

The default CUPS configuration disables remote administration. We +do not recommend that remote administration be enabled for all hosts. +However, if you have a trusted network or subnet, access can be +restricted accordingly. Also, we highly recommend using Digest +authentication when possible. Unfortunately, most web browsers do not +support Digest authentication at this time.

+

A Glossary

+

A.1 Terms

+
+
C
+
A computer language.
+
parallel
+
Sending or receiving data more than 1 bit at a time.
+
pipe
+
A one-way communications channel between two programs.
+
serial
+
Sending or receiving data 1 bit at a time.
+
socket
+
A two-way network communications channel.
+
+

A.2 Acronyms

+
+
ASCII
+
American Standard Code for Information Interchange
+
CUPS
+
Common UNIX Printing System
+
ESC/P
+
EPSON Standard Code for Printers
+
FTP
+
File Transfer Protocol
+
HP-GL
+
Hewlett-Packard Graphics Language
+
HP-PCL
+
Hewlett-Packard Page Control Language
+
HP-PJL
+
Hewlett-Packard Printer Job Language
+
IETF
+
Internet Engineering Task Force
+
IPP
+
Internet Printing Protocol
+
ISO
+
International Standards Organization
+
LPD
+
Line Printer Daemon
+
MIME
+
Multimedia Internet Mail Exchange
+
PPD
+
PostScript Printer Description
+
SMB
+
Server Message Block
+
TFTP
+
Trivial File Transfer Protocol
+
+ + diff --git a/doc/ssr.pdf b/doc/ssr.pdf new file mode 100644 index 0000000000000000000000000000000000000000..ce2a566dc17d44830e0906d647237442f1b13ffa GIT binary patch literal 29096 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 Dq^xaU literal 0 Hc-jL100001 diff --git a/doc/ssr.shtml b/doc/ssr.shtml new file mode 100644 index 0000000000..a192cdad47 --- /dev/null +++ b/doc/ssr.shtml @@ -0,0 +1,167 @@ + + + + + + CUPS Software Security Report + + + +

Scope

+ +

Identification

+ +

This software security report provides an analysis of possible security +concerns for the Common UNIX Printing System ("CUPS") Version 1.1.

+ + + +

Document Overview

+ +

This software security report is organized into the following sections:

+ +
    +
  • 1 - Scope
  • +
  • 2 - References
  • +
  • 3 - Local Access Risks
  • +
  • 4 - Remote Access Risks
  • +
  • A - Glossary
  • +
+ + + +

Local Access Risks

+ +

Local access risks are those that can be exploited only with a local user +account. This section does not address issues related to dissemination of the +root password or other security issues associated with the UNIX operating +system. + +

Security Breaches

+ +

There is one known security vulnerability with local access: + +

    + +
  1. Device URIs are passed to backend filters in argv[0] and in + an environment variable. Since device URIs can contain + usernames and passwords it may be possible for a local user to + gain access to a remote resource. + +

    We recommend that any password-protected accounts used for + remote printing have limited access priviledges so that the + possible damages can be minimized. + +

    The device URI is "sanitized" (the username and password are + removed) when sent to an IPP client so that a remote user + cannot exploit this vulnerability. + +

+ +

Remote Access Risks

+ +

Remote access risks are those that can be exploited without a local user +account and/or from a remote system. This section does not address issues +related to network or firewall security. + +

Denial of Service Attacks

+ +

Like all Internet services, the CUPS server is vulnerable to denial of +service attacks, including: + +

    + +
  1. Establishing multiple connections to the server until the server + will accept no more. + +

    This cannot be protected against by the current software. It + is possible that future versions of the CUPS software could be + configured to limit the number of connections allowed from a + single host, however that still would not prevent a distributed + attack. + +

  2. Repeatedly opening and closing connections to the server as fast + as possible. + +

    There is no easy way of protecting against this in the CUPS + software. If the attack is coming from outside the local + network it might be possible to filter such an attack, however + once the connection request has been received by the server it + must at least accept the connection to find out who is + connecting. + +

  3. Flooding the network with broadcast packets on port 631. + +

    It might be possible to disable browsing if this condition + is detected by the CUPS software, however if there are large + numbers of printers available on the network such an algorithm + might think that an attack was occurring when instead a valid + update was being received. + +

  4. Sending partial IPP requests; specifically, sending part of an + attribute value and then stopping transmission. + +

    The current code is structured to read and write the IPP + request data on-the-fly, so there is no easy way to protect + against this for large attribute values. + +

  5. Sending large/long print jobs to printers, preventing other users + from printing. + +

    There are limited facilities for protecting against large print + jobs (the MaxRequestSize attribute), however this will + not protect printers from malicious users and print files that + generate hundreds or thousands of pages. In general, we recommend + restricting printer access to known hosts or networks, and adding + user-level access control as needed for expensive printers. + +

+ +

Security Breaches

+ +

The current CUPS server supports Basic, Digest, and local certificate +authentication: + +

    + +
  1. Basic authentication essentially places the clear text of + the username and password on the network. Since CUPS uses the + UNIX username and password account information, the + authentication information could be used to gain access to + accounts (possibly priviledged accounts) on the server. + +
  2. Digest authentication uses an MD5 checksum of the username, + password, and domain ("CUPS"), so the original username and + password is not sent over the network. However, the current + implementation does not authenticate the entire message and + uses the client's IP address for the nonce value, making it + possible to launch "man in the middle" and replay attacks from + the same client. The next minor release of CUPS will support + Digest authentication of the entire message body, effectively + stopping these methods of attack. + +
  3. Local certificate authentication passes 128-bit + "certificates" that identify an authenticated user. + Certificates are created on-the-fly from random data and stored + in files under /etc/cups/certs. They have + restricted read permissions: root + system for the root + certificate, and lp + system for CGI certificates. Because + certificates are only available on the local system, the CUPS + server does not accept local authentication unless the client + is connected to the localhost address (127.0.0.1.) + +
+ +

The default CUPS configuration disables remote administration. We do +not recommend that remote administration be enabled for all hosts. +However, if you have a trusted network or subnet, access can be +restricted accordingly. + +Also, we highly recommend using Digest authentication when possible. +Unfortunately, most web browsers do not support Digest authentication +at this time. + + + + + diff --git a/doc/stp.html b/doc/stp.html new file mode 100644 index 0000000000..748c46a821 --- /dev/null +++ b/doc/stp.html @@ -0,0 +1,174 @@ + + + + DRAFT - CUPS Software Test Plan + + + + + + + +


+

DRAFT - CUPS Software Test Plan


+CUPS-STP-1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
1 Scope + +2 References + +3 Local Tests +
+
4 Remote Tests +
+
A Glossary + +
+

1 Scope

+

1.1 Identification

+

This software test plan provides detailed tests that are used to +evaluate the stability of the Common UNIX Printing System ("CUPS") +Version 1.1.

+

1.2 System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+

1.3 Document Overview

+

This software test plan is organized into the following sections:

+
    +
  • 1 - Scope
  • +
  • 2 - References
  • +
  • 3 - Local Tests
  • +
  • 4 - Remote Tests
  • +
  • A - Glossary
  • +
+

2 References

+

2.1 CUPS Documentation

+

The following CUPS documentation is referenced by this document:

+
    +
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • +
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • +
  • CUPS-IPP-1.1: CUPS Implmentation of IPP
  • +
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • +
  • CUPS-SDD-1.1: CUPS Software Design Description
  • +
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual
  • +
  • CUPS-SSR-1.1: CUPS Software Security Report
  • +
  • CUPS-STP-1.1: CUPS Software Test Plan
  • +
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • +
  • CUPS-SVD-1.1.x: CUPS Software Version Description
  • +
+

2.2 Other Documents

+

The following non-CUPS documents are referenced by this document:

+ +

3 Local Tests

+

4 Remote Tests

+

A Glossary

+

A.1 Terms

+
+
C
+
A computer language.
+
parallel
+
Sending or receiving data more than 1 bit at a time.
+
pipe
+
A one-way communications channel between two programs.
+
serial
+
Sending or receiving data 1 bit at a time.
+
socket
+
A two-way network communications channel.
+
+

A.2 Acronyms

+
+
ASCII
+
American Standard Code for Information Interchange
+
CUPS
+
Common UNIX Printing System
+
ESC/P
+
EPSON Standard Code for Printers
+
FTP
+
File Transfer Protocol
+
HP-GL
+
Hewlett-Packard Graphics Language
+
HP-PCL
+
Hewlett-Packard Page Control Language
+
HP-PJL
+
Hewlett-Packard Printer Job Language
+
IETF
+
Internet Engineering Task Force
+
IPP
+
Internet Printing Protocol
+
ISO
+
International Standards Organization
+
LPD
+
Line Printer Daemon
+
MIME
+
Multimedia Internet Mail Exchange
+
PPD
+
PostScript Printer Description
+
SMB
+
Server Message Block
+
TFTP
+
Trivial File Transfer Protocol
+
+ + diff --git a/doc/stp.pdf b/doc/stp.pdf new file mode 100644 index 0000000000000000000000000000000000000000..05444510ffd2e6154cc1aac90ca7b781ae5a1a11 GIT binary patch literal 25064 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 literal 0 Hc-jL100001 diff --git a/doc/stp.shtml b/doc/stp.shtml new file mode 100644 index 0000000000..729a8f6412 --- /dev/null +++ b/doc/stp.shtml @@ -0,0 +1,47 @@ + + + + + + + DRAFT - CUPS Software Test Plan + + + +

Scope

+ +

Identification

+ +

This software test plan provides detailed tests that are used to evaluate +the stability of the Common UNIX Printing System ("CUPS") Version 1.1. + + + +

Document Overview

+ +

This software test plan is organized into the following sections: + +

    +
  • 1 - Scope
  • +
  • 2 - References
  • +
  • 3 - Local Tests
  • +
  • 4 - Remote Tests
  • +
  • A - Glossary
  • +
+ + + +

Local Tests

+ + + + +

Remote Tests

+ + + + + + + + diff --git a/doc/sum.html b/doc/sum.html new file mode 100644 index 0000000000..71b559cfa7 --- /dev/null +++ b/doc/sum.html @@ -0,0 +1,1643 @@ + + + + CUPS Software Users Manual + + + + + + + +

+

CUPS Software Users Manual


+CUPS-SUM-1.1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
Preface + +1 - Printing System Overview + +2 - Using the Printing System + +3 - Standard Printer Options + +4 - Saving Printer Options and Defaults + +A - Software License Agreement + +
+

Preface

+

This software users manual describes how to use the Common UNIX +Printing SystemTM ("CUPSTM") Version 1.1.1.

+

System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+ + +

Document Overview

+

This software users manual is organized into the following sections:

+ +

Notation Conventions

+

Various font and syntax conventions are used in this guide. Examples +and their meanings and uses are explained below: +

+ + + + + + + + + + + + +
Example   Description
 
lpstat +
lpstat(1)
   The names of commands; +the first mention of a command or function in a chapter is followed by +a manual page section number.
 
/var +
/usr/share/cups/data/testprint.ps
    +File and directory names.
 
Request ID is Printer-123 +   Screen output.
 
lp -d printer filename ENTER +   Literal user input; special keys like ENTER are + in ALL CAPS.
 
12.3   Numbers in the text are +written using the period (.) to indicate the decimal point.
+
+ + +

+

Abbreviations

+ The following abbreviations are used throughout this manual: +
    +
    +
    kb
    +
    Kilobytes, or 1024 bytes +
     
    +
    Mb
    +
    Megabytes, or 1048576 bytes +
     
    +
    Gb
    +
    Gigabytes, or 1073741824 bytes +
     
    +
    +
+

Other References

+
    +
    +
    CUPS Software Administrators Manual
    +
    An administration guide for the CUPS software. +
     
    +
    CUPS Software Programmers Manual
    +
    A programmer guide for interfacing with and/or extending the CUPS + software. +
     
    +
    +
+

1 - Printing System Overview

+

This chapter provides an overview of how the Common UNIX Printing +System works.

+

The Printing Problem

+

For years the printing problem has plagued UNIX. Unlike +Microsoft® Windows® or Mac OS, UNIX has no standard interface or system +in place for supporting printers. Among the solutions currently +available, the Berkeley and System V printing systems are the most +prevalent.

+

These printing systems support line printers (text only) or +PostScript printers (text and graphics), and with some coaxing they can +be made to support a full range of printers and file formats. However, +because each varient of the UNIX operating system uses a different +printing system than the next developing printer drivers for a wide +range of printers and operating systems is extremely difficult. That +combined with the limited volume of customers for each UNIX varient has +forced most printer vendors to give up supporting UNIX entirely.

+

CUPS is designed to eliminate the printing problem. One +common printing system can be used by all UNIX varients to support the +printing needs of users. Printer vendors can use its modular filter +interface to develop a single driver program that supports a wide range +of file formats with little or no effort. Since CUPS provides both the +System V and Berkeley printing commands, users (and applications) can +reap the benefits of this new technology with no changes.

+

The Technology

+

CUPS is based upon an emerging Internet standard called the Internet +Printing Protocol. IPP has been embraced by dozens of printer and +printer server manufacturers and is supported by Microsoft Windows +2000.

+

IPP defines a standard protocol for printing as well as managing +print jobs and printer options like media size, resolution, and so +forth. Like all IP-based protocols, IPP can be used locally or over the +Internet to printers hundreds or thousands of miles away. Unlike other +protocols, however, IPP also supports access control, authentication, +and encryption, making it a much more capable and secure printing +solution than older ones.

+

IPP is layered on top of the Hyper-Text Transport Protocol ("HTTP") +which is the basis of web servers on the Internet. This allows users to +view documentation, check status information on a printer or server, +and manage their printers, classes, and jobs using their web browser.

+

CUPS provides a complete IPP/1.1 based printing system that provides +Basic, Digest, and local certificate authentication and user, domain, +or IP-based access control. TLS encryption will be available in future +versions of CUPS.

+

Jobs

+

Each file or set of files that is submitted for printing is called a +job. Jobs are identified by a unique number starting at 1 and are +assigned to a particular destination, usually a printer. Jobs can also +have options associated with them such as media size, number of copies, +and priority.

+

Classes

+

CUPS supports collections of printers known as classes. Jobs +sent to a class are forwarded to the first available printer in the +class.

+

Filters

+

Filters allow a user or application to print many types of files +without extra effort. Print jobs sent to a CUPS server are filtered +before sending them to a printer. Some filters convert job files to +different formats that the printer can understand. Others perform page +selection and ordering tasks.

+

CUPS provides filters for printing many types of image files, +HP-GL/2 files, PDF files, and text files. CUPS also supplies PostScript +and image file Raster Image Processor ("RIP") filters that convert +PostScript or image files into bitmaps that can be sent to a raster +printer.

+

Backends

+

Backends perform the most important task of all - they send the +filtered print data to the printer.

+

CUPS provides backends for printing over parallel, serial, and USB +ports, and over the network via the IPP, JetDirect (AppSocket), and +Line Printer Daemon ("LPD") protocols. Additional backends are +available in network service packages such as the SMB backend included +with the popular SAMBA software.

+

Backends are also used to determine the available devices. On +startup each backend is asked for a list of devices it supports, and +any information that is available. This allows the parallel backend to +tell CUPS that an EPSON Stylus Color 600 printer is attached to +parallel port 1, for example.

+

Printer Drivers

+

Printer drivers in CUPS consist of one of more filters specific to a +printer. CUPS includes sample printer drivers for Hewlett-Packard +LaserJet and DeskJet printers and EPSON 9-pin, 24-pin, Stylus Color, +and Stylus Photo printers. While these drivers do not generate optimal +output for the different printer models, they do provide basic printing +and demonstrate how you can write your own printer drivers and +incorporate them into CUPS.

+

Networking

+

Printers and classes on the local system are automatically shared +with other systems on the network. This allows you to setup one system +to print to a printer and use this system as a printer server or spool +host for all of the others. Users may then select a local printer by +name or a remote printer using "name@server".

+

CUPS also provides implicit classes, which are collections of +printers and/or classes with the same name. This allows you to setup +multiple servers pointing to the same physical network printer, for +example, so that you aren't relying on a single system for printing. +Because this also works with printer classes, you can setup multiple +servers and printers and never worry about a single point of failure +unless all of the printers and servers go down!

+

2 - Using the Printing System +

+

This chapter shows you how to submit, query, and cancel print jobs +to different printers.

+

Submitting Files for Printing

+

CUPS provides both the System V (lp(1)) and Berkeley ( +lpr(1)) printing commands. Type the following command to print a +file to the default (or only) printer on the system:

+
    +
    +lp filename ENTER
    +
    +
+

or:

+
    +
    +lpr filename ENTER
    +
    +
+

CUPS understands many different types of files directly, including +PostScript and image files. This allows you to print from inside your +applications or at the command-line, whichever is most convenient!

+

Choosing a Printer

+

Many systems will have more than one printer available to the user. +These printers can be attached to the local system via a parallel, +serial, or USB port, or available over the network.

+

Use the lpstat(1) command to see a list of available +printers:

+
    +
    +lpstat -p -d ENTER
    +
    +
+

The -p option specifies that you want to see a list of +printers, and the -d option reports the current system +default printer or class.

+

Use the -d option with the lp command to +print to a specific printer:

+
    +
    +lp -d printer filename ENTER
    +
    +
+

or the -P option with the lpr command:

+
    +
    +lpr -P printer filename ENTER
    +
    +
+

Setting Printer Options

+

For many types of files, the default printer options may be +sufficient for your needs. However, there may be times when you need to +change the options for a particular file you are printing.

+

The lp and lpr commands allow you to pass +printer options using the -o option:

+
    +
    +lp -o landscape -o scaling=75 -o media=A4 filename.jpg
    +lpr -o landscape -o scaling=75 -o media=A4 filename.jpg
    +
    +
+

The available printer options vary depending on the printer. The +standard options are described in Chapter +3, "Standard Printing Options".

+

Printing Multiple Copies

+

Both the lp and lpr commands have options +for printing more than one copy of a file:

+
    +
    +lp -n num-copies filename ENTER
    +lpr -#num-copies filename ENTER
    +
    +
+

Copies are normally not collated for you. Use the -o +Collate=True option to get collated copies :

+
    +
    +lp -n num-copies -o Collate=True filename ENTER
    +lpr -#num-copies -o Collate=True filename ENTER
    +
    +
+ + +

Checking the Printer Status from the Command-Line

+

The lpstat command can be used to check for jobs that +you have submitted for printing:

+
    +
    +lpstat ENTER
    +Printer-1 johndoe 4427776
    +Printer-2 johndoe 15786
    +Printer-3 johndoe 372842
    +
    +
+

The jobs are listed in the order they will be printed. Use the +-p option to see which files and printers are active:

+
    +
    +lpstat -p ENTER
    +printer DeskJet now printing DeskJet-1.
    +
    +
+ + +

Use the -o and -p options together to show +the jobs and the printers:

+
    +
    +lpstat -o -p ENTER
    +Printer-1 johndoe 4427776
    +Printer-2 johndoe 15786
    +Printer-3 johndoe 372842
    +printer DeskJet now printing DeskJet-1.
    +
    +
+

Checking the Printer Status from the Web

+

Since CUPS uses the Internet Printing Protocol, it is also a +fully-functional web server. To use your web browser to monitor the +printers on your system, open the URL:

+ +

From there you can view the status of classes, jobs, and printers +with the click of a button!

+

Canceling a Print Job

+

The cancel(1) and lprm(1) commands cancel +a print job:

+
    +
    +cancel job-id ENTER
    +lprm job-id ENTER
    +
    +
+

The job-id is the number that was reported to you by +the lp or lpstat commands.

+

3 - Standard Printer +Options

+

This chapter describes the standard printer options that are +available when printing with the lp and lpr + commands.

+

General Options

+

The following options apply when printing all types of files.

+

Setting the Orientation

+

The -o landscape option will rotate the page 90 degrees +to print in landscape orientation:

+
    +
    +lp -o landscape filename ENTER
    +lpr -o landscape filename ENTER
    +
    +
+ + +

Selecting the Media Size, Type, and Source

+

The -o media=xyz option sets the media size, type, +and/or source:

+
    +
    +lp -o media=Letter filename ENTER
    +lp -o media=Letter,MultiPurpose filename ENTER
    +lpr -o media=Letter,Transparency filename ENTER
    +lpr -o media=Letter,MultiPurpose,Transparency filename ENTER
    +
    +
+ + +

The available media sizes, types, and sources depend on the printer, +but most support the following options (case is not significant):

+
    +
  • Letter - US Letter (8.5x11 inches, or 216x279mm)
  • +
  • Legal - US Legal (8.5x14 inches, or 216x356mm)
  • +
  • A4 - ISO A4 (8.27x11.69 inches, or 210x297mm)
  • +
  • COM10 - US #10 Envelope (9.5x4.125 inches, or + 241x105mm)
  • +
  • DL - ISO DL Envelope (8.66x4.33 inches, or 220x110mm)
  • +
  • Transparency - Transparency media type or source
  • +
  • Upper - Upper paper tray
  • +
  • Lower - Lower paper tray
  • +
  • MultiPurpose - Multi-purpose paper tray
  • +
  • LargeCapacity - Large capacity paper tray
  • +
+

The actual options supported are defined in the printer's PPD file +in the PageSize, InputSlot, and +MediaType options.

+

Printing On Both Sides of the Paper

+

The -o sides=two-sided-short-edge and -o +sides=two-sided-long-edge options will enable duplexing on the +printer, if the printer supports it. The -o +sides=two-sided-short-edge option is suitable for landscape +pages, while the -o sides=two-sided-long-edge option is +suitable for portrait pages:

+
    +
    +lp -o sides=two-sided-short-edge filename ENTER
    +lp -o sides=two-sided-long-edge filename ENTER
    +lpr -o sides=two-sided-long-edge filename ENTER
    +
    +
+

The default is to print single-sided:

+
    +
    +lp -o sides=one-sided filename ENTER
    +lpr -o sides=one-sided filename ENTER
    +
    +
+

Banner Options

+

The following options apply when printing all types of files.

+

Selecting the Banner Page(s)

+

The -o jobsheets=start,end option sets the banner +page(s) to use for a job:

+
    +
    +lp -o job-sheets=none filename ENTER
    +lp -o job-sheets=standard filename ENTER
    +lpr -o job-sheets=classified,classified filename ENTER
    +
    +
+

If only one banner file is specified, it will be printed before the +files in the job. If a second banner file is specified, it is printed +after the files in the job.

+

The available banner pages depend on the local system configuration; +CUPS includes the following banner files:

+
    +
  • none - Do not produce a banner page.
  • +
  • classified - A banner page with a "classified" label +at the top and bottom.
  • +
  • confidential - A banner page with a "confidential" +label at the top and bottom.
  • +
  • secret - A banner page with a "secret" label at the +top and bottom.
  • +
  • standard - A banner page with no label at the top and +bottom.
  • +
  • topsecret - A banner page with a "top secret" label +at the top and bottom.
  • +
  • unclassified - A banner page with an "unclassified" +label at the top and bottom.
  • +
+

Document Options

+

The following options apply when printing all types of files.

+

Selecting a Range of Pages

+

The -o page-ranges=pages option selects a range of +pages for printing:

+
    +
    +lp -o page-ranges=1 filename ENTER
    +lp -o page-ranges=1-4 filename ENTER
    +lp -o page-ranges=1-4,7,9-12 filename ENTER
    +lpr -o page-ranges=1-4,7,9-12 filename ENTER
    +
    +
+

As shown above, the pages value can be a single page, a +range of pages, or a collection of page numbers and ranges separated by +commas. The pages will always be printed in ascending order, regardless +of the order of the pages in the page-ranges option.

+

The default is to print all pages.

+

Selecting Even or Odd Pages

+

Use the -o page-set=set option to select the even or +odd pages:

+
    +
    +lp -o page-set=odd filename ENTER
    +lp -o page-set=even filename ENTER
    +lpr -o page-set=even filename ENTER
    +
    +
+

The default is to print all pages.

+

N-Up Printing

+

The -o number-up=value option selects N-Up printing. + N-Up printing places multiple document pages on a single printed page. + CUPS supports 1-Up, 2-Up, and 4-Up formats:

+
    +
    +lp -o number-up=1 filename ENTER
    +lp -o number-up=2 filename ENTER
    +lp -o number-up=4 filename ENTER
    +lpr -o number-up=4 filename ENTER
    +
    +
+

The default format is 1-Up.

+

Setting the Brightness

+

You can control the overall brightness of the printed output using +the -o brightness=percent option:

+
    +
    +lp -o brightness=120 filename ENTER
    +lpr -o brightness=120 filename ENTER
    +
    +
+

Values greater than 100 will lighten the print, while values less +than 100 will darken it.

+

Setting the Gamma Correction

+

You can control the overall gamma correction of the printed output +using the -o gamma=value option:

+
    +
    +lp -o gamma=1700 filename ENTER
    +lpr -o gamma=1700 filename ENTER
    +
    +
+

Values greater than 1000 will lighten the print, while values less +than 1000 will darken it. The default gamma is 1000.

+

Text Options

+

The following options apply when printing text files.

+

Setting the Number of Characters Per Inch

+

The -o cpi=value option sets the number of characters +per inch:

+
    +
    +lp -o cpi=10 filename ENTER
    +lp -o cpi=12 filename ENTER
    +lpr -o cpi=17 filename ENTER
    +
    +
+

The default characters per inch is 10.

+

Setting the Number of Lines Per Inch

+

The -o lpi=value option sets the number of lines per +inch:

+
    +
    +lp -o lpi=6 filename ENTER
    +lpr -o lpi=8 filename ENTER
    +
    +
+

The default lines per inch is 6.

+

Setting the Number of Columns

+

The -o columns=value option sets the number of text +columns:

+
    +
    +lp -o columns=2 filename ENTER
    +lpr -o columns=3 filename ENTER
    +
    +
+

The default number of columns is 1.

+

Setting the Page Margins

+

Normally the page margins are set to the hard limits of the printer. +Use the -o page-left=value, -o page-right=value +, -o page-top=value, and -o page-bottom=value + options to adjust the page margins:

+
    +
    +lp -o page-left=value filename ENTER
    +lp -o page-right=value filename ENTER
    +lp -o page-top=value filename ENTER
    +lp -o page-bottom=value filename ENTER
    +lpr -o page-bottom=value filename ENTER
    +
    +
+

The value argument is the margin in points; each point +is 1/72 inch or 0.35mm.

+

Pretty Printing

+

The -o prettyprint option puts a header at the top of +each page with the page number, job title (usually the filename), and +the date. Also, C and C++ keywords are highlighted, and comment lines +are italicized:

+
    +
    +lp -o prettyprint filename ENTER
    +lpr -o prettyprint filename ENTER
    +
    +
+

Image Options

+

The following options apply when printing image files.

+

Positioning the Image

+

The -o position=name option specifies the position of +the image on the page:

+
    +
  • center - Center the image on the page (default)
  • +
  • top - Print the image centered at the top of the page
  • +
  • left - Print the image centered on the left of page
  • +
  • right - Print the image centered on the right of the +page
  • +
  • top-left - Print the image at the top left corner of + the page
  • +
  • top-right - Print the image at the top right corner of + the page
  • +
  • bottom - Print the image centered at the bottom of + the page
  • +
  • bottom-left - Print the image at the bottom left + corner of the page
  • +
  • bottom-right - Print the image at the bottom right + corner of the page
  • +
+

Scaling the Image

+

The -o scaling=percent and -o ppi=value + options change the size of a printed image:

+
    +
    +lp -o scaling=percent filename ENTER
    +lp -o ppi=value filename ENTER
    +lpr -o ppi=value filename ENTER
    +
    +
+

The percent value is a number from 1 to 800 specifying +the size in relation to the page (not the image.) A scaling of +100 percent will fill the page as completely as the image aspect ratio +allows. A scaling of 200 percent will print on up to 4 pages.

+

The ppi value is a number from 1 to 1200 specifying the +resolution of the image in pixels per inch. An image that is 3000x2400 +pixels will print 10x8 inches at 300 pixels per inch, for example. If +the specified resolution makes the image larger than the page, multiple +pages will be printed to satisfy the request.

+

Adjusting the Hue (Tint) of an Image

+

The -o hue=value option will adjust the hue of the +printed image, much like the tint control on your television:

+
    +
    +lp -o hue=value filename ENTER
    +lpr -o hue=value filename ENTER
    +
    +
+ + +

The value argument is a number from -360 to 360 and +represents the color hue rotation. The following table summarizes the +change you'll see with different colors: +

+ + + + + + + + +
Originalhue=-45hue=45
RedPurpleYellow-orange
GreenYellow-greenBlue-green
YellowOrangeGreen-yellow
BlueSky-bluePurple
MagentaIndigoCrimson
CyanBlue-greenLight-navy-blue
+
+

+

The default hue adjustment is 0.

+

Adjusting the Saturation (Color) of an Image

+

The -o saturation=percent option adjusts the saturation +of the colors in an image, much like the color knob on your television:

+
    +
    +lp -o saturation=percent filename ENTER
    +lpr -o saturation=percent filename ENTER
    +
    +
+

The percent argument specifies the color saturation +from 0 to 200. A color saturation of 0 produces a black-and-white +print, while a value of 200 will make the colors extremely intense.

+

The default saturation is 100. + +

+

HP-GL/2 Options

+

The following options apply to HP-GL/2 files.

+

Printing in Black

+

The -o blackplot option specifies that all pens should +plot in black:

+
    +
    +lp -o blackplot filename ENTER
    +lpr -o blackplot filename ENTER
    +
    +
+

The default is to use the colors defined in the plot file or the +standard pen colors defined in the HP-GL/2 reference manual from +Hewlett Packard.

+

Fitting the Plot on the Page

+

The -o fitplot option specifies that the plot should be +scaled to fit on the page:

+
    +
    +lp -o fitplot filename ENTER
    +lpr -o fitplot filename ENTER
    +
    +
+

The default is to use the absolute distances specified in the plot +file. +

+ + +
NOTE: +

This feature depends upon an accurate plot size (PS) + command in the HP-GL/2 file. If no plot size is given in the file + than the HP-GL/2 filter assumes the plot is ANSI E size.

+
+
+

+

Setting the Default Pen Width

+

The -o penwidth=value option specifies the default pen +width for HP-GL/2 files:

+
    +
    +lp -o penwidth=value filename ENTER
    +lpr -o penwidth=value filename ENTER
    +
    +
+

The pen width value specifies the pen width in +micrometers. The default value of 1000 produces lines that are 1 +millimeter in width. Specifying a pen width of 0 produces lines that +are exactly 1 pixel wide. +

+ + +
NOTE: +

This option is ignored when the pen widths are set in the plot +file.

+
+
+

+

Raw or Unfiltered Output

+

The -o raw option allows you to send files directly to +a printer without filtering. This is sometimes required when printing +from applications that provide their own "printer drivers" for your +printer:

+
    +
    +lp -o raw filename ENTER
    +lpr -o raw filename ENTER
    +
    +
+

The -l option can also be used with the lpr + command to send files directly to a printer:

+
    +
    +lpr -l filename ENTER
    +
    +
+

4 - Saving Printer Options +and Defaults

+

This chapter describes how to save printer options for your printer +and set your own default printer.

+

Printer Options

+

Each printer supports a large number of options, which you learned +about in Chapter 3, "Standard Printer +Options". Rather than specifying these options each time you print +a file, CUPS allows you to save them as "default" options for the +printer.

+

The lpoptions(1) command saves the options for your +printers. Like the lp and lpr commands, it +accepts printer options using the -o argument:

+
    +
    +lpoptions -o media=A4 -o sides=two-sided-long-edge ENTER
    +lpoptions -o media=Legal -o scaling=100 ENTER
    +
    +
+

Once saved, any lp or lpr command will use +them when you print.

+

Setting Options for a Specific Printer

+

The previous example shows how to set the options for the default +printer. The -p printer option specifies the options are +for another printer:

+
    +
    +lpoptions -p laserjet -o media=A4 -o sides=two-sided-long-edge ENTER
    +lpoptions -p deskjet -o media=Legal -o scaling=100 ENTER
    +
    +
+

Viewing the Current Defaults

+

The lpoptions command can also be used to show the +current options by not specifying any new options on the command-line:

+
    +
    +lpoptions ENTER
    +media=A4 sides=two-sided-long-edge
    +lpoptions -p deskjet ENTER
    +media=Legal scaling=100
    +
    +
+

Setting the Default Printer

+

The administrator normally will set a system-wide default printer +that is normally used as the default printer by everyone. Use the +-d printer option to set your own default printer:

+
    +
    +lpoptions -d deskjet ENTER
    +
    +
+

The printer can be local (deskjet) or remote ( +deskjet@server).

+

Printer Instances

+

Besides setting options for each print queue, CUPS supports +printer instances which allow you to define several different sets +of options for each printer. You specify a printer instance using the +slash (/) character:

+
    +
    +lpoptions -p laserjet/duplex -o sides=two-sided-long-edge ENTER
    +lpoptions -p laserjet/legal -o media=Legal ENTER
    +
    +
+

The lp and lpr commands also understand this notation:

+
    +
    +lp -d laserjet/duplex filename ENTER
    +lpr -P laserjet/legal filename ENTER
    +
    +
+

Removing Instances

+

Use the -x printer/instance option to remove a printer +instance that you no longer need:

+
    +
    +lpoptions -x laserjet ENTER
    +lpoptions -x laserjet/duplex ENTER
    +lpoptions -x laserjet/legal ENTER
    +
    +
+

The -x option only removes the default options for that +printer and instance; the original print queue will remain until +deleted with the lpadmin(8) command by the administrator.

+

A - Software License Agreement

+

Common UNIX Printing System License +Agreement

+

Copyright 1997-2000 by Easy Software Products +
44141 AIRPORT VIEW DR STE 204 +
HOLLYWOOD, MARYLAND 20636-3111 USA +
+
Voice: +1.301.373.9603 +
Email: cups-info@cups.org +
WWW: http://www.cups.org

+

Introduction

+

The Common UNIX Printing SystemTM, ("CUPSTM"), +is provided under the GNU General Public License ("GPL") and GNU +Library General Public License ("LGPL"), Version 2. A copy of these +licenses follow this introduction.

+

The GNU LGPL applies to the CUPS API library, located in the "cups" +subdirectory of the CUPS source distribution and in the +"/usr/include/cups" directory and "libcups.a", "libcups.sl", or +"libcups.so" files in the binary distributions.

+

The GNU GPL applies to the remainder of the CUPS distribution, +including the "pstoraster" filter which is based upon GNU Ghostscript +5.50 and the "pdftops" filter which is based upon Xpdf 0.90.

+

For those not familiar with the GNU GPL, the license basically +allows you to:

+
    +
  • Use the CUPS software at no charge.
  • +
  • Distribute verbatim copies of the software in source or binary +form.
  • +
  • Sell verbatim copies of the software for a media fee, or sell +support for the software.
  • +
  • Distribute or sell printer drivers and filters that use CUPS so +long as source code is made available under the GPL.
  • +
+

What this license does not allow you to do is make changes or +add features to CUPS and then sell a binary distribution without source +code. You must provide source for any new drivers, changes, or +additions to the software, and all code must be provided under the GPL +or LGPL as appropriate.

+

The GNU LGPL relaxes the "link-to" restriction, allowing you to +develop applications that use the CUPS API library under other licenses +and/or conditions as appropriate for your application.

+

Trademarks

+

Easy Software Products has trademarked the Common UNIX Printing +System, CUPS, and CUPS logo. These names and logos may be used freely +in any direct port or binary distribution of CUPS. To use them in +derivative products, please contract Easy Software Products for written +permission. Our intention is to protect the value of these trademarks +and ensure that any derivative product meets the same high-quality +standards as the original.

+

Binary Distribution Rights

+

Easy Software Products also sells rights to the CUPS source code +under a binary distribution license for vendors that are unable to +release source code for their drivers, additions, and modifications to +CUPS under the GNU GPL and LGPL. For information please contact us at +the address shown above.

+

The Common UNIX Printing System provides a "pstoraster" filter that +utilizes the GNU GhostScript 5.50 core to convert PostScript files into +a stream of raster images. For binary distribution licensing of this +software, please contact:

Miles Jones +
Director of Marketing +
Artifex Software Inc. +
454 Las Gallinas Ave., Suite 108 +
San Rafael, CA 94903 USA +
Voice: +1.415.492.9861 +
Fax: +1.415.492.9862 +
EMail: info@arsoft.com
+

+

The "pdftops" filter is based on the Xpdf 0.90 software. For binary +distribution licensing of this software, please contact:

+ Derek B. Noonburg +
Email: derekn@foolabs.com +
WWW: +http://www.foolabs.com/xpdf/

+

Support

+

Easy Software Products sells software support for CUPS as well as a +commercial printing product based on CUPS called ESP Print Pro. You can +find out more at our web site:

+ + + +

GNU GENERAL PUBLIC LICENSE

+

Version 2, June 1991

+
+Copyright 1989, 1991 Free Software Foundation, Inc.
+59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+Everyone is permitted to copy and distribute verbatim
+copies of this license document, but changing it is not allowed.
+
+
+
+
+

Preamble

+

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too.

+

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things.

+

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it.

+

For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights.

+

We protect your rights with two steps: (1) copyright the software, +and (2) offer you this license which gives you legal permission to +copy, distribute and/or modify the software.

+

Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, +we want its recipients to know that what they have is not the original, +so that any problems introduced by others will not reflect on the +original authors' reputations.

+

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all.

+

The precise terms and conditions for copying, distribution and +modification follow.

+

GNU GENERAL PUBLIC LICENSE +
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+
    +
  1. This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you".
  2. +

    Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does.

    +
  3. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy an appropriate copyright notice +and disclaimer of warranty; keep intact all the notices that refer to +this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the +Program.
  4. +

    You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee.

    +
  5. You may modify your copy or copies of the Program or any portion of +it, thus forming a work based on the Program, and copy and distribute +such modifications or work under the terms of Section 1 above, provided +that you also meet all of these conditions: +
      +
    1. You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change.
    2. +
    3. You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any part +thereof, to be licensed as a whole at no charge to all third parties +under the terms of this License.
    4. +
    5. if the modified program normally reads commands interactively when +run, you must cause it, when started running for such interactive use +in the most ordinary way, to print or display an announcement including +an appropriate copyright notice and a notice that there is no warranty +(or else, saying that you provide a warranty) and that users may +redistribute the program under these conditions, and telling the user +how to view a copy of this License. (Exception: if the Program itself +is interactive but does not normally print such an announcement, your +work based on the Program is not required to print an announcement.)
    6. +
    +
  6. +

    These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it.

    +

    Thus, it is not the intent of this section to claim rights or +contest your rights to work written entirely by you; rather, the intent +is to exercise the right to control the distribution of derivative or +collective works based on the Program.

    +

    In addition, mere aggregation of another work not based on the +Program with the Program (or with a work based on the Program) on a +volume of a storage or distribution medium does not bring the other +work under the scope of this License.

    +
  7. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: +
      +
    1. Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections 1 +and 2 above on a medium customarily used for software interchange; or,
    2. +
    3. Accompany it with a written offer, valid for at least three years, +to give any third party, for a charge no more than your cost of +physically performing source distribution, a complete machine-readable +copy of the corresponding source code, to be distributed under the +terms of Sections 1 and 2 above on a medium customarily used for +software interchange; or,
    4. +
    5. Accompany it with the information you received as to the offer to +distribute corresponding source code. (This alternative is allowed +only for noncommercial distribution and only if you received the +program in object code or executable form with such an offer, in accord +with Subsection b above.)
    6. +
    +
  8. +

    The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that +is normally distributed (in either source or binary form) with the +major components (compiler, kernel, and so on) of the operating system +on which the executable runs, unless that component itself accompanies +the executable.

    +

    If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent access +to copy the source code from the same place counts as distribution of +the source code, even though third parties are not compelled to copy +the source along with the object code.

    +
  9. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, +parties who have received copies, or rights, from you under this +License will not have their licenses terminated so long as such parties +remain in full compliance.
  10. +
  11. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying the +Program or works based on it.
  12. +
  13. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License.
  14. +
  15. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program.
  16. +

    If any portion of this section is held invalid or unenforceable +under any particular circumstance, the balance of the section is +intended to apply and the section as a whole is intended to apply in +other circumstances.

    +

    It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice.

    +

    This section is intended to make thoroughly clear what is believed +to be a consequence of the rest of this License.

    +
  17. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License may +add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among countries +not thus excluded. In such case, this License incorporates the +limitation as if written in the body of this License.
  18. +
  19. The Free Software Foundation may publish revised and/or new +versions of the General Public License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns.
  20. +

    Each version is given a distinguishing version number. If the +Program specifies a version number of this License which applies to it +and "any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a +version number of this License, you may choose any version ever +published by the Free Software Foundation.

    +
  21. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally.
  22. +
+

NO WARRANTY

+
    +
  1. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. + EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, +EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. + THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS +WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
  2. +
  3. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES.
  4. +
+

END OF TERMS AND CONDITIONS

+ + +

GNU LIBRARY GENERAL PUBLIC LICENSE

+

Version 2, June 1991

+
+Copyright (C) 1991 Free Software Foundation, Inc.
+59 Temple Place - Suite 330, Boston, MA  02111-1307, USA
+Everyone is permitted to copy and distribute verbatim copies
+of this license document, but changing it is not allowed.
+
+[This is the first released version of the library GPL.  It is
+ numbered 2 because it goes with version 2 of the ordinary GPL.]
+
+

Preamble

+

The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users.

+

This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too.

+

When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it in +new free programs; and that you know you can do these things.

+

To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the library, or if you modify it.

+

For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights.

+

Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library.

+

Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations.

+

Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all.

+

Most GNU software, including some libraries, is covered by the +ordinary GNU General Public License, which was designed for utility +programs. This license, the GNU Library General Public License, +applies to certain designated libraries. This license is quite +different from the ordinary one; be sure to read it in full, and don't +assume that anything in it is the same as in the ordinary license.

+

The reason we have a separate public license for some libraries is +that they blur the distinction we usually make between modifying or +adding to a program and simply using it. Linking a program with a +library, without changing the library, is in some sense simply using +the library, and is analogous to running a utility program or +application program. However, in a textual and legal sense, the linked +executable is a combined work, a derivative of the original library, +and the ordinary General Public License treats it as such.

+

Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better.

+

However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended +to permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to +achieve this as regards changes in header files, but we have achieved +it as regards changes in the actual functions of the Library.) The +hope is that this will lead to faster development of free libraries.

+

The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library.

+

Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one.

+

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

+

0. This License Agreement applies to any software +library which contains a notice placed by the copyright holder or other +authorized party saying it may be distributed under the terms of this +Library General Public License (also called "this License"). Each +licensee is addressed as "you".

+

A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables.

+

The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".)

+

"Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control +compilation and installation of the library.

+

Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does and +what the program that uses the Library does.

+

1. You may copy and distribute verbatim copies of +the Library's complete source code as you receive it, in any medium, +provided that you conspicuously and appropriately publish on each copy +an appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the Library.

+

You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee.

+

2. You may modify your copy or copies of the +Library or any portion of it, thus forming a work based on the Library, +and copy and distribute such modifications or work under the terms of +Section 1 above, provided that you also meet all of these conditions:

+
    +
  1. The modified work must itself be a software library.
  2. +

    +

  3. You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change.
  4. +

    +

  5. You must cause the whole of the work to be licensed at no charge +to all third parties under the terms of this License.
  6. +

    +

  7. If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses the +facility, other than as an argument passed when the facility is +invoked, then you must make a good faith effort to ensure that, in the +event an application does not supply such function or table, the +facility still operates, and performs whatever part of its purpose +remains meaningful.
  8. +

    (For example, a function in a library to compute square roots has a +purpose that is entirely well-defined independent of the application. + Therefore, Subsection 2d requires that any application-supplied +function or table used by this function must be optional: if the +application does not supply it, the square root function must still +compute square roots.)

    +
+

These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it.

+

Thus, it is not the intent of this section to claim rights or +contest your rights to work written entirely by you; rather, the intent +is to exercise the right to control the distribution of derivative or +collective works based on the Library.

+

In addition, mere aggregation of another work not based on the +Library with the Library (or with a work based on the Library) on a +volume of a storage or distribution medium does not bring the other +work under the scope of this License.

+

3. You may opt to apply the terms of the ordinary +GNU General Public License instead of this License to a given copy of +the Library. To do this, you must alter all the notices that refer to +this License, so that they refer to the ordinary GNU General Public +License, version 2, instead of to this License. (If a newer version +than version 2 of the ordinary GNU General Public License has appeared, +then you can specify that version instead if you wish.) Do not make +any other change in these notices.

+

Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy.

+

This option is useful when you wish to copy part of the code of the +Library into a program that is not a library.

+

4. You may copy and distribute the Library (or a +portion or derivative of it, under Section 2) in object code or +executable form under the terms of Sections 1 and 2 above provided that +you accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections 1 +and 2 above on a medium customarily used for software interchange.

+

If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to distribute +the source code, even though third parties are not compelled to copy +the source along with the object code.

+

5. A program that contains no derivative of any +portion of the Library, but is designed to work with the Library by +being compiled or linked with it, is called a "work that uses the +Library". Such a work, in isolation, is not a derivative work of the +Library, and therefore falls outside the scope of this License.

+

However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. Section +6 states terms for distribution of such executables.

+

When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law.

+

If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.)

+

Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, whether +or not they are linked directly with the Library itself.

+

6. As an exception to the Sections above, you may +also compile or link a "work that uses the Library" with the Library to +produce a work containing portions of the Library, and distribute that +work under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications.

+

You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things:

+
    +
  1. Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that uses +the Library", as object code and/or source code, so that the user can +modify the Library and then relink to produce a modified executable +containing the modified Library. (It is understood that the user who +changes the contents of definitions files in the Library will not +necessarily be able to recompile the application to use the modified +definitions.)
  2. +

    +

  3. Accompany the work with a written offer, valid for at least three +years, to give the same user the materials specified in Subsection 6a, +above, for a charge no more than the cost of performing this +distribution.
  4. +

    +

  5. If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place.
  6. +

    +

  7. Verify that the user has already received a copy of these + materials or that you have already sent this user a copy.
  8. +
+

For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major components +(compiler, kernel, and so on) of the operating system on which the +executable runs, unless that component itself accompanies the +executable.

+

It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute.

+

7. You may place library facilities that are a work +based on the Library side-by-side in a single library together with +other library facilities not covered by this License, and distribute +such a combined library, provided that the separate distribution of the +work based on the Library and of the other library facilities is +otherwise permitted, and provided that you do these two things:

+
    +
  1. Accompany the combined library with a copy of the same work based +on the Library, uncombined with any other library facilities. This +must be distributed under the terms of the Sections above.
  2. +

    +

  3. Give prominent notice with the combined library of the fact that +part of it is a work based on the Library, and explaining where to +find the accompanying uncombined form of the same work.
  4. +
+

8. You may not copy, modify, sublicense, link with, +or distribute the Library except as expressly provided under this +License. Any attempt otherwise to copy, modify, sublicense, link with, +or distribute the Library is void, and will automatically terminate +your rights under this License. However, parties who have received +copies, or rights, from you under this License will not have their +licenses terminated so long as such parties remain in full compliance.

+

9. You are not required to accept this License, +since you have not signed it. However, nothing else grants you +permission to modify or distribute the Library or its derivative works. + These actions are prohibited by law if you do not accept this License. + Therefore, by modifying or distributing the Library (or any work based +on the Library), you indicate your acceptance of this License to do so, +and all its terms and conditions for copying, distributing or modifying +the Library or works based on it.

+

10. Each time you redistribute the Library (or any +work based on the Library), the recipient automatically receives a +license from the original licensor to copy, distribute, link with or +modify the Library subject to these terms and conditions. You may not +impose any further restrictions on the recipients' exercise of the +rights granted herein. You are not responsible for enforcing compliance +by third parties to this License.

+

11. If, as a consequence of a court judgment or +allegation of patent infringement or for any other reason (not limited +to patent issues), conditions are imposed on you (whether by court +order, agreement or otherwise) that contradict the conditions of this +License, they do not excuse you from the conditions of this License. + If you cannot distribute so as to satisfy simultaneously your +obligations under this License and any other pertinent obligations, +then as a consequence you may not distribute the Library at all. For +example, if a patent license would not permit royalty-free +redistribution of the Library by all those who receive copies directly +or indirectly through you, then the only way you could satisfy both it +and this License would be to refrain entirely from distribution of the +Library.

+

If any portion of this section is held invalid or unenforceable +under any particular circumstance, the balance of the section is +intended to apply, and the section as a whole is intended to apply in +other circumstances.

+

It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is implemented +by public license practices. Many people have made generous +contributions to the wide range of software distributed through that +system in reliance on consistent application of that system; it is up +to the author/donor to decide if he or she is willing to distribute +software through any other system and a licensee cannot impose that +choice.

+

This section is intended to make thoroughly clear what is believed +to be a consequence of the rest of this License.

+

12. If the distribution and/or use of the Library +is restricted in certain countries either by patents or by copyrighted +interfaces, the original copyright holder who places the Library under +this License may add an explicit geographical distribution limitation +excluding those countries, so that distribution is permitted only in or +among countries not thus excluded. In such case, this License +incorporates the limitation as if written in the body of this License.

+

13. The Free Software Foundation may publish +revised and/or new versions of the Library General Public License from +time to time. Such new versions will be similar in spirit to the +present version, but may differ in detail to address new problems or +concerns.

+

Each version is given a distinguishing version number. If the +Library specifies a version number of this License which applies to it +and "any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation.

+

14. If you wish to incorporate parts of the Library +into other free programs whose distribution conditions are incompatible +with these, write to the author to ask for permission. For software +which is copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally.

+

NO WARRANTY

+

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, +THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT +WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE +OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU +ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

+

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW +OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY +WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE +LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL +OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES.

+

END OF TERMS AND CONDITIONS

+ + diff --git a/doc/sum.pdf b/doc/sum.pdf new file mode 100644 index 0000000000..3c1f188e8e --- /dev/null +++ b/doc/sum.pdf @@ -0,0 +1,1299 @@ +%PDF-1.2 +%âãÏÓ +1 0 obj<>endobj +2 0 obj<>endobj +3 0 obj<>endobj +4 0 obj<>endobj +5 0 obj<>endobj +6 0 obj<>endobj +7 0 obj<>endobj +8 0 obj<>endobj +9 0 obj<>endobj +10 0 obj<>endobj +11 0 obj<>endobj +12 0 obj<>endobj +13 0 obj<>endobj +14 0 obj<>endobj +15 0 obj<>endobj +16 0 obj<>endobj +17 0 obj<>endobj +18 0 obj[15 0 R +17 0 R +]endobj +19 0 obj<>endobj +20 0 obj<>endobj +21 0 obj<>endobj +22 0 obj<>endobj +23 0 obj<>endobj +24 0 obj[19 0 R +20 0 R +21 0 R +22 0 R +23 0 R +]endobj +25 0 obj<>endobj +26 0 obj<>endobj +27 0 obj[25 0 R +26 0 R +]endobj +28 0 obj<>endobj +29 0 obj<>endobj +30 0 obj[29 0 R +]endobj +31 0 obj<>endobj +32 0 obj<>endobj +33 0 obj[31 0 R +32 0 R +]endobj +34 0 obj<>endobj +35 0 obj<>endobj +36 0 obj<>endobj +37 0 obj<>endobj +38 0 obj[35 0 R +37 0 R +]endobj +39 0 obj<>endobj +40 0 obj<>endobj +41 0 obj<>endobj +42 0 obj<>endobj +43 0 obj<>endobj +44 0 obj<>endobj +45 0 obj[40 0 R +42 0 R +44 0 R +]endobj +46 0 obj<>endobj +47 0 obj<>endobj +48 0 obj[47 0 R +]endobj +49 0 obj<>endobj +50 0 obj<>endobj +51 0 obj<>endobj +52 0 obj<>endobj +53 0 obj<>endobj +54 0 obj<>endobj +55 0 obj<>endobj +56 0 obj<>endobj +57 0 obj<>endobj +58 0 obj<>endobj +59 0 obj<>endobj +60 0 obj<>endobj +61 0 obj<>endobj +62 0 obj<>endobj +63 0 obj<>endobj +64 0 obj<>endobj +65 0 obj<>endobj +66 0 obj<>endobj +67 0 obj<>endobj +68 0 obj<>endobj +69 0 obj<>endobj +70 0 obj<>endobj +71 0 obj<>endobj +72 0 obj<>endobj +73 0 obj<>endobj +74 0 obj<>endobj +75 0 obj<>endobj +76 0 obj<>endobj +77 0 obj<>endobj +78 0 obj<>endobj +79 0 obj<>endobj +80 0 obj<>endobj +81 0 obj<>endobj +82 0 obj<>endobj +83 0 obj<>endobj +84 0 obj<>endobj +85 0 obj<>endobj +86 0 obj<>endobj +87 0 obj<>endobj +88 0 obj<>endobj +89 0 obj<>endobj +90 0 obj<>endobj +91 0 obj<>endobj +92 0 obj<>endobj +93 0 obj[49 0 R +50 0 R +51 0 R +52 0 R +53 0 R +54 0 R +55 0 R +56 0 R +57 0 R +58 0 R +59 0 R +60 0 R +61 0 R +62 0 R +63 0 R +64 0 R +65 0 R +66 0 R +67 0 R +68 0 R +69 0 R +70 0 R +71 0 R +72 0 R +73 0 R +74 0 R +75 0 R +76 0 R +77 0 R +78 0 R +79 0 R +80 0 R +81 0 R +82 0 R +83 0 R +84 0 R +85 0 R +86 0 R +87 0 R +88 0 R +89 0 R +90 0 R +91 0 R +92 0 R +]endobj +94 0 obj<>endobj +95 0 obj<>endobj +96 0 obj<>endobj +97 0 obj<>endobj +98 0 obj<>endobj +99 0 obj<>endobj +100 0 obj<>endobj +101 0 obj<>endobj +102 0 obj<>endobj +103 0 obj<>endobj +104 0 obj<>endobj +105 0 obj<>endobj +106 0 obj<>endobj +107 0 obj<>endobj +108 0 obj<>endobj +109 0 obj<>endobj +110 0 obj<>endobj +111 0 obj<>endobj +112 0 obj<>endobj +113 0 obj<>endobj +114 0 obj<>endobj +115 0 obj<>endobj +116 0 obj<>endobj +117 0 obj[94 0 R +95 0 R +96 0 R +97 0 R +98 0 R +99 0 R +100 0 R +101 0 R +102 0 R +103 0 R +104 0 R +105 0 R +106 0 R +107 0 R +108 0 R +109 0 R +110 0 R +111 0 R +112 0 R +113 0 R +114 0 R +115 0 R +116 0 R +]endobj +118 0 obj<>endobj +119 0 obj<>endobj +120 0 obj<>endobj +121 0 obj<>endobj +122 0 obj<>endobj +123 0 obj<>endobj +124 0 obj<>endobj +125 0 obj<>endobj +126 0 obj<>endobj +127 0 obj<>endobj +128 0 obj<>endobj +129 0 obj<>endobj +130 0 obj<>endobj +131 0 obj<>endobj +132 0 obj<>endobj +133 0 obj<>endobj +134 0 obj<>endobj +135 0 obj<>endobj +136 0 obj<>endobj +137 0 obj<>endobj +138 0 obj<>endobj +139 0 obj<>endobj +140 0 obj<>endobj +141 0 obj<>endobj +142 0 obj<>endobj +143 0 obj<>endobj +144 0 obj<>endobj +145 0 obj<>endobj +146 0 obj<>endobj +147 0 obj<>endobj +148 0 obj<>endobj +149 0 obj<>endobj +150 0 obj<>endobj +151 0 obj<>endobj +152 0 obj<>endobj +153 0 obj<>endobj +154 0 obj<>endobj +155 0 obj<>endobj +156 0 obj<>endobj +157 0 obj<>endobj +158 0 obj<>endobj +159 0 obj<>endobj +160 0 obj<>endobj +161 0 obj<>endobj +162 0 obj<>endobj +163 0 obj<>endobj +164 0 obj<>endobj +165 0 obj<>endobj +166 0 obj<>endobj +167 0 obj<>endobj +168 0 obj<>endobj +169 0 obj<>endobj +170 0 obj<>endobj +171 0 obj<>endobj +172 0 obj<>endobj +173 0 obj<>endobj +174 0 obj<>endobj +175 0 obj<>endobj +176 0 obj<>endobj +177 0 obj<>endobj +178 0 obj<>endobj +179 0 obj<>endobj +180 0 obj<>endobj +181 0 obj<>endobj +182 0 obj<>endobj +183 0 obj<>endobj +184 0 obj<>endobj +185 0 obj<>endobj +186 0 obj<>endobj +187 0 obj<>endobj +188 0 obj<>endobj +189 0 obj<>endobj +190 0 obj<>>>>>endobj +191 0 obj<>stream +xÚìÏsë8rÇIŠºÌ‰öŒî´üt§çyšÝ­ÚJñÙfvçÖ$ÁÊ!•S*Ç6•üÿ±~X"H€èn$è5¦jêÙE|ˆÆ·@ƒúÇOßòýÛßò?=å¿ýžÿçÿô,~*ÅOÿÈÛÿù×?þøÛï¿ÿºÏÿü—_Ÿò§§§·kýñõ¥ù÷¯|­ÿöœþº?•ßNå÷SùË©¼œÊ¿žÊ¿üÇ×?òÿýŸÿû¯¯ÿ–ÿíÛ׿ç‡oß¾>ÃKþ=ÿãõ§öcøä²+âõi»Ý>ÜËÛ?¶ß_—Î%^¶wY¤*w÷¯ËäOj¤Üöû¸ē‰é½Ü?–KáÂC]о/ëå!"—x[ÎõœE¼r˜ë‰KåÒ!˜¾rÛg޹^òȾü\ÆÕÊÏ3s=GžJRÎÉõ-òVâÃl\ŽuЄõV¾ÌÂ%²( + ‚B¹ü29×$X,0X –€Åƒ %ƒ/° ¬(ÚMÄåÝoÙ9h6×ÄXo`å\ûhò’LÀõ#𡬼sÕÑ,åÏ\M6A!|…gi,A +Ú Ñ ê£s5Ѭåà‹+›— 9Ä`™ãÅ`ž‹,öD.1?V{àÊàŠRç\uD98æY\‰c®}HÙ8媣`Jé++D91WT蚐°ŒÒË TÔ  LÔ‹Š4ðZåªBÃ2t,OãQ ÔxŒsÆq‰±FãzX¢Æ#F,Ï%£FL×]w÷Ûí—×cy>|ðÛa0IwÅ÷_†ƒüxÂ[‡ÿîŠG’þÅ˃ŸßÝuoœ*=[ í,¸ö~ºªÛk[ça=xì.Bú±àæØ\ìPƒ–.Î$[q¹¸¡==·aMJ&³»XéԜ.K™\¬@ž› É貘ÇUùÑv‡]¶cqeSÙà՛eN¤ܯjؤ½s’  ®|²¡ÅϼJé\Í Xd°˜ÎEùØÍÉÜZ9ƹfÂ"‚­¨\Õ FÈ1ŒȕυEÛи'’ –Y¹0p7ñú¥uZj+Cg‘¼c,Òé« …«rÎX•½ÅÍÁ‘jÄ¥{.B J<—°ÒlKÃ7D=Ì:¸ÎåÛÁÉ %i=•œkˆàBf½ .Ú`Ø`¹Š¹2O”,Á W­Ç’ó ìÍПR4q‡ãÚa…„–¤8®´&1Š«žÙ#3ì€á«aÚz/8 [c¸²0Dƒ¢õ ‚«æfóuXiæ*B J‡íÌ\Y OjOjäªÃê.d‡%F®"°îBú°ÒĕÖ]È'½1p5Á¸dZ“RW\wá¢ÄÄÀ•6ºÐRVŽr‰» 7æw£\u€Ý…[FJG¹*OŠ…²¢d”+ (2$*ÇVå'ÆB ÃRåÓ©¹Z’ Wå“s! q5ÂÀÚÛ=W¢È£­ÔrAˆ"v@;-W¨jàLi­ã¡ªnè¯t\5-4”=Ùí§ž±¿ÿ.Ï´’T¹Æúù=¾aÀ +¢6(®–KH·Kh%ºÖRÕÓbQ®•–ër›®Îa‡Àà ¯Çé¹ £^ >ÜÌіœáµCrí´\MçùÖ 1£$UsÑys¥Z®³í%·NH)}¢æÊ‰Îkœ+ÑsÝ´BPf=ègŒàp‡åz7.×MÛk¼b”¾Tq5ÔÊÀµÑrÝD° ¬•T؇ô¹WŠçZ鹊÷G”Q&ß V<זByW¤çª/ŸÕPÌ1PRWF4C#×NËu¾×úü+ü’QØV +.A5C#WªçڟòáªÕr[¬àª©fhäŠõ\盽§5Rì•K,×êZ[Éu6Ž;êÊ12BªWNZ,×:{—'%WG¤(³ÔgO@• ž«x j®Š5K5†ˆëWC6Ãq®ZÂp ÖbI…Ó5 ÊFÒâ¹Ä»Y¨¹®&EZ,ip-â\9%pžê¹*֚Nè(; +\n£á¬5;c+\ŒôÅq®æ" +®K‰kvª‰@“¤¥pµ¥×qgéB™ÐdcMãº(½Ž«àôWòD@“ë¢ô:®Œ3¾êÙwCÅuQz WÍÛÃÈ0’ ¤h#!r]”^ÃUðûMÏ%s Æð2r•^Õñ6g +ÌÃ’lì¨\g¥Ws5Ì]Œ +㘁´¶ÑR¹ÎJ¯æ½ØER2WÁ^f®“Ò«¹rfæŽÀ8f DQ)ëd݅~^¹e¢IàkSYŽ­\§Öç*®³Ý Fȑ#š ”(ªT?º²k ±ÌukDŸ+?krN7Ä="àVÌµë>š>h¸Þ;а›‚]†Yw¹k6+IlºŠšô¸ Wuáiè†X!dr¸Ñ˜ÄjøCýsȵèÝJ´§•¸rŽlH[âã‹:\…’K\[°'¢@Ø¢C­I¤€]Ÿ«VrU×Ê=öEèà£ÃDïû¯´ùÖṌŸêsí¯#èùVž«áxåÛ-â;^WÈ\OÌɱonn0¾d=äª\ÝT”‚lˆ{ó€¼0ÚT¹WWojò$ ð\{–l lbÕ¹.¶*qeÝKž„‰×ñÒáÊY²Ñ˜×Ó{Šyq—KΈÚ{ÈhzªX¯üPy8Å:F—« »òúh9ÔNþnï5ùÒ*¹Ä€+“,¯ñª è¨Wo'ÍéŧñýGH©\SßËy°†ÇeŽæãvQ°2Ÿ,’+çEQÁse¼(*t.a#‡s5–r*W͍çª>š^¸ +vt6מ͕4™¿peM/\œ¥ùp‰'óg®úÃÉ<–k2ߝÎ-‡͋ó·•Ü:\[æ»uîªßFwÒ²ßmµwpœOm›.Ò,²Î-ï\·u›þà,•\×FÍÕI¿\¹r¶ûRãkT§×ćk¥äjÔûËÛ}©4fÜkbÄኔ\¹z߁¿h£¶W]nj¯‰;×NÁU UPn9Ár­4áËNŕr¸RW6|ŒŽ¹Î«Ëë51áp%C®wшﲫÝÊ-§h®š+Vqõó¡¸g¯r~ô'/ÙÅlp\ëQ®Ó¿^òHjÁZv,¥Šk£tEr<Џ¨ëdÞ7ÛnlÌ\—᯻?"éx@·‰+×à¢Zr—Ûj{‡àꤥÈ]|Ëíé71âp .’7.y<€ +£®[‘"K~­lâŽÃÕ¿(—óM +-áðì8—Ðpz®”ÃÕ¿¨7RNf™*Œj1\·Ùÿj®˜ÃÕ»¨ðTà¹b\Šã|f.ÅEußÁnßÊ#`ÂÃĞk¨Šã|f.ÝÀT5_ŽÜp ×^­óŠã|®áE…ÒÁ&ŒJ[=Ì®9·r‡Çù\Ër¥#Bq­Q\µÚ՚8JqœÁ5¼HËU;â*”ñÆË- é5qxœÁ5¼(S:"×Ã%¢"ÎSÇù0\ƒ‹´\?Œê´áò;ô¼RqœÃ5¸¨[ývGסµœm”MçÃp .Òr?ŒjÕ£YU4ñ"Ú4®þE\-š+Uý6.5MìçCqõ/Òr¹ê^,ÕMìçCqõ/Òríùáa«68Íòþ ‰ýã|(®þEY/Mõʕ;ãŠK W'T•šØ;·ãê]ÄçJ\ñ®óۋ_¾,{lÔMìçÃqõ.Ê;Š-qen¸:ù‡Ýxã¼ì‘ª›Ø;·ãê]4ˆ£*,WÚâæ)­Š«ó~(EO¢Må’/Ú÷#¢âÂùåªÇ¸äã|H.ÅÀn÷X®µW£‹ç¯AeNä’/ªúC%;s Ï\BsŠCqœÉ%_T÷$[DX®W;Ê.é"Ñ Í« ¸—|Q&°üÂeÎ=Üy䒎óa¹ä‹ +E2þW=/WÁá’.ªn»Ê·EÞÙ¹j—t‘è¶²¾Æ6ÓJ\‚Ã%_”ßö¿ž#W铫{œÍ%_T ö+Càª8\òE½H0?qÙL—Q\Ù8WÃá’/’gÆé>®Îq>ès¥”ºór=ŸÞa?bšK©;3×Cÿøšü²¡ÎæuÕ»ꝪHqPJÛ:k®|¾!çéw·§†u\y1Ô׏áŒF~™WsÛìø9QeäÚÉÔ—Pì(É/4¬®KüuòÈȵ™‚ TSë¼;Àz齺 ®u+ M?\™j« ºã “Òdúu\©l)^¸š÷§»nÝî«ko»õʺ ®Dºµ®êºQ(¾unڑÀ[v…².Ÿ«öÉUtv¬÷7ïÒqY·äsM]Õ2¿ú®òöNå“+ª›v^Ȭ©K㊯ۧoƒ8ñƕu—áòžÒߌ§©KãJ®£0qÙÄóҟá¦×VËIÚªº$®Õõq¼=™t®êöÓ5ä$mU]WÚ}tk;.CúáõÏÍÝ[ÙtĪ윑Ò×%qÏ]ÓÆ+W¢ûѧ“T<¶ÔçÊ/ƒô8„wÞ¸2]:ÎeO¹éÀd#©;x®ýåóŽŸ|ðÆuŽš¸1‘†‘¶.‰«¸ÈÐÑÒKo\—½Îûƒ:À:eR¼Ë¹¶.‰ nÙ¯qëë¢Z{þ⇬ã‹õu•\ÃÄÎEu¯G÷叫“Òkmñîm®¾X_—ÂU_ `ü`;®±}½n=é½ÄÕ0‹V[—ÂÕ\~<ºeK®±}ØByŽCš—ƺ.]_ˆ¾ç²Ú_ÚÌÒ|Õ¢¯Kàj/Žùô[\½,Ú¸ôdЍKá:;æ“[öÉÕyіL¡ú’9]] +×Ù1×'ï“ëý ì —J•l:ZÇuvÌõ©¾—1ïë9Sš\ùPÔuñ~ùäËãÿc—‹|¶—‡á¤¦ÒLrTu \ÕÉOnÙ?×­µ«^(u@Õ%póÉ-OÁõ. +‰vЌÕ%póÉ-[raß-Z‹ÁX]—x÷b멸n‰×f®^]×Ù1ŸEr”Ë&ûø*™ìе\cu)\o&˜4·õS/\²{ãb§®.…ëM2âúì-¹JÜú¡k¬.…ëØÓUt}Q7®D²­x”KW—Âçð±‰ËæÜM.ý9Õù±º®ê|²&±çڍO¿6ÝyÈJË5V—ÂUߜº7®ªÛŸûÞmz«Kájn³Q.›sˆçkãï·M­–k¬®!ž—Þ¶%ä]A ®qö¶ ©Ÿ,ŽÕ¥puÞ ë«™«õ¹F꒸r—Õ¹ìf¤jŸk¤.ƒ«´çZãÒmú¡ÿ VÑ×%qƒßxàjô +3àj¸ëQ2\ŸÊ(—Õû7䵘_ÚQ.}]—îý¬n¹:}l \Úº$®úêÓǹ¬²Þè!Ón”ØÔµ*–ïí¹Ê×ëMóU|–ïY +¶X¾ë“kz.ó떗ÉUüÓr•‹ä2/pÉe3aþ䚞Ëjb¹h®õ"¹Ä?-WºH.ólõA¹’ere0ðµü>ŽO®¸ö0ðÅ}Ïn‘\ðA¹ª Z~¯Ù\Åô²×å÷ÐÍULMÞá¾70¸@ªrÃ\ e’ºÒò{9ç*Š+[\Àa +%°ß{ZÀ‘›ì ù=Å¡­´e&=@~¯thG„â‚¥Âèo‘ßoXÀQã¸÷}ô•±mç˜Á8lc®Á9æ½Qæ#/Á9°Üè–ã‚s`™±Åš3‡}€²×ÀXcV@éK`3Ëڬހò9°ÊÜX@=€ÀXa6.@l`3°½9êT˜ËÍ"8á Kèmœ£ Jè„m®gƒú¡€S˜ „A:àª%ô¢©€ìڐ„>G˜ ‡bH}fv_ï\bAB/0Ò -Vè׋‘Ã]‡+_Ž V˜Ȑ+ A,0 +-V裥ÈaÜ媗#ˆ(Â-ôDˆ *âƒ-ôéBäpÝåB} Â(»‚-ôÇ¥€VÏP„#C̾:\ÕB")£œ· Å }ºÙHd.„Ð'‹TæB,Ýċu+_†pd8üƒ"âȇxà B8j¤—Â!Gl#´A `1Û¨«>BðÌØå +h)‚¸xí\Åú,(ÖCéÑg­¡% ÇÜ ýŽhIÂ1ó3?ú•‚+~€áï€d¼s°=z @KŽy>r’s˜y€Õø©bå™a÷H*:sˆH؇–(30Ê&ÐúyÖ9eˆιÈQDs‘ƒ²Ôā9£Ò7”AОQéI+Ò@½t>¥Ï)Mª’ζÚ&HšÔ¡9›!"li¥åڇkˆ´åhél¨vc! »ô™ ±¢g83âžö¼nų¢ †®@žâÌcˆñqCË`3Ĉ9qx@Ë`iˆf(Í4€ó`¦Ÿ¬Tԇ -g€M>kΩj-k€MœdY“½´¬6± +ÈcX]>±rz‹€5D'VFÔ +œéöÔ1GNÀY™8樼A:©ÔgB©œÇ Üϙ.H,8ޏÃtºc wàÊêd†kÍÁ…Tú‰:,c=càÔ4Æ €?R§é°ŒÖÛNÓaә_‚& :C¢Åqí±`»0ºk…äªé0‘qƒph­ ±÷UKó„ªY.´v†èuâ,øV­!zÕzìÓÝ ¹ð†èQ:j ›ÖÖãrfWŠØ ¬OKüñÍPË%¢¹-±±’.h­ ѓ&æV>¬­'BõÊXZ?Þ¹±´°öõ^†˜È,e \<1÷3–½í#×½{&ܸ¥rU¤s©ÍJÉ\"š LdöܹK0‘;¸)82‡i\o\´;¼•Ÿ'–‘P¬.t¬Â^¿¹1p1_uFÃÒÇàd}¡ãNSbé¥ +\EiW°/)áøf08Ô&[õ cœFwžÿf<[l2êR6W›qÀúßtŽ*OôÛø\‹+Š¿S;‹añcq€‰‹ÙaQt_zî¬ñ¹‘‘«ˆ¸ÿ¥ó/9k·6\"â—{”56¼OßYqYtØqœ=šÌñ…Ie˜>˜¹l:ìŒöªÿ짌ý¹K.ê4Li¯ƒ~/ÛÌæqµ¶\Mä¦ÜÝo·Û/¯oåe»}È,?mcÍå¢ÃœSþ#†KȵqÀe'‰³tŽ+¼Û9á +®ÃÌK_8.±´îBrvm¦(ˆ=$W›…ÄupÇU/«»Ð\¬•O_ºäj‚áÚ´.¹‚ÑzÜöžKdKÑxw gÑ q!Øý^ +—XŒÒ¸°DôÖ!‰kvKÄgиš…X!•kæø—°MäšÕ)¹/T®9½3eû‰Ê5c`OJš#sÍ6Ähi/t®™†1±ŒÁ5Ï#îí2¸fbÔ,%=pÍ`sM®ôT9×ÄÚÁÈdr‰<\)´ášRY©Ã\®éÀx™dl.FÚÏ$ŽËšk¢Éóā×þ9椰áòoŠü,M+.ß`ɧv\~UÑ&Yؒ˧ƒ¶Ê¶åòf—ŒoÍEΡö41qÏåcÚb™®î†Ë½,ڟ›pÂÕ +·¶øhß"7\o¶è®Ë’CW+Âé,—\ŽºìþІÆÕŠ'küâª-.¹ø©ÕªGw-qËe‘^Hݞ“‹Kæ–ʇìþ‹ë6øà"æÅÇ[ï¹ðÃõV^qÙññýw/·÷Æuê5ƒAÞm_}ÝÛ'ש۞¶wê~z|õy_ß\çŽ;žpØ>ÜËývûøúêý–“pÍPàÿÿÿârõä +äÿÿMÎM‚0à=§xKMlmKºTƒ;„r"ş1-h¸½ÔÄhf7ó¾—Ùé`}P ºgŒrðDÒºY`_å%ʾ^µ5¨œ±Y}ën©o³“àüë6 <¤Â;ÏHYe„Óy|”(ƒˆˆJOk7ýjsÛ7ãipŸœ iôWÔ?&{=_p¥b"c+l»…_:f~éiOSƒ7Üdï^endstream +endobj +192 0 obj +6279 +endobj +193 0 obj<>>>endobj +194 0 obj<>stream +xÚ+ä2T0BCc3JÎår +ár á +äHÉHendstream +endobj +195 0 obj +31 +endobj +196 0 obj<>>>/Annots 18 0 R>>endobj +197 0 obj<>stream +xڅUßoÓ0~ï_qâiH4$iÖfŒQĶ@:ÄÃ^Ü了9q°Vå¯çÎv·®€P¥H¶Ïþ~Üg÷ç(˜~ ÌR˜L¡jGç‹ÑÛgÆ°XA–dÑ ¦³õI¡q%*|½øA$ WŒ}Éx’¥QÊU‹ucÀ¨•Ý +0ÔZÑ BB¦ÒÍ ¬Õ¬âU°k„÷ªmUw7óïP観M÷åÎXl÷h9ƒMf9LÌõKIJxîO^½¿+ʗó(ûϾW÷¯yeœe1ëI&^Î7âß·$âŸß{Ɍ÷Æ´5¥ƒ©Ì“…Û êMƒ[®»\Œâ(&wù“ðçëdÓ$Ê!¥ïZÈrFñ# ¥÷~Ï,¦…”ètÖ½V›†,½ÒV,%Ò\0KŠjX)íL¼OO§ã¥0XƒêQ WbEÁÜÂZX"vԒ Jª©a¹f}DY?ÀÉ¥0» +¢¤ÛKrÒè4 XÍ_Ô?´'O[ƒvž?÷*´ª‡Êš—Üâ=7NÓ*‹ä‹±¢«…®Ÿ}1J–ûÇÖ)}Æ6ØÕŠrIÕ>¡¼°Ø=g€#üÍí9GýˆwPQpib,› Qó 1Q8 z5îp2.ís®ëÐ>GDZU)ÉٝE„¯¥&Òubò„#¸Øiƒjéùÿp DXPõg¢qÄÝaP4.ò#€ÏÅ””Tš¿FcĹTÕ#/—×ç´üƝý®ïKš&ª÷'"zŒDŸÐ^4+KGô6¡N iÔ¸zŽ*¥kÛØ5h¤VÒ`5t7EÈÆî‚õ¢® )[¥½D"·ÔjkX3“)”±%½}0õڅ{^z×nRxþ<B¹uù 숖c•eCW£¿Kí%k¥~Wrð²ŒUmó‹6áÁP+¸º¹ƒ«5Ñö¼ˆT5h•»@K­þ¬:NcÿhcDM˽Z5tõ¿Î Jˆ°žÙúPR§ºñ_ÁOJI)ڞ6׺až.X gïeQÞÞ¡î÷9Œ ·ö¨áé6Ž;Û¿ùÓë5N’™·ìà#ËãèŒi6 oʗÑo*ö÷ëendstream +endobj +198 0 obj +833 +endobj +199 0 obj<>>>/Annots 24 0 R>>endobj +200 0 obj<>stream +xÚµ—Msâ8†ïüŠ>& 2øƒS&ÉlmU6“ dO\4¶ Úñ×X2 ûë·[²Añ“Ãl%exÔî~_©Ýü1˜âƒYHÿI>ú¼M¾,€E°Úà7aÌ`•^ܔI“‹BÃם¨wR¼\®þAnŒYnìG^HäêY*PåF¿ðZ@£D­ çEÃ3À/ÊzË ù¯HAºý,`SfYù"‹-(‘hYê7È;D>—ÈáÏ;đmõsr’ïè ô|´nĆ7™þLˆESCÊÜ\¼cê@SÚ±´˜NÅi NœÁ]ùx†Ï#ÿÑ£¹ÕçŠDïßw2…pµ­… çÿ{ZwÃCg¾õï¾Ôœì‚ë²Øáâîžœþæµ,…ãNd¯Úš¿Br\ íDAÃöQ'¶L…·¯<¯2a·6XYC.pÎ(¶ö#\c›ì[A¼V—Æû&piǎ ÍùÔ»)?SL{b¶¥s§¹H¨¤–fSÚÕÓnÓùYpÐ"«ŠÑKÀ~¸¾`ëË·ºølŽªtØ +ϱ†rƒzä8N¥ê“žd­úQs+Á¼Ãqð‚MS˜ù +Õë­@ì™Wt¾¤jç1eëíèÖã+¾Ý´E“µg à‡òM‡ò';^÷‚LUOÔ3Ú2IšJMR®ùD ¥+:ë^¥†$ù"3a¬Mey”õÞ*äõ]°iÌ»ÉŏïÜP¥mS£Ó§îe ^&¸óQËFWn£³wŠÌ*§Pµ­jƒ)RNp{¿º}|÷waŽiRFgð.Ÿ@U"‘øÙw±WÉïâí}Oľ0ÇOÈÕÝ\_=,MÖý\±+›¢LÊ.Z¼j꥖Z£ Í/= ¬žÜÖÞúp¨—E*®…‰’b%ùϨ$‹mÞq§æ"ôfàcÜLLpýô°>>>>>endobj +203 0 obj<>stream +xڍ’ÍRƒ0…÷<Å]êŒP4PwÕÑ.œŽ?¥J€($š«oo¨àØêd“äÞ|ç̹yqøf!ˆ1ìç"uf× @1¤…©àAšŸ,³LÒWF4\¦¦'„ú7ˆ=l»ÒŠB!êZì/Œß‘ZEsЕmY‰V›-SÐޒú¼‡âj¼¸ö"K}ʦ‚¶†B/°µV‹ì]SuBòƒºã”æŽqë#¸5-É%óÿI\!®Ø”‡q„’©ÍÏ´]37š÷YÞêŠJx •”ï~êwòCê—Û» lD¡÷6ãeÞ0Δ–D ©`Ý¥{Øß’ù~a&eËr;FiÆC¡ƒ«î aêâNŠR’¦¡ÿ±Ï_Ý#uÆ5•ÙÙ¯´gºÂ󙹧ošòÜÞò— " !B½=˜úÛª©3áÄæïÿúÙ£Ä÷ÐÕB{¾J{çƒìàendstream +endobj +204 0 obj +355 +endobj +205 0 obj<>>>>>endobj +206 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS04³P072PIÑPp VÎO+)O,JU-N-*VðMÌ+MÌÑ ÉâÒ)Յª5‰˜è™(€ùŽIIE©e™‰%™ùyÅ 9×®@.: ‰endstream +endobj +207 0 obj +114 +endobj +208 0 obj<>>>>>endobj +209 0 obj<>stream +xڝUÁrÓ0½ç+öØÎ¤¦IKҁ4LRàЋb¯cQY2’œ¿ç­ì¤Áía:“iâÝ÷Þ¾}’&t‰¿ ͧt5£¼½]^}¸¥é%­J|β+šÍohUœMè‚^ۨ톖û¹¦»-û­æÝùê'Ú®i2‘¶‹®ïâêzšM¥uUé@y¥šÈžﶺà@ʒëûɕT¹Ŋ靫kgéþ˧ÏøvÎ?†¬c»¥É\Ø.A4Í®;~jYx·6\ÿ- ÅÓy6“âÎӞ•ԕÌú’3ÑPš—PΨR£6-IiF÷ÖèG¦Ï:÷.¸2>L_Ïè»¶…Û…ô?è>«œî–ãn6°N€!jrÕ9¢²…òž}©r–¾ÐM¯­pâ§R~k›Æù^cª½s›äbp¦ÚYøÞzÏ6š=©­ÒFaœ±” ˜ß²dè²ÅÁîoO>t°4Ï ¿v!â)o•xփMgÇE~ÞÜk&£-UÓÃYäߑœ5û‡swìeîuŸ‰¸WM¥óðp>Nßw:VC]͔;õ[wvì)GÚ֐­ +èwG%ŠÊÖòÊnXBxäàR›äu­"¼ýèvŒ¸Ž“«ã±Ê‡¼[å5ì$1)íÙ5ìՉ „^àS¡Ë’e3CŸÐ +±Òoe䬯5'‹¦Âk( rI…‚˜ðåy†JáX‚Âs͈‡ÒykbF«JEøW¯±¨Îà¤ÇèZG.†C#jubËÛá<èD‹øÓYp°E"'90ûütólÇ]XÌ“QۜÆ[ ”Óš‡¹{w¿XÊP¸^ôF¤‘EµU‘ÿãœgtg%HéF®©ÖYÐç9zAj?{8MÝ_̖¹â€ä /¦ÄM£vEk”—dJÉÓ%ð>'¤†g$Èq—™ç'e,ô„g±9M~·~£c4é2²°´Ä3Äd©-¸“é‡[}@¾v}tŽ7Šñx×M‹ñ$Œ;pÜ¥N5Ñ¹J÷®q³jàš-—âI:kzHlñR‰œWÖ·Ùw3@9^Bñð +¹yz+ÌçÙ?½å®o.³[4 ôµ|¿}ý üjºendstream +endobj +210 0 obj +836 +endobj +211 0 obj<>>>>>endobj +212 0 obj<>stream +xÚ}WMoÛ8¼çW<ô”¶»…““¦Ù¦H°ÞÚÁ^z¡)*f-‘*IÅëþúGJ²-ÄE$²È÷13oHÿ:›Ð%~&ôaÆ¿²:»]ž½¿ÿD“+Zx3»žÐ2?_®-•\[ڗÝÅò'}¤É$-O¯²/ûü<_ö´^åÔÔ֐0¤*å^´y¡”3*ÂäÂå$EYbe@øþåÜixùÜÙ`¥-3z˜Ïi-W)Ãɑrò!›rJU­œˆ±ÚQn+ãÉTs å=ïÿ÷ʽâO%LS§œ P°oêÚºÂ'ÿùì C^*:¶{ÇÜ»5\ÒùVôŽørqYDÄnqÐ$HÙ +í|‚ÒK²›nmââçt¯÷ºäjOöÚ¾O®Ã‚ðÉ8D]—ÝL¡¬t´Á3v`‡~/T¦È6`N*øÌÊÒ ùǾeÆu¨±t Gb%,LU°Ëc_Þ:OՊ­“ÒÂVÝú8Ì“u³c)×E`Ȝ¼±(ÄzûŒÂĈ€|îgô7Ÿqžàü:áŠZ!DYPæbÂoüŸí°«õh†ÑÔ§ˆ Œèë|ü×ãûi÷8¿»ïþǻ¢øœ½…i—˜ š[Òé:¤‹RŸ†¾ ϝ?ÄOpž±5¢>hßâyÖU¡ë`>ˆg‡ŽqÐä V:T¢î"¤[Ê^.ÐÑzR÷Bn †Ó"îôtñ`T(íò Ζg¾GyÁ.*¬¸VzIæ¹¢›ÅÃâNÒ»êòñ¯_0HöiÜu u-ÊÄàó▢»¤Çþ¢†[ÀÖº Î|‘.nóùh€ñ7AÔM]/,R‡)Ð#.¯iöðN¨ +ZŸó;泿±et“çš•Œ£µ/>ºûÁÉ7HÜÕÆ#«%Á>Ðí{kæ‚O·]@De“¸8Z®ãQ±¸yº½!¾žÃøTKüuËëdv¯,ŸÎQߘ÷´’žã¥è ×Qò®1/_M/yíŒ?ùxyñ¢7¿ð|Yžýsö?e&Yeendstream +endobj +213 0 obj +1446 +endobj +214 0 obj<>>>>>endobj +215 0 obj<>stream +xڅUێÛ6}÷WLóÒ-`k}YØÞ·`sAQ´‰‹uÐg®4Z±K‘*‡ZUßRRl¥AàY¼Ì9sÎÌèŸÅÖüÛÀa »=äõâἸýx› œKÞÙp.nTþ‚¶ PArÐÐ×Ú"„Š·^•6êÉ ¯¿ê)ƒÏ((ÚPå<¥P 9½pÒyP`4på/ç¿kXmvÙVp‡( PÛ4ÎZ‚âÛÊö -_­UÐÎ2¸ +1äH ƒs%ïÆ¸Ž"·Fy~C31`öw_N1À \Yøpzüü CoZ‚wÎ0Õýz ×–ÓŽ€!pVI‹ AˆÂfSÃUÝ0 ~ûñ6‡¤ìj·Íîæ4{ïõ+zJç¾:°Ú²ýå¹"ãôóÜYJâcøQ;v©Ô&È1j0ץ΅ ™g骶¹i ֗"ÇqwnÂ(ÙüŠÁV'ÖPù~W„þ7 є÷H/òCq1Ix¿j´]Âö.=/†Î ‡ýSåDÖ!\UÚÄB#œd(Xà-z8ÿ&èZpmhÚI‹û….Kôh'v¬R†–3d>ÛKÌÆ»W]  ±vñ޶Ï1£k–>>>>>endobj +218 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS04³P072PIÑPp VÎO+)O,JU-N-*VðMÌ+MÌÑ ÉâÒ)Յªµ‰˜šé™+€ùE™y%©E +.E™e@m Y×®@.ž!/endstream +endobj +219 0 obj +115 +endobj +220 0 obj<>>>>>endobj +221 0 obj<>stream +xڍ”MsÚ0†ïüŠíÌ`;=&“ÜÚI‹é‰‹°×±Yr$Æÿ¾»!MÒ3€Ì~¼ûì+'Ìé•Á2‡óTÝ䲜|½YA>‡²¡÷"Í`±¼€²žæÀÆI}¾E¸µR{>¬Gç±;+ï)¯€,ã¼$&&çEžæœ[¶ÒAՊޣךƒƒÑ @_Àpî“~ÚqB×P ]¡‚ž»À½Ù9Ž«eÓ Ezž£ui컂lÉ}çÔ2O î¸5ƒÂ©ÐAcìIôkµ”•/Óg]mn×TÜìeM);ãÛ0lœ~ÃvSçÇÔ©ê·Ól{öºàt{†¸Dû€ +Ç÷Òìyý×Êtq)”cAFc”2‡£~RGºÇPF hhf>sZ”'„Àh5>µA>†üåd°b5ä‡$/"MՇŠZt×?Êë_oöbAc?«bÿ·LXÄ kÚ±g +@Ž/ à‰‰ӄzŽ~°XyE摺RCÍoóëÊÊއeÈNÜa '¤ìGÁ4Ý–lËÇÆšŽ*:rûՂè{%+á¥ÑԝÎ>à;. QRã ­¬ZÜ]jґ +ú]ïQKþåCÃ^µÆ„Û%¢MÑ~èÒïÌ"®ÌÁA*­Ø#µ²ì¡i«xÚ°Ø ©ÄîÙƒCËН‚ß7Ø!Íãi¯±oØ(S ul {)Hj/,aD5ª*}•Íúzc}8<÷7Œ„hôcÒcù| l\´ù_w…,àß».ðÂøI=(I´ÉÏMŸ&ü̕\’’ú¥+/^¹²ˆèÿù'X\ÌÓ-‹bW|¾.'?'‰#©8endstream +endobj +222 0 obj +640 +endobj +223 0 obj<>>>/Annots 27 0 R>>endobj +224 0 obj<>stream +xÚ­VێÛ6}÷W ’ˆTÝV²ìCãnZIëÆÎÐmi#‘*I­á¿ï u‰oòîÁ.lSšË™™33üo⃇>„1ý§ÕäÃzòëÇ|Ö[|ÏXgÓuÎá—õ#¾òºWS§nô²Sµ)¤]ó´Ø\ƒÉ™ƒl`τ#As ÊB[¨U! Wú0‘¡ð¥‹ląâµTF[´QŠ£y}ІW¤àã‡n@¸3¾eMizW ¤%ÓÚí䂨Hî«æ¯°/L~M¡¼HJ*«Ê†'[ôƒõ9J{`ï[5椅•p‚¨EVÖàdþmQrÁ*¯¾œúr¬ZLJæµh–¯ŽF„s ¯gyðüdÚ:­¸1…ØÁ²SûÇÓ§Þ©^‰küˆ"Ž˜CDC2‘#dEqQôÖ*`ÃA7[Ì|AœÙ¢ä§Áy¦]øSîùW֌âÂ¥LQ¡Ç}΅¥6iRMӜ‰]K¢ÞYgP3eŠ´)Y› «ÄиE‡1ŸSqýV£^\, ¬,åÞz&"ÿ/rÓhJÿ5ÒÈ뤹ÍX %9NYÍé€?J´ŸÜÑ©âYÁî‹r¸õ®Ï²çÎý˜•‡õÄs=kôáÓǗ? +dNäûXÄ +¢ÄÃïöTÂê|èE~Ð֚jÁžXQ²MÉ/röÄÔÉVs‘Qò°‘(” ¤¬ ÀT6èPå3®SUl7…€qÄG ñ ³{‚øLEí† ;ô‹œÕ„7|7êÎgø‰.b7ìäá +¢ïÌ"÷î¦ô‘@~ºó#q‚Ç9Á|³ê“´ìZ¢oÿ7–ƒe¯ sêžÎ¦H˽ÁÂgEE[ÈWÑè ù _:È_Ùr9{:}¿C%Í &1¸¾d} ùÅ,ow•è„íë©h*'=НS›^™ºç­õö‡-]]8m–-»…TΛC‡5îS#¤¹LVY2ƒ}ÐÍaÆö°Ä:ZÙûµjøÈÃÙ¶ãæ»Õ6 øI9=Ãðsü¼å«;s‘óô[?µûʼn½d$œ’•}¾hùè|*m‚«+G—»Ì¤H^ܤîw"±E|”›£kŸíÝlªÂôUî»àVQÈóqì^+t”Þ.ZÇG‡¹È$‡( +’$‰ÏÊÐ˃œ—ÌƤÂA*L‚YŒ²òe#%¾Óm¶åv÷«ŒÛË×oUeIYjB6NîzœÏtaÞçEš·÷;„úk3y?»›°ÔOüÙÜ:õíôö‹îw®¿ý…%ðò0Œ¯î¡ãwSxÖÁö‘•q>>>/Annots 30 0 R>>endobj +227 0 obj<>stream +xڕTQo›0~ϯ¸½¥R HHû¸®VmSÖPí¥/†8…ÖØÌ6òïë³ mšDZ…„À÷Ýùî¾ïî߈@dY É Êfô5ß¤@äkk™Í3ÈWã{ÍÀT Îò'kŽzó8þ`‡«Pû$[SK¡ÁÈGf£*ûº’wœ,´ ƒ?­ª…aJ_ú.0‚Í4ˆÓ0ÅÌx« 5HZ¸þ_ßí®¿ð$ +çˆ\øX±WTb%¤iœeÙ ŽàâG¦Ùü*PIÏÓø¬/¾1ý|Ë [¥;«Åãî0 ¡ÏùH†IX`£ÿUÅÊgÄb7ú;ai+î4¬•lÜù_Vì·Ø&gá ,kQ2¸º_,¡ÓL;üŒ"l6‹]& %,%Ÿ@m ¶ýçZ…uÇù6Xw¢DÂ(‡ +@3õÂT¹Äˆ°•Âó]áIè/”ÜhOm#Em¤Ú#¤ðžz« k&VL8ÄýÝOÇöu>ŠÂȪ__wß-óaӘØ; i:üqX¢t?x¨G”`{:cŸ\eL{y~ÎeIy%µ¹œ%Äå?¸Gƒû®§Ž”Øõô¦o¼rÕCI¼ÔÌËW{näJNµíøÄ)zâ$=T¿©Måà%¯ËgDS(:c¤ø²/……à•~E-“Ù¢ž8¸•§yϧµtÆäáì?Ɩ·ª9Š-eÓX¼ÏfãÊÂ2OiõöÄÛÇÖ#¨W{>ã·~7E˜Ë§|Òv¤%UXû1]S ‚+»_6Tƒb­T†­PÓÈ{±=¶ùáºS‡”É©ÆöÛ`ÞÈlI:Å +ü/åÚl¨ŸÝÊVK¿¨è(GŸ¡AGŸÝi–ÚF;7Búáû3z`æºendstream +endobj +228 0 obj +668 +endobj +229 0 obj<>>>>>endobj +230 0 obj<>stream +xÚ-‹»Â0C÷|…G*z*™©`C*J*æPn@S‘¤â÷!²¿!ÿ…°-R›QŒØœˆ`ZP¡°—9Ì}…²®4ôÔÆõŒ:°8[7Û×Ú>>>>>endobj +233 0 obj<>stream +xڕTÝn›0¾ç)Îe&Â_C˜´›JénÖµ[xN‚'c»¶³,}úÙ84 jE+îà|¿Çæ9H ¶OE +Ùê.¸­‚Å] i ÕÒä&Ê`Y¬ jf„°1„7D5ð¨(7¨àA*¸þRý±°’ÄÁB ³<R­Zª¡n‰tu­èj0-‚å‰QxFû‘ +ü%”‘'†ph‘û9Êwp ¦í)¼x|Ÿ1yífVáz&†0ɼ5&Õx¼]g!:òJHŠ(K£Ü¾#GEØÛéí\ZDKŸa+gxHF¤dÇQ˜£´¥ˆ-l)à õ|`-½úMqÙEnˆ#~ÃÅàaÔP(€¹€5‘8ïMÚr­!%,3ö:’ìÊØ.o§Ð­Nxï@ù™ ÄÙÍWOœ@éxíÙ +ÓÜÛg. ôi9éÖ?«õos뉣Õi=SÓçŽÂ^¦ô1¬_[ºÇ†ØÐœCe[ž»#±W5~ª¶Î}ûw|y§6Æë~t¯hŅP {Ñ©v¼Î»h{#& +ÏÏï÷ÌÐǽ’B¬Ý+t¥×Ò^<^?¾Ôž¢ZÜ­††kàfåoäÔ&/r«»Ñ$s/ÖUð+øB0pÅendstream +endobj +234 0 obj +480 +endobj +235 0 obj<>>>>>endobj +236 0 obj<>stream +xڝVÝoâ8ç¯éŽJ$›àNû°ýX©R{åúÖ“8à•±}±³Ðûëol'- l  ™ßŒgü›ù·C„Ÿ†©ýË6½«EïË÷Ä1, +”¤“1,òþbMü$Œ“%§°¡9# ÙTÀ¼(ûˆ´¬ÊŒjÈ©¢øS +0h§J& -°¬ l¤6 +¥diœ´œË-+Ê0)ôÅâG/‚ †‰E~îgDS`„DK¶¬`æùâ«úå{V›LÐ"HÒpäì’t ^!ªú÷Ô` þe“bxšƒÁs^îPÂD¶¶iÉ’8Ý%ãéfó|Ñ܏ò(ڊð_€¡¤Áu±†—éÙXßF‡@wóGø6r0És +Ói*Ú%ÓñÙP׏qt4­ßânÅOÊ¥¢;ÅìFaœ\¶PGñ.Ž.ÏF½¹?žàÍý>ä$LSÄ[I„ÙGgC.J"´"%ÙË!ø¾´¾ö&X@ ÎÂzRêhcÚ× ˆý6%y9¯ÿäö˜O÷ú³>*nج*•Ôôе“ʋ?6)Wôš(’1säܝ²ZÞ ÚàX+3^¶š\ê¡9`鐨 +&𙵘êw ³Ù  ©®–tbœ‘#ýuÂtõ̜Ks ˆtÙÖÝ;•ÛM l¦nöu¡?äo™L}Â3›€åÒGWÒ¬aÎräcY¸$fä É¬í+Áw‚$Ò-š5[ا<Ðk<»€æ«ƒÐ,ýlÏ¥X5oʳeœwnæä•âtçæDg¬°bÿwSa ̄p4­ÀéIú(í,Ò3.¬ï;Çä5v¤mù•%íÚ¶Žùötm3- 3¹ˆ1L­Îó ùÆà +Þ-§kvA6nÿZÜþÓD…“_[¿Æú‘qy®õ[âK"m:ï+AޱÇ`¤¯8:+N½×Ó@ŠZýŒÀß³qWqüîÐUöŠÝøø¶Ôtn]øšÕÁ +D)þ‚mD…OÒÊç~ײ×ÙñÌ)§™³²MX‡bI빯›)x"üK½¦Ôè¯ÚÒ hC\½©QÉá-=žjðl­*í–X‡• U‚TàÁŸÒœ{&§ÈIyZu÷ì2N´Æå’惷ÇS»ó®@^šÙpëüýüÀ «hæÝ"%9†ƒeCW9>â±x²pEm&zÅ=›fÙµíµË#- mܓÂrâQ﵋ְ|]ñ÷jØÝç¹Ìp êmè0´‚­ª’Øø®Ÿfs»{ñÊΝö~ï]vwQÕý0©5N'Ž/­Ø;œËÂlí¼~Ò´Ôð@Då7ëÀªã$²º±Û‡qŽ!:cÞ.z÷þª'Ó>>>>>endobj +239 0 obj<>stream +xÚ­VMoÛ0 ½çW=u@ìÅ®'zèÖì¶¶kÒÛ.Š-7dI“äù÷£$»IóÑ8[P @#>¾Gò‘ÍŸ^ü‰ ájYÕû:ë}þžAÁ¬€xÆ0¥0Ë/ÅÃ>Í~ãó y¾ä‚SÿQÒ~Ü à€T"¯3 +æ„sª@’úð–`At…ògŒh]%ÍwYn7Ó²4 dºX#.€‘9e@ ˜#$žÃ\#ªe^”9å¦$¬³ Ì¥hš)jºŠðÑç¤7ˆ$ªÛ8¸81bO+ݒ½üšŸêH› .ZÆ¥6eà¶/¸ŠÃÄê¹Y]¡ŸàAšRpýž…Çi8´3L\ÆÄ²ä/ |4)Ù +– Êq1K´%¾ÆÀ¬$Õ +(JFõZBÒf{ú)e4ó(x" DÌ#ºOH+c«}p­ ”Å빋¾lôâè,ÊՒ¹p¬L½ðŃ#[,Þ¯ N¼Z&a‹,rrRQ˜ÜÏ&Oj§=GAò~ÚQ| ©N‚®û¸"ݘo5è…Xr sñJûÎO[ýÞÛàWÂj +:sno³Æ>2ê´ôwºÝì6 Ýd‡si^€×՜*ÝÖìŒõ²/(‰"†¢¹W˜ ªˆÁzqY¢÷[’•¶:ÜD1¶ÄrtFyrªú è ^4§³©-Ó=lQ7O>;¦9Ў¦ßû]69ã¡w‘•›Ó‚ÔÌ@©q[½N·7Ž¨ËºL^q對yþá¾>>>>>endobj +242 0 obj<>stream +xڝV]Ú0|çWì#•”„J÷rˆV•ÚëõÈUê£/8Ö±SÛ9ÚßµãCG!‰à™Ý™qà÷ˆ@ˆ/ÓØ¾ójt›Þ}˜™AVà7qŠÖã3¦0[·ªÜl`Z¿É~bñ ñÅA”Øâ²œ +È¥0Jr’ÏLQÎáiY¸ojU +ÃÖ S7ýÂ㻇m÷q À75S9æt‚1ÈڔR¼÷Çæö÷ +¢ÙÄíÁk8íC¢Š’3A+Ë»lù`±¸ + '©G¨NÃ#Œ-ø;å Ó°QŒ¦p+T…„!ìJ”‚ÛŽLDx »-ö…gâV¤SȚª_ˆ(ÍÄS| +¢ùä•SiUQXH¥XnuàׯµÈ÷-¸æZܸ¥†Ùå$ìfÕÅò>6 ñé•Q!lÍ +ÚpãG{™z:‰,y©îàhҚ3¼ûcà«Sê܍›¸,K!9—;k„×U­kþ§ÅQÜäÎ$ÛÎ +£»…让žPô}±¥Šæ¨†{<ù$ò핝 B^——bší(Ş2?P⍇)¯¥Å²«IÙWF2åJ“®y:¶üÌà,ï«þçŸ>Äçý…玭«æ– î$¤­L‡èx:•0î_ɛJè~™õ˜¾ò¹KÖb¯¶¥è˜Ä¶z:DÄ£‹åÛ¸(¶:¦-–Ä)ÄIêŸ+°x¼_ÁJfGƒGmƒü…Іr‹ +lqà/"֒ØMkBxù_Ã2}ý¨n†Kendstream +endobj +243 0 obj +582 +endobj +244 0 obj<>>>>>endobj +245 0 obj<>stream +xÚ­WKsÛ8 ¾ûWàèL#U’½¶ÓNm&;³‡í¦{ó…‘(‹)%j)z=Ù__€¤â—œX‰Ç>Ø€ ôï †?1LM -_烏^A<†yŽO&3ü‘ ï¹1¢Z‚)8ܱ%‡¿™^Šª¹˜?¢øâ؉ɔĿ)]2)Ÿ¬|Mò¥“¦94܀QöYÁtR”Â4 r'®Ee¸ágÃíÃˆ<Æ0PÖb yn®ÿcrÅw^jÐ:Â„ܳúZ,‹“ 8H£ê# +¬ÊŽ)=(cTÙ©ª6BaV0,{\5†îp¶Mß'g †+ÒǂÉ8´’5ì$Æ Žœàp Üë!’W¬äpûm~û£Âٞ9—§óÙ£$žÏšÏî» êsXܔ6°µ™íù!…;¹€^•¼2 K{WrÀo­°#šÏÀYZ¸?$Ğ) Q8ú£,CgsÓ½Aråèq§±ŸàŽz ûøHÛλ»ÍêÚ¶ìæ/Ô+l_g×À,‹‘Ó5µ´sš8¼¦Ø „jU>p} êŒ0’Ãb¸jV45ö€TÚ\/.\¯ÑYÆ á‹lÔ%ÜØÓ›àZ+¹IS w%ñ—gN/U¥Í±w"Â0)Rñ?Ï^m®MNcӋò¶LÓg®Œl¨•”šÜTè(RøÌ¨\I©Ö4’ÛÂêîºà•¡ôLX{Þ¼À Õ2ÑÎwëD?†x ×âŽ45OE.¸#w«Ñ}ç(þoùዑz3É ¹€ å<^$“é¾)§[c<€{Þ ‚”ËxÎVÒ,.vñ¶è׆Ü>D²Íµä<âÙ^C´à½i¦÷@ô1’Aö†³3¿?žU{sŒ˜Ÿà´8·jCL•®°Æï>1â-dì;¡ÝeӟKNý²í!ϑpß/çÿå´·ã-ðϸû‡ü›Ç[ã´¯k®©w÷îW‹—w¾´`ÕÒm¸ ^? óËoæ"íBjýÚ]Uv¼ìµO¡ÇgÚ£ÞhéÔýéH!,­FÌokdLLëõ,ŠüôÔÁf×+Í%³w‘'ñ7ƒ³>i­Wêáâ¾ìm-¾8TÖ±½Ë¸II‘Ë kh-©%7/pÖlSŸ\6 É?`tã7¸ñÀ–í$Šöß¶‘Üö±­j +olÛ]`æ#‰'3˜\En¹€›Ÿw÷p¯r³¦õ_Âtƒo{nf¤p0M¢×Þ +ÇÓ1rŠÅS:¸¾~ÀR0ôendstream +endobj +246 0 obj +958 +endobj +247 0 obj<>>>>>endobj +248 0 obj<>stream +xÚ¥WMoÛ8½çWÌm] Òê+²´@MíØn»±{X Z¦lÖ©RTbï¯ß!)Y¶»Z ˜zšyofH¾ü¸ +!ÀŸâÔüÕÕíüê×ßC˜—ø$ͦ0_Næk +uÍàÝü;>ºÇ“'Â[êÖúW&À ÚjA”JV]K£ €¦¦+wL¬@cDEÉ[ͤYÚV‘~ +¨Ù–òjŒÁD±öáƒ0yðÂØ %Õk¢MÆ8‚m”`ŽîÍgÆ9Ԋ a°ÍlŠÌ´ž†¿†R* [R՜úðàÈ8¶Œ.O2ЮȃÌ9Q+Œ‰¬„]­qñª–k†‘í׎ڂ:vtiªÓ͚r×UåGKí»ºæ&®^”û‰Éÿaù½mt_Ä?Z +ß&s õí)#f~0\ŽÛb^ßwò¤‹ž„uKß¿ÚLY[–2±ymRÄ÷-ëUØ­Å8ÛPûP›úRh%9`œlÕI55åô‰5˜å7—<„ÜäÆqô¢Ä)æ5t$$vÃùëޚ@É8¤¢pÿ×üþ±Oø™ ¤Þi¨Œgé¥g*új)q4ڊ +ýrƒ`°ÀLùCÄ' ÆC¨­BrœNSr%51ýðÁ$-%çòçà´¢d³Ö´UEû·›ÏGð ¶²¡{ª×°deIµ]Â,M׃›ŽuGØ/Ê\>+¶b‚pšF~Œc…«¦š^rcóäpÑ­Ýϯ÷Üðñøƒ;’d‘gLè‡æH^Q˜½FXށ33—ÀQ:Eœgø1€Î¶0Š ƒ47lÝ&·L,ý/­Â kÖlB»ö5õö¤2•ü™²4ÂϱÊ,x¬2 ~©¬Ó“änÒ?*Jű¦Žÿª2(»ÅqÖ/ÉJb?-˂ÇʲೲâÀO Ǻ>ï2(²ò½Ý}I“=eÆj²à±š,ø¬¦0t»ê¶;,E³ÍÎ[t«ƒ¦a&/© n0ÓX5á5 49ô –l%åÜ)V5òggéø#Gêqà³z¦±%¹#'»èx¯ rþd«µöyZwIVšŽ?x¬, ~)+€8‰üýµ¤%A[b¯w±÷wS0Öÿn•½Ð€Ü™ëã ¤Ù{®¬@.g¬ˆ#ë.µá¥Þ¸[Ì8Hdñš%9¹+ÝݺrÑÛoH8»‰#ÿ˙¼9äX‹r¦È{“Ò›ßC rPnë[¬iA_îü%Bš–×J.Û忔Ҽ/8)6šïyÍtç"¯¿ u!` ” aþk°æÓ8íÃÓ­V´¢|Æ~Іú]†(u-:òZ8àaЏxÖ{4ƒ›dê:w_¿Ì`&KýLpó|m(¦ûDDë|gÀÞ4²›>ÌÌRŒMìlÏxoއÃßWÿÁ»Ÿzendstream +endobj +249 0 obj +1085 +endobj +250 0 obj<>>>>>endobj +251 0 obj<>stream +xÚ¥VMoÛ8½ûW zrV,[ñG=lv¶ÀnâôÒ #Q6[ZTI*Júëw†¤lÇM‚ ˆœ÷†óތø³Cb`8‚lݹL;³´Ó&ø~óÐKH&Ñâ~õa8™F#¸ãCs(:niØ¿Àÿý҄v¹¥K‚êJû@¨ó«)ÄcH dMbHóîçyïÓ?縩¬P¥9K¿wίˆc¿«7 2ܗ®UI©Q.AùÝÀªJ>UÐÂBryäJZ”i”Ê\‹Ò€(áR²ìǾ–Í/õÃR·§àž"*©ìó¨nHLÅ3QnÀ®˜&%T³4+UË(’ˆÌGÔ PÞ ñ9Ê +v¹Ü‘J¶æ0»Ng·†iƨŽß¬_Ú½M´çh6åÌyÁj‰)ª`m8¦Í!SRiC‹¢ä9åKo7Ø ´{a,+s¦s:ቘ I›ñ0³æ×¼Ì8¬YY3 …VkøÌÉ­…9žQO+x%¬攔òds¶äo³öõRnJ¤¼ÇdLâY­Cj³¨0‹—” įÒõôÞ7ªÊµÅeAÊex°öˆ‡‡ê_‚‹»¼7øC\ߤ³‡•ùÕt…¼g¶Ö” +š#7PWX†¿YVkfÛRŠ_¾u÷”™/öùv†öZ£Wö}µMuÇ]_ +(Õ>f³hÑë,Œ’ Y®S¯ä!EŒþózñf{,í˜gSîöœœŠ šŠ»®Œ'¾l ¾uõßAÀ9fýUävõ&[cÅ +úãÉš¿ÂÝ[ÇP'»X´úùD}ÉÓV¿oè÷uwr¡ÝWÙþ]p';c{¾½²-ÕómcÑHk‘áÌâhÁnÏ9 P~.Ñ +•VyM&q*úA²ç#†¦ˆNJáàܱD°pôOd +¶Ã®ÈG€ ø#Ë,~c¨Ä#—òî^ŽÁ¿Ä²T§E³âåóšÇn¸=>IN7ɱ[ŶIÂEa<ôÞ¸e }|îJß­˜ÉMm«ÚþöÊpØ š5'º‚ÑíÂÀ“ªir]Þü835w…Å×(Ý!P«FXüØ0>>>>>endobj +254 0 obj<>stream +xÚuPÛN„0|ïWÌ#>Ú."룆Õ/«Ë~@…’ÅŠm7Ä¿—ÂFã-=I›™9Ó3çp°ép¬²PUG®J’l8Ö(›€dùôª#=€X9¢iµêe§P<”ÅóYùJ(gq¾Èìÿºd“‚óàK'c*²ÐQ’Èˆêïêfð­éQÉR;ƒ…£S5ÆÖà;Lcü´¨L×ɾ†7pjºÃxukUåõ{€%Ûö^ÙË¥÷kT¤qúOÿ-?ýÄWk‹ Çõ~»ÃÎ4~”Vaï”u¸—ýQÎ )ÏrÐ Á‚V°¥ŒÅ瘁Û-½¹Kçì.°EIžÈ:ØwUendstream +endobj +255 0 obj +256 +endobj +256 0 obj<>>>/Annots 33 0 R>>endobj +257 0 obj<>stream +xÚ­UMo›@½ûWŒ|r$Cù +ؕrhS·—¨IczËek³ °”]âæßwöã¸I¥Êò²3ofÞ¼~M|ððçC@CVM>§“_—xnÀ÷=wq²€4ŸEàÀš<±z 7-«%mẑŒ×HÃº!])ÅYú€ú*Ç@8a¸BI & +H£üs*²–ÝS߁ä È…Æ¢s‹¾á-<ó®Ý_¨p‚Jó’ïjÄѱ{×ä°?Q9x>p#}”¸²[¥ÏõõðÕãö„aâ" I„¹W&çî¹=•°6õzxqîj†V$+öIŠ®ix+‘(I»¥PwÕ½ªjÓ6‡]ÁÐˀ’’¶¦9{ÞI`5œNm ¦¶ˆR{Å~`QA„L,þj?´@û8p“ÃÒG.ívϖ¥áÒv7œÃt-±Y¤Í{ɜ, ľ«¢–nh}L<xDtÛº©Bzñl*3n‰,0º,H ¢¡Û<+ÍâKA÷š¢ªU’UT³¯{†Ú°’ÎáòçÍHYòÐ·½.¡¢Eƒ’òC#è©ßô@¯h{ Ftb£Á¯Œ@=+¡YÙXß»™wv8A3ÈxUiÉcB#Ÿš áÂ{ԙ‡Ã*È#£öDp+“£ÊI–Ñ>ž×NX¾Çð?Ê¡Ýv­åGsáÃR½ÇMä‘akO 8*š3rñ)RÿÃíq!wÜQÿr§äõÖ¡9Úê{ººísõŒ&_¹¢[Rj¤Œ”˜ñ…ÚûV˜NÇh¯Î¨nC>GúžßæûónŠaÇÊɳBÛ´~ç镶¦R*¾¯š °ÖÂgÙpî†;Ë 3N©*}b¼Ã©øMª¦Ä ¥ý~'㦋NÇK^¶Óô×GÌh´‘¢Ì¸²‘ÊIKMU5דmߥ™—¯ íÖð¿ôÓ¨ÏÖãâ[RZ ¥y¦ØøžFzÿzÊ+ðí +ý1ùžõ<ûendstream +endobj +258 0 obj +749 +endobj +259 0 obj<>>>>>endobj +260 0 obj<>stream +xڝVQoÚ0~çWÜ#H `@7UÚÚuÒ¤mêZ:i/nrwŽÚNÿ~g'¡4Mð€ˆïî»û¾ûœÇNCú„0žºo”v.Á×3g°HèÉtÂ"îþæXp¹»F¸ÌµFiá &,Öô20,C‚Ѭ?uA :\>V»"S™åJ6‚º©4e2†ˆI`Â(¸GÈ Æ`˜µ*|娪\å€û-HeÁdñdëð1Ia{UP8î %Ë4e­@p‰J !œ94‚`4éOÜáT¸ú¹¸º©9«š ‡ý¹;–bÌÙùç £9·… +Ü/Ê®ä*Àx…/*ìE>2 Ø¿hO©õWL€‰á_‡Ãay¼æ,pMŒ}¿·hmÍZÅ\k.-êWIcqÊ%7V3«4X§Lˆ-\P]ÉÀlÅ4(¨S‚^fÎÊÌTYàæ9ÎóȌ‡Ñ8Ü ˆÅ'Ô[%±w}HCBA¼¼¯¡rœ^1r«r ªÍ’§0N5ŽRWòí¦U÷í¤KªŠ˜e·»Ê×À¼ìMXcª,¶Æ|2¨ŸÚ]öú/‰:ÚËN*’á›4–ÉÛwô½nÝļTê $ Y´.»ƒÇs|—w×·`ò,SښŠ˜i ¨ž?^´ ŚSB’­3±ãˆ"nh *0N4Ø' ú…'tT҂uþP¾ÊHžM($ÁzŒ`f}8êÁ!1њiª˜ (1j¢kç™À ªÝžeÕf»l¯;%Ûßþ·Uy`¼M6œÛŠL×nhJÛÍeŒÚ œwí—Ø2‡éµ¸ui6Ÿp’¥mj®›-†5µZ–'ÇæÛânsM-A-v+q»ù„Ç4å}ÎéX*pÄÒ3‰Ÿ¤–Í®ù·”°9íéâÿ´lZÆ¡$¹y9—n¾¿—~,õ°œŽê}ô!Jó—kÏXüÍÒ0*ø$=ZNN€-]"·ëcŒŠÌ_YËî|Ùk{³ »Å6ï¶ÊAçÕáp:‡÷³I  4»[•Ø‚it·‘6ðƒÉœy¨;ÌFCwv4r'3žò¶tµèüêüéçendstream +endobj +261 0 obj +835 +endobj +262 0 obj<>>>/Annots 38 0 R>>endobj +263 0 obj<>stream +xڍTÑnÚ0}ç+®xj5qÒ§±–1$Z„ÒJ} ‰O!Îlgˆ¿ßµ +¥£š'çž{îñq~7Øø!8àúìߢFç{Ž ÑHеðƒDéMÚ0çkµ…1Kh.)ô7‚ÒÍÕmôË’@¶‰ZÚ®×C,¾ç»Ïañ4z©`¹bùæ©èî—„h®0°zÐv˯ˆŠƒ`›­†AÛ±mVÄòP«› +ž–‰’šÈéZžÖSéð<âèfÓÉ,‚çÑ` 3˜GœØÓpÝ(¨ñ?&ãñër2yhÁcö:î?= Òwý¶KPÞbÞ×Eݞå¢D;aÍ3ǁîà ±\¿k…¾íjÜ jØ +6¢/³!8ØËÇÕVïÀµµÞj•Á\ïéð+Iƒ]̲;Ð|db7IYÈ6Ë×ü«þgq±ù¤±Î:ŽcÙ¦q€üÕêØ¸.±ô$M‰«…,—Ë«2¶JwÎ~¿·Îu|d4™ñªÌò¶V6ŽrUm#ãùûDØ:m)|’¬SUÏdÙ÷×ß󓪴àí¦y¿˜ÎßUzù¼°ùvÛ&¡üKi +ežR +õ Ÿ0¤9qÓr•±äø*n8®_ç û§c¤ƒ8OM혭D,W8´àqUтg*$šŽ}Hð _k Ë*¸„5Ï2¾Ç»Ìœ»nÍÎü¶ŽÏN‘ŽŽƒèVEƐJq3 ö úÓö0J[ñ$VhË  ©ÐY®R&h¢¸8 «j%/EB/Ô¤L*ÁV¥Vc¼8‘uJ):,O²2¥Š¹¦ÕÀ&ê0™‹›­z!3\qqvƒ7aÍ2œ£b¾è¿b¹vý\†¼æÊ?LO©ÉÀù¤çl˜3„Ž«¬8BŒ¹FþÂ~˒-|Ø©U,uÄ +tÆ´ßr©d"X¡ kumãBE™®×]ðÁà ‚ð4†¶Ue»W2O¿yÿëÍïBm vNoºŸ¿EÁκendstream +endobj +264 0 obj +771 +endobj +265 0 obj<>>>/Annots 45 0 R>>endobj +266 0 obj<>stream +xڝW]sÛ6|÷¯¸ñS:•)RßòSì:ö¤c§nd×éL_ ’P“„€’Õ_ß=Ôm%MÇI¤·w{‹%ôõ$¢uüg'—'íëE=ÌðÍ`4¤‡äݵ6äÚJʵ£™ÈTª„¡µr ܗtóé‘nîo[þ"U±Ì:VÅ"M7„½¶´Ñ9}þÓÃßÀˆ+ŒÎ(èÐYgôè¯Î`He@]Ä»Gä⼿<ÞOÈê™[ #I8ÔBñB˜¹ S†tu‘õH¾+eQÓÂIZI3Ne륒–ôÌ#mATŽÏ…‰%€©Ê…ÙÐL›ìÇ'2M¿ …´$(“‰4“²Åˆ–Úb¹ÔÆù€ýÿ»é:ñÒ¨ÜIC‰Q(ΒÈš©Ôñg·¿…Ý’N©Îç$lMG¬°c)x+¡R1M%cƒÑ®’"OdY5Ôá >ƒÌ¶Ó~b·@žZ3eÕýºêDƒ)H®ÑL)¨JO”è²’gÉrÈçL.¸LЍ®0¸F”o„[D5yI€¨FÊÙ÷èKjª”νÄuáöûèOg…u P¯T"ëoý ó år]³ÚªkjUE)Në+B! äz´-_(š,yöPSY£%t@+ç½åwLG,ƒ¹ +WÊ#ÜqýPmSjd*^˜ÜÓe@Ÿ´Î§…™çoD4Œ‚Ó7è »¿Ø±7ìà’É˾E^€ùû™Ö8àٚ¿7‡Ý ¤þ…fÔ @ôâkÊQC¿rä§§§£,œ[ž·Ûëõ:Ø«¢ýúÛoϲ}=ª<êvh0ËFK·Ûî üª€·Þ‰08¸;!Çvz|«‡ß&] +_,Ðÿï'ÿë”5endstream +endobj +267 0 obj +1377 +endobj +268 0 obj<>>>/Annots 48 0 R>>endobj +269 0 obj<>stream +xÚ]Q±nƒ0ÜùŠÛ!Æ&HÆVI§Ji!CG‡˜”Ê`j¡þ}Ÿ!ÍYz~ø¸;¿óO$Ài ä Öê.z®¢x¿HQ5„d5ç‡rcýcõMh +!t•äÝI÷‹Ò4~’Vá`Íy¬½ƒSZSý?w‹cñr<”ýv‰Út²u+5Ûö¾í/ÔÌJ8I§Î0}°'S±fI°Ej©5»ò@ÆÄ ö Ÿf$¤GÓöD=:C7žzK¦'¸Ö«mÐÛUgœBE„òñJQ0],EGQlh_¾4ʐÐÃ^ï96!J1@üò~ØÆñ4MLQDnb4å<čÏoü⚪X'œ³,(,AÝ¢=:eÞd?JtV"+°Ê~÷Fiž²óiòtò=ú-¦Švendstream +endobj +270 0 obj +311 +endobj +271 0 obj<>>>>>endobj +272 0 obj<>stream +xڅW]Sã6}çWÜ·]fŒ7l€ö v`g;얖ÐÎÎð¢Ør¬bK©$'›ßs%;1t2Cléž{Ï=÷ƒ2šà'£ÓÿæÍÑõüèÃí%eç4/ñfv‘ѼxÿùÛ#}¾ùvóçÕÝ?^ß}ùDøÜ|{¸9žÿƒ g”eñÂÉô<ñ•¿¤uÊhš&ô[«%e——Y<<¡ËþìYzÆg?™ÕÖªeåqêâ2 géÖJI¦ôa%ݚVÂÃbB_tž²)XÈ&é[ø“²YՒîk‘Ë„Zå%žNº6Îóµ¯W4™fYv’NÎéñ᪳1Í¢Ç7ki·®*G+iå½,ÈÊá ]P¡œ·jÑÂ2Î.àN3òG•tdJòÌÔ*—ÚI*LÞ6Rû„p™òJè¥ÒKRž±´ñ$êÚld‘F†.÷t~œ°Ù{+E³¨å!Û³È༒=˜£ÒXj4¹ž=þÒ©¥ŽyñŒ‡±¥­i-• º0 ¿qU8`ƒ— çt½Ú[á|Ò|šNØ8¨CjiEM÷í~Ð]8ÂSÚK]DÜe+¬Àwùs\~7ÂêÃ99Á…†Cp-.± »HÈ7 î;j´˜Òœ3ò†Ÿbµª9ql˜™3å+q¾¥ÈwnÀ´ +½%ƒ;–VÖ,­hhSÆi}e¬ ôÅ'[•ÒÓûӌcŽFÞB~wn Jð¼ØRŸ•;µ°Ânß̎v^Š"}:¡~7-åBZ¶ ë¢q ž˜¾{þ]IM$c%Å3×@ÈDïb¯ØU+Ki-G «’P+ ÇRú@¯{ìØÀÈס®‡¢ž]¦J¬£DbÔñ¾`_8‹dtZ´Ë(&®ç±¥]Ã/Re@Ú(W='{h+s©Öl´µ9C’`‰‰]Jª¿»‰šÀ×ÁU>Ó|£Ø´Mˆ 1°IMZnb4}¶~²ì?k³Ù¡†ã %nœÓ¹a+^æ> + ´ir©å€t+™ÒœEé"H[¨‚+{*³.uè7^´Ä1p½¸g~5.:ÃÉ´Ü>lÈa¼Ã¥,¼ÀDcqµð*—Ö 0+¼T U+¯ºÖÈ.tÄ¿&„W +/a\ï®6¦P%ׯ˜±[œ‘?£äÿpZ^‘è“J+Šß¼ +Ą&F¥„¡Ù¢3-Õú5M@k +†5å¶·'ëe%¤ô½74ªÜ؆ªNvºh5²°“q:B¿‚¼vº +ò…¦f)wÈŇ¿T¯¥ƒ."_SªËWä7P„—+÷ +4{:£9n/óÄzz?Å S¢Ût²LäM¥À>“9®j>ZË%zOX\Øbº- f¤ BâCºªhålJÁ9CS£‹“ØaD++ôƒ¾²z-‡,É~Gi¹&œÇ5·Ë_£h´5ËCw»kc/[]J_ʃ‚Rq˜8L%†”µ‹óm%œÃ+Þ©zg1fß$"é²?7½ØbgîöÆ7H¤Ò¢N¢VpŒ§(8Ââӄ=š¢Í£Sa.²* v8/kgn`¹¿ï ñUëÃ=Ðß-Ÿ¬·I@¶QöÕWØÄ°ÏÀ lD̿ǀ $uä­ø5÷(è˜'Bènk£ŠàIÁ-݆è\ÞI‹ôñ=„ªt¡ÖªhÙC2‹ Œˆ¸[ÿªÏC‡9[í̌PñCWz, èªÜë¡0d²’Ôˆ‚AÊk)ì 58ýb·QèPßujã9eì8ýþ–[ðÁü ®CK»Fæ²±ï3—&âTg_RQÇy\–JÃ[v·c_tKt6» ÙÙ,:DŸïö‹Ö#/ŽôUhðÍ·NøðÉù4ìäÓ?:ÍÎhòó‘næGýöÆ|endstream +endobj +273 0 obj +1438 +endobj +274 0 obj<>>>>>endobj +275 0 obj<>stream +xڅX]oÛ¸}ϯäeSÀuc·›tÛ§~¤½Ú4·qp±@^h‰¶xW"½¤WÿþžR²,;{Q´H%j>Î̜9Ìßg3ºÄŸ]ÏéõeÕÙÇåÙ«/ÐlFË5Þ\½½¦e~ñõö¾ÞÜÞüüðî>~[|"ü½¹½¿y±üïÙ%½œ½žÎùàòæç÷{úpû™>ý¸ý¼X.~ÜÞӗ?ñß»?·_'ôyq¿ü¹øøÀ¯äà÷Ÿ_Ÿ>ð¶öê˛ä~þ;½œ_Mß°áË)ñˋea}3™¶A“ÚnK£Վ”miëÝÆ«Šœ'WÚÓÎù¿hW˜¬ ÌÙZH‘u5¾§m©2Óª%œÅûmëͦ¨Ù Ü÷®Ìa*¨ÖØ ™š*ÕÒJSnBíͪ©a£±|„ÍÔÚWÜÿAœ_µÕ^•t׬J“uaOi‰“çw1ÚóÉ•.ÝnB^¯µïS räǙMð&G>ç’æJD⬄ÑÙ¦J+䬍ÀF¾îöÙ ²0Oª6O:Bóê¡¡RíÞÁŠªÉHdAij `i,\*Ú:_ +”L=é‚{Ò~×1;<¢Êåfm2Åg§ú +oj|JÅ +ØÄJ—ÊnµÑӑ·Ç‹i¯UkTfÒÎ±YÙä°Å]ƒMeêôÚö¥óa,çÓÇt£P2ÖSÃÔ8É<÷:pAT óÖ5ç]`]?ȳ©¹{]*޲5œì»‹Cá2# å5w1޵®‡÷sñž#oùÔ(,¤LŽxë@¾R+ª¬æbøÆ•FÙ’A8`MÇG`l ÈÖÞU£OF^»(-[2kñÎÝ¢mü!Ô¦Æutª‘éñ ·ÿX ¶POëJk;rW)dDN¤óøbJÿ)t‡wlcß`˜Åt`¯;~>t;¤z/™ºúÍýéa®œ@³ç…}Kã¥z=4üjàŸ1÷ b4 +úHgšç'ÃpéÛ1!U:7M5a6x2ܼ’ ËXnMÖ¸&”1¤w[o00x²e +g©•p¢Ä< q›¼Ê ¼XmáN˜œöŽ8ˆ ƒÄãô6Œ¹£QFWIš%'¯ãy-:EhgðíxfûZÊo¸_טýµ‹Ì¿-ڀù,»iªA¾ž{0g§MVbрá6±!ÂêRæZ×:ëxIÿBv}KÇý9õ§ðG=F@üé¶ìvÁˆ¥ë¢ 쯊éì'uܞ‡ƒS>5²Ñ9>íµSëô>e?nr95 ª ÛOÇVŒ)5›ñöŽ-ÍŸ^ Œ 1køU5ø†‰ÂÁڔQpd¨ˆ0'uxítS)µÊ»í;»Dz—Ñ\G©9&°k÷øÙ¾°½<8¤Lƒ×û` `ÓìOï1ϹRÞàç­òõ^!ñ³0.«HÎL÷]»° EíÖÆ)íGY‚*9TŒT7A¼ÀËr<ý…ñ¹Øãæ|NZuZ*âs€i–2ëÃÒuòÉ¢‹áB«œ7PU)&PÔïe&Ë]¡-ïIØ=Ҙ†ã:Êi”Þ³2é6§´ùÀ2‰ ›"ƒQçsÈÏüÖ +p b^qž Êƒ3nzk]f¬¸ï¢†‘©<`r:Éݽú­Óšó:îøç˜çñ‘è2`Ȓî, —6†0Š­ŒÈò•©»ߊÇ´+K_éƒ1MzC—e·ËÙ0nÇX=½{†á•àͯL ×¾#sHyP$º\GE¸¯â•å/ +¨ošX)ë?f¹öyIÓK«¿Ãò¨/=×q`rSš÷³žÝ—‚Rú´’µÇw¡–Òêì{^ÜïÇoJ ¤É +¯Õ +ó"±¦ÁBÝâGґC}ŽÉ#³°ÝЁ3/b}¯ÞøpÐpîRvǰ‘€®P“'˜±´=(môÇ2R8jÙ ”\¤&Ã9¢Dv0®^…5¥hg¾Æ8TøX(Ù;Q]¼xšÖ帚w¢'&q µZÎÑ¢°0vöyFœðÙ#³ÅQ‚„ºîïÇÝ7Ä_ãy×>Ü>9í#[Ot#?з‰õ½Þ(Ÿc…?«ÃÂюŠÊ5–SK؜ð:M{6r-èsJðʾeÉIBh!Š IC¥Ç8¯üÞÔ°“ò(Û1ô¢ƒÞ*]È­pï8Þkõ/í3“VäP޽+OÖhps–ØÊR ‰Ä_h¼M¿Ð˜½žÓÕ¯9úôpwO÷n]ïø6÷ lù]ÙF•q¥]½¥—×óËÿÿۗ7×o¦oIίùÁÍòìßgÿÂ0Oendstream +endobj +276 0 obj +1818 +endobj +277 0 obj<>>>>>endobj +278 0 obj<>stream +xڝXÛrÛ6}÷Wì[Zñ-ŽÛ>%'ÍLšIkû¡3~HP‚ @ZÑß÷,R$¤8ÓN.Ž r÷ìÙ³äÛѝâ×]\ñï²9z{wôòý%Ñ]ÍGWׯé®:ÞX÷ÕÓRxY‘5Ô­%}qvåD³xq÷xtJ'çW‹K~ò£!QUªSÖÔH'I¬VN®Ÿ­I‹×±I¿Z¥êÖ³ƒ‡cëâ©HÏ.綃F^ð '«ûFßä;ëÄ +UÊwN-û¬‘•ꪬô”SfŒ´‡\ö¦Büˆ/mìwkåé“*¥ñ2s"Gj.ÄgÇÿ؞±%¼µÕ‰ÜYÐ<>ÕÉó­,ôsÄ©@íò0Zqtìˆ}ˆåwYöXjIµuÍ|']ã|²ç!uNbiŸ$µÎ>© +λµèh ìB{ ¦€&-3zj«µÝ€Àßø‹óW‹«Ýw"‘ð¦,mÓ +³ED»ló™–ÿÃ9é[k*ÎC#ʵ2òÄIQ…¼í])C°mÖª\SÓû.D} +¶GwK9a·úaå$U”0má”ÞRÏy¨m®oën# ve`¹\ ³’¿#Ũ‚Ñ @ªê:ÉeRKWГÐ*8#0¯¥ð ;)i+…óu–V +XÙ¤ç*j…ë¶E|%—@9(ßXj¬c¥ Ãét`†ÁD»ÞzU +([éX&Ì}¢zZ- ™ÊxØËTyTI–ÔYÊó©ÊüüÿÄÑOR5“Où¬Z•a’bgãÂp²”ÈGEÂs@¡{p&ùäÆg4ìKvÂË=àŽ{ŠÐ€jà †¨¯ÐÇd¬@´ÛR =ïlÌMxNÕ 2ãq„Ì`ÛÔxöº åí#Pà{”Պ·h‚ +ùÛÌÏm¿ô©_-c¢/á2c‡¼[ÏJ;ê86ÀF +¤:¢”ðçb6›A[á!~¾_C˰•ª¡æ($@u z¿W·€?‰»&4…ýƒøØñs8‡Ç^c|(¦ÍtB”h«{¿ç]ß{‹T±Îƒ +kÁ%&keÂä¤ZÁR|;M§ÚÎG#và¬P•c¢á³–p°_1lií‚þ€ˆž8uÐ+Fc+ƒzä÷R¶±ÌóP§õi$ÿ…Q©L©ûJîG‰–f(š—⩊RáÞ25òp ÕH‚äl.•.›gøXnx´.„ŒÉcºœ×‡ãÈôÕ"u8ñ<©xˆ`T;ðà hë;ÙpÈdN¹žØd‡(2#dÜK]õs“PÒçTçKR=¯Q@›8FÓòwÀÏå6VC‡«€ÊÆþZ;Û ƒ•ôjeXUÔVC_!fgC~ë& ™ÛS8›‡{T0†/z¤ÊÉ\åqe¶ +‚âxK³ýj=ZÌ÷d³(µ”>$´MsºŽ +™Ð¶¿~]fëWtÕb\†^Ÿ¾_긼³q¾–Åúàš‘ßы¼çy9,Iajå“w¶Ò®ŒùFÂr¹Q^¡ó Ø}²ª*öŠ›0z’èyþuiªó U¬8÷Z­¹§¤A;Å8v†!7›µ¥µÀôÆ^1´Š;–ÌQ5<÷Dpœ€`)G)Z¿ƒj—óÍdó´ÉeÀ9Ù Ûòª{›¢V” ¯¼šˆ`ЛãJpQn\ m7‹T ÅÎ"\~‡ ›w7áŠ/6¡°´—¹-.¶ÑrxÞs}t6¥û™ãôÔ¶Cµ† \Æ„a &EZ‚LΎ³kµTL#Z‡›´ðêÎ!5ÅxÅ~XðKÇ4»/śQæn~kÆŸ¹—‡ÂTŽjŒp8kùM*¬OZ8$sž¼ÌOÜçù¤äÅ*’R‡yÑrÅ?/ +cpÝóËnæßÕUՍà)¢™¶Ágïu?cˆ?¢ØêÊt¹œæuj’‡øÐ2ƖmQŽ(&¾±n×i&ðF:¦(ò+N»kÜl½~ø|On>ßüýæ}¹ûéã;Ÿ›Ï·7üØÍÝÑ_GÿŒÙüendstream +endobj +279 0 obj +1737 +endobj +280 0 obj<>>>>>endobj +281 0 obj<>stream +xڅWÛnÛF}÷W ò”²|­/ȓlÓ¶P[R%º®¿¬È¥´ ÉewI«úûžÙ%%‘rRA"rîsæÌðŸƒ:Ɵº<¥³ вƒ›ðàèþœNN(LøÑÅÕ%…ñ×÷¯¹.)U™*eL¥¦B”2/IY[Iûþ­G‘ÎcU*[F’Ê +m!ªsZëŠÞ¿®–²\JCó5D+S’6±4= #eƶ´ùþ}pL‡'gýSvªYa¥¬|ÿFåR”ì£4"VQ‰ßr×¥NðDYzR‘Ì­ìñû5Ś8lùoTYéâHŒÎ:º]§mK}&N39ۊ•-šW¥$«IX®…¥²Éš¬Êª´¹Ô•M׬eHÏSµ>È*GÆÎzÇgí‹Dãïš\âTHSªÜUfkÄe–³cÁ9XùO%óÈ'—‰5ub„pÇ×Äè…¡œ"Mût¯ +$²"EÕT³ukÓ:¨•®ÒØÙE@è?½i¹>LÐ82rã áù>üÌ%Z—Ðlv©¡IõÁÍ(”´ˆJT!©|ó«\]-–œb=7Pçxµ®Ì‘‹¸éÊÕ$„ÍÅÝílØ\r LŒP9!q¸…e”OR£:™~íóô¢Î>î\¡ÍV¾,RàßøïR›Ê?DªbΰBkm")橬±áL˜ˆªTŠ”‰ªÌR‘‡t'ѹHùUڎ3•£‡±UQHȧ¿rBàûSyÃÁ°[۝ì^˜TØSQ怽ZÀº[Õ u¿£ò…¬ÓgôY®P=Fó$¬É¨Å +•í ­a;LҖäJ¬ ¡}Sl-k½ïíP–<À\.ÃN¼ðY²H¾p¯¹: ‹Ÿq…$7V'劙¯»¶¥Ìz(´B \h4¦;ÔóPTíh3k…ðʕ¥gDÞqWH e‘ÉD,i!s‰Ù°žkŸŽ’8¬•‚ˆ\Xºw»-f׎39Ãó <ÌrG9Ðg~`˜¨HláFñJßyܐkU4¡ˆ +CoŽbûNÅ2âà@7{˜†€]:L®Tšºè6ëÖy4±o ³Ù±hSRÙ·_HŸe-5d»X;ã»;!™øÁ–´ ³¥Óºâ +@rŽzÉ/ viót Ã8ÕI'’Öâáw‡ØÃ›ˆ®úÄϘjØD gÈùˆ9ÅÊOq@ìÌ`iJæŠ0LLu`I xWªf3ï ßÜ¡ýoiµX»tvJi¤ö<ã…ÊEJ!µ0¥1Ï)K¶ÂÚî c}uê!bއXOŒ4`j!Y¹À,ÁS+w™x,bÛ§UìG—;¾É³ÇÛÁ´¥º·ýš+ÝñR!˜9Ó°¸­™'9Œžw'c +yÍ4 ;©©<Ò ƒòÚOx|'z¦be8€œ}sÑæ:^wOœ->+×5>BhÜ3%͚Q¹Gر·Ï7‚#».>ßh5xr¹¢iìö ’ôÀ ƒbOOuѤç¯*•¹UÊÿöiƕhYäqæyÀ•¤x¹!7[($ڐDœ2±Ô=Bƒ>E¬’D:õXÈ©[Yq eë‚»±P3bLàžï-ª@ ºÚOÈWjï€äT¨¨‘È«l.;w1l ÐXÂhÑ_v½ JG×õyò…¹,HLcïKÏ-IGùnΊ†o¦zÕl(¨ì-E¶¸s"×SÞPu°6͚l9n@â×TمTÇÕ`{EŠu=-¾ZëÏjչݛ[ĬÝU܅@c,kþ'Ðì×sÑÿm „“ã-©²Ûυ;I6ë2»G«9¤üÚqë¿ðÏ-óm“³›çuˤ­o%h@¿ç_¶·¦Ã·ý†[ëê̇ûfnî‹’î‹¿®NÇ÷Ïľӊwp&y̭ۄ? DYøä8dnmŸÆøâ¥ïÚÖ0æ,Þ¶­\iZh‘Z€ ÌGoa"+÷_]RF} ÀéøË«}•ñ0øÃ.ӛ»Î.žî¥‘õòܨ,<÷¥kœ£ûëú«øŸÅÆô:˜N£ðÍK5ßÎ'×-œÔ8» n/³€Âǀ&ÓñÃtðLÃ= oƒÑ,¸£ûiÐøžnӇ ÇrӀ%:ŽÚ€ºOw-Bmì~…Á(¤I0}†!Ìß¼Ñ`2·ÁÍS@Oƒ×>dnƒIØ©çëc0¢1;"ÚY8`íáˆ^§Ãp8zpÖoǓ·éðá1¤ÇñÓ]0Ñ`tw„Pœb÷#p0 ‡ÁŒCüsx×.À—Á )~¡×aø8~ 7‰r!£7ú}8ºëuìCv‚è'Ó`ƕƒßá3R îzôöéåqöèöFãF Ž]QYß´«¦ig§tq}Æöéöe2ÛNÀ àhù(¯DZóÈ^ž³ìÃè…‚Q0<ÑäååmÊ¢ç—çý+r‚§×ü þ8øéÅÔ÷endstream +endobj +282 0 obj +1871 +endobj +283 0 obj<>>>>>endobj +284 0 obj<>stream +xÚmTMoA ½ó+|L$ ,¤„½³^ÖêìÌf>@H¹Dmr¨ú¡&­ú÷kR;c?û=?ï¯Q3ùT°Xê÷ó÷QFWí5T¤G=Z®n }¹ØbèSßBOÁtòˆ5[N;@×@ËÉQŒÐú†Ä&[ 0ä0øHÓËôu4ƒIµ˜Î1u$ˆ pü!yÐÓی/¨ìÑÒÂz=¿ØÇ3Ä-§v>O!v>ÛæM´ünjÉ$ÞÐX¥fÌ=•8ãc’ +gh-82 Ã"… vë1WãCPLï +ÃIµœ~x¨æSÐã và<ÐF(CvV• +t›…~µpËkK`q«¸¸$w¢‰¤n'©«Hoñ·,¢ÛIÃ.ðºKÐyÛP ¹ðÂ.”yì`Ûyèq½o¸-_ùpFYâ˜×9Ñe@2žS’¶°ö*b-íréZúTEÛwx ö¸¦8ÆæFX”¶Öä( CȰþ‘{nD´{Y]}Ô!hÿ (ÆQ<ŸÓÑ9’f³;ZSúÒ³"g`w¯ g™RNBs/¾õ±X¾Á„Š\~kÒè@N„¦æ Pj“¦Ò‰æK«1DŽìöÃV¡ä*ušý¦èZéÚ´È6zoÄÓAHW^&¡ŠåO¦¼ˆw—ãb5àV*›îà‰3L©xjŽN\“$a³á(÷MðAMÀ;L 8þªýxx]Lä}1™/§×Š.â±L,«,mX÷$î³V‡¬j¹‚yu3]i˜<ˆZ?ÿ½z€üüðô ýý?÷ßÛµ‚ÉÍ|¦±‹™-ªk(k—®’wN-ë$s4$6Ò0J£ÛÑ?XÙBXendstream +endobj +285 0 obj +661 +endobj +286 0 obj<>>>>>endobj +287 0 obj<>stream +xڍWMsÛ6½ûWì-É ­˜²ëöd{ìŒ;NêÆr3™ºˆ„$Ô  Uýû¾]E;i&ÉLl»owßî>ü³—Óþät2¦Ãc*–{“½÷×g”ŸÐd†/ǧ9MÊ·>=ÐíÍÅçóÏ_éÃÕ§«Ïç·t÷pq{s‰__^}º¿z7ù(ÏÓÅýñÉ蘯þ¡}0ÎÒ8£_k«)?;ËÓá:kÏŽøì¥[m¼™/"=¾½||'géÚkM÷n×Êkºvµ-U„ÅŒnl1bS°ŒNÙÂO0©—«JÓ]¥ +Mût_›¨éðð £ "ßûxNt0Îó|??<8Éèáþ|`æêYûZh¥ýÒĨKŠŽ + $eK*MˆÞLkØÆÙ)-ù£Ña`ÊÍ(.`¦2…¶ASéŠz©mÌ—©X(;7vN&²/ë"©ªrk]¶‘ó”Ç?'lãBÓÌøÉëJ«`ÏMŽÅ—†«©W~CînGD7lyŠl½œj«cšêBÕs§­M\tÇ­MçKc[£¥žõª-ï¼VËi¥_’á8x"è$fÎÓ%¡Ð—ÿ•:˜¹MÙŽê ¿\« m\íi&”nÉ_ÂBΣ’AF?¢‹ J`£W!fmÀ‡£1;æ˜Ä´Õ^UtWOƒn[,lÍØ¨m™<Ïkå~Öÿ ¼µíïã’ƒ5.1ˆ.VT’oJPreð¡+|—³-{2±qÛÖ÷Õ`2R«U" +Z·„Ï•. |lšä*&óN[ ðo›¬Ã›IȰ¨ì†Pø†fìh½p ªãÂù'…)5ŸM´ÑWWS¡ló³„Ìixíì!Jç†iø²Ð–ÖŒzbVJö¶ð։>^Ï´÷ÜQðߔ-“¾ZyägD¿¡œßaÁSŸýBªÈÐB=§²öқ i ¼‹éÖðÇÏxB 9¤ý3p‘™‰§µ ‹ÇwÙֵׅ6Ïl´ö»*¹I%Ísež47ÁcüØ»Êgòû7¸ËƸ^ˆ H1°IKV¯S4+ïæ^-Ã/‰­ñ'ë֝—Ò±‡À~P’—Ôvl%ê"¦6“Ù¤–V÷’î5§´`B†ä I›š’ÉÈSš³®­L‰Æ_²Ä10eÃŽÇÅôÜò^j˜îŒh’,ìøÄ0úFv€öQ!8±ÂG35•‰¦h ¡IükDxe,5Ó:c°ÍÍ¥+Ílí3HØ5Îè/¸ì{nhÇðz¡¥aQ®h$)2th¦aEü՘ÂsÓpÌ2°c㐒<¦¶‰J…@©æÜ0“ú\l Z—6ÒÔYGÛUÓXìX<¢›Ù+媌}æ†uiKíDÙ‚#Ï<€ +ÇyBZÜôo¦ØÌTi(î ß[” jà[–]ãëk^Õ,"³ˆ—GNjªÎG»‡¹?àpÀÙõ#:Çï:Äaža/éÁ½Ò @é/üÏ´í2ä¸% +îJ&BÓ_ì¶×b\@¹FD½ +?c å[E'¿vCÔÇ·cp3 צ˶Kiz½0ÅBØäh¥çµ¢¢‚hŠFFe}æÂÇ{‘BüžûatçU‹˜¿ZÁMgÂù7¡ –Eˆ)“¯!m×J©u«ïjîþá>t$HËÙºa\ʳ$Øt;Á'³¶_t|—h æØt#‹˜ê*$õ°R¥[*K€o6âhJÏ]×ñU6P£“N3ГHx£à²ŽÞ¼¸‘ È3° ZÇ»².8Ùç¬üÐà0ô¢f÷—®ï¡Ù÷o€yUG‘ /ÈxÍ'+!Ñfgm$% ½ÍÐm\…"ÉjvЊ?óLþ¢eÊ4v¦$%w›—萹הåYØ„;`w K¸Æ–Ó¢yä¦B‘䵪¼9kNið‰m,Ef¼Ø ]„6Ê~ƒðБ)ÑzƊá !óL +H%—ª‰T@Ùû^Ý"ÓNB—LŁó–Ùozò +_™Ý-%Œa©>²g¼ÕTÆU]r”¢#{ Õ+ܳ¼ ¦›Áá›2;{uR¬U؊~î-Ô + uÓ ÞÈC ,Ò–Áé=rÚ¼GòãS:>;NÏ*º|¸»ß>/XÓGeA¾µÏ‡÷OÆ?þ +>:9Â#K.ÊK÷j²÷ûÞ ¾'dendstream +endobj +288 0 obj +1631 +endobj +289 0 obj<>>>>>endobj +290 0 obj<>stream +xڍW]oÛ¸}ϯøå¶€ë6É"mwŸ’4éHÓÜÄA±@_h‰²x+“^’Šëýõ{f¨/Ë^ÜEò K$gæÌ™3Ã?ONéþNéü‚ÿ³õÉÕâäíí/tzJ‹_.>¼§Eþ*Ó>*c)×Á¬¬Š:§Ê,½òF‡-Jð;Ó6hÂ㟵‰šrSÚk©ðnM±Ôä|n¬ò;rVÿFKM¡öš¢#¯UN&LuUMIÙüõâ'ïèÍéùìŒ]ȝýO$B½Æ–RáÙîbiìŠwñÞ 6‚ÂwøåžÉÆ¿YsìÙÅì>v5°œ¥­¦R½`3½QQÒ¦^b_[á<‡ó»à“U8[;ZVµ«¹ ÑØ,štljUU»QDkõC„¸ÕÚÒÚ¯G*Ïù À(Úx·òj͈P0ëMµÃquœÑ±?ø¹_¶5±ÄÏäàn:2É_])+•]‰‰Rwk9 &‰wÏÞÞRö˕U•[¹:Hkk“3u4•‰ãx[9À͘*Á§y=£ßÝV¿h?e'Eý35±TéžÄ§iã‡ýêŸ:«£ZVB;E™[/Õcêlÿ—Á^o^`9vEÃpö^`{¼ù¬­öXñ¨p×P!‚410ïÀµPgå˜XW:Suh,Á;憇ÏjLÈþ?{L½žu¹ÉɺH%–q@Õ°× ®ˆ[…* %¶ÚÕŒKŽ­]ˆ€{ÝFûþLþÖçZ +ü›´6«ê\ç‰î[ òú‘M¬É hmVe¤Î‰d›Éµ#Õå½¶^‡èM–ô%QøYgß^ë–*¶®®¥ÞxN&{ ¯ƒ€íÂ`%Þ ô`ÙêÂđÝ0Éé!ªX‡–=Øøµºzé¤î.‘åŸR%eµ°ÜõåîGÄ>΃¼ì<™Ò¶4¯Òˆö…ÑÙ9(¯Ê‰â` øLæäñ”ÓEtü0\ÖV0,u~ã¼È}’STé÷Wߝd²Ö®ÒmE«²ÒhIc÷¨aŸ‡Æ°(M Շ³bBlË:öœŽÊ›ú:²—W™(DQ§rjS72Üdköý5±Ø—@} Úxڤ℠+@Ѷ.Öܾpê>DÇzr’®d;ˆŠ ª‹7s›Ô €7ˆ–ŏŠô·jX¸ªrÛ=¨eSY¡f¬|ƒ{‡áµm6ë{‰¢ K-U„Î¥{"&Ûö–Ì(8½Öì·åÖð]~`›&º:êd4U^±ÿ`¤E#a›Ì¾•ÆŸzÕ`Û×{Öq1µ÷ Á°Ø3ž]cX–,PÐø²Üý+=«ÙœnÓ3&lØ £ØˆYE{{û±‹úÔß<~y¢ËûOtýõþÓ|1ÿzÿD·_ñóáùýç)}š?-çWÏüI~ùúi~;¿¾äéÜ÷‡ç¾kL¶“Ø«Vy’÷—+RÈ)TKIcê徉ÈÊ>‰Š«‡Ð¦RY“Ó³d0(]Å +¸À¥jÈ«7a'&¤{j—fZƒ°KݳKj›ë4¥ªh[áqý<(Ûê÷Wª +Ð+¨8ŽœÄ “ï¯gt­h´4ä9ô‘™å˜@ 'c^]Ò¤«†µV68? l,ž-Œ½¶ lÞ‡\E¶x@„8¦BG@û¢­ARª]; 0ÃGq}‚Lyb͗ù«kd{ˆuèëªs0ÿÕ¤Iô„›>Te +!-¸å´dA‹8d ‚mH•ˆoÉ¢r4±a¬’è]S »}̵i*°û"“!üÌirJ2×q’²ýulWTB"%yؓ ïÛ!khjâÛt›8m݁ˆ,aZ¦Tѧ¡:·,÷ˆ§’6 ŒûˆôÔLÀ(Àh§ú©Ð¿jµÒÜF‡\A¢ŠÈ£O{;$óC3lµ{e0C4ŸíAì©Àh2ôu‚†7âÄä ÓB¦EÉ'ˆ +L)!1µ10„©-kf!YÄëqea,÷1A||¹Šòô`4ÄMBË<Ú¹ÐÖº¯\Ü_Ä7¼‡¡ºÒ2f·6…tÕAx‚Ë ƒD§ñ´ƒU ý©³¦1Cv‹½Ì› Fø:¤9 xWñ%bcšTÈ5Çb0¬š{ÃáAúäYÖà±ëÛË¿ìü\ƒžó*º~~x¢§VnŸåÂòEYŒ°¼ç /}óþì¯=?ãWg糏$/>ß?ÓÝüêñòñú|sóxyGÏWwók¼¾¾¹ºá 7‹“ÿžü ˜AGendstream +endobj +291 0 obj +1878 +endobj +292 0 obj<>>>>>endobj +293 0 obj<>stream +xڕWMoÛ8½çWÌmSÀñÆI7ɶ§¦›²E·qz¡%ÚæFU’²£¿o†”,˰E€–È™7oÞ|èçɌÎñ7£ë º¼¢¬<¹Ÿüþéšf3š/ñæêæšæùélúfþ/^¼M/Né»m¨T-e¶nIU9åÆgMдÑn¡‚)ù¥Ñžì’ÂZӃY8åÚß<ž—u¡qÒÛÆe¿sMÊS £NgÚl4™0!S±Ûs:›]N/‡ªZ*unšrBµ³“ë¶U«™­|m²Æ6¾ˆ TSµ3*h<©›EaüšlEZeëûðÔÈŸpfµTÙ`€4EšʔÚqd[圪Bûžžµ®9¨,* +‰9^ó£ÓKÜ ¿Œ™®|4)ÏÆÎÕÂë +>á„ãÞ9Ñ­b ÂòÐna«mMXٟ&'WÓ·ì¤ÏãZ¹ÛZjMKëäN½n½ÉTAۏœåèv"hÚd%&¼ÔÁ€e»ä€;à£ðÀyЙœ3HÈ T«è[P$Éí´Øc¾xU¥ÍͲ")î¸ù“Z[—ŠàºñŒ Œn­{¦…òÎf(‹«ß@f +4²#ώÅlSå:²´+ßc¢cFja7z'ñ‘Û^ðªðõ £Þb„žË©Êx{Ç7/þ˜^íÈSS⇧sxŽÈ *À‚׌,o—ÉÓT ´sv>´¶HÖ$|?S pXKS€öÞ$žA-zuúâð܀ð]!‹òðÊ~ï šr”lWñRÄ8;¼dö:ÈíÚºÓ†°œ ŽXŠ(gEW¶«¼‹…m\Nµ‚tm”H)î; £ÂLg;|yÂw¿då«Ì&´\a˜£N¹ÒE¼`¡eSEÉHѵˆÁ€•ñM]|}Áâs¨øeT&çeåT³~|¤?Á™ÅOŽ“¦—¶éVMÉy¬•gª¶k]íÝ!ãGÊ5ÕÆ>ëœ gÛ.¥zf½­¬Íq™;–^¢ +ÇʧդãDoØmìÜ=þÜ2$5r)´±‡t Y“}¼>®£Z;èÊDzÆnáá!F›$>6 ‘âjëÇ}ÁéRÔz©Ua/›bÜvœ~ý¢xN†™Dˆª+8)ÌJi%?.Eg-Ü®9ó˜1 ¤‡A7B³ÕEq–ë%Š.‡ù\×ÿªÐÉ~@â”Ð 0ëê±ÁŠ .rÈîgëi”¡àÆÓjgå¬Ýá,,Ñ¢TDÿZTµÆ¹¡Šwd°I‚GN‘nJ Ží{§‘ý˜Ýc|N¼‘¢¼t¶¹´Ò5ËÜ ˜6ÍêQï”|H3™ÊØ0¿x-!'Óyñ†ÓGԊV‚åÄ¡IçU1ü‚A)–E++œ¹Qfù°×*÷GvçSé”èîHû`¢HéîšTôÇ +—¦6ùŒvH+¯mÛÕó`ø±;&fÈtäú¶ ¯Ý&¯Ê˜êJ/qÿemü±Y½£îpp÷~Òìߍ‚^‰ÕþlÞ'g+Ñ£5”Æ{ÇkKìit RôKÐÕÁðŽò‰µF²e÷à†Ç«)?àfÓÆ^)—c +\¢-oOHи±Ìa}Rú'Œ}a'íËÝøŽPi.¼Ç’l¸>îJ8êÓ—ã˜p»u&ÀNße¸Šqîý¸÷)fa2tlb\/Úe&ÍݸTK{«‚³qYgEе¯ÁVŒ|Ó)ºKö¡–_[vïÑ[ó¸MМÁ¿Z­˜ÛΣªb%`¦ï˜ vjúqÊ[?:!:fäÇ~ hc Ѩi¬S+ vŠøÅÓ8Z¸¸-i •5ä{©¦c;ÈÑÝúòÕݽY–ŽØökƒ1ç¦b.>y¢ÏºÂ-è+peý FbÐ*?øRa«#ä+¤¹|×ìRJsË͈ Lv„*€æ¾º&XnãkœO;ÕñBýMø‹×˜œì¹ïs +ÈŠWé-uwx£¹îÍý +»²ÔµÆ`.X<3|­3þ.’€“ñƒÍ,ÂÆÜå[[|'c*Ò_±íÇ Kv\úT‹#Å÷|'éÜ$éÌ®nèêÏK¶NŸ¾>Òc÷=ñäyƒý[U*â6Œ£g×ç|–C|¸¿ýöáÛwú|÷åîۇúútûpÿ?Þ}y¼ã+o¯ßNoH.\^òƒ»ùÉ?'ÿ¶j¦´endstream +endobj +294 0 obj +1675 +endobj +295 0 obj<>>>>>endobj +296 0 obj<>stream +xڍX]oÛ6}ϯ ö²pÜØIÝv{J‹´ µ]ã`(àš¢m¶é’T<ÿûKR²Då Yy¿Î9÷Ò¿Ž&ì ?v>£_Q½Ÿ½úxÁ&6_áÉìí6/Ž¿h!™ß(ÇĆëµd¸ªxÿšq¶V÷R3a¶ûSžž)kå½´N-KÉVÆb-÷é gðI2c ¥¹Ý³OŸïØ'©¥å%ûZ/K%Næ?ŽÎØéä|<%ã7JHí$ãÛm©¤cÞ0^–ÌÕK'ÕR‡é×+¤U÷ÜÃ#¶3ögrseMuðaœ Lgã 20§ÀÌÖ+£ÉùÚÉU]²ÝAíMÍvÊmÈ(-e[n=3«‚0Ø:]ߨ¥¥h”&÷ØÖšµåÉ&öÔÆ3žÅUÆ%Á›Wß´9oýºHšr³ïp§âûèJW9oÕ²ö²çÅâ9‡Ɔ ð¡“x¬üˆÕ÷Ø­á•éℊi–?p#Ef3‡åRԞ§šVi²ë¥­mœ¶s€¹7e|i`é¸W…,b>(©\Sm¹ÞbvÊoRF«m)½Ì <¹­Ñ€Ì ¥å©•¼Î8S[Ë1Bٔذªvž-e'?ÅKÜÍìFç a¼’…ª+&°¯©¸UåžpRp;³ò;n‰ Ø92$ÇØõêàK(ɪ—ë†OË=ž¬P+ĉIçZä sÒ©µæжä{j³*/Ù¯e/‰$Ùv”‡NâŠà&¯dÜ—^¹UàXÚÌʊ6Ã.}èev{%‘$~cê5UYÙ"°(0I#jPÝeY@†îñÒ -F:i{œ:¯Ô¹ìsRí¹ÒÄ̌„É–8=r¢¥RÅDoIeZçÊ鈪.%•”âT&PS*ýWa)ñ‘Ä•‡pö[Ø58 +”¹®¿Ùm „ó`ËtfT9Srò~Ô +O®Šƒ¸ü¸a%à (À Уöœ•@M’ÔaÏ$È9Äÿ2;ýQˆ,øÉ8mÒ$Àhtœu¤¦‘PÞ¯Su_ý–Rp$mi jê²à'#f9O–ô#N—mòçƒ*w|U®“Fñ°(çrßO[«¹3æ|8êII®ŽJ}0àòœÿKÜ&ÏáNCV¡Å&Ù@<òJu2Üím-4”ˆrÑôö„*êLÐÜçà–éA_†"dÇ ¥šÐ8áòjÛ:¼Š¦ ¢‚#ÕJ uR«ƒS¸ANuØ`÷CD ÝdÐ;YB +X·GwìÏ©‰lГ6¦,RTÐV˜jœ#êm-üÃ^{äd¥tDCÉw´‡PjÞ¶àP™P:£±\×’ + *A¡QM7b÷ ²µð5Wò=±6Ð9ʽ¡·è£«hfBë´&Oæá±ÒHŠZëÔÇ¥¢›.H5L è'k¿!æ„ÞC™#¶¥2w qJ#Oµ@ËÕäšÛ‚6ʼÀâ]ªyœ!K¼I…Ài ·®”hNŠªÐí«Û²0ÿ‘Þ)*=ý%Ìæ£Ùxq’Õì 9‹á.ƒO&U}´íÓ —n]¯{¬ +~< vùÙ%z—|,5 yؐ—Á +qÔVö ½¸Þç`±-— + —û¡Gú<ޝgÃîœT_È8†ûxHhç³0‰rBHÍ´é¥/i7O4 XĀPÔ4p$å8$ï‘Þ1ÎàM’Ó°ÙÔŽç5£h|ëÏÆ‡ÊnñL¨Ld­; HâH*íï0´ÓˆäU<€ z•^ƒÌq¾ ýF.ëõš>ùéôšpø ¹šÎ{äv…­ ¶@ +‰(˜Íã×uµ¬ˆ‹Ó3´!Æé£ÿÊTÅèžê­­“®Æq‘ÔãàM÷½ëŽ{Eò‰ƒÈ3Û¨/Æá½ ;YµÞ4!»H2§´(ë4-åïµ¥jÂç• Œ”䨣/ýψ˜#$½#Õ"ƒÖچ!Gw ~tœ+ šH£D.œäõÚýA榯dzC‰ù˜ÑÍãËötÖ&ipFc/?•å “3˜< ­!}´Ï@ è¦o(;V¶hiÝY?wÐ{ÉÙnqò'= +xoíNê=ö?wnää) +Pèv8ö*œ.;G©ðåIb +Á êèÛ¤£“ó)›½;'ÓìÃÝ×[vۜLïð®cs]ó’ÖœNfoÙé›é½{~0;¿cá}%ssýþÛå·ïìÓÕç«o—7ìëÝû›ë¸ýáêóí-¸šýsô?DÌ+endstream +endobj +297 0 obj +1699 +endobj +298 0 obj<>>>>>endobj +299 0 obj<>stream +xÚ¥WMoÛ8½çW{YpÔ|5I÷–i7@¶è6Ér¡(Úf+‘*)Åõ¿ß7CQ’e{/‹m-‘óñfޛÑÏ£3qŠ?gâú\\\ U½:zóñRœ‰§=ºº¹OÅLI+*W˜ÅF4+-Lî¥ßi úm…×¥±?DãDí]Ñ*-d.1{‰chàqÚG*©qrΑyÂÃkn±*aÿƒÏÞa3ŒÉó›¨ZTßXU¶( up!Ɋ€ú•¦™ò °ô² +à—.¢#xr‘ô`¤Œ³i2ñ§[ëW¢ÁK"KœTº¦>‰á×zEYèCí—ä™)> +²sÉBc‘½,Aüñµ—¢AKÀÚ9Bì¹±$„×ËqdmG·Ó1Û¾ã(qÜYÖ¥—Y§"Hè‡öV—sÆ,8á,ìtÈ;p +â‚ÈÂ&4±Ð:£VS˜|kÁþÖBÞ¦Äãœz×À2èrAÍΊcºz¶²î~êHo%7蹺Ö6õ00êZ¥"£¤·^F5Ñ4QÛ@íDð©(¾ÈÉ1x(vín·’û(F˅›DÏJœª!·dr +NõR+îø H¥%œm0½È‰tîbª4»öˆÁRsÌ(ý]2-ÂȽùxݍ͆×Ý«4Qgân¬¬ +è"©ˆ3=ÒÓeúå2 ÝÖèÁú$ߜп"žØeÙœ¶BʆÛ4ckIAøHòM¬öC¬hìÒ!e䈀ó¹ù.ë_ ѽ×À k‰òéÃj¿7crŸÈq(þÙÃ'×uGËT4P‹˜ÈvX\M×)o³¦ÿÍðY;›ÔSîÛSÒ IzÓ# +'+»³*šƒ³C™gâ‰jŒœë-ñâՉ]a T!…ó¨;rò¤Ë.(Ÿh©Z˜îÄwtú¡W»ÝÌ;󭉨¢Ø¼$Ö×===^="T'ý <‰ûâ©ó"†ÅªˆC:^øm°ö G·fâÍA–FFԈ&n¿sô}^&JðÎKXÌi ŒÈ1nÜ8©hz!èb€ž¥ö›´kªÕ@»LÜ¢ì[ÁÆÐÎÝ®ò?ÂÚáÊ«39x–m㰄`Ç%¦Þ1´VW0·ÍrÕ±/Þ~\Sቔ´¢óޒv‰_äcj4;³ŸH¹ë@ôk:ÛDFƧ©†0y –ŽÖÄ¥ª gâc íE +ºha—ú©4Òªÿôw{›…›¢ê÷(Tˆöʺ™È(tZéa™£;´±Ò>^vðœ]"gìM´;àÒT])ߺîípÍñ[vdÕ·!f3X=Hùd’ϔ_™Ü4q”r-Ìbâ¼SMÊ`O¦lÔkpIÃD ŽRǗ¿áˌ×ÓÍ~™ØÓ/ÇsÆ’@_c]{Æp¨ŒQFí˜sp±ÓÑیH”Fz‚¢Hߌ¼¹Õóüà7MÌgHn7ã;äì+Hþ´±î$-|¦Šý‚®Ú_Öà‰LqËWl£ož1½wHÁD%µNû\ÿÕãÀQ0¬ìÞÐÇI’¢!º‘ èlï/mþ]ӈp;K+Ïà=õȶDÙ`­ ñ»cÑz‹Û;§ÝN8üN;œW$žq4L“Ž’ÆT~Ô»ÆfnìÒÁðç òÒó·Ë ÝÞä‹^ÿ·Í‹X䛮ÈgW7âêÝE ><ynѬÉã3¾â‚øKÚV–q<ãèÉõù)ýôùY<Ü¿ÿzûõ›øt÷ùîëíƒøòüþáþ¸ûüxGW.¯/³Á.Þ҃»§£¿þ#ÈÀendstream +endobj +300 0 obj +1762 +endobj +301 0 obj<>>>>>endobj +302 0 obj<>stream +xڅWÛRÛH}ç+ºò”T9N Y’Tž p-±½²XBU^ÆÒ؞DÒhg$ýýžž‘|‘!)¨K3}9}útû¿“½ÇψÎÎù7ÎN.¢“w×i4¢h…7çŸ>R”¼†o¢xó¡}óš&« K‚b[ù_%óX’^¹•)éG•¬3™—¤ ‰4•kQ*ó‰B”ü\å+£òµì­ø`ސ.7Ґ‘Ââø÷×¹.Ùõ{z;:žr0©ÊT)*õ֔µ•´ßß 8˜D±#Df$©¬ÐGa©Ñ¬ÕéÌ/›6LmiÉÚÈm$.‚ZYùý •Ñ÷¥‰ŠK¼•û.‘\¹Q–îT,ʀß7”hB$ŕ•.Ž•ÑÙî0Ÿíû9ÛJ”-ZV¥$«¹ ÀÂ`»jȪ¬JK‘K]Ù´aÈh™*_KUŽŒ|ödúBšRåÀ¢ç{ψË,?®?'—‰†z1rªwji„iH”L‡!]hùKdE +œó¦-fêƒê9¯u•&Î.ÂCýÉèF¤eóv…-[o-Éö]¢Øp‰GàՍã±TO ¡¤E¤xP+mz^U¾}WnŒ®ÖN±Íž]è¯já`fF!Æ®K I”Á=@Û§²”\4#WF¨¼ç0À-,;¢ü&µa{ñô|ø/‚3\ÇB›Ýax¶H?ãߍ„o•?‰T%Ìõ +…FçÅR,SÙrÙ0W©0+W™¥bOiZŠ”?ôùáCÛs¦rT4ñ­*Š"m-»SŽB¨ œ?wOZVîGaòf pì`ÛEe¸íÒ‡Q´jyê>y j3fúÙ­Pa4·BCF­7%Å©P™{]êgAڒª +7´¯ƒ­âM{ïËa(îY†ߋ>K>’¯ÝkÆcmZ‹ü€ÙÞsnõª¬Yìxb[Ê È*„ÀÈr£±À\ôCQ¡™ã®×àVÀ)K_Rã8¢D“d"é»\Ë\¢,9)l]:âk• #㊨Ããò¶ÍÄêڅŠJƒóJ¸9’;YÁcb^¨Xì¾5ñ…Û ¹VEЍÐôæ]¢sW6JdÌÁAn¸w ٍ£]­ÒÔA®•ÕGÞóßžÌ6§¢¤/Õ~ù0ãÆÛ>y£^‹î7A&~ò]í\¢âT¢#k6†“Kà%ŸüIèÉÑ,f ³í„^&ݨñ£}7ô·‘NŸûÎêאø;–+ûʋÙ¿Á¬”,;£¡ÿÕ3â+U7÷pÙuXѸ6tfJiVlõj¤ñBå"¥í!‚ž°±Ö)Ÿ<ˆê™ ÈCK$<ûRü‹Ù^­¥^Q Ÿàé }·x>bƧU⻗«¾MsÀsÚqàà*"ðã¬tKŠÓ»¾ªB3 ‹;ȼΡý¼;™`YÈ[±~íØKM屆¾ ëa؋*„^¨ ûvZ¯“æh9y™1gGŒ‰`䚇ô¢S‚kd’øw§Ev¦<)^ÖZ:岦'iìn;ÚUð†u˜;{žÖ향27hùсan}îlMЇ¸i @: )@`^KÚBé\؉Z­¤9-‘`xê&X’à²u!ì°~~ KÑùÑ ¢ký05ÖØQP#GpªHL­îD^eKi†]KvØØ"·bžˆÞÑßË@;+œ¼J'æíòòŠ•.}LgïÕÀMP7\¯tšêº_¸‚ŒÙÆnÑí÷—oÿNÈ»€µéfèãŽ+~ˆ•¿aÖ,‰–}ßÜG­f'Ü=Ì۝â­­_º#Ð^ó‡z.÷|¹‡><§ºFÍmâö–mK»Eí¨? ‘ºNn?û ^¨Eídé@ƒ¿2-À±Î ̊·Ãµb7,1¬òpÌ:Ê۟S5k]!xÓßnۅd_Ñ=p}¨^¨lÏ÷KǾPÍ#<“ÜùÖRè¥,|ª$÷°çu†oK¼%¸úvâ€ÖKvõ-kMk-Rë6Àaž:Æ;´±¤–•{Ë_;0kÔBz’îûÝÇÝâÁLo÷@»¼¨º—F¶ƒv{eíÕ0m^æÔtFã0O£ÇžèŒþ:bÛEp9¾_Ýt7¹Çá#Mø÷2˜.‚+ºƒ€f×ty;o‚Ÿ >±ç…®ga/Å=s¸3sæƒoQ0h„_'Qۏ4žÏáj|q‡ãã‡!Î\óˆnƒi¿Xìùa‚PјoO¦ôN¢ÉôÆY¿œÍÃÉÍmD·³»« \Ðxzõn’»HóqM‚EÏè<œý;¹:ÌþÕxü^ÑÃ$ºÝG»,ÂxúHO¦W +&Îlðm ê‚ÉW¤àèdzyw…8t{ÓY_€—¢™C”Ú³/ +o¾TŸÚRÎ?Ñùç3¶L—÷óÅ®îAJË»|%R¾ó–¾ýxúžÏžó£Óó³ágrn¦÷ÛTo‚iŽïh~*tEç AtòÏÉÿ~õ‹endstream +endobj +303 0 obj +1894 +endobj +304 0 obj<>>>>>endobj +305 0 obj<>stream +xÚeTMoÛ0 ½çWð¸IZ'A’e™Ž‰É’KI ôRlíaØÖnØßé¸Aæ"‡¢ÞãããS~Í +¸“O»¬·ðùû¬L³ÛzEéY*Ûýҗ-²mŒO¦$G©ã+¨)yŒêÀ` 3œÈfgºÌ]ˆ¸„Ô  OÄLñ˜)ܤ¯³;XëåJ™õÎ}6ÖY[ã-B¨ +G%î"œ(5Ї¼„Ø„ìªëú„¸ãpD¨°F›èˆs…‰‚˜[P6ĤŒsàÑÊ$Ú#"ɒ?́±3ÄxBl³r¿ÔÊm½»¸µXm—½SlÇڛ“€<øxC {§Î1Þg1§‚Rfï:G֔Næ1'POŒRKA¡'¦$ªÄç&zŒïe˜®g:4 šà*äù@ … £ò°œNM€ÖôІŠêÁíÛwÉЉ©Ì ÿ3_v'«i)%ÑdÊ Ž–Z$‹HµW£P™Ö0Î'Ää­Ë•Ž ²葍›CìВþ:Uâq*ÝÅ Œ”`$EÂ0a9½%%GT4ù·œŠ.=»äáJŠL)KIR“Á¯'Ü.Ț„¼2ÉÀ0œ|—¨XF/F HºY›Ù¤¡·"DjÌ1òç݊5SÍ,šˆ«ó³‘ûê ¹Ìïr/Cñ^ ù¿ìuBCN†ñáf>ä ¨¶3¡=®ãÐÈJK”k¦:R¥ç¶Óg$óÐèfùÆ}Œÿø>þbÍÀ&‰Ã«–}V¤O&ž1ûSl÷°ZŠ›;ñíçóᅬ/O_Ÿ^^¡}üñçñ›bzu±[Ýé݃ÏwÆ(É¿N)HŽ-Jv²Ùm–{ë`šÝÏþÇ?C +endstream +endobj +306 0 obj +651 +endobj +307 0 obj<>>>>>endobj +308 0 obj<>stream +xÚ-‹» +Â0E÷|Åu¨6 Ä86!–B 5Á1h;ˆlßFäžépî“P”ó(ϜnD²Þ PŠ0€rMU"œP±óðáõIc8õã„}º¿Óu.¤Èiño™ÈªâlµÅO46´ÒÕîˆF[íjƒ.JÓªY+m½Îȁ|[Í$Àendstream +endobj +309 0 obj +134 +endobj +310 0 obj<>>>/Annots 93 0 R>>endobj +311 0 obj<>stream +xÚ͜KsÜ8€ïþ:ÎTm:"õ¢ŽÏ$5S›8;vj/s‘mÙîM«åU·ÍüúPÛ6)Wml%UI_š ‚ÎŽT’ÂO•T:ÉÊä¢;zwvôö}è49»JTQ'e•'g—?5ç›6鯒ã~»o·ûÝÏgÿ>úõì(]¥@À_þòÇl$eV¬LÒ%ð[΍MrŠðýá:yû¾H”ÂíJP…îóÐ^5-þ#Y¶Ê@¹Züõ¤W cÐ=­W%¸¥R+Å vËÛ÷9;†¡ÔH Ã§ßwû¶Kž„ +Næùªð©,gÚÉ};ܯÛoˆËÕª^Sc~Kkˆ£.19ô„ÜCô–JW6Dé/î:ͧý%ìÁ_ºx4’;žç/½ÒË𗻪¨Kø¤büFÉUE øÔï›ýºßBk²We\åÑXÎÛxl­.2E)ðì¦ x}‚€×sô±$²˜IñALÎ +C@òX>òz¨Ý:[Ka=¶„™s>„u::ß6DÊRf¦Ã™¢RÝö0,'P{q³í7ýõw»v)¨–”áˈ«ÒÌædèQÉ áª4§„ü{nS±ª—_LG:œ×©­waõq©Ãy­¨Ø=Þ4»-?ْ{ë,ÔY˜\KœÑԝ­ eÖ÷ë;lg¡¨-=À±COmýj p©!:\”ÒÞ5_Ûí厷2z©=Žu’ &¨ÒÀÊI ÑÙbZ ‚•ÙdŒ©N¢Xna¿ ë{”,]XžƒUÄ]YeS1ãÔîÊ ¥ºOíþ[?|…Ô¦s½Ì„WkÐ\©±¥??RƒæP…Ûé¯Ã5¨ƒÙRÑ£‘TÏ«AªùÚǰ˜9_vÁÚE˜Û´vð‘X̬}hÆøå¡¯X®ç–Ɓeînü~²‚–Õ±K‹¨êðìÉjc3«© P㱂6«kʱ§wçÝzv™`á®PÇ<2˙ËT» ø_ØÓñLîӜã®ú@V”æ+õáGs +µ_ts•¬^m8c£h +›èM +ó„SÌ Õ>7}ž„ÂÚ¦ÓÒG±ØÂše2ÄÑǬìcH^Še̖(õ‚Îcàg¦†pw¥iÉ9m#óD˜cªÂ#ZÆrí¿#K¾$`¦ÂšÏã9žÜŽX™^ÀP¥¯†Îɱü£†ðzQ¯Êy]ØÓù¸ñi,gÞÇ»Í~}»iCjBàî¦= S`âq»¦=ˆ6¯íö¨Ïmo\b± ásX–sJ-íÅש…au™Ôƒ±¸œ±¾ c\p9öP,/Åúœ4‚ÐáÕžä9žî›ý]h¹à¼eñy¬À¼«¡¥I{ ÕzëæxNšw‰†4Àj¯«Ç}×5ÛË7ÿXoí•[•þ¿c5}™¦âƇmˆèË2¾f˜} £‘03nFô1‰CC¢Xž­ôs¢Ïñ(4$Ï)0pfô9‡ÇcæÍŠ>G«ôÖ)Ìñœ4‡èÓxeâÃj¯«ÿjÏmŠ|‘«¹jÌTMEcSC¢¶Ÿï¸Ù^´›pNæ‡j»8´b¢ +,aˆë–¥¦Vbã/´pM¶X0¤‡c‚ýÞÛQù"‹#†[e]Óõ7–öôçG¶Êºæ;ð,¼Uv0»£õh$eJl«ì0°M} ‹Ýýþ²n3\÷¸Sñpç€WæmFÙ¨$-3‡… '‹F|•ñʑ "·œº¢ký +?>5ÛÞj÷ûÚm;4›@ñ8Ü‚‡%¹ÃIoeËz[ñ´ãla K¾äOñN„Z®‹ó%_ñG÷8ÒWL Å£9…jÎ"Ìq:âêáÃXa'úÝқ{&l^ç@&êë"syÅ-áë‚ +ÏvÓ^D|-ìé°öiNaF­(Œé äàƒ9‹úØ^® –4ǪGLJ±utýWû·PQ2™C=Ê`¬@Ծ߆`Ò`vŽz0§`a–(a ¨Ÿ]ù(V Nöw?dKÄQt4ä2÷f/ˆ©%B.OřC$æ&ÎoÜ;x8VpēmhzOÖX céç³HÁ±Þõû›P-<Ùc²ÀÊܧ‘‚£®/ƒç€A\^q«àpýU(†k1:-Ç&Rp¢JcŒ`Œ&Å +ãˆ6·|ÞöãPª<²8ÃpÚ;¶1UÕZWTq¼k¶ÛPý"¬i¹Ê}Ë«‡õK¾¬+€»hÎ*~RCY\‰'58g•{ž3{¡pÀ±Bá¾µ1 ˜rùÌäåùTä]œÒôš­0èJí¿‹ŸÐ«Ýÿê(aÙ%5¦OÃbýpŸ`–öX,Øiů +lÜ¥•¿º¦fæi?¶¤93c¯*Í;›³>šSpoöîºóðN!•ξkðy¬`flɅ5^Oáù·Ïbfß4Csïk{sAéì<õ™N™ŸC•泏 |XžN¨ß¶7ö¶Ÿyþ€ØÅ_ÛñšSôÕßsÌ >‡²±!Q,fڌÈs$‰ÄLšvfјañ˜cu©"1ƒð>k“9žŠâÊ,Y Iá0›Lñ8©:øL,fÒe?øû±h3JTLFy“ÑϪ—ÊF„Q‡Õ’ѳ‹%G²áà‘H̤yÑæ`6$<‰6i…™Ç‘X»·›»Ž—¿ú…ŽÉb£\Q«•Æ+ÕÊúY•šCّ(׳Ë4GÊñÊ#‘Ø=$m‚§“5-ëƒþ±˜Q›ázÍCS¼ü×:T¥¢¿rÀi” +ސÁ }]H;N†_•¼Ž.îìð~1öE~4JÏÅý¯)ð“Ìߺ`œL¦ä`åqHúÈã΅}Õ!AšRꏍW;h÷ʳ߭±ƒá¹>è\Hy8×sê‡É3º±wü‚Db&ÙA´‡/åkm{­‡§n¤ãªa¦ÿT£æ7 +Éñ—ϧÉiµÿÖ mòe‡5íÇf{×lèDïRÞTôhÍ.úçÑÿ 5è6endstream +endobj +312 0 obj +2841 +endobj +313 0 obj<>>>/Annots 117 0 R>>endobj +314 0 obj<>stream +xÚ͚ÝSÛ8Àßù+üØ>`,ɶäÇB¡Ç G9îc¦/np¨ÛÄáç:ýïO+­â•iäô®|”Th÷kw¥]­û÷‹ýÅ"‘ÃßÙòàxzptVD<‰¦óˆeE”Ë4šÞ¾š–U´šG'«¦«šnýzúùàtzÄ‰&À7ß®ßE’ÇI”‹,VÑ2b‰Ô?íhM?Ðh³4b >Pr-›kYý‰“Y¹¨›»hçQ¶þ$.âÂÿ$'€ÀîS€u ËXœ`(€°óeyW§ú ü*~–?LŽx‚ó8‡%13á’ÀÚzU9<ü›Ûϛu¶7!hžHcáóœ"Ãö&ê`ï ìíÁPa¿lB0¢®aJ€Û= + ìëiÝt^ˆ„¡‰Eː¨7ÆnÑ^ꝥ Ž< + «lv³¨¶féh˜Í «Ó,f¦LÄaRègÝÆ¡‘8dIœþX:žÊC‡Ü'Lñ0+à`“²Û´eW¯šPðpÂäL‚“<¦p̯NV‹UŠG +ÑH^ ‘(à¡x¤Úš•ò8°¬€cã‘hk–L¶žv,+àX}FGöj¯9ši x0'`xuhS]MJå𱜀!/ÊÙLÏÏkóQCçVJ)’Cëeꍳº±4ÑK'zy4pÀ‘j¨WcƒŽ³vµXuч\.ñiVÀтg+ÑÖ,­",+°ß2‰:dy>ô +l—‰‡+~þáõÿ‚(Ëm¡’d:ûÛ ¢LÚj`RQ¯Ad BiN@îSâup»>š@ØÛj^n¡8"ð½|ðt(€À«*HDª²Tÿôa(€°?êÛî“9Q@扜ð»Íh©0‰7ƒ¢ÏHFKS›t¯Ë¯»í@T—‘ tƒÓHZµ»AD×VyÎ#香׋®j«Ûp¡G)ì:éù~ÓÝo:“i“g½’íöÔG™. ‡)È`æß¸œ£³ ïÁ dNœ4P†lÕa/€i(ËÎÆahlõt10&…à´½Ž—ÿ¢­—¦†(œVÛ²¡ +„Q‡Sè 穯BǐG³Q䭒\ل’(ÃeAé¸óQ( ÈyfK¿'îp6rp$Âä¼\A~3ƒmºf !Iïç2‚4•®‡ÅyÄùE±x)Eñ^¦K‹Ä¤ ]'8èÏÜ´`{¦Z¢nÛd™ÃyčG9!ØfóyNóÐQNÕᆠEC„•¡ûu¯¬QzUƒu:g·ûjVÏëY€HP´=$¢1tMê† |²X $)m҅‚ÂH Ie“Úïuõ5HD}éVù,œV{ôBˆ2„P¡Sˆ‡ÂyDlÚ¶jBå!€ë¡Wåñœ½ó2ävÕn¯ñ¯å©¹øÛýiÄkyfoý{nd)X­ÇÂi¤½F”í {ðX8¨ñ"›l#\ù<'€@º½Š§«Œÿ‹çôZ—óì€x.ãûç9Gb ¬ØCἁ7ë®lfVÏûžàG%¤Iå +îEv@Œe7‹j¹ +—…D¢3ƒ“™Òpy¾Å ø,°Ôó)cö„3‰Ì ¾SЧŒc‡;”Ä·ÈlCN#'TÖ„“ {œ‚r&«y÷µl' !À*M <œGÞE=«šu¨/@¶ô`VÀì®­ª¥N5@4/æž-(¸ïQ(slJ°°|¯¬EaϓÕrêvŽ=m +ŸŠóH»¹<ÿ3dö^îAðŽÄƒ9‚ìánaØ×nb@D$N¾­»j~é&¶<Ρ3ìóPy£‘F¨“ê`ÉN^¤¥ù#؁2<¡2¼ôBµdG}#O(ûR¯éÚÕífW³'øË8&ÇÖ&fèÐÚY›ä6LÛò¶Z–í—õKZ[:²¶LáEN3;"kË +{9®›²ýnâË–íƃ9ä½­×][܌¼$اУð©(€Ôëúî“-ß²×¹§¡Ó ÓlO;"†NsLj›ûûUk{üE^1ÏFrˆàö‚oõí ¯¼„ö¨zwyHؽ*´bs +Ây‡:½<½~sêÃöHØ +¶/å9^Ý_œŸ„úø=Zïbø|Nyvz995‡2Â×y<ñ”.¤’­§Ì€xŠ'{ú )Œ‰!ÆÎ[ÐÅùñõ›ë¿B^”–K°*¥¡>×¨Ó œ=g,nÌåT_Ó2èz4pkí.«e#L{¦Ôdû¿ÑVj‡ +î¸ib>>:¹¹šDÛbùf]µëèײٔ à²\E‡Ò>]£!~;ø-kSendstream +endobj +315 0 obj +1868 +endobj +316 0 obj<>endobj +317 0 obj<>endobj +318 0 obj<>endobj +319 0 obj<>endobj +320 0 obj<>endobj +321 0 obj<>endobj +322 0 obj<>endobj +323 0 obj<>endobj +324 0 obj<>endobj +325 0 obj<>endobj +326 0 obj<>endobj +327 0 obj<>endobj +328 0 obj<>endobj +329 0 obj<>endobj +330 0 obj<>endobj +331 0 obj<>endobj +332 0 obj<>endobj +333 0 obj<>endobj +334 0 obj<>endobj +335 0 obj<>endobj +336 0 obj<>endobj +337 0 obj<>endobj +338 0 obj<>endobj +339 0 obj<>endobj +340 0 obj<>endobj +341 0 obj<>endobj +342 0 obj<>endobj +343 0 obj<>endobj +344 0 obj<>endobj +345 0 obj<>endobj +346 0 obj<>endobj +347 0 obj<>endobj +348 0 obj<>endobj +349 0 obj<>endobj +350 0 obj<>endobj +351 0 obj<>endobj +352 0 obj<>endobj +353 0 obj<>endobj +354 0 obj<>endobj +355 0 obj<>endobj +356 0 obj<>endobj +357 0 obj<>endobj +358 0 obj<>endobj +359 0 obj<>endobj +360 0 obj<>endobj +361 0 obj<>endobj +362 0 obj<>endobj +363 0 obj<>endobj +364 0 obj<>endobj +365 0 obj<>endobj +366 0 obj<>endobj +367 0 obj<>endobj +368 0 obj<>endobj +369 0 obj<>endobj +370 0 obj<>endobj +371 0 obj<>endobj +372 0 obj<>endobj +373 0 obj<>endobj +374 0 obj<>endobj +375 0 obj<>endobj +376 0 obj<>endobj +377 0 obj<>endobj +378 0 obj<>endobj +379 0 obj<>endobj +380 0 obj<>endobj +381 0 obj<>endobj +382 0 obj<>endobj +383 0 obj<>endobj +384 0 obj<>endobj +385 0 obj<>1<>2<>4<>]>>>>endobj +xref +0 386 +0000000000 65535 f +0000000015 00000 n +0000000220 00000 n +0000001786 00000 n +0000001860 00000 n +0000001939 00000 n +0000002025 00000 n +0000002103 00000 n +0000002180 00000 n +0000002259 00000 n +0000002342 00000 n +0000002419 00000 n +0000002501 00000 n +0000002586 00000 n +0000002645 00000 n +0000002697 00000 n +0000002782 00000 n +0000002834 00000 n +0000002918 00000 n +0000002949 00000 n +0000003053 00000 n +0000003157 00000 n +0000003261 00000 n +0000003365 00000 n +0000003469 00000 n +0000003521 00000 n +0000003626 00000 n +0000003730 00000 n +0000003761 00000 n +0000003812 00000 n +0000003897 00000 n +0000003921 00000 n +0000004026 00000 n +0000004130 00000 n +0000004161 00000 n +0000004217 00000 n +0000004302 00000 n +0000004352 00000 n +0000004437 00000 n +0000004468 00000 n +0000004521 00000 n +0000004606 00000 n +0000004662 00000 n +0000004747 00000 n +0000004806 00000 n +0000004890 00000 n +0000004928 00000 n +0000004980 00000 n +0000005065 00000 n +0000005089 00000 n +0000005193 00000 n +0000005298 00000 n +0000005403 00000 n +0000005508 00000 n +0000005613 00000 n +0000005718 00000 n +0000005822 00000 n +0000005927 00000 n +0000006032 00000 n +0000006137 00000 n +0000006242 00000 n +0000006347 00000 n +0000006452 00000 n +0000006557 00000 n +0000006662 00000 n +0000006766 00000 n +0000006871 00000 n +0000006976 00000 n +0000007081 00000 n +0000007186 00000 n +0000007291 00000 n +0000007396 00000 n +0000007501 00000 n +0000007605 00000 n +0000007710 00000 n +0000007815 00000 n +0000007920 00000 n +0000008025 00000 n +0000008130 00000 n +0000008235 00000 n +0000008340 00000 n +0000008445 00000 n +0000008550 00000 n +0000008655 00000 n +0000008760 00000 n +0000008865 00000 n +0000008970 00000 n +0000009075 00000 n +0000009180 00000 n +0000009285 00000 n +0000009390 00000 n +0000009494 00000 n +0000009597 00000 n +0000009700 00000 n +0000010025 00000 n +0000010130 00000 n +0000010235 00000 n +0000010340 00000 n +0000010444 00000 n +0000010549 00000 n +0000010654 00000 n +0000010760 00000 n +0000010865 00000 n +0000010970 00000 n +0000011075 00000 n +0000011180 00000 n +0000011285 00000 n +0000011390 00000 n +0000011495 00000 n +0000011600 00000 n +0000011705 00000 n +0000011810 00000 n +0000011916 00000 n +0000012022 00000 n +0000012128 00000 n +0000012234 00000 n +0000012339 00000 n +0000012444 00000 n +0000012640 00000 n +0000012674 00000 n +0000012708 00000 n +0000013674 00000 n +0000013723 00000 n +0000013772 00000 n +0000013821 00000 n +0000013870 00000 n +0000013919 00000 n +0000013968 00000 n +0000014017 00000 n +0000014066 00000 n +0000014115 00000 n +0000014164 00000 n +0000014213 00000 n +0000014262 00000 n +0000014311 00000 n +0000014360 00000 n +0000014409 00000 n +0000014458 00000 n +0000014507 00000 n +0000014556 00000 n +0000014605 00000 n +0000014654 00000 n +0000014703 00000 n +0000014752 00000 n +0000014801 00000 n +0000014850 00000 n +0000014899 00000 n +0000014948 00000 n +0000014997 00000 n +0000015046 00000 n +0000015095 00000 n +0000015144 00000 n +0000015193 00000 n +0000015242 00000 n +0000015291 00000 n +0000015340 00000 n +0000015389 00000 n +0000015438 00000 n +0000015487 00000 n +0000015536 00000 n +0000015585 00000 n +0000015634 00000 n +0000015683 00000 n +0000015732 00000 n +0000015781 00000 n +0000015830 00000 n +0000015879 00000 n +0000015928 00000 n +0000015977 00000 n +0000016026 00000 n +0000016075 00000 n +0000016124 00000 n +0000016173 00000 n +0000016222 00000 n +0000016271 00000 n +0000016320 00000 n +0000016369 00000 n +0000016418 00000 n +0000016467 00000 n +0000016516 00000 n +0000016565 00000 n +0000016614 00000 n +0000016663 00000 n +0000016712 00000 n +0000016761 00000 n +0000016810 00000 n +0000016859 00000 n +0000016908 00000 n +0000016957 00000 n +0000017006 00000 n +0000017411 00000 n +0000017565 00000 n +0000023915 00000 n +0000023937 00000 n +0000024032 00000 n +0000024134 00000 n +0000024154 00000 n +0000024301 00000 n +0000025205 00000 n +0000025226 00000 n +0000025420 00000 n +0000026543 00000 n +0000026565 00000 n +0000026707 00000 n +0000027133 00000 n +0000027154 00000 n +0000027268 00000 n +0000027453 00000 n +0000027474 00000 n +0000027616 00000 n +0000028523 00000 n +0000028544 00000 n +0000028686 00000 n +0000030203 00000 n +0000030225 00000 n +0000030367 00000 n +0000031354 00000 n +0000031375 00000 n +0000031489 00000 n +0000031675 00000 n +0000031696 00000 n +0000031847 00000 n +0000032558 00000 n +0000032579 00000 n +0000032762 00000 n +0000033871 00000 n +0000033893 00000 n +0000034067 00000 n +0000034806 00000 n +0000034827 00000 n +0000034941 00000 n +0000035145 00000 n +0000035166 00000 n +0000035317 00000 n +0000035868 00000 n +0000035889 00000 n +0000036050 00000 n +0000037158 00000 n +0000037180 00000 n +0000037341 00000 n +0000038208 00000 n +0000038229 00000 n +0000038380 00000 n +0000039033 00000 n +0000039054 00000 n +0000039233 00000 n +0000040262 00000 n +0000040283 00000 n +0000040452 00000 n +0000041608 00000 n +0000041630 00000 n +0000041799 00000 n +0000042812 00000 n +0000042833 00000 n +0000042974 00000 n +0000043301 00000 n +0000043322 00000 n +0000043487 00000 n +0000044307 00000 n +0000044328 00000 n +0000044488 00000 n +0000045394 00000 n +0000045415 00000 n +0000045562 00000 n +0000046404 00000 n +0000046425 00000 n +0000046591 00000 n +0000048039 00000 n +0000048061 00000 n +0000048217 00000 n +0000048599 00000 n +0000048620 00000 n +0000048762 00000 n +0000050271 00000 n +0000050293 00000 n +0000050426 00000 n +0000052315 00000 n +0000052337 00000 n +0000052460 00000 n +0000054268 00000 n +0000054290 00000 n +0000054423 00000 n +0000056365 00000 n +0000056387 00000 n +0000056520 00000 n +0000057252 00000 n +0000057273 00000 n +0000057415 00000 n +0000059117 00000 n +0000059139 00000 n +0000059281 00000 n +0000061230 00000 n +0000061252 00000 n +0000061384 00000 n +0000063130 00000 n +0000063152 00000 n +0000063284 00000 n +0000065054 00000 n +0000065076 00000 n +0000065208 00000 n +0000067041 00000 n +0000067063 00000 n +0000067195 00000 n +0000069160 00000 n +0000069182 00000 n +0000069324 00000 n +0000070046 00000 n +0000070067 00000 n +0000070181 00000 n +0000070386 00000 n +0000070407 00000 n +0000070563 00000 n +0000073475 00000 n +0000073497 00000 n +0000073654 00000 n +0000075593 00000 n +0000075615 00000 n +0000075670 00000 n +0000075775 00000 n +0000075919 00000 n +0000076022 00000 n +0000076140 00000 n +0000076261 00000 n +0000076375 00000 n +0000076479 00000 n +0000076644 00000 n +0000076752 00000 n +0000076867 00000 n +0000076972 00000 n +0000077080 00000 n +0000077188 00000 n +0000077297 00000 n +0000077413 00000 n +0000077511 00000 n +0000077677 00000 n +0000077794 00000 n +0000077913 00000 n +0000078037 00000 n +0000078162 00000 n +0000078312 00000 n +0000078453 00000 n +0000078562 00000 n +0000078727 00000 n +0000078866 00000 n +0000078977 00000 n +0000079120 00000 n +0000079243 00000 n +0000079394 00000 n +0000079499 00000 n +0000079652 00000 n +0000079766 00000 n +0000079894 00000 n +0000080008 00000 n +0000080131 00000 n +0000080247 00000 n +0000080396 00000 n +0000080525 00000 n +0000080662 00000 n +0000080792 00000 n +0000080917 00000 n +0000081020 00000 n +0000081170 00000 n +0000081279 00000 n +0000081397 00000 n +0000081536 00000 n +0000081670 00000 n +0000081822 00000 n +0000081927 00000 n +0000082056 00000 n +0000082173 00000 n +0000082285 00000 n +0000082461 00000 n +0000082564 00000 n +0000082703 00000 n +0000082832 00000 n +0000082960 00000 n +0000083078 00000 n +0000083184 00000 n +0000083338 00000 n +0000083507 00000 n +0000083607 00000 n +0000083718 00000 n +0000083845 00000 n +0000083940 00000 n +0000084067 00000 n +0000084189 00000 n +trailer +<]>> +startxref +84417 +%%EOF diff --git a/doc/sum.shtml b/doc/sum.shtml new file mode 100644 index 0000000000..627b66f9bd --- /dev/null +++ b/doc/sum.shtml @@ -0,0 +1,878 @@ + + + + + + + CUPS Software Users Manual + + + +

Preface

+ +

This software users manual describes how to use the Common UNIX Printing +SystemTM ("CUPSTM") Version 1.1.1. + + + + +

Document Overview

+ +

This software users manual is organized into the following sections:

+ + + +

Notation Conventions

+ +

Various font and syntax conventions are used in this guide. Examples and +their meanings and uses are explained below: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Example   Description
 
lpstat
+ lpstat(1)
   The names of commands; the first mention of a command or + function in a chapter is followed by a manual page section + number.
 
/var
+ /usr/share/cups/data/testprint.ps
   File and directory names.
 
Request ID is Printer-123   Screen output.
 
lp -d printer filename ENTER   Literal user input; special keys like ENTER are + in ALL CAPS.
 
12.3   Numbers in the text are written using the period (.) to indicate + the decimal point.
+ + +

Abbreviations

+ +The following abbreviations are used throughout this manual: + +
    +
    + +
    kb +
    Kilobytes, or 1024 bytes
      + +
    Mb +
    Megabytes, or 1048576 bytes
      + +
    Gb +
    Gigabytes, or 1073741824 bytes
      + +
    +
+ +

Other References

+ +
    +
    + +
    CUPS Software Administrators Manual + +
    An administration guide for the CUPS software.
      + +
    CUPS Software Programmers Manual + +
    A programmer guide for interfacing with and/or extending the CUPS + software.
      + +
    +
+ + + + + +

2 - Using the Printing System

+ +

This chapter shows you how to submit, query, and cancel print jobs to +different printers. + +

Submitting Files for Printing

+ +

CUPS provides both the System V (lp(1)) and Berkeley +(lpr(1)) printing commands. Type the following command to +print a file to the default (or only) printer on the system: + +

    +lp filename ENTER
    +
+ +

or: + +

    +lpr filename ENTER
    +
+ +

CUPS understands many different types of files directly, including +PostScript and image files. This allows you to print from inside your +applications or at the command-line, whichever is most convenient! + +

Choosing a Printer

+ +

Many systems will have more than one printer available to the user. These +printers can be attached to the local system via a parallel, serial, or USB +port, or available over the network. + +

Use the lpstat(1) command to see a list of available printers: + +

    +lpstat -p -d ENTER
    +
+ +

The -p option specifies that you want to see a list of +printers, and the -d option reports the current system +default printer or class. + +

Use the -d option with the lp command to +print to a specific printer: + +

    +lp -d printer filename ENTER
    +
+ +

or the -P option with the lpr command: + +

    +lpr -P printer filename ENTER
    +
+ +

Setting Printer Options

+ +

For many types of files, the default printer options may be sufficient for +your needs. However, there may be times when you need to change the options +for a particular file you are printing. + +

The lp and lpr commands allow you to pass +printer options using the -o option: + +

    +lp -o landscape -o scaling=75 -o media=A4 filename.jpg
    +lpr -o landscape -o scaling=75 -o media=A4 filename.jpg
    +
+ +

The available printer options vary depending on the printer. The standard +options are described in Chapter 3, "Standard +Printing Options". + +

Printing Multiple Copies

+ +

Both the lp and lpr commands have options for +printing more than one copy of a file: + +

    +lp -n num-copies filename ENTER
    +lpr -#num-copies filename ENTER
    +
+ +

Copies are normally not collated for you. Use the -o +Collate=True option to get collated copies : + +

    +lp -n num-copies -o Collate=True filename ENTER
    +lpr -#num-copies -o Collate=True filename ENTER
    +
+ + +

Checking the Printer Status from the Command-Line

+ +

The lpstat command can be used to check for jobs that you +have submitted for printing: + +

    +lpstat ENTER
    +Printer-1 johndoe 4427776
    +Printer-2 johndoe 15786
    +Printer-3 johndoe 372842
    +
+ +

The jobs are listed in the order they will be printed. Use the +-p option to see which files and printers are active: + +

    +lpstat -p ENTER
    +printer DeskJet now printing DeskJet-1.
    +
+ + +

Use the -o and -p options together to show +the jobs and the printers: + +

    +lpstat -o -p ENTER
    +Printer-1 johndoe 4427776
    +Printer-2 johndoe 15786
    +Printer-3 johndoe 372842
    +printer DeskJet now printing DeskJet-1.
    +
+ +

Checking the Printer Status from the Web

+ +

Since CUPS uses the Internet Printing Protocol, it is also a +fully-functional web server. To use your web browser to monitor the +printers on your system, open the URL: + +

+ +

From there you can view the status of classes, jobs, and printers +with the click of a button! + +

Canceling a Print Job

+ +

The cancel(1) and lprm(1) commands cancel +a print job: + +

    +cancel job-id ENTER
    +lprm job-id ENTER
    +
+ +

The job-id is the number that was reported to you by +the lp or lpstat commands. + + +

3 - Standard Printer Options

+ +

This chapter describes the standard printer options that are available +when printing with the lp and lpr commands. + +

General Options

+ +

The following options apply when printing all types of files. + +

Setting the Orientation

+ +

The -o landscape option will rotate the page 90 degrees +to print in landscape orientation: + +

    +lp -o landscape filename ENTER
    +lpr -o landscape filename ENTER
    +
+ + +

Selecting the Media Size, Type, and Source

+ +

The -o media=xyz option sets the media size, type, +and/or source: + +

    +lp -o media=Letter filename ENTER
    +lp -o media=Letter,MultiPurpose filename ENTER
    +lpr -o media=Letter,Transparency filename ENTER
    +lpr -o media=Letter,MultiPurpose,Transparency filename ENTER
    +
+ + +

The available media sizes, types, and sources depend on the printer, but +most support the following options (case is not significant): + +

    + +
  • Letter - US Letter (8.5x11 inches, or 216x279mm) + +
  • Legal - US Legal (8.5x14 inches, or 216x356mm) + +
  • A4 - ISO A4 (8.27x11.69 inches, or 210x297mm) + +
  • COM10 - US #10 Envelope (9.5x4.125 inches, or + 241x105mm) + +
  • DL - ISO DL Envelope (8.66x4.33 inches, or 220x110mm) + +
  • Transparency - Transparency media type or source + +
  • Upper - Upper paper tray + +
  • Lower - Lower paper tray + +
  • MultiPurpose - Multi-purpose paper tray + +
  • LargeCapacity - Large capacity paper tray + +
+ +

The actual options supported are defined in the printer's PPD file +in the PageSize, InputSlot, and +MediaType options. + +

Printing On Both Sides of the Paper

+ +

The -o sides=two-sided-short-edge and -o +sides=two-sided-long-edge options will enable duplexing on the +printer, if the printer supports it. The -o +sides=two-sided-short-edge option is suitable for landscape +pages, while the -o sides=two-sided-long-edge option is +suitable for portrait pages: + +

    +lp -o sides=two-sided-short-edge filename ENTER
    +lp -o sides=two-sided-long-edge filename ENTER
    +lpr -o sides=two-sided-long-edge filename ENTER
    +
+ +

The default is to print single-sided: + +

    +lp -o sides=one-sided filename ENTER
    +lpr -o sides=one-sided filename ENTER
    +
+ +

Banner Options

+ +

The following options apply when printing all types of files. + +

Selecting the Banner Page(s)

+ +

The -o jobsheets=start,end option sets the banner page(s) to +use for a job: + +

    +lp -o job-sheets=none filename ENTER
    +lp -o job-sheets=standard filename ENTER
    +lpr -o job-sheets=classified,classified filename ENTER
    +
+ +

If only one banner file is specified, it will be printed before the +files in the job. If a second banner file is specified, it is printed after +the files in the job. + +

The available banner pages depend on the local system configuration; CUPS +includes the following banner files: + +

    + +
  • none - Do not produce a banner page. + +
  • classified - A banner page with a "classified" + label at the top and bottom. + +
  • confidential - A banner page with a + "confidential" label at the top and bottom. + +
  • secret - A banner page with a "secret" label + at the top and bottom. + +
  • standard - A banner page with no label at the + top and bottom. + +
  • topsecret - A banner page with a "top secret" + label at the top and bottom. + +
  • unclassified - A banner page with an + "unclassified" label at the top and bottom. + +
+ +

Document Options

+ +

The following options apply when printing all types of files. + +

Selecting a Range of Pages

+ +

The -o page-ranges=pages option selects a range of +pages for printing: + +

    +lp -o page-ranges=1 filename ENTER
    +lp -o page-ranges=1-4 filename ENTER
    +lp -o page-ranges=1-4,7,9-12 filename ENTER
    +lpr -o page-ranges=1-4,7,9-12 filename ENTER
    +
+ +

As shown above, the pages value can be a single page, a +range of pages, or a collection of page numbers and ranges separated by +commas. The pages will always be printed in ascending order, regardless +of the order of the pages in the page-ranges option. + +

The default is to print all pages. + +

Selecting Even or Odd Pages

+ +

Use the -o page-set=set option to select the even or odd pages: + +

    +lp -o page-set=odd filename ENTER
    +lp -o page-set=even filename ENTER
    +lpr -o page-set=even filename ENTER
    +
+ +

The default is to print all pages. + +

N-Up Printing

+ +

The -o number-up=value option selects N-Up printing. +N-Up printing places multiple document pages on a single printed page. +CUPS supports 1-Up, 2-Up, and 4-Up formats: + +

    +lp -o number-up=1 filename ENTER
    +lp -o number-up=2 filename ENTER
    +lp -o number-up=4 filename ENTER
    +lpr -o number-up=4 filename ENTER
    +
+ +

The default format is 1-Up. + +

Setting the Brightness

+ +

You can control the overall brightness of the printed output using the +-o brightness=percent option: + +

    +lp -o brightness=120 filename ENTER
    +lpr -o brightness=120 filename ENTER
    +
+ +

Values greater than 100 will lighten the print, while values less than +100 will darken it. + +

Setting the Gamma Correction

+ +

You can control the overall gamma correction of the printed output +using the -o gamma=value option: + +

    +lp -o gamma=1700 filename ENTER
    +lpr -o gamma=1700 filename ENTER
    +
+ +

Values greater than 1000 will lighten the print, while values less +than 1000 will darken it. The default gamma is 1000. + +

Text Options

+ +

The following options apply when printing text files. + +

Setting the Number of Characters Per Inch

+ +

The -o cpi=value option sets the number of characters per inch: + +

    +lp -o cpi=10 filename ENTER
    +lp -o cpi=12 filename ENTER
    +lpr -o cpi=17 filename ENTER
    +
+ +

The default characters per inch is 10. + +

Setting the Number of Lines Per Inch

+ +

The -o lpi=value option sets the number of lines per inch: + +

    +lp -o lpi=6 filename ENTER
    +lpr -o lpi=8 filename ENTER
    +
+ +

The default lines per inch is 6. + +

Setting the Number of Columns

+ +

The -o columns=value option sets the number of text columns: + +

    +lp -o columns=2 filename ENTER
    +lpr -o columns=3 filename ENTER
    +
+ +

The default number of columns is 1. + +

Setting the Page Margins

+ +

Normally the page margins are set to the hard limits of the printer. +Use the -o page-left=value, -o +page-right=value, -o page-top=value, and -o +page-bottom=value options to adjust the page margins: + +

    +lp -o page-left=value filename ENTER
    +lp -o page-right=value filename ENTER
    +lp -o page-top=value filename ENTER
    +lp -o page-bottom=value filename ENTER
    +lpr -o page-bottom=value filename ENTER
    +
+ +

The value argument is the margin in points; each point is 1/72 inch +or 0.35mm. + +

Pretty Printing

+ +

The -o prettyprint option puts a header at the top of each page with the +page number, job title (usually the filename), and the date. Also, C and C++ +keywords are highlighted, and comment lines are italicized: + +

    +lp -o prettyprint filename ENTER
    +lpr -o prettyprint filename ENTER
    +
+ +

Image Options

+ +

The following options apply when printing image files. + +

Positioning the Image

+ +

The -o position=name option specifies the position of the +image on the page: + +

    + +
  • center - Center the image on the page (default) + +
  • top - Print the image centered at the top of the page + +
  • left - Print the image centered on the left of page + +
  • right - Print the image centered on the right of the page + +
  • top-left - Print the image at the top left corner of + the page + +
  • top-right - Print the image at the top right corner of + the page + +
  • bottom - Print the image centered at the bottom of + the page + +
  • bottom-left - Print the image at the bottom left + corner of the page + +
  • bottom-right - Print the image at the bottom right + corner of the page + +
+ +

Scaling the Image

+ +

The -o scaling=percent and -o ppi=value +options change the size of a printed image: + +

    +lp -o scaling=percent filename ENTER
    +lp -o ppi=value filename ENTER
    +lpr -o ppi=value filename ENTER
    +
+ +

The percent value is a number from 1 to 800 +specifying the size in relation to the page (not the image.) A +scaling of 100 percent will fill the page as completely as the image +aspect ratio allows. A scaling of 200 percent will print on up to 4 +pages. + +

The ppi value is a number from 1 to 1200 specifying the +resolution of the image in pixels per inch. An image that is 3000x2400 +pixels will print 10x8 inches at 300 pixels per inch, for example. If +the specified resolution makes the image larger than the page, multiple +pages will be printed to satisfy the request. + +

Adjusting the Hue (Tint) of an Image

+ +

The -o hue=value option will adjust the hue of the +printed image, much like the tint control on your television: + +

    +lp -o hue=value filename ENTER
    +lpr -o hue=value filename ENTER
    +
+ + +

The value argument is a number from -360 to 360 and represents the +color hue rotation. The following table summarizes the change you'll see with +different colors: + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Originalhue=-45hue=45
RedPurpleYellow-orange
GreenYellow-greenBlue-green
YellowOrangeGreen-yellow
BlueSky-bluePurple
MagentaIndigoCrimson
CyanBlue-greenLight-navy-blue
+ +

The default hue adjustment is 0. + +

Adjusting the Saturation (Color) of an Image

+ +

The -o saturation=percent option adjusts the saturation +of the colors in an image, much like the color knob on your television: + +

    +lp -o saturation=percent filename ENTER
    +lpr -o saturation=percent filename ENTER
    +
+ +

The percent argument specifies the color saturation +from 0 to 200. A color saturation of 0 produces a black-and-white +print, while a value of 200 will make the colors extremely intense. + +

The default saturation is 100. + + +

HP-GL/2 Options

+ +

The following options apply to HP-GL/2 files. + +

Printing in Black

+ +

The -o blackplot option specifies that all pens should +plot in black: + +

    +lp -o blackplot filename ENTER
    +lpr -o blackplot filename ENTER
    +
+ +

The default is to use the colors defined in the plot file or the +standard pen colors defined in the HP-GL/2 reference manual from +Hewlett Packard. + +

Fitting the Plot on the Page

+ +

The -o fitplot option specifies that the plot should be +scaled to fit on the page: + +

    +lp -o fitplot filename ENTER
    +lpr -o fitplot filename ENTER
    +
+ +

The default is to use the absolute distances specified in the plot +file. + +

+ + + +
+ NOTE: + +

This feature depends upon an accurate plot size (PS) + command in the HP-GL/2 file. If no plot size is given in the file + than the HP-GL/2 filter assumes the plot is ANSI E size. +

+ +

Setting the Default Pen Width

+ +

The -o penwidth=value option specifies the default pen +width for HP-GL/2 files: + +

    +lp -o penwidth=value filename ENTER
    +lpr -o penwidth=value filename ENTER
    +
+ +

The pen width value specifies the pen width in micrometers. +The default value of 1000 produces lines that are 1 millimeter in width. +Specifying a pen width of 0 produces lines that are exactly 1 pixel wide. + +

+ + + +
+ NOTE: + +

This option is ignored when the pen widths are set in the + plot file. +

+ +

Raw or Unfiltered Output

+ +

The -o raw option allows you to send files directly to +a printer without filtering. This is sometimes required when printing +from applications that provide their own "printer drivers" for your +printer: + +

    +lp -o raw filename ENTER
    +lpr -o raw filename ENTER
    +
+ +

The -l option can also be used with the +lpr command to send files directly to a printer: + +

    +lpr -l filename ENTER
    +
+ + +

4 - Saving Printer Options and Defaults

+ +

This chapter describes how to save printer options for your printer and +set your own default printer. + +

Printer Options

+ +

Each printer supports a large number of options, which you learned about +in Chapter 3, "Standard Printer Options". +Rather than specifying these options each time you print a file, CUPS allows +you to save them as "default" options for the printer. + +

The lpoptions(1) command saves the options for your printers. +Like the lp and lpr commands, it accepts printer +options using the -o argument: + +

    +lpoptions -o media=A4 -o sides=two-sided-long-edge ENTER
    +lpoptions -o media=Legal -o scaling=100 ENTER
    +
+ +

Once saved, any lp or lpr command will +use them when you print. + +

Setting Options for a Specific Printer

+ +

The previous example shows how to set the options for the default +printer. The -p printer option specifies the options are +for another printer: + +

    +lpoptions -p laserjet -o media=A4 -o sides=two-sided-long-edge ENTER
    +lpoptions -p deskjet -o media=Legal -o scaling=100 ENTER
    +
+ +

Viewing the Current Defaults

+ +

The lpoptions command can also be used to show the current +options by not specifying any new options on the command-line: + +

    +lpoptions ENTER
    +media=A4 sides=two-sided-long-edge
    +lpoptions -p deskjet ENTER
    +media=Legal scaling=100
    +
+ +

Setting the Default Printer

+ +

The administrator normally will set a system-wide default printer +that is normally used as the default printer by everyone. Use the +-d printer option to set your own default printer: + +

    +lpoptions -d deskjet ENTER
    +
+ +

The printer can be local (deskjet) or remote +(deskjet@server). + +

Printer Instances

+ +

Besides setting options for each print queue, CUPS supports +printer instances which allow you to define several different +sets of options for each printer. You specify a printer instance using +the slash (/) character: + +

    +lpoptions -p laserjet/duplex -o sides=two-sided-long-edge ENTER
    +lpoptions -p laserjet/legal -o media=Legal ENTER
    +
+ +

The lp and lpr commands also understand +this notation: + +

    +lp -d laserjet/duplex filename ENTER
    +lpr -P laserjet/legal filename ENTER
    +
+ +

Removing Instances

+ +

Use the -x printer/instance option to remove a printer +instance that you no longer need: + +

    +lpoptions -x laserjet ENTER
    +lpoptions -x laserjet/duplex ENTER
    +lpoptions -x laserjet/legal ENTER
    +
+ +

The -x option only removes the default options for that +printer and instance; the original print queue will remain until deleted +with the lpadmin(8) command by the administrator. + + +

A - Software License +Agreement

+ + + + + diff --git a/doc/svd.html b/doc/svd.html new file mode 100644 index 0000000000..60b724f65d --- /dev/null +++ b/doc/svd.html @@ -0,0 +1,297 @@ + + + + CUPS Software Version Description + + + + + + + +

+

CUPS Software Version Description


+CUPS-SVD-1.1
+Easy Software Products
+Copyright 1997-2000, All Rights Reserved
+
+
+

Table of Contents

+
+
1 Scope + +2 References + +3 Additions + +4 Changes + +A Glossary + +
+

1 Scope

+

1.1 Identification

+ This software version description document provides release +information for the Common UNIX Printing System ("CUPS") Version 1.1. +

1.2 System Overview

+

CUPS provides a portable printing layer for UNIX®-based operating +systems. It has been developed by Easy +Software Products to promote a standard printing solution for all +UNIX vendors and users. CUPS provides the System V and Berkeley +command-line interfaces.

+

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based printing +options to support real-world printing under UNIX.

+

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters.

+

1.3 Document Overview

+

This software version description document is organized into the +following sections:

+ +

2 References

+

2.1 CUPS Documentation

+

The following CUPS documentation is referenced by this document:

+
    +
  • CUPS-CMP-1.1: CUPS Configuration Management Plan
  • +
  • CUPS-IDD-1.1: CUPS System Interface Design Description
  • +
  • CUPS-IPP-1.1: CUPS Implmentation of IPP
  • +
  • CUPS-SAM-1.1.x: CUPS Software Administrators Manual
  • +
  • CUPS-SDD-1.1: CUPS Software Design Description
  • +
  • CUPS-SPM-1.1.x: CUPS Software Programming Manual
  • +
  • CUPS-SSR-1.1: CUPS Software Security Report
  • +
  • CUPS-STP-1.1: CUPS Software Test Plan
  • +
  • CUPS-SUM-1.1.x: CUPS Software Users Manual
  • +
  • CUPS-SVD-1.1: CUPS Software Version Description
  • +
+

2.2 Other Documents

+

The following non-CUPS documents are referenced by this document:

+ +

3 Additions

+

CUPS 1.1 includes many new features from the 1.0.x releases.

+

3.1 Filters

+

3.1.1 imagetoraster, imagetops +

+

The image file filters have been upgraded to support conversion of +Microsoft Bitmap ("BMP") and Alias PIX files.

+

3.1.2 pdftops

+

A new pdftops filter has been developed that is based on the +excellent Xpdf 0.90 software from Derek B. Noonburg. The new filter is +faster, smaller, and considerably more reliable than the +Ghostscript-based filter in CUPS 1.0.

+

3.1.3 pstoraster

+

The pstoraster filter has been integrated with GNU +GhostScript 5.50. The new RIP supports most Level 3 PostScript language +features.

+

3.1.4 rastertoepson

+

The new rastertoepson filter supports EPSON printers +using the ESC/P or ESC/P2 command sets. PPDs are supplied for 9-pin, +24-pin, Stylus Color, and Stylus Photo printers.

+

3.2 User-Defined Printers and Options

+

The new lpoptions command allows users to configure +default document options and create additional "instances" of existing +printers, each with unique options.

+

The lp, lpr, and lpstat + commands have been upgraded to use this option and printer instance +information automatically.

+

3.3 Daemons

+

CUPS 1.1 includes two new daemons that provide enhanced network +printing support.

+

3.3.1 cups-lpd

+

The cups-lpd daemon provides support for clients using +the Line Printer Daemon protocol.

+

3.3.2 cups-polld

+

The cups-polld daemon provides remote polling services +for the scheduler.

+

3.4 Commands

+

CUPS 1.1 includes several new printing commands.

+

3.4.1 lpoptions

+

The lpoptions command provides user-defined printers +and options.

+

3.4.2 lpmove

+

The lpmove command moves a print job to a new +destination.

+

3.4.3 lpinfo

+

The lpinfo command lists the available PPD files or +devices.

+

3.5 IPP Implementation

+

CUPS 1.1 adds support for the set-job-attributes + extension operation as well as two new CUPS-specific extension +operations to determine which devices and printer drivers are available +on the system.

+

Further information on the CUPS implementation of IPP can be found +in CUPS-IPP-1.1.

+

4 Changes

+

CUPS 1.1 includes many changes from the 1.0.x releases.

+

4.1 Directory Structure

+

The directory structure in CUPS 1.1 has been modified to conform to +the Filesystem Hierarchy Standard, 2.0. The following table describes +the new file locations. +

+ + + + + + + + + + + + + + + + +
Table 1: Directory structure +changes from CUPS 1.0.x to 1.1.x.
DescriptionCUPS 1.0.xCUPS 1.1.x
Backends/var/cups/backend/usr/lib/cups/backend
CGI programs/var/cups/cgi-bin +/usr/lib/cups/cgi-bin
Configuration files/var/cups/conf/etc/cups
Documentation/usr/share/cups/doc +/usr/share/doc/cups
Filter programs/var/cups/filter +/usr/lib/cups/filter
Interface scripts/var/cups/interfaces +/etc/cups/interfaces
Locale data/usr/lib/locale/usr/share/locale
Log files/var/cups/logs/var/log/cups
PPD files/var/cups/ppd/etc/cups/ppd
Request files/var/cups/requests/var/spool/cups
+
+

+

4.2 IPP Implementation

+

CUPS 1.1 is based on version 1.1 of the Internet Printing Protocol.

+

The new scheduler supports the create-job and +send-document operations. In addition, the job-sheets +, job-sheets-default, and job-sheets-supported + attributes are now supported for banner pages.

+

The CUPS-get-printers and CUPS-get-classes + operations have been upgraded to support limited filtering based upon +the printer-type, printer-location, +printer-info, and printer-make-and-model + attributes.

+

The CUPS-add-printer operation now supports the +ppd-name attribute to specify a locally-available PPD file +rather than sending the PPD file from the client with the request.

+

Further information on the CUPS implementation of IPP can be found +in CUPS-IPP-1.1.

+

A Glossary

+

A.1 Terms

+
+
C
+
A computer language.
+
parallel
+
Sending or receiving data more than 1 bit at a time.
+
pipe
+
A one-way communications channel between two programs.
+
serial
+
Sending or receiving data 1 bit at a time.
+
socket
+
A two-way network communications channel.
+
+

A.2 Acronyms

+
+
ASCII
+
American Standard Code for Information Interchange
+
CUPS
+
Common UNIX Printing System
+
ESC/P
+
EPSON Standard Code for Printers
+
FTP
+
File Transfer Protocol
+
HP-GL
+
Hewlett-Packard Graphics Language
+
HP-PCL
+
Hewlett-Packard Page Control Language
+
HP-PJL
+
Hewlett-Packard Printer Job Language
+
IETF
+
Internet Engineering Task Force
+
IPP
+
Internet Printing Protocol
+
ISO
+
International Standards Organization
+
LPD
+
Line Printer Daemon
+
MIME
+
Multimedia Internet Mail Exchange
+
PPD
+
PostScript Printer Description
+
SMB
+
Server Message Block
+
TFTP
+
Trivial File Transfer Protocol
+
+ + diff --git a/doc/svd.pdf b/doc/svd.pdf new file mode 100644 index 0000000000..19bccc4c3c --- /dev/null +++ b/doc/svd.pdf @@ -0,0 +1,546 @@ +%PDF-1.2 +%âãÏÓ +1 0 obj<>endobj +2 0 obj<>endobj +3 0 obj<>endobj +4 0 obj<>endobj +5 0 obj<>endobj +6 0 obj<>endobj +7 0 obj<>endobj +8 0 obj<>endobj +9 0 obj<>endobj +10 0 obj<>endobj +11 0 obj<>endobj +12 0 obj<>endobj +13 0 obj<>endobj +14 0 obj<>endobj +15 0 obj<>endobj +16 0 obj<>endobj +17 0 obj<>endobj +18 0 obj<>endobj +19 0 obj<>endobj +20 0 obj[12 0 R +14 0 R +15 0 R +16 0 R +17 0 R +18 0 R +19 0 R +]endobj +21 0 obj<>endobj +22 0 obj<>endobj +23 0 obj<>endobj +24 0 obj<>endobj +25 0 obj<>endobj +26 0 obj<>endobj +27 0 obj<>endobj +28 0 obj<>endobj +29 0 obj<>endobj +30 0 obj<>endobj +31 0 obj<>endobj +32 0 obj<>endobj +33 0 obj<>endobj +34 0 obj<>endobj +35 0 obj<>endobj +36 0 obj<>endobj +37 0 obj<>endobj +38 0 obj<>endobj +39 0 obj<>endobj +40 0 obj<>endobj +41 0 obj<>endobj +42 0 obj<>endobj +43 0 obj[22 0 R +24 0 R +26 0 R +28 0 R +30 0 R +32 0 R +34 0 R +36 0 R +38 0 R +40 0 R +42 0 R +]endobj +44 0 obj<>endobj +45 0 obj<>endobj +46 0 obj<>endobj +47 0 obj<>endobj +48 0 obj<>endobj +49 0 obj<>endobj +50 0 obj<>endobj +51 0 obj<>endobj +52 0 obj<>endobj +53 0 obj<>endobj +54 0 obj<>endobj +55 0 obj<>endobj +56 0 obj<>endobj +57 0 obj<>endobj +58 0 obj<>endobj +59 0 obj<>endobj +60 0 obj<>endobj +61 0 obj<>endobj +62 0 obj<>endobj +63 0 obj<>endobj +64 0 obj<>endobj +65 0 obj<>endobj +66 0 obj<>endobj +67 0 obj<>endobj +68 0 obj<>endobj +69 0 obj<>endobj +70 0 obj<>endobj +71 0 obj<>endobj +72 0 obj[44 0 R +45 0 R +46 0 R +47 0 R +48 0 R +49 0 R +50 0 R +51 0 R +52 0 R +53 0 R +54 0 R +55 0 R +56 0 R +57 0 R +58 0 R +59 0 R +60 0 R +61 0 R +62 0 R +63 0 R +64 0 R +65 0 R +66 0 R +67 0 R +68 0 R +69 0 R +70 0 R +71 0 R +]endobj +73 0 obj<>endobj +74 0 obj<>endobj +75 0 obj<>endobj +76 0 obj<>endobj +77 0 obj<>endobj +78 0 obj<>endobj +79 0 obj<>endobj +80 0 obj<>endobj +81 0 obj<>endobj +82 0 obj<>endobj +83 0 obj<>endobj +84 0 obj<>endobj +85 0 obj<>endobj +86 0 obj<>endobj +87 0 obj<>endobj +88 0 obj<>endobj +89 0 obj<>endobj +90 0 obj<>endobj +91 0 obj<>endobj +92 0 obj<>endobj +93 0 obj<>endobj +94 0 obj<>endobj +95 0 obj<>endobj +96 0 obj<>endobj +97 0 obj<>endobj +98 0 obj<>endobj +99 0 obj<>endobj +100 0 obj<>endobj +101 0 obj<>endobj +102 0 obj<>endobj +103 0 obj<>endobj +104 0 obj<>endobj +105 0 obj<>endobj +106 0 obj<>>>>>endobj +107 0 obj<>stream +xÚìÏsë8rÇIŠºÌ‰öŒî´üt§çyšÝ­ÚJñÙfvçÖ$ÁÊ!•S*Ç6•üÿ±~X"H€èn$è5¦jêÙE|ˆÆ·@ƒúÇOßòýÛßò?=å¿ýžÿçÿô,~*ÅOÿÈÛÿù×?þøÛï¿ÿºÏÿü—_Ÿò§§§·kýñõ¥ù÷¯|­ÿöœþº?•ßNå÷SùË©¼œÊ¿žÊ¿üÇ×?òÿýŸÿû¯¯ÿ–ÿíÛ׿ç‡oß¾>ÃKþ=ÿãõ§öcøä²+âõi»Ý>ÜËÛ?¶ß_—Î%^¶wY¤*w÷¯ËäOj¤Üöû¸ē‰é½Ü?–KáÂC]о/ëå!"—x[ÎõœE¼r˜ë‰KåÒ!˜¾rÛg޹^òȾü\ÆÕÊÏ3s=GžJRÎÉõ-òVâÃl\ŽuЄõV¾ÌÂ%²( + ‚B¹ü29×$X,0X –€Åƒ %ƒ/° ¬(ÚMÄåÝoÙ9h6×ÄXo`å\ûhò’LÀõ#𡬼sÕÑ,åÏ\M6A!|…gi,A +Ú Ñ ê£s5Ѭåà‹+›— 9Ä`™ãÅ`ž‹,öD.1?V{àÊàŠRç\uD98æY\‰c®}HÙ8媣`Jé++D91WT蚐°ŒÒË TÔ  LÔ‹Š4ðZåªBÃ2t,OãQ ÔxŒsÆq‰±FãzX¢Æ#F,Ï%£FL×]w÷Ûí—×cy>|ðÛa0IwÅ÷_†ƒüxÂ[‡ÿîŠG’þÅ˃ŸßÝuoœ*=[ í,¸ö~ºªÛk[ça=xì.Bú±àæØ\ìPƒ–.Î$[q¹¸¡==·aMJ&³»XéԜ.K™\¬@ž› É貘ÇUùÑv‡]¶cqeSÙà՛eN¤ܯjؤ½s’  ®|²¡ÅϼJé\Í Xd°˜ÎEùØÍÉÜZ9ƹfÂ"‚­¨\Õ FÈ1ŒȕυEÛи'’ –Y¹0p7ñú¥uZj+Cg‘¼c,Òé« …«rÎX•½ÅÍÁ‘jÄ¥{.B J<—°ÒlKÃ7D=Ì:¸ÎåÛÁÉ %i=•œkˆàBf½ .Ú`Ø`¹Š¹2O”,Á W­Ç’ó ìÍПR4q‡ãÚa…„–¤8®´&1Š«žÙ#3ì€á«aÚz/8 [c¸²0Dƒ¢õ ‚«æfóuXiæ*B J‡íÌ\Y OjOjäªÃê.d‡%F®"°îBú°ÒĕÖ]È'½1p5Á¸dZ“RW\wá¢ÄÄÀ•6ºÐRVŽr‰» 7æw£\u€Ý…[FJG¹*OŠ…²¢d”+ (2$*ÇVå'ÆB ÃRåÓ©¹Z’ Wå“s! q5ÂÀÚÛ=W¢È£­ÔrAˆ"v@;-W¨jàLi­ã¡ªnè¯t\5-4”=Ùí§ž±¿ÿ.Ï´’T¹Æúù=¾aÀ +¢6(®–KH·Kh%ºÖRÕÓbQ®•–ër›®Îa‡Àà ¯Çé¹ £^ >ÜÌіœáµCrí´\MçùÖ 1£$UsÑys¥Z®³í%·NH)}¢æÊ‰Îkœ+ÑsÝ´BPf=ègŒàp‡åz7.×MÛk¼b”¾Tq5ÔÊÀµÑrÝD° ¬•T؇ô¹WŠçZ鹊÷G”Q&ß V<זByW¤çª/ŸÕPÌ1PRWF4C#×NËu¾×úü+ü’QØV +.A5C#WªçڟòáªÕr[¬àª©fhäŠõ\盽§5Rì•K,×êZ[Éu6Ž;êÊ12BªWNZ,×:{—'%WG¤(³ÔgO@• ž«x j®Š5K5†ˆëWC6Ãq®ZÂp ÖbI…Ó5 ÊFÒâ¹Ä»Y¨¹®&EZ,ip-â\9%pžê¹*֚Nè(; +\n£á¬5;c+\ŒôÅq®æ" +®K‰kvª‰@“¤¥pµ¥×qgéB™ÐdcMãº(½Ž«àôWòD@“ë¢ô:®Œ3¾êÙwCÅuQz WÍÛÃÈ0’ ¤h#!r]”^ÃUðûMÏ%s Æð2r•^Õñ6g +ÌÃ’lì¨\g¥Ws5Ì]Œ +㘁´¶ÑR¹ÎJ¯æ½ØER2WÁ^f®“Ò«¹rfæŽÀ8f DQ)ëd݅~^¹e¢IàkSYŽ­\§Öç*®³Ý Fȑ#š ”(ªT?º²k ±ÌukDŸ+?krN7Ä="àVÌµë>š>h¸Þ;а›‚]†Yw¹k6+IlºŠšô¸ Wuáiè†X!dr¸Ñ˜ÄjøCýsȵèÝJ´§•¸rŽlH[âã‹:\…’K\[°'¢@Ø¢C­I¤€]Ÿ«VrU×Ê=öEèà£ÃDïû¯´ùÖṌŸêsí¯#èùVž«áxåÛ-â;^WÈ\OÌɱonn0¾d=äª\ÝT”‚lˆ{ó€¼0ÚT¹WWojò$ ð\{–l lbÕ¹.¶*qeÝKž„‰×ñÒáÊY²Ñ˜×Ó{Šyq—KΈÚ{ÈhzªX¯üPy8Å:F—« »òúh9ÔNþnï5ùÒ*¹Ä€+“,¯ñª è¨Wo'ÍéŧñýGH©\SßËy°†ÇeŽæãvQ°2Ÿ,’+çEQÁse¼(*t.a#‡s5–r*W͍çª>š^¸ +vt6מ͕4™¿peM/\œ¥ùp‰'óg®úÃÉ<–k2ߝÎ-‡͋ó·•Ü:\[æ»uîªßFwÒ²ßmµwpœOm›.Ò,²Î-ï\·u›þà,•\×FÍÕI¿\¹r¶ûRãkT§×ćk¥äjÔûËÛ}©4fÜkbÄኔ\¹z߁¿h£¶W]nj¯‰;×NÁU UPn9Ár­4áËNŕr¸RW6|ŒŽ¹Î«Ëë51áp%C®wшﲫÝÊ-§h®š+Vqõó¡¸g¯r~ô'/ÙÅlp\ëQ®Ó¿^òHjÁZv,¥Šk£tEr<Џ¨ëdÞ7ÛnlÌ\—᯻?"éx@·‰+×à¢Zr—Ûj{‡àꤥÈ]|Ëíé71âp .’7.y<€ +£®[‘"K~­lâŽÃÕ¿(—óM +-áðì8—Ðpz®”ÃÕ¿¨7RNf™*Œj1\·Ùÿj®˜ÃÕ»¨ðTà¹b\Šã|f.ÅEußÁnßÊ#`ÂÃĞk¨Šã|f.ÝÀT5_ŽÜp ×^­óŠã|®áE…ÒÁ&ŒJ[=Ì®9·r‡Çù\Ër¥#Bq­Q\µÚ՚8JqœÁ5¼HËU;â*”ñÆË- é5qxœÁ5¼(S:"×Ã%¢"ÎSÇù0\ƒ‹´\?Œê´áò;ô¼RqœÃ5¸¨[ývGסµœm”MçÃp .Òr?ŒjÕ£YU4ñ"Ú4®þE\-š+Uý6.5MìçCqõ/Òr¹ê^,ÕMìçCqõ/Òríùáa«68Íòþ ‰ýã|(®þEY/Mõʕ;ãŠK W'T•šØ;·ãê]ÄçJ\ñ®óۋ_¾,{lÔMìçÃqõ.Ê;Š-qen¸:ù‡Ýxã¼ì‘ª›Ø;·ãê]4ˆ£*,WÚâæ)­Š«ó~(EO¢Må’/Ú÷#¢âÂùåªÇ¸äã|H.ÅÀn÷X®µW£‹ç¯AeNä’/ªúC%;s Ï\BsŠCqœÉ%_T÷$[DX®W;Ê.é"Ñ Í« ¸—|Q&°üÂeÎ=Üy䒎óa¹ä‹ +E2þW=/WÁá’.ªn»Ê·EÞÙ¹j—t‘è¶²¾Æ6ÓJ\‚Ã%_”ßö¿ž#W铫{œÍ%_T ö+Càª8\òE½H0?qÙL—Q\Ù8WÃá’/’gÆé>®Îq>ès¥”ºór=ŸÞa?bšK©;3×Cÿøšü²¡ÎæuÕ»ꝪHqPJÛ:k®|¾!çéw·§†u\y1Ô׏áŒF~™WsÛìø9QeäÚÉÔ—Pì(É/4¬®KüuòÈȵ™‚ TSë¼;Àz齺 ®u+ M?\™j« ºã “Òdúu\©l)^¸š÷§»nÝî«ko»õʺ ®Dºµ®êºQ(¾unڑÀ[v…².Ÿ«öÉUtv¬÷7ïÒqY·äsM]Õ2¿ú®òöNå“+ª›v^Ȭ©K㊯ۧoƒ8ñƕu—áòžÒߌ§©KãJ®£0qÙÄóҟá¦×VËIÚªº$®Õõq¼=™t®êöÓ5ä$mU]WÚ}tk;.CúáõÏÍÝ[ÙtĪ윑Ò×%qÏ]ÓÆ+W¢ûѧ“T<¶ÔçÊ/ƒô8„wÞ¸2]:ÎeO¹éÀd#©;x®ýåóŽŸ|ðÆuŽš¸1‘†‘¶.‰«¸ÈÐÑÒKo\—½Îûƒ:À:eR¼Ë¹¶.‰ nÙ¯qëë¢Z{þ⇬ã‹õu•\ÃÄÎEu¯G÷叫“Òkmñîm®¾X_—ÂU_ `ü`;®±}½n=é½ÄÕ0‹V[—ÂÕ\~<ºeK®±}ØByŽCš—ƺ.]_ˆ¾ç²Ú_ÚÌÒ|Õ¢¯Kàj/Žùô[\½,Ú¸ôdЍKá:;æ“[öÉÕyіL¡ú’9]] +×Ù1×'ï“ëý ì —J•l:ZÇuvÌõ©¾—1ïë9Sš\ùPÔuñ~ùäËãÿc—‹|¶—‡á¤¦ÒLrTu \ÕÉOnÙ?×­µ«^(u@Õ%póÉ-OÁõ. +‰vЌÕ%póÉ-[raß-Z‹ÁX]—x÷b멸n‰×f®^]×Ù1ŸEr”Ë&ûø*™ìе\cu)\o&˜4·õS/\²{ãb§®.…ëM2âúì-¹JÜú¡k¬.…ëØÓUt}Q7®D²­x”KW—Âçð±‰ËæÜM.ý9Õù±º®ê|²&±çڍO¿6ÝyÈJË5V—ÂUߜº7®ªÛŸûÞmz«Kájn³Q.›sˆçkãï·M­–k¬®!ž—Þ¶%ä]A ®qö¶ ©Ÿ,ŽÕ¥puÞ ë«™«õ¹F꒸r—Õ¹ìf¤jŸk¤.ƒ«´çZãÒmú¡ÿ VÑ×%qƒßxàjô +3àj¸ëQ2\ŸÊ(—Õû7䵘_ÚQ.}]—îý¬n¹:}l \Úº$®úêÓǹ¬²Þè!Ón”ØÔµ*–ïí¹Ê×ëMóU|–ïY +¶X¾ë“kz.ó떗ÉUüÓr•‹ä2/pÉe3aþ䚞Ëjb¹h®õ"¹Ä?-WºH.ólõA¹’ere0ðµü>ŽO®¸ö0ðÅ}Ïn‘\ðA¹ª Z~¯Ù\Åô²×å÷ÐÍULMÞá¾70¸@ªrÃ\ e’ºÒò{9ç*Š+[\Àa +%°ß{ZÀ‘›ì ù=Å¡­´e&=@~¯thG„â‚¥Âèo‘ßoXÀQã¸÷}ô•±mç˜Á8lc®Á9æ½Qæ#/Á9°Üè–ã‚s`™±Åš3‡}€²×ÀXcV@éK`3Ëڬހò9°ÊÜX@=€ÀXa6.@l`3°½9êT˜ËÍ"8á Kèmœ£ Jè„m®gƒú¡€S˜ „A:àª%ô¢©€ìڐ„>G˜ ‡bH}fv_ï\bAB/0Ò -Vè׋‘Ã]‡+_Ž V˜Ȑ+ A,0 +-V裥ÈaÜ媗#ˆ(Â-ôDˆ *âƒ-ôéBäpÝåB} Â(»‚-ôÇ¥€VÏP„#C̾:\ÕB")£œ· Å }ºÙHd.„Ð'‹TæB,Ýċu+_†pd8üƒ"âȇxà B8j¤—Â!Gl#´A `1Û¨«>BðÌØå +h)‚¸xí\Åú,(ÖCéÑg­¡% ÇÜ ýŽhIÂ1ó3?ú•‚+~€áï€d¼s°=z @KŽy>r’s˜y€Õø©bå™a÷H*:sˆH؇–(30Ê&ÐúyÖ9eˆιÈQDs‘ƒ²Ôā9£Ò7”AОQéI+Ò@½t>¥Ï)Mª’ζÚ&HšÔ¡9›!"li¥åڇkˆ´åhél¨vc! »ô™ ±¢g83âžö¼nų¢ †®@žâÌcˆñqCË`3Ĉ9qx@Ë`iˆf(Í4€ó`¦Ÿ¬Tԇ -g€M>kΩj-k€MœdY“½´¬6± +ÈcX]>±rz‹€5D'VFÔ +œéöÔ1GNÀY™8樼A:©ÔgB©œÇ Üϙ.H,8ޏÃtºc wàÊêd†kÍÁ…Tú‰:,c=càÔ4Æ €?R§é°ŒÖÛNÓaә_‚& :C¢Åqí±`»0ºk…äªé0‘qƒph­ ±÷UKó„ªY.´v†èuâ,øV­!zÕzìÓÝ ¹ð†èQ:j ›ÖÖãrfWŠØ ¬OKüñÍPË%¢¹-±±’.h­ ѓ&æV>¬­'BõÊXZ?Þ¹±´°öõ^†˜È,e \<1÷3–½í#×½{&ܸ¥rU¤s©ÍJÉ\"š LdöܹK0‘;¸)82‡i\o\´;¼•Ÿ'–‘P¬.t¬Â^¿¹1p1_uFÃÒÇàd}¡ãNSbé¥ +\EiW°/)áøf08Ô&[õ cœFwžÿf<[l2êR6W›qÀúßtŽ*OôÛø\‹+Š¿S;‹añcq€‰‹ÙaQt_zî¬ñ¹‘‘«ˆ¸ÿ¥ó/9k·6\"â—{”56¼OßYqYtØqœ=šÌñ…Ie˜>˜¹l:ìŒöªÿ짌ý¹K.ê4Li¯ƒ~/ÛÌæqµ¶\Mä¦ÜÝo·Û/¯oåe»}È,?mcÍå¢ÃœSþ#†KȵqÀe'‰³tŽ+¼Û9á +®ÃÌK_8.±´îBrvm¦(ˆ=$W›…ÄupÇU/«»Ð\¬•O_ºäj‚áÚ´.¹‚ÑzÜöžKdKÑxw gÑ q!Øý^ +—XŒÒ¸°DôÖ!‰kvKÄgиš…X!•kæø—°MäšÕ)¹/T®9½3eû‰Ê5c`OJš#sÍ6Ähi/t®™†1±ŒÁ5Ï#îí2¸fbÔ,%=pÍ`sM®ôT9×ÄÚÁÈdr‰<\)´ášRY©Ã\®éÀx™dl.FÚÏ$ŽËšk¢Éóā×þ9椰áòoŠü,M+.ß`ɧv\~UÑ&Yؒ˧ƒ¶Ê¶åòf—ŒoÍEΡö41qÏåcÚb™®î†Ë½,ڟ›pÂÕ +·¶øhß"7\o¶è®Ë’CW+Âé,—\ŽºìþІÆÕŠ'küâª-.¹ø©ÕªGw-qËe‘^Hݞ“‹Kæ–ʇìþ‹ë6øà"æÅÇ[ï¹ðÃõV^qÙññýw/·÷Æuê5ƒAÞm_}ÝÛ'ש۞¶wê~z|õy_ß\çŽ;žpØ>ÜËývûøúêý–“pÍPàÿÿÿârõä +äÿÿMŒË‚0D÷|Å]jbko©<–*¸F¨ì ÅKÚªáï¥nt7™™s2؞Rà d1£1`"h²[ÁñRTPéÞ½£ VÆú™²­&·äµ¼/´DOc¸‚!åö,©êŒ E#(7á~Î;ÿԅÑݳuö{!þ>>>endobj +110 0 obj<>stream +xÚ+ä2T0BCc3JÎår +ár á +äHÉHendstream +endobj +111 0 obj +31 +endobj +112 0 obj<>>>/Annots 20 0 R>>endobj +113 0 obj<>stream +xÚµV]s£6}ϯ¸³OÉLMƒ?ú–mêÎn–g§~‘AØly%ˆÇýõ=’°!NâÍL·ãÆBGºçÜ{tÅ÷3\ü<û4QRž]ÍÏ~ý}J¾Kó 3£ñ„æé¹Gq"6übþÍÌzc;;Žoæf)¯ê<ËV碲Ѐ<¯…úcg¤¡óu®H‰¬Þ2Éé‰K4¥\%2ßÔæ¿Hš{ÑFЧ3$yÁ™â”W™¥ÙŸðê5§kQ–>ÜÍþ¦Hæ P­tp„ô†–]¼S5/iqþáú!Š?,.èk¼—¢|'°¢|j—~ϧœo5öãüÌu\¤M?<ý¸¿¥`ä9 +ßq©¤`¢#ÛQA±Mj—‹0êý5™N#£5[ï¬ *؎K£TË[øáh°DRB-$3e*‡f5­™¢%ç:›O¼&¥åŽL2ž–+:ÿÈÔîM9PèO b|'lZË+Ú;@Iï°´U®‡SÇØ(ޗ=’"m’Z=çæî¹Q-tbJQsäEÕ¬J™L»¼(Q4°¢°ÕâU*$2Y¥Ô(TØ¡g)>r…6O[Þ¯fÍ—0ڎX +/E^iÏÕ\f,áÊi7ðGÖfsRƇ3«x}0¡Y‹DÚx³(Ò¾c‹"âhòˆÃVl´Ñ7±´ü¿7¼ADšý 4ޏ›°Æ ãÚüð)ºÑbøï?s¥ØŠÓU!’G=¾Âô/fïËÍ&ÆkP]œ3çÑaýÉë›\ò¤Æ›–6ˆ R¬Pâ(¸j6Úªp×6¯×8œ(%YS%º(¬Èë]›z–¦Š”­V"È-¥Ø*­Y“‰„ªcsô©uí¦× $²:í18B˜y¥}Ó²-V ·èÁš*åö,½ZK­õNŠÆȤQµ(óiß§DF·wt»mË ¤’FJô«b×ÒÙKTè„îââH›N«(/u­²Gÿ~Á!¬6¹oôf=I•¨½|µù„KbVn°8•¹æiŒõGdÒû1Š¿ÜEݯ31Z¹©ŠˆÚ Ê°1{ŸèŽCºÙwê~ü¯]@!W¬2ySaŽL&ŠBlÍáçÆfê7,iƒ¡åø]=þhLo¶·áMjè¹À¢¿é;ÌÞèo ¤pøt€nèâbìÐWóW:q—/ÜÀCÏkÓKƒîÎ}Ù";݃1zë¡¶ïÐíOÇÀ¶ºíà„î=ÚÈ:…îJò\Â;ø…ûӉU€"Ò=Ï8NTÂÕÏW? ìmęÁ)õ-ڊ;îJšŽ`úýñ“PÓBúešæÆÞ?_ùص÷¹f§”·h+캀rý!ءߡ|ìÙOƒÚ¯×¬Zý5u‚ò‘3no(ïPê*ž@÷P€T‡~‡òpb[ã%”߶ܽ%}²—Ž…ƒÃÊÞWy€N3EÃÕoÛdüuö/û*›endstream +endobj +114 0 obj +1103 +endobj +115 0 obj<>>>>>endobj +116 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Ñ3V072PIÑPp VÎO+)O,JUK-*ÎÌÏSpI-N.Ê,(²5C²¸t!zt¡šŒ@b&&fzf +`¾¡Bpr~A*HÔ5„+ >Ï!Eendstream +endobj +117 0 obj +116 +endobj +118 0 obj<>>>/Annots 43 0 R>>endobj +119 0 obj<>stream +xÚµ˜KSãH Çï| +ÙªÄãGâ7 À°5Ylæ´ãt‚·b;k;ÅðíGêöCYB;¶¨ +ÕÉÏjEú·¤Î¿'˜øggƒãB’\D'ß®°Mˆ–ø‰ëù-NmxKQŠ<ÕÑ?±<…Œ‰aKȰàòq¬H¶™Èë¸N‹\á°¬·=Ã%ÂþnXZë_ŽpþŽëó²X•q–‘´Žö;|Øçw(’m™Ö¯x$6EYa7šï³‰êXᅏï„ᱟIÜϽ‰û‰6Ioo2×ք±:ŒŽ­£‹õ³(»ÂPXò"ï† +ȁOW…«èÄ4L¬|ôbÑËà Ö?ÃÇwБ \‹™Z¬!ÜC3 ÃÍ|Ã×â–år~2È3"Ãjlðœ@Þ¶ OÏ3ù©‡qÒòŒÈÀ±Í8¼k „Ó™ú†ÓóÞdÇþś|•+èõƒËñ'J@ç‹â QÕ¡'V‚”*0W+\§k×E™Å5„‘¤Ë4‘5tԉ{b8I¥ß×ìömÕ5öÐË·ÇH£.ÏD%¶ê’ ººQ—oÔÕò.8-Ï̾eSì5<'wcªç¼G¹éù²éYêľɿ]œ¯¶Ø¥ûydÑsZ.àj‘RM«}ØDÏàÏâ â|ÑÉ'5üØ5*Tª¥hï›,£WyR,¨®‘ᨌóêà ¤³E­_Î*Tào¶éBgç¾Xˆµt(Yœ×irÀ—Ó(ܜȜO¥äb¿Dïuî§@çÁÀ9AÕÖ&ýéxF ïËÚ¨ãAç'0Æ osªôýp}‰ïzÁîÒ\ôµ*Ö bê")Ö_^‡ìÀB¶É’Zh²ÔÒ2 :šEÛÀ9AY +0&ZžTå&u-Ïä=ª©Zž”Õé€ÿœ Jñ×òŒ@>0w‚?¬;°U†I5öÔõFí }SÄë +禲ºpä¢é|Tnþ?aÄÌNGr¡ÓQC+™hh`ÞpŒÔ㜠yÎp‚täàYÖòŒ YÌÅ(éxNŽüûœ î*U«ã¼KÓ­–gòþt žœ YzÏ S/`*õGð ›f¼R¢x€°.·I½ÅY/­ôF߆ôb=íLèeþQ»4|¶¢– ¨ZiVC3€ŠãqNH}J¹Žgòݽ´<#H¤4 ëxNÐ# ÉêxFÐh‘ˆ:þ¹SÃg2Âyo6”ç'Q¿‘ÃÝ|&ƒ³L—ûêëkÜԒw•m¹ÐÉ¡¡U¶54¨Æ9T148'¨— òçmkˆç„J¯Þ}NPzJoǐީ­îk2½®åŽàû+Ž×µøU«ÑÇû.«0Ã÷(’#ë×'Øñû‘U-t nh•? ÍY= +ç þ€3œPʧå9¡šŒÞNdÍiÔòŒ áÆ¥jÔñ ú‘Ã eηXìéZ"{È\ÄUšÈc?KWô‹Ùy’ˆªz¯[ì>®:ƒß*·wûþ÷'î‰oâW0é#§Ð_'¿VÐTÂendstream +endobj +120 0 obj +1330 +endobj +121 0 obj<>>>>>endobj +122 0 obj<>stream +xÚ-‹;‚@„ûýSJ²Ç‰Ô¾j•Õޜ{ &‚Ü‘ø÷åÔÌóÈ7£œÅ¨êd÷¤ÐòЀâÁ+[TX›r_`{9¶h?½oAqÕ»¡ÇN£ Ýkšs&ÊLþ‡lÚ¬á¢Æ·œÕkÐÞiL×^èDó(#Iendstream +endobj +123 0 obj +120 +endobj +124 0 obj<>>>>>endobj +125 0 obj<>stream +xڕVËnÛ:Ýû+Y¹€­J²Ç˼ZhSÝkè¢FYl)’%);ùû;%§õC¸…[Ï̜9󐍈é“À"…Ùäõèv=zÿa i ë’N®×°.Æ3¸) +öÝú!æ$1M¯£Ôc$Q\æ¢)ÐBÍä+HÜA‰Ì5†ž”FÕà*$\½€AÌ¢‚Ó%$‹Îé,æm`ò÷ ‡Æî1óGW†Pá8éŽÇ¼ftÊ0K¶šŽ'gÀúDr aMŒ[ ”\´_žTl‹ðŒ(¡Ñà +,À)°ÖÊ8ȕÜŠ4UžeUéà–»šiø>¾¸ý’]|Lp#8³}úæPÜdDõñ~“§O=]îå!œ.Êò7m :Lǝ¨ÛÀ¼À- +¥=õŠ9àô˜*R±öu—…@éày€8ZÆà³Ø1ƒ¡š÷hð'ÜFÄ•’ύÙDàÅk› D¦e[” ؚ‘oºð +\–hسx…Z‘{êNwè™6+eÍ ×nh§±¹„®ãaéf íŸ=r²ôá(îŽÆçlÆGâréÃÑw||| +9¬Úà2ºŒßú÷SÖ7Í¡à³/ÎAr3ÈÞ&7M݄ۗ ç;‡ÀÛ)ÔVɁ”=Ÿƒ´L÷™ïé?d«¯ W€&¥±\nÚ>¬îÞg L¸H©ìuíËoÑÙÃʲ{ ¾Ñ¼[Á}¹Ép9Õ\N ‡ß•{…;%T×Iݓ¬R4=…¡““E3½Ç’K +’õ¬½³¯úÌÖ[„åsF,¡Õ)Ãñ>_ê|µóÂø@ēڿä*!MdÉá PySûÉë<…)1ThÖmcvØ\ZÇdŽöÂo|áÖyé{&€,¯B76’ÿj°wߋŸ^YN4¾ÐÙLŽæâiÁˆ¤;#͹½JRQÑú„[¿]ZÐg}´¨ajàSþ2'å_‡ºa÷ 롚¿éÜNµ]P˰KµQ[Úh€²òÜ +BÎü ¬}UºqZÿÌm§BÿE¶wüzfvÿ®òs•Ó„I÷û¬~¦qè§¡ś:•+1Ì9 œµâoYŸ°9æmè–ÆÀc[Ñlyîÿ_Pž¹Í+,z·t4¯ß¢Ï–'þÐ̯éÍF§tréïÖ£Fÿ¨]¿†endstream +endobj +126 0 obj +900 +endobj +127 0 obj<>>>>>endobj +128 0 obj<>stream +xڕ”Aoœ0…ïüŠ9n¦k ìæÚ¤‘r£ +íÝ Cב±©m ý÷cPÒî6UÄJhñ̼7OüH8ìé␗á×ôɧ:ùøp üuG'å‘CÝîò´€;Ó÷B·îCýL%pKXvHËPt÷µzžrºQc‹Nh…3 Vj/õwhÖ9iDZÅ6è–d¢MQƒ¼4úš`¨ªÏñh¿íþѲÛ4 ÂL2-k±“ۈ†ÖA(Y'¼M—]o&|Úeý W8#ùHÏæÞÐßàђm"@½Í”“ԝyÓeý “’Î;ðÔ&&!•8)„ªº‡N*b5–È&Ùà+§Ö̰<Û¨n౪à±ö¨ýòÿϏh[ÊÎ8 ÆzèHÉ_²;ôŒ|bÂ{+O£Ç‹ãOÚ‘ ­”R¤A8˜Q©p÷³ þ†.bà9íte`nÀFv²¹6…ʹHqé);0Ÿesޜ€±%LÐZ9-™²¯ ¤Qô2‰º_ÎcŸ®O³2º÷0Z*µvdûÈÛaqJþá*˜nñºNH®Ä"õRÊ耑±ë¦Ž«Eü&„&/ŽÑþ8õÉt~Ìß>̽G×X9l›c±‹²}h*󂇅ï¯}(>×ɗä7®™L4endstream +endobj +129 0 obj +484 +endobj +130 0 obj<>>>>>endobj +131 0 obj<>stream +xڕ˜Ûrâ8†ïó}™­ŠO`ØËI6³©š vÂ<€hƶ<’œ o¿­ƒ9L¥*è·ÔŸºÕêöï‡"ü‹!O ­¾,F¯3H"X¬pd’OaQǶ°Ù4uN}þúkIª~`ºæÁ’×W4W€ó- ìՁºx’ùƒ'•¯[i=PW¸Q{ +Í4µƒ7@ÇÓ0êÕAº4ÛÃ*h[±Z“ýqÝÇ© ‘Ìa‚^r­SààÞtj¬ÊëÕyº71¿£Í˜s5“·ƒyeuWcy/¹Bl“ã`b¯HìÔ}ÄÑÄ%ª·­\ÊÀ%æ~fÞ)U_8ŸH®pGÑ=9Ë«r;uw:Í]Îú† ¹‰&—"Û¸±´’þ¨Þ÷“¦ÓøŽdÕ©‡‘zuéÄ×CßÄúFŠ*Åú̧fplÓIrGšêԝº1›[çó—€MSôƬ»Â—%w¤¥N=Ï©ûø’™KKßÙï–)}ƒR:ÕEWªFˆrˆ3“ôŽŒÔ©Â:õ¥"j_v'³´+»x›Ïá­jJvt ]¬º÷U?VÖXЀ7ó“ÊÜÐæw±²°Íw5Ó0—˜­L<—B *Ê®šÞUÁ¾^VtʶÄkAµM#¤v¥´³$ò–鋟N×Þ+ƒ‚­H[ê³'.X|ð”ßVœjF«±9Àôµø„#큹Øç —êÚܵdí»¯“½?±À88X34Ò^3jÀ>%QŠ©þ­ÆŽìƒ¹–¬mðî/\Kæí‡’Wü…½âM ¹ˆkŒµ ±á-ô¶a·ÜÓi»m¨žcïxɑ½Ó=X‘_,@a€­(+û}:ÔE¯‹z·û06.ž&LÊAM*ÖkŽuNÃ(_mØn¶,·ù ¼4Í뉣ºpù ƜÆÌ!´}2.¿ìÞВãلO®7ö»O®§»ðÚJ;#·­»ƒóA`3?Ê^& ™œFqù¥éÕ[ŒYÿ^ ÀÀ´¹Žyº÷ØÌwG¯>²iÎ\‚Ï}JÿïáZÛz—endstream +endobj +132 0 obj +1206 +endobj +133 0 obj<>>>>>endobj +134 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Ñ3V072PIÑPp VÎO+)O,JUK-*ÎÌÏSpI-N.Ê,(²5C²¸t!zt¡š,@b&ÆÆz +`¾‰‚sFb^zj1HÜ5„+ …œ" endstream +endobj +135 0 obj +118 +endobj +136 0 obj<>>>>>endobj +137 0 obj<>stream +xڝ•QsÚ0 ÇßùzÜH`Ð>–4´éAë]Ò»½GM=›Ù¦Œ}ú*cíÝâÒ9ŽDâ'ýeIùՋáœ>1L0ƒ¨{Ó¢w6»„Á9OdO. (¿\Á2Îq»ûZülâÉÞ¡?EƒÖ%Š¡@[»½Çâøà1˜DãÆ#Ù[F ÅëÇÃßA˜z½ñhAq]mx…Ñ{Nÿ­ûš[®ªn`Žº”ºcÁ¢@ùÒܔÜs¨EðÏ\“ê¥ôÀé/ëp@¹ÆPöFcËwŠz£¥à^í@P +–è·ˆüÖÀښÊòڅÂ9´’ÿ—ºOhrF¬Ð‡TQº­*Mé»êP½o‰6ÆpöM1€+aÞúâ*O²,GMÕt^¹çºä¶„Ä”O$>Óô]·éÐoêž&¥ +¢“G–w‡JH ¡ï³À¬Ô¾©k¾së3͓3Ö MYþpÿäÛh]€<+ܙT…åÚ=aC3Þ£´[Ö¿™wónq«Ðû>ãbÕ$zcùúY +óÃD†Ñ,ù›Ž*¡½5êTþÝgøûڝYž‚ÏÒbÖ o;‹fR]IÔÔw+˜+‚\ÆNÀ;í„3Ìò‡ˆí8puì8¶âZþi öœ]w³ç¤üXÖkŽuµÈi7k±QÍr*%‡c\*H8À,”$3ÎçÂʵÿ›*ºöAXz¾˜†¶­}!ÒéHm;U´8¬"8µ…¥mM§šÞ‹·Øo£Ã–|÷ +]œG—´DÉpÙܧEï{#—endstream +endobj +138 0 obj +596 +endobj +139 0 obj<>>>>>endobj +140 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Ñ3V072PIÑPp VÎO+)O,JUK-*ÎÌÏSpI-N.Ê,(²5C²¸t!zt¡š @‚&ÆÆzF +`G÷œüââÄ¢J„kW Ì,"Öendstream +endobj +141 0 obj +120 +endobj +142 0 obj<>>>/Annots 72 0 R>>endobj +143 0 obj<>stream +xÚ՚Ënã6†÷~ +.[ Qě(.Ó¤Ì*éØ3{צ3*,K• òöååP$¶ˆnb5Ÿñ‹ù“üyË? ŒJý‘ ˆVhÓ.~_-n%"%ZíæU‚¡Õö—Õú¯½BÝÝw‡“:œŽ¿®þ^ü±Z”E© æ›—/ŸL€*ʋµ¨.¼ß£¥aÿôøð‚n9ÂØü5S¬Òê¿†ÑE|@¶ÈþHø. ”å¦ë•®áúÅì¿ðÅzëJi)*]qN +Tüö‘Œº+BuÆèXL(AZ]-c$äõy«[½Ù5›õ©éʅ.1#]sڕ²`£v6€ŠÅpY0§É)œZhaŽK{ÒòýxRíDGåµüÑwe›÷´§75¼5ê‡Á1\ÈYŸQœËJ« Š» (ΥбUœf÷\šþœ€ ¨‡nóÚênz™#41­nô1‘èß]Yv>>>>>endobj +146 0 obj<>stream +xÚ+ä2T0BCc3JÎår +áÒw³P04TIS045Ñ3V072PIÑPp VÎO+)O,JUK-*ÎÌÏSpI-N.Ê,(²5C²¸t!zt¡š23A‚®!\\½Wendstream +endobj +147 0 obj +100 +endobj +148 0 obj<>endobj +149 0 obj<>endobj +150 0 obj<>endobj +151 0 obj<>endobj +152 0 obj<>endobj +153 0 obj<>endobj +154 0 obj<>endobj +155 0 obj<>endobj +156 0 obj<>endobj +157 0 obj<>endobj +158 0 obj<>endobj +159 0 obj<>endobj +160 0 obj<>endobj +161 0 obj<>endobj +162 0 obj<>endobj +163 0 obj<>endobj +164 0 obj<>endobj +165 0 obj<>endobj +166 0 obj<>endobj +167 0 obj<>endobj +168 0 obj<>endobj +169 0 obj<>endobj +170 0 obj<>endobj +171 0 obj<>endobj +172 0 obj<>endobj +173 0 obj<>endobj +174 0 obj<>endobj +175 0 obj<>endobj +176 0 obj<>endobj +177 0 obj<>endobj +178 0 obj<>1<>2<>4<>]>>>>endobj +xref +0 179 +0000000000 65535 f +0000000015 00000 n +0000000227 00000 n +0000001793 00000 n +0000001867 00000 n +0000001946 00000 n +0000002024 00000 n +0000002101 00000 n +0000002180 00000 n +0000002256 00000 n +0000002337 00000 n +0000002396 00000 n +0000002448 00000 n +0000002533 00000 n +0000002585 00000 n +0000002669 00000 n +0000002774 00000 n +0000002879 00000 n +0000002984 00000 n +0000003089 00000 n +0000003194 00000 n +0000003260 00000 n +0000003361 00000 n +0000003446 00000 n +0000003547 00000 n +0000003632 00000 n +0000003733 00000 n +0000003818 00000 n +0000003905 00000 n +0000003990 00000 n +0000004077 00000 n +0000004162 00000 n +0000004228 00000 n +0000004313 00000 n +0000004379 00000 n +0000004464 00000 n +0000004530 00000 n +0000004615 00000 n +0000004681 00000 n +0000004766 00000 n +0000004832 00000 n +0000004917 00000 n +0000004983 00000 n +0000005068 00000 n +0000005162 00000 n +0000005266 00000 n +0000005371 00000 n +0000005476 00000 n +0000005581 00000 n +0000005685 00000 n +0000005790 00000 n +0000005895 00000 n +0000005999 00000 n +0000006104 00000 n +0000006209 00000 n +0000006314 00000 n +0000006419 00000 n +0000006524 00000 n +0000006629 00000 n +0000006734 00000 n +0000006839 00000 n +0000006944 00000 n +0000007049 00000 n +0000007154 00000 n +0000007259 00000 n +0000007364 00000 n +0000007469 00000 n +0000007573 00000 n +0000007678 00000 n +0000007783 00000 n +0000007887 00000 n +0000007992 00000 n +0000008097 00000 n +0000008310 00000 n +0000008342 00000 n +0000008374 00000 n +0000008762 00000 n +0000008810 00000 n +0000008858 00000 n +0000008906 00000 n +0000008954 00000 n +0000009002 00000 n +0000009050 00000 n +0000009098 00000 n +0000009146 00000 n +0000009194 00000 n +0000009242 00000 n +0000009290 00000 n +0000009338 00000 n +0000009386 00000 n +0000009434 00000 n +0000009482 00000 n +0000009530 00000 n +0000009578 00000 n +0000009626 00000 n +0000009674 00000 n +0000009722 00000 n +0000009770 00000 n +0000009818 00000 n +0000009866 00000 n +0000009914 00000 n +0000009963 00000 n +0000010012 00000 n +0000010061 00000 n +0000010110 00000 n +0000010159 00000 n +0000010340 00000 n +0000010492 00000 n +0000016844 00000 n +0000016866 00000 n +0000016961 00000 n +0000017063 00000 n +0000017083 00000 n +0000017238 00000 n +0000018412 00000 n +0000018434 00000 n +0000018547 00000 n +0000018734 00000 n +0000018755 00000 n +0000018910 00000 n +0000020311 00000 n +0000020333 00000 n +0000020446 00000 n +0000020637 00000 n +0000020658 00000 n +0000020807 00000 n +0000021778 00000 n +0000021799 00000 n +0000021939 00000 n +0000022494 00000 n +0000022515 00000 n +0000022664 00000 n +0000023941 00000 n +0000023963 00000 n +0000024076 00000 n +0000024265 00000 n +0000024286 00000 n +0000024426 00000 n +0000025093 00000 n +0000025114 00000 n +0000025227 00000 n +0000025418 00000 n +0000025439 00000 n +0000025593 00000 n +0000027187 00000 n +0000027209 00000 n +0000027322 00000 n +0000027493 00000 n +0000027514 00000 n +0000027569 00000 n +0000027674 00000 n +0000027818 00000 n +0000027924 00000 n +0000028044 00000 n +0000028153 00000 n +0000028302 00000 n +0000028412 00000 n +0000028519 00000 n +0000028667 00000 n +0000028802 00000 n +0000028920 00000 n +0000029034 00000 n +0000029151 00000 n +0000029258 00000 n +0000029396 00000 n +0000029544 00000 n +0000029646 00000 n +0000029750 00000 n +0000029899 00000 n +0000030002 00000 n +0000030115 00000 n +0000030215 00000 n +0000030325 00000 n +0000030471 00000 n +0000030582 00000 n +0000030692 00000 n +0000030826 00000 n +0000030923 00000 n +0000031023 00000 n +trailer +<]>> +startxref +31250 +%%EOF diff --git a/doc/svd.shtml b/doc/svd.shtml new file mode 100644 index 0000000000..e47acf5bca --- /dev/null +++ b/doc/svd.shtml @@ -0,0 +1,212 @@ + + + + + + CUPS Software Version Description + + + +

Scope

+ +

Identification

+ +This software version description document provides release information for the +Common UNIX Printing System ("CUPS") Version 1.1. + + + +

Document Overview

+ +

This software version description document is organized into the following +sections:

+ + + + + +

Additions

+ +

CUPS 1.1 includes many new features from the 1.0.x releases. + +

Filters

+ +

imagetoraster, imagetops

+ +

The image file filters have been upgraded to support conversion of +Microsoft Bitmap ("BMP") and Alias PIX files. + +

pdftops

+ +

A new pdftops filter has been developed that is based on the +excellent Xpdf 0.90 software from Derek B. Noonburg. The new filter is +faster, smaller, and considerably more reliable than the +Ghostscript-based filter in CUPS 1.0. + +

pstoraster

+ +

The pstoraster filter has been integrated with GNU +GhostScript 5.50. The new RIP supports most Level 3 PostScript language +features. + +

rastertoepson

+ +

The new rastertoepson filter supports EPSON printers +using the ESC/P or ESC/P2 command sets. PPDs are supplied for 9-pin, +24-pin, Stylus Color, and Stylus Photo printers. + +

User-Defined Printers and Options

+ +

The new lpoptions command allows users to configure default +document options and create additional "instances" of existing printers, +each with unique options. + +

The lp, lpr, and lpstat commands +have been upgraded to use this option and printer instance information +automatically. + +

Daemons

+ +

CUPS 1.1 includes two new daemons that provide enhanced network printing +support. + +

cups-lpd

+ +

The cups-lpd daemon provides support for clients using the +Line Printer Daemon protocol. + +

cups-polld

+ +

The cups-polld daemon provides remote polling services for +the scheduler. + +

Commands

+ +

CUPS 1.1 includes several new printing commands. + +

lpoptions

+ +

The lpoptions command provides user-defined printers and +options. + +

lpmove

+ +

The lpmove command moves a print job to a new destination. + +

lpinfo

+ +

The lpinfo command lists the available PPD files or devices. + +

IPP Implementation

+ +

CUPS 1.1 adds support for the set-job-attributes +extension operation as well as two new CUPS-specific extension +operations to determine which devices and printer drivers are available +on the system. + +

Further information on the CUPS implementation of IPP can be found +in CUPS-IPP-1.1. + + +

Changes

+ +

CUPS 1.1 includes many changes from the 1.0.x releases. + +

Directory Structure

+ +

The directory structure in CUPS 1.1 has been modified to conform to the +Filesystem Hierarchy Standard, 2.0. The following table describes the +new file locations. + +

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Table 1: Directory structure changes from CUPS 1.0.x to 1.1.x.
DescriptionCUPS 1.0.xCUPS 1.1.x
Backends/var/cups/backend/usr/lib/cups/backend
CGI programs/var/cups/cgi-bin/usr/lib/cups/cgi-bin
Configuration files/var/cups/conf/etc/cups
Documentation/usr/share/cups/doc/usr/share/doc/cups
Filter programs/var/cups/filter/usr/lib/cups/filter
Interface scripts/var/cups/interfaces/etc/cups/interfaces
Locale data/usr/lib/locale/usr/share/locale
Log files/var/cups/logs/var/log/cups
PPD files/var/cups/ppd/etc/cups/ppd
Request files/var/cups/requests/var/spool/cups
+ +

IPP Implementation

+ +

CUPS 1.1 is based on version 1.1 of the Internet Printing Protocol. + +

The new scheduler supports the create-job and +send-document operations. In addition, the +job-sheets, job-sheets-default, and +job-sheets-supported attributes are now supported for +banner pages. + +

The CUPS-get-printers and CUPS-get-classes +operations have been upgraded to support limited filtering based upon +the printer-type, printer-location, +printer-info, and printer-make-and-model +attributes. + +

The CUPS-add-printer operation now supports the +ppd-name attribute to specify a locally-available PPD file +rather than sending the PPD file from the client with the request. + +

Further information on the CUPS implementation of IPP can be found +in CUPS-IPP-1.1. + + + + + diff --git a/doc/system-overview.shtml b/doc/system-overview.shtml new file mode 100644 index 0000000000..54b7df5e97 --- /dev/null +++ b/doc/system-overview.shtml @@ -0,0 +1,19 @@ +

System Overview

+ +

CUPS provides a portable printing layer for UNIX®-based +operating systems. It has been developed by +Easy Software Products to promote a +standard printing solution for all UNIX vendors and users. CUPS +provides the System V and Berkeley command-line interfaces. + +

CUPS uses the Internet Printing Protocol ("IPP") as the basis for +managing print jobs and queues. The Line Printer Daemon ("LPD") Server +Message Block ("SMB"), and AppSocket (a.k.a. JetDirect) protocols are +also supported with reduced functionality. CUPS adds network printer +browsing and PostScript Printer Description ("PPD") based +printing options to support real-world printing under UNIX. + +

CUPS also includes a customized version of GNU Ghostscript +(currently based off GNU Ghostscript 5.50) and an image file RIP that +are used to support non-PostScript printers. Sample drivers for HP and +EPSON printers are included that use these filters. diff --git a/filter/Makefile b/filter/Makefile new file mode 100644 index 0000000000..573b5e10af --- /dev/null +++ b/filter/Makefile @@ -0,0 +1,207 @@ +# +# "$Id$" +# +# Filter makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1997-2000 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +TARGETS = hpgltops texttops pstops imagetops imagetoraster \ + rastertoepson rastertohp + +HPGLOBJS = hpgl-attr.o hpgl-config.o hpgl-main.o hpgl-prolog.o \ + hpgl-char.o hpgl-input.o hpgl-polygon.o hpgl-vector.o +IMAGEOBJS = image-bmp.o image-colorspace.o image-gif.o image-jpeg.o \ + image-photocd.o image-pix.o image-png.o image-pnm.o \ + image-sgi.o image-sgilib.o image-sun.o image-tiff.o \ + image-zoom.o image.o raster.o +FORMOBJS = form-attr.o form-main.o form-ps.o form-text.o form-tree.o +OBJS = $(HPGLOBJS) $(IMAGEOBJS) $(FORMOBJS) \ + imagetops.o imagetoraster.o common.o pstops.o raster.o \ + rastertoepson.o rastertohp.o texttops.o textcommon.o + + +# +# Make all targets... +# + +all: $(TARGETS) + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) $(TARGETS) $(LIBCUPSIMAGE) + + +# +# Install all targets... +# + +install: + -$(MKDIR) $(SERVERBIN)/filter + $(CHMOD) ugo+rx $(SERVERBIN) + $(CHMOD) ugo+rx $(SERVERBIN)/filter + $(INSTALL_BIN) $(TARGETS) $(SERVERBIN)/filter + -$(MKDIR) $(INCLUDEDIR)/cups + $(CHMOD) ugo+rx $(INCLUDEDIR) + $(CHMOD) ugo+rx $(INCLUDEDIR)/cups + $(INSTALL_DATA) raster.h $(INCLUDEDIR)/cups + -$(MKDIR) $(LIBDIR) + $(CHMOD) ugo+rx $(LIBDIR) + $(INSTALL_LIB) $(LIBCUPSIMAGE) $(LIBDIR) + -if test $(LIBCUPSIMAGE) != "libcupsimage.a" -a $(LIBCUPSIMAGE) != "libcupsimage.la"; then \ + $(RM) `basename $(LIBCUPSIMAGE) .2`; \ + $(LN) $(LIBCUPSIMAGE) `basename $(LIBCUPSIMAGE) .2`; \ + fi + + +# +# formtops +# + +formtops: $(FORMOBJS) common.o ../Makedefs ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ $(FORMOBJS) common.o $(LIBS) -lm +$(FORMOBJS): form.h + + +# +# hpgltops +# + +hpgltops: $(HPGLOBJS) common.o ../Makedefs ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ $(HPGLOBJS) common.o $(LIBS) -lm +$(HPGLOBJS): hpgltops.h + + +# +# libcupsimage.so.2, libcupsimage.sl.2 +# + +libcupsimage.so.2 libcupsimage.sl.2: $(IMAGEOBJS) ../Makedefs + echo Linking $@... + $(DSO) $@ $(IMAGEOBJS) $(DSOLIBS) -lm + $(RM) `basename $@ .2` + $(LN) $@ `basename $@ .2` + + +# +# libcupsimage.la +# + +libcupsimage.la: $(IMAGEOBJS) ../Makedefs + echo Linking $@... + $(CC) -o $@ $(IMAGEOBJS:.o=.lo) -rpath $(LIBDIR) \ + -version-info 2:0 + + +# +# libcupsimage.a +# + +libcupsimage.a: $(IMAGEOBJS) ../Makedefs + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(IMAGEOBJS) + $(RANLIB) $@ + +$(IMAGEOBJS): image.h +raster.o: raster.h + + +# +# imagetops +# + +imagetops: imagetops.o common.o $(LIBCUPSIMAGE) ../Makedefs \ + ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ imagetops.o common.o $(LINKCUPSIMAGE) \ + $(IMGLIBS) $(LIBS) +imagetops: common.h image.h + + +# +# imagetoraster +# + +imagetoraster: imagetoraster.o common.o $(LIBCUPSIMAGE) ../Makedefs \ + ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ imagetoraster.o common.o $(LINKCUPSIMAGE) \ + $(IMGLIBS) $(LIBS) +imagetoraster: common.h image.h raster.h + + +# +# pstops +# + +pstops: pstops.o common.o ../Makedefs ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ pstops.o common.o $(LIBS) +pstops.o: common.h + + +# +# rastertoepson +# + +rastertoepson: rastertoepson.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ rastertoepson.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) +rastertoepson.o: raster.h + + +# +# rastertohp +# + +rastertohp: rastertohp.o ../Makedefs ../cups/$(LIBCUPS) $(LIBCUPSIMAGE) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ rastertohp.o $(LINKCUPSIMAGE) $(IMGLIBS) $(LIBS) +rastertohp.o: raster.h + + +# +# texttops +# + +texttops: texttops.o textcommon.o common.o ../Makedefs \ + ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o $@ texttops.o textcommon.o common.o $(LIBS) +texttops.o: common.h textcommon.h + +common.o: common.h +textcommon.o: textcommon.h common.h + + +$(OBJS): ../Makedefs ../cups/cups.h ../cups/ppd.h ../cups/language.h + + +# +# End of "$Id$". +# diff --git a/filter/common.c b/filter/common.c new file mode 100644 index 0000000000..b41cc4ec32 --- /dev/null +++ b/filter/common.c @@ -0,0 +1,255 @@ +/* + * "$Id$" + * + * Common filter routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * SetCommonOptions() - Set common filter options for media size, etc. + */ + +/* + * Include necessary headers... + */ + +#include "common.h" + + +/* + * Globals... + */ + +int Orientation = 0, /* 0 = portrait, 1 = landscape, etc. */ + Duplex = 0, /* Duplexed? */ + LanguageLevel = 1, /* Language level of printer */ + ColorDevice = 1; /* Do color text? */ +float PageLeft = 18.0f, /* Left margin */ + PageRight = 594.0f, /* Right margin */ + PageBottom = 36.0f, /* Bottom margin */ + PageTop = 756.0f, /* Top margin */ + PageWidth = 612.0f, /* Total page width */ + PageLength = 792.0f; /* Total page length */ + + +/* + * 'SetCommonOptions()' - Set common filter options for media size, etc. + */ + +ppd_file_t * /* O - PPD file */ +SetCommonOptions(int num_options, /* I - Number of options */ + cups_option_t *options, /* I - Options */ + int change_size) /* I - Change page size? */ +{ + float temp; /* Swapping variable */ + ppd_file_t *ppd; /* PPD file */ + ppd_size_t *pagesize; /* Current page size */ + const char *val; /* Option value */ + + + ppd = ppdOpenFile(getenv("PPD")); + + ppdMarkDefaults(ppd); + cupsMarkOptions(ppd, num_options, options); + + if ((pagesize = ppdPageSize(ppd, NULL)) != NULL) + { + PageWidth = pagesize->width; + PageLength = pagesize->length; + PageTop = pagesize->top; + PageBottom = pagesize->bottom; + PageLeft = pagesize->left; + PageRight = pagesize->right; + + fprintf(stderr, "DEBUG: Page = %.0fx%.0f; %.0f,%.0f to %.0f,%.0f\n", + PageWidth, PageLength, PageLeft, PageBottom, PageRight, PageTop); + } + + if (ppd != NULL) + { + ColorDevice = ppd->color_device; + LanguageLevel = ppd->language_level; + } + + if ((val = cupsGetOption("landscape", num_options, options)) != NULL) + Orientation = 1; + + if ((val = cupsGetOption("orientation-requested", num_options, options)) != NULL) + { + /* + * Map IPP orientation values to 0 to 3: + * + * 3 = 0 degrees = 0 + * 4 = 90 degrees = 1 + * 5 = -90 degrees = 3 + * 6 = 180 degrees = 2 + */ + + Orientation = atoi(val) - 3; + if (Orientation >= 2) + Orientation ^= 1; + } + + if ((val = cupsGetOption("page-left", num_options, options)) != NULL) + { + switch (Orientation) + { + case 0 : + PageLeft = (float)atof(val); + break; + case 1 : + PageBottom = (float)atof(val); + break; + case 2 : + PageRight = PageWidth - (float)atof(val); + break; + case 3 : + PageTop = PageLength - (float)atof(val); + break; + } + } + + if ((val = cupsGetOption("page-right", num_options, options)) != NULL) + { + switch (Orientation) + { + case 0 : + PageRight = PageWidth - (float)atof(val); + break; + case 1 : + PageTop = PageLength - (float)atof(val); + break; + case 2 : + PageLeft = (float)atof(val); + break; + case 3 : + PageBottom = (float)atof(val); + break; + } + } + + if ((val = cupsGetOption("page-bottom", num_options, options)) != NULL) + { + switch (Orientation) + { + case 0 : + PageBottom = (float)atof(val); + break; + case 1 : + PageRight = PageWidth - (float)atof(val); + break; + case 2 : + PageTop = PageLength - (float)atof(val); + break; + case 3 : + PageLeft = (float)atof(val); + break; + } + } + + if ((val = cupsGetOption("page-top", num_options, options)) != NULL) + { + switch (Orientation) + { + case 0 : + PageTop = PageLength - (float)atof(val); + break; + case 1 : + PageLeft = (float)atof(val); + break; + case 2 : + PageBottom = (float)atof(val); + break; + case 3 : + PageRight = PageWidth - (float)atof(val); + break; + } + } + + if (change_size) + switch (Orientation) + { + case 0 : /* Portait */ + break; + + case 1 : /* Landscape */ + temp = PageLeft; + PageLeft = PageBottom; + PageBottom = temp; + + temp = PageRight; + PageRight = PageTop; + PageTop = temp; + + temp = PageWidth; + PageWidth = PageLength; + PageLength = temp; + break; + + case 2 : /* Reverse Portrait */ + temp = PageWidth - PageLeft; + PageLeft = PageWidth - PageRight; + PageRight = temp; + + temp = PageLength - PageBottom; + PageBottom = PageLength - PageTop; + PageTop = temp; + break; + + case 3 : /* Reverse Landscape */ + temp = PageWidth - PageLeft; + PageLeft = PageWidth - PageRight; + PageRight = temp; + + temp = PageLength - PageBottom; + PageBottom = PageLength - PageTop; + PageTop = temp; + + temp = PageLeft; + PageLeft = PageBottom; + PageBottom = temp; + + temp = PageRight; + PageRight = PageTop; + PageTop = temp; + + temp = PageWidth; + PageWidth = PageLength; + PageLength = temp; + break; + } + + if ((val = cupsGetOption("sides", num_options, options)) != NULL && + strncasecmp(val, "two-", 4) == 0) + Duplex = 1; + else if ((val = cupsGetOption("Duplex", num_options, options)) != NULL && + strncasecmp(val, "Duplex", 6) == 0) + Duplex = 1; + else if (ppdIsMarked(ppd, "Duplex", "DuplexNoTumble") || + ppdIsMarked(ppd, "Duplex", "DuplexTumble")) + Duplex = 1; + + return (ppd); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/common.h b/filter/common.h new file mode 100644 index 0000000000..c92a121186 --- /dev/null +++ b/filter/common.h @@ -0,0 +1,67 @@ +/* + * "$Id$" + * + * Common filter definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include + + +/* + * Globals... + */ + +extern int Orientation, /* 0 = portrait, 1 = landscape, etc. */ + Duplex, /* Duplexed? */ + LanguageLevel, /* Language level of printer */ + ColorDevice; /* Do color text? */ +extern float PageLeft, /* Left margin */ + PageRight, /* Right margin */ + PageBottom, /* Bottom margin */ + PageTop, /* Top margin */ + PageWidth, /* Total page width */ + PageLength; /* Total page length */ + + +/* + * Prototypes... + */ + +extern ppd_file_t *SetCommonOptions(int num_options, cups_option_t *options, + int change_size); + + +/* + * End of "$Id$". + */ diff --git a/filter/form-main.c b/filter/form-main.c new file mode 100644 index 0000000000..941cafa0c3 --- /dev/null +++ b/filter/form-main.c @@ -0,0 +1,60 @@ +/* + * "$Id$" + * + * CUPS form main entry for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Load the specified form file and output PostScript. + */ + +/* + * Include necessary headers... + */ + +#include "form.h" + + +/* + * Globals... + */ + +int NumOptions; /* Number of command-line options */ +cups_option_t *Options; /* Command-line options */ +ppd_file_t *PPD; /* PPD file */ + + +/* + * 'main()' - Load the specified form file and output PostScript. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/form-ps.c b/filter/form-ps.c new file mode 100644 index 0000000000..4d1349f3b9 --- /dev/null +++ b/filter/form-ps.c @@ -0,0 +1,47 @@ +/* + * "$Id$" + * + * CUPS form PostScript routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + */ + +/* + * Include necessary headers... + */ + +#include "form.h" + + +/* + * 'formWrite()' - Write PostScript output for the given form document. + */ + +void +formWrite(tree_t *t) /* I - Document tree to write */ +{ +} + + +/* + * End of "$Id$". + */ diff --git a/filter/form-tree.c b/filter/form-tree.c new file mode 100644 index 0000000000..9e44558d20 --- /dev/null +++ b/filter/form-tree.c @@ -0,0 +1,622 @@ +/* + * "$Id$" + * + * CUPS form document tree routines for the Common UNIX Printing + * System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + */ + +/* + * Include necessary headers... + */ + +#include "form.h" + + +/* + * Local functions... + */ + +static int compare_attr(attr_t *a0, attr_t *a1); +static int compare_elements(char **e0, char **e1); +static int parse_attr(tree_t *t, FILE *fp); +static int parse_element(tree_t *t, FILE *fp); + + +/* + * Local globals... + */ + +static char *elements[] = + { + "", + "!--", + "ARC", + "BOX", + "BR", + "B", + "CUPSFORM", + "DEFVAR", + "FONT", + "H1", + "H2", + "H3", + "H4", + "H5", + "H6", + "HEAD", + "IMG", + "I", + "LINE", + "PAGE", + "PIE", + "POLY", + "PRE", + "P", + "RECT", + "TEXT", + "TT", + "VAR" + }; + + +/* + * 'formDelete()' - Delete a node and its children. + */ + +void +formDelete(tree_t *t) /* I - Tree node */ +{ +} + + +/* + * 'formGetAttr()' - Get a node attribute value. + */ + +char * /* O - Value or NULL */ +formGetAttr(tree_t *t, /* I - Tree node */ + const char *name) /* I - Name of attribute */ +{ +} + + +/* + * 'formNew()' - Create a new form node. + */ + +tree_t * /* O - New tree node */ +formNew(tree_t *p) /* I - Parent node */ +{ + tree_t *t; /* New tree node */ + + + /* + * Allocate the new node... + */ + + if ((t = (tree_t *)calloc(sizeof(tree_t), 1)) == NULL) + return (NULL); + + /* + * Set/copy attributes... + */ + + if (p == NULL) + { + t->bg[0] = 1.0; + t->bg[1] = 1.0; + t->bg[2] = 1.0; + t->halign = HALIGN_LEFT; + t->valign = VALIGN_MIDDLE; + t->typeface = "Courier"; + t->size = 12.0; + } + else + { + memcpy(t, p, sizeof(tree_t)); + + t->prev = NULL; + t->next = NULL; + t->child = NULL; + t->last_child = NULL; + t->parent = NULL; + t->num_attrs = 0; + t->attrs = NULL; + t->data = NULL; + } + + /* + * Return the new node... + */ + + return (t); +} + + +/* + * 'formRead()' - Read a form tree from a file. + */ + +tree_t * /* O - New form tree */ +formRead(FILE *fp, /* I - File to read from */ + tree_t *p) /* I - Parent node */ +{ + int ch, /* Character from file */ + closech, /* Closing character */ + have_whitespace; /* Leading whitespace? */ + static char s[10240]; /* String from file */ + uchar *ptr, /* Pointer in string */ + glyph[16], /* Glyph name (&#nnn;) */ + *glyphptr; /* Pointer in glyph string */ + tree_t *tree, /* "top" of this tree */ + *t, /* New tree node */ + *prev, /* Previous tree node */ + *temp; /* Temporary looping var */ + uchar *face, /* Typeface for FONT tag */ + *color, /* Color for FONT tag */ + *size; /* Size for FONT tag */ + + + /* + * Start off with no previous tree node... + */ + + prev = NULL; + tree = NULL; + + /* + * Parse data until we hit end-of-file... + */ + + while ((ch = getc(fp)) != EOF) + { + /* + * Ignore leading whitespace... + */ + + have_whitespace = 0; + closech = '/'; + + if (p == NULL || !p->preformatted) + { + while (isspace(ch)) + { + have_whitespace = 1; + ch = getc(fp); + } + + if (ch == EOF) + break; + } + + /* + * Allocate a new tree node - use calloc() to get zeroed data... + */ + + t = formNew(p); + + /* + * See what the character was... + */ + + if (ch == '<') + { + /* + * Markup char; grab the next char to see if this is a /... + */ + + ch = getc(fp); + if (ch == ' ') + { + /* + * Illegal lone "<"! Ignore it... + */ + + free(t); + continue; + } + + if (ch != '/') + ungetc(ch, fp); + + if (parse_element(t, fp) < 0) + { + free(t); + break; + } + + if ((closech = getc(fp)) == '/') + getc(fp); + + /* + * If this is the matching close mark, or if we are starting the same + * element, or if we've completed a list, we're done! + */ + + if (ch == '/') + { + /* + * Close element; find matching element... + */ + + for (temp = p; temp != NULL; temp = temp->p) + if (temp->element == t->element) + break; + + free(t); + + if (temp != NULL) + break; + else + continue; + } + } + else if (t->preformatted) + { + /* + * Read a pre-formatted string into the current tree node... + */ + + ptr = s; + while (ch != '<' && ch != EOF && ptr < (s + sizeof(s) - 1)) + { + if (ch == '&') + { + for (glyphptr = glyph; + (ch = getc(fp)) != EOF && (glyphptr - glyph) < 15; + glyphptr ++) + if (!isalnum(ch)) + break; + else + *glyphptr = ch; + + *glyphptr = '\0'; + if (atoi(glyph) > 0) + ch = atoi(glyph); + else if (strcmp(glyph, "lt") == 0) + ch = '<'; + else if (strcmp(glyph, "gt") == 0) + ch = '>'; + else if (strcmp(glyph, "quot") == 0) + ch = '\''; + else if (strcmp(glyph, "nbsp") == 0) + ch = ' '; + else + ch = '&'; + } + + if (ch != 0) + *ptr++ = ch; + + if (ch == '\n') + break; + + ch = getc(fp); + } + + *ptr = '\0'; + + if (ch == '<') + ungetc(ch, fp); + + t->element = ELEMENT_FRAGMENT; + t->data = strdup(s); + } + else + { + /* + * Read the next string fragment... + */ + + ptr = s; + if (have_whitespace) + *ptr++ = ' '; + + while (!isspace(ch) && ch != '<' && ch != EOF && ptr < (s + sizeof(s) - 1)) + { + if (ch == '&') + { + for (glyphptr = glyph; + (ch = getc(fp)) != EOF && (glyphptr - glyph) < 15; + glyphptr ++) + if (!isalnum(ch)) + break; + else + *glyphptr = ch; + + *glyphptr = '\0'; + if (atoi(glyph) > 0) + ch = atoi(glyph); + else if (strcmp(glyph, "lt") == 0) + ch = '<'; + else if (strcmp(glyph, "gt") == 0) + ch = '>'; + else if (strcmp(glyph, "quot") == 0) + ch = '\''; + else if (strcmp(glyph, "nbsp") == 0) + ch = ' '; + else + ch = '&'; + } + + if (ch != 0) + *ptr++ = ch; + + ch = getc(fp); + } + + if (isspace(ch)) + *ptr++ = ' '; + + *ptr = '\0'; + + if (ch == '<') + ungetc(ch, fp); + + t->element = ELEMENT_FRAGMENT; + t->data = strdup(s); + } + + /* + * If the p tree pointer is not NULL and this is the first + * entry we've read, set the child pointer... + */ + + if (p != NULL && prev == NULL) + p->child = t; + + if (p != NULL) + p->last_child = t; + + /* + * Do the prev/next links... + */ + + t->parent = p; + t->prev = prev; + if (prev != NULL) + prev->next = t; + else + tree = t; + + prev = t; + + /* + * Do child stuff as needed... + */ + + if (closech == '>') + t->child = formRead(t, fp); + } + + return (tree); +} + + +/* + * 'formSetAttr()' - Set a node attribute. + */ + +void +formSetAttr(tree_t *t, /* I - Tree node */ + const char *name, /* I - Attribute name */ + const char *value) /* I - Attribute value */ +{ +} + + +/* + * 'compare_attr()' - Compare two attributes. + */ + +static int /* O - -1 if a0 < a1, etc. */ +compare_attr(attr_t *a0, /* I - First attribute */ + attr_t *a1) /* I - Second attribute */ +{ + return (strcasecmp(a0->name, a1->name)); +} + + +/* + * 'compare_elements()' - Compare two elements. + */ + +static int /* O - -1 if e0 < e1, etc. */ +compare_elements(char **e0, /* I - First element */ + char **e1) /* I - Second element */ +{ + return (strcasecmp(*e0, *e1)); +} + + +/* + * 'parse_attr()' - Parse an element attribute string. + */ + +static int /* O - -1 on error, 0 on success */ +parse_attr(tree_t *t, /* I - Current tree node */ + FILE *fp) /* I - Input file */ +{ + char name[1024], /* Name of attr */ + value[10240], /* Value of attr */ + *ptr; /* Temporary pointer */ + int ch; /* Character from file */ + + + ptr = name; + while ((ch = getc(fp)) != EOF) + if (isalnum(ch)) + { + if (ptr < (name + sizeof(name) - 1)) + *ptr++ = ch; + } + else + break; + + *ptr = '\0'; + + while (isspace(ch) || ch == '\r') + ch = getc(fp); + + switch (ch) + { + default : + ungetc(ch, fp); + return (formSetAttr(t, name, NULL)); + case EOF : + return (-1); + case '=' : + ptr = value; + ch = getc(fp); + + while (isspace(ch) || ch == '\r') + ch = getc(fp); + + if (ch == EOF) + return (-1); + + if (ch == '\'') + { + while ((ch = getc(fp)) != EOF) + if (ch == '\'') + break; + else if (ptr < (value + sizeof(value) - 1)) + *ptr++ = ch; + + *ptr = '\0'; + } + else if (ch == '\"') + { + while ((ch = getc(fp)) != EOF) + if (ch == '\"') + break; + else if (ptr < (value + sizeof(value) - 1)) + *ptr++ = ch; + + *ptr = '\0'; + } + else + { + *ptr++ = ch; + while ((ch = getc(fp)) != EOF) + if (isspace(ch) || ch == '>' || ch == '/' || ch == '\r') + break; + else if (ptr < (value + sizeof(value) - 1)) + *ptr++ = ch; + + *ptr = '\0'; + if (ch == '>' || ch == '/') + ungetc(ch, fp); + } + + return (formSetAttr(t, name, value)); + } +} + + +/* + * 'parse_element()' - Parse an element. + */ + +static int /* O - -1 on error or ELEMENT_nnnn */ +parse_element(tree_t *t, /* I - Current tree node */ + FILE *fp) /* I - Input file */ +{ + int ch; /* Character from file */ + char element[255], /* Element string... */ + *eptr, /* Current character... */ + comment[10240], /* Comment string */ + *cptr, /* Current char... */ + **temp; /* Element variable entry */ + + + eptr = element; + + while ((ch = getc(fp)) != EOF && eptr < (element + sizeof(element) - 1)) + if (ch == '>' || ch == '/' || isspace(ch)) + break; + else + *eptr++ = ch; + + *eptr = '\0'; + + if (ch == EOF) + return (ELEMENT_ERROR); + + eptr = element; + temp = bsearch(&mptr, elements, sizeof(elements) / sizeof(elements[0]), + sizeof(elements[0]), + (int (*)(const void *, const void *))compare_elements); + + if (temp == NULL) + { + /* + * Unrecognized element stuff... + */ + + t->element = ELEMENT_COMMENT; + strcpy(comment, element); + cptr = comment + strlen(comment); + } + else + { + t->element = (element_t)((char **)temp - elements); + cptr = comment; + } + + if (t->element == ELEMENT_COMMENT) + { + while (ch != EOF && ch != '>' && cptr < (comment + sizeof(comment) - 1)) + { + *cptr++ = ch; + ch = getc(fp); + } + + *cptr = '\0'; + t->data = strdup(comment); + } + else + { + while (ch != EOF && ch != '>' && ch != '/') + { + if (!isspace(ch)) + { + ungetc(ch, fp); + parse_variable(t, fp); + } + + ch = getc(fp); + } + + if (ch != EOF) + ungetc(ch, fp); + } + + return (t->element); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/form.h b/filter/form.h new file mode 100644 index 0000000000..2644b2889f --- /dev/null +++ b/filter/form.h @@ -0,0 +1,175 @@ +/* + * "$Id$" + * + * CUPS form header file for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +/* + * Include necessary headers... + */ + +#include "common.h" + + +/* + * Form elements... + */ + +typedef enum +{ + ELEMENT_FILE = -1, /* Pseudo element, not in file, but above */ + ELEMENT_FRAGMENT, /* Text fragment */ + ELEMENT_COMMENT, /* */ + ELEMENT_ARC, + ELEMENT_BOX, + ELEMENT_BR, + ELEMENT_B, + ELEMENT_CUPSFORM, + ELEMENT_DEFVAR, + ELEMENT_FONT, + ELEMENT_H1, + ELEMENT_H2, + ELEMENT_H3, + ELEMENT_H4, + ELEMENT_H5, + ELEMENT_H6, + ELEMENT_HEAD, + ELEMENT_IMG, + ELEMENT_I, + ELEMENT_LINE, + ELEMENT_PAGE, + ELEMENT_PIE, + ELEMENT_POLY, + ELEMENT_PRE, + ELEMENT_P, + ELEMENT_RECT, + ELEMENT_TEXT, + ELEMENT_TT, + ELEMENT_VAR +} element_t; + + +/* + * Font styles... + */ + +typedef enum +{ + STYLE_NORMAL, + STYLE_BOLD, + STYLE_ITALIC, + STYLE_BOLD_ITALIC +} style_t; + + +/* + * Text alignments... + */ + +typedef enum +{ + HALIGN_LEFT, + HALIGN_CENTER, + HALIGN_RIGHT +} halign_t; + +typedef enum +{ + VALIGN_BOTTOM, + VALIGN_CENTER, + VALIGN_TOP +} valign_t; + + +/* + * Text directions... + */ + +typedef enun +{ + DIR_LEFT_TO_RIGHT, + DIR_RIGHT_TO_LEFT +} dir_t; + + +/* + * Attribute structure... + */ + +typedef struct +{ + char *name, /* Name of attribute */ + *value; /* Value of attribute */ +} attr_t; + + +/* + * Form document tree structure... + */ + +typedef struct tree_str +{ + struct tree_str *prev, /* Previous tree node */ + *next, /* Next tree node */ + *parent, /* Parent tree node */ + *child, /* First child node */ + *last_child; /* Last child node */ + element_t element; /* Element type */ + float x, y, w, h; /* Position and size in points */ + float bg[3], fg[3]; /* Colors of element */ + float thickness; /* Thickness of lines */ + int preformatted; /* Preformatted text? */ + float size; /* Height of text in points */ + char *typeface; /* Typeface of text */ + style_t style; /* Style of text */ + halign_t halign; /* Horizontal alignment */ + valign_t valign; /* Vertical alignment */ + dir_t dir; /* Direction of text */ + int num_attrs; /* Number of attributes */ + attr_t *attrs; /* Attributes */ + void *data; /* Text fragment data */ +} tree_t; + + +/* + * Globals... + */ + +extern int NumOptions; /* Number of command-line options */ +extern cups_option_t *Options; /* Command-line options */ +extern ppd_file_t *PPD; /* PPD file */ + + +/* + * Prototypes... + */ + +extern void formDelete(tree_t *t); +extern char *formGetAttr(tree_t *t, const char *name); +extern tree_t *formNew(tree_t *p); +extern tree_t *formRead(FILE *fp, tree_t *p); +extern void formSetAttr(tree_t *t, const char *name, const char *value); +extern void formWrite(tree_t *p); + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgl-attr.c b/filter/hpgl-attr.c new file mode 100644 index 0000000000..6f78a5d8d7 --- /dev/null +++ b/filter/hpgl-attr.c @@ -0,0 +1,446 @@ +/* + * "$Id$" + * + * HP-GL/2 attribute processing for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * CR_color_range() - Set the range for color values. + * AC_anchor_corner() - Set the anchor corner. + * FT_fill_type() - Set the fill type or pattern. + * LA_line_attributes() - Set the line drawing attributes. + * LT_line_type() - Set the line type (style)... + * NP_number_pens() - Set the number of pens to be used. + * PC_pen_color() - Set the pen color... + * PW_pen_width() - Set the pen width. + * RF_raster_fill() - Set the raster fill pattern. + * SM_symbol_mode() - Set where symbols are drawn. + * SP_select_pen() - Select a pen for drawing. + * UL_user_line_type() - Set a user-defined line type. + * WU_width_units() - Set the units used for pen widths. + */ + +/* + * Include necessary headers... + */ + +#include "hpgltops.h" + + +/* + * 'CR_color_range()' - Set the range for color values. + */ + +void +CR_color_range(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + { + /* + * Default to 0 to 255 for all color values. + */ + + ColorRange[0][0] = 0.0; + ColorRange[0][1] = 255.0; + ColorRange[1][0] = 0.0; + ColorRange[1][1] = 255.0; + ColorRange[2][0] = 0.0; + ColorRange[2][1] = 255.0; + } + else if (num_params == 6) + { + /* + * Set the range based on the parameters... + */ + + ColorRange[0][0] = params[0].value.number; + ColorRange[0][1] = params[1].value.number - params[0].value.number; + ColorRange[1][0] = params[2].value.number; + ColorRange[1][1] = params[3].value.number - params[2].value.number; + ColorRange[2][0] = params[4].value.number; + ColorRange[2][1] = params[5].value.number - params[4].value.number; + } + else + fprintf(stderr, "WARNING: HP-GL/2 \'CR\' command with invalid number of parameters (%d)!\n", + num_params); +} + + +/* + * 'AC_anchor_corner()' - Set the anchor corner. + */ + +void +AC_anchor_corner(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'FT_fill_type()' - Set the fill type or pattern. + * + * Note: + * + * This needs to be updated to support non-solid fill. + */ + +void +FT_fill_type(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0 || + params[0].value.number == 1 || + params[0].value.number == 2) + { + /**** SOLID PATTERN ****/ + } +} + + +/* + * 'LA_line_attributes()' - Set the line drawing attributes. + */ + +void +LA_line_attributes(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + int i; /* Looping var */ + + + if (num_params == 0) + { + MiterLimit = 3.0f; + LineCap = 0; + LineJoin = 0; + } + else for (i = 0; i < (num_params - 1); i += 2) + switch ((int)params[i].value.number) + { + case 1 : + LineCap = params[i + 1].value.number == 1 ? 0 : + params[i + 1].value.number == 4 ? 1 : 2; + break; + case 2 : + switch ((int)params[i + 1].value.number) + { + case 1 : + case 2 : + case 3 : + LineJoin = 0; + break; + case 5 : + LineJoin = 2; + break; + default : + LineJoin = 1; + break; + } + break; + case 3 : + MiterLimit = 1.0 + 0.5 * (params[i + 1].value.number - 1.0); + break; + } + + if (PageDirty) + { + printf("%.1f setmiterlimit\n", MiterLimit); + printf("%d setlinecap\n", LineCap); + printf("%d setlinejoin\n", LineJoin); + } +} + + +/* + * 'LT_line_type()' - Set the line type (style)... + * + * Note: + * + * This needs to be updated to support line types. + */ + +void +LT_line_type(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'NP_number_pens()' - Set the number of pens to be used. + */ + +void +NP_number_pens(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + int i; /* Looping var */ + + + if (num_params == 0) + PenCount = 8; + else if (num_params == 1 && params[0].value.number <= 1024) + PenCount = (int)params[0].value.number; + else + fprintf(stderr, "WARNING: HP-GL/2 \'NP\' command with invalid number of parameters (%d)!\n", + num_params); + + for (i = 0; i <= PenCount; i ++) + Pens[i].width = PenWidth; + + PC_pen_color(0, NULL); +} + + +/* + * 'PC_pen_color()' - Set the pen color... + */ + +void +PC_pen_color(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + int i; /* Looping var */ + static float standard_colors[8][3] = /* Standard colors for first 8 pens */ + { + { 1.0, 1.0, 1.0 }, /* White */ + { 0.0, 0.0, 0.0 }, /* Black */ + { 1.0, 0.0, 0.0 }, /* Red */ + { 0.0, 1.0, 0.0 }, /* Green */ + { 1.0, 1.0, 0.0 }, /* Yellow */ + { 0.0, 0.0, 1.0 }, /* Blue */ + { 1.0, 0.0, 1.0 }, /* Magenta */ + { 0.0, 1.0, 1.0 } /* Cyan */ + }; + + if (num_params == 0) + { + for (i = 0; i <= PenCount; i ++) + if (i < 8) + { + Pens[i].rgb[0] = standard_colors[i][0]; + Pens[i].rgb[1] = standard_colors[i][1]; + Pens[i].rgb[2] = standard_colors[i][2]; + } + else + { + Pens[i].rgb[0] = 0.0f; + Pens[i].rgb[1] = 0.0f; + Pens[i].rgb[2] = 0.0f; + } + + if (PageDirty) + printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0], + Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2], + Pens[PenNumber].width * PenScaling); + } + else if (num_params == 1 || num_params == 4) + { + i = (int)params[0].value.number; + + if (num_params == 1) + { + Pens[i].rgb[0] = standard_colors[i & 7][0]; + Pens[i].rgb[1] = standard_colors[i & 7][1]; + Pens[i].rgb[2] = standard_colors[i & 7][2]; + } + else + { + Pens[i].rgb[0] = (params[1].value.number - ColorRange[0][0]) / + (ColorRange[0][1] - ColorRange[0][0]); + Pens[i].rgb[1] = (params[2].value.number - ColorRange[1][0]) / + (ColorRange[1][1] - ColorRange[1][0]); + Pens[i].rgb[2] = (params[3].value.number - ColorRange[2][0]) / + (ColorRange[2][1] - ColorRange[2][0]); + } + + if (PageDirty && i == PenNumber) + printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0], + Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2], + Pens[PenNumber].width * PenScaling); + } + else + fprintf(stderr, "WARNING: HP-GL/2 \'PC\' command with invalid number of parameters (%d)!\n", + num_params); +} + + +/* + * 'PW_pen_width()' - Set the pen width. + */ + +void +PW_pen_width(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + int pen; /* Pen number */ + float w; /* Width value */ + + + if (WidthUnits == 0) + { + /* + * Metric... + */ + + if (num_params == 0) + w = 0.35f / 25.4f * 72.0f; + else + w = params[0].value.number / 25.4f * 72.0f; + } + else + { + /* + * Relative... + */ + + w = (float)hypot(PlotSize[0], PlotSize[1]) / 1016.0f * 72.0f; + + if (num_params == 0) + w *= 0.01f; + else + w *= params[0].value.number; + } + + if (num_params == 2) + { + pen = (int)params[1].value.number; + + Pens[pen].width = w; + + if (PageDirty && pen == PenNumber) + printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0], + Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2], + Pens[PenNumber].width * PenScaling); + } + else if (num_params < 2) + { + /* + * Set width for all pens... + */ + + for (pen = 0; pen <= PenCount; pen ++) + Pens[pen].width = w; + + if (PageDirty) + printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0], + Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2], + Pens[PenNumber].width * PenScaling); + } + else + fprintf(stderr, "WARNING: HP-GL/2 \'PW\' command with invalid number of parameters (%d)!\n", + num_params); +} + + +/* + * 'RF_raster_fill()' - Set the raster fill pattern. + * + * Note: + * + * This needs to be implemented. + */ + +void +RF_raster_fill(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'SM_symbol_mode()' - Set where symbols are drawn. + */ + +void +SM_symbol_mode(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'SP_select_pen()' - Select a pen for drawing. + */ + +void +SP_select_pen(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + PenNumber = 1; + else if (params[0].value.number <= PenCount) + PenNumber = (int)params[0].value.number; + else + fprintf(stderr, "WARNING: HP-GL/2 \'SP\' command with invalid number or value of parameters (%d, %d)!\n", + num_params, (int)params[0].value.number); + + if (PageDirty) + printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0], + Pens[PenNumber].rgb[1], Pens[PenNumber].rgb[2], + Pens[PenNumber].width * PenScaling); +} + + +/* + * 'UL_user_line_type()' - Set a user-defined line type. + */ + +void +UL_user_line_type(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'WU_width_units()' - Set the units used for pen widths. + */ + +void +WU_width_units(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + WidthUnits = 0; + else if (num_params == 1) + WidthUnits = (int)params[0].value.number; + else + fprintf(stderr, "WARNING: HP-GL/2 \'WU\' command with invalid number of parameters (%d)!\n", + num_params); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgl-char.c b/filter/hpgl-char.c new file mode 100644 index 0000000000..5d139b103e --- /dev/null +++ b/filter/hpgl-char.c @@ -0,0 +1,500 @@ +/* + * "$Id$" + * + * HP-GL/2 character processing for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * AD_define_alternate() - Define the alternate font. + * CF_character_fill() - Set whether or not to fill or outline + * characters. + * CP_character_plot() - Move the current pen position for the given + * number of columns and rows. + * DI_absolute_direction() - Set the direction vector for text. + * DR_relative_direction() - Set the relative direction vector for text. + * DT_define_label_term() - Set the label string terminator. + * DV_define_variable_path() - Define a path for text. + * ES_extra_space() - Set extra spacing (kerning) between characters. + * LB_label() - Display a label string. + * LO_label_origin() - Set the label origin. + * SA_select_alternate() - Select the alternate font. + * SD_define_standard() - Define the standard font... + * SI_absolute_size() - Set the absolute size of text. + * SL_character_slant() - Set the slant of text. + * SR_relative_size() - Set the relative size of text. + * SS_select_standard() - Select the standard font for text. + * TD_transparent_data() - Send transparent print data. + */ + +/* + * Include necessary headers... + */ + +#include "hpgltops.h" + + +/* + * 'AD_define_alternate()' - Define the alternate font. + */ + +void +AD_define_alternate(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + int i; /* Looping var */ + + + /* + * Set default font attributes... + */ + + AlternateFont.typeface = 48; + AlternateFont.posture = 0; + AlternateFont.weight = 0; + AlternateFont.height = 11.5; + + /* + * Loop through parameter value pairs... + */ + + for (i = 0; i < (num_params - 1); i += 2) + switch ((int)params[i].value.number) + { + case 4 : + AlternateFont.height = params[i + 1].value.number; + break; + case 5 : + AlternateFont.posture = (int)params[i + 1].value.number; + break; + case 6 : + AlternateFont.weight = (int)params[i + 1].value.number; + break; + case 7 : + AlternateFont.typeface = (int)params[i + 1].value.number; + break; + } + + /* + * Define the font... + */ + + if (PageDirty) + printf("/SA {\n" + " /%s%s%s%s findfont\n" + " [ %f %f %f %f 0.0 0.0 ] makefont\n" + " setfont\n" + "} bind def\n", + AlternateFont.typeface == 48 ? "Courier" : "Helvetica", + (AlternateFont.weight != 0 || AlternateFont.posture != 0) ? "-" : "", + AlternateFont.weight != 0 ? "Bold" : "", + AlternateFont.posture != 0 ? "Oblique" : "", + AlternateFont.x * AlternateFont.height, + -AlternateFont.y * AlternateFont.height, + AlternateFont.y * AlternateFont.height, + AlternateFont.x * AlternateFont.height); + + CharHeight[1] = AlternateFont.height; +} + + +/* + * 'CF_character_fill()' - Set whether or not to fill or outline characters. + */ + +void +CF_character_fill(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + CharFillMode = 0; + else + CharFillMode = (int)params[0].value.number; + + if (num_params == 2) + CharPen = (int)params[1].value.number; +} + + +/* + * 'CP_character_plot()' - Move the current pen position for the given number + * of columns and rows. + */ + +void +CP_character_plot(int num_params, + param_t *params) +{ + if (num_params < 2) + return; + + switch (Rotation) + { + case 0: + PenPosition[0] += params[0].value.number * 1.2f / CharHeight[CharFont]; + PenPosition[1] += params[1].value.number * CharHeight[CharFont]; + break; + case 90: + PenPosition[0] -= params[1].value.number * 1.2f / CharHeight[CharFont]; + PenPosition[1] += params[0].value.number * CharHeight[CharFont]; + break; + case 180: + PenPosition[0] -= params[0].value.number * 1.2f / CharHeight[CharFont]; + PenPosition[1] -= params[1].value.number * CharHeight[CharFont]; + break; + case 270: + PenPosition[0] += params[1].value.number * 1.2f / CharHeight[CharFont]; + PenPosition[1] -= params[0].value.number * CharHeight[CharFont]; + break; + } +} + + +/* + * 'DI_absolute_direction()' - Set the direction vector for text. + */ + +void +DI_absolute_direction(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (CharFont) + { + if (num_params == 2) + { + AlternateFont.x = params[0].value.number; + AlternateFont.y = params[1].value.number; + } + + if (PageDirty) + { + printf("/SA {\n" + " /%s%s%s%s findfont\n" + " [ %f %f %f %f 0.0 0.0 ] makefont\n" + " setfont\n" + "} bind def\n", + AlternateFont.typeface == 48 ? "Courier" : "Helvetica", + (AlternateFont.weight != 0 || AlternateFont.posture != 0) ? "-" : "", + AlternateFont.weight != 0 ? "Bold" : "", + AlternateFont.posture != 0 ? "Oblique" : "", + AlternateFont.x * AlternateFont.height, + -AlternateFont.y * AlternateFont.height, + AlternateFont.y * AlternateFont.height, + AlternateFont.x * AlternateFont.height); + puts("SA"); + } + } + else + { + if (num_params == 2) + { + StandardFont.x = params[0].value.number; + StandardFont.y = params[1].value.number; + } + + if (PageDirty) + { + printf("/SS {\n" + " /%s%s%s%s findfont\n" + " [ %f %f %f %f 0.0 0.0 ] makefont\n" + " setfont\n" + "} bind def\n", + StandardFont.typeface == 48 ? "Courier" : "Helvetica", + (StandardFont.weight != 0 || StandardFont.posture != 0) ? "-" : "", + StandardFont.weight != 0 ? "Bold" : "", + StandardFont.posture != 0 ? "Oblique" : "", + StandardFont.x * StandardFont.height, + -StandardFont.y * StandardFont.height, + StandardFont.y * StandardFont.height, + StandardFont.x * StandardFont.height); + puts("SS"); + } + } +} + + +/* + * 'DR_relative_direction()' - Set the relative direction vector for text. + */ + +void +DR_relative_direction(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'DT_define_label_term()' - Set the label string terminator. + */ + +void +DT_define_label_term(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + StringTerminator = '\003'; + else + StringTerminator = params[0].value.string[0]; +} + + +/* + * 'DV_define_variable_path()' - Define a path for text. + */ + +void +DV_define_variable_path(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'ES_extra_space()' - Set extra spacing (kerning) between characters. + */ + +void +ES_extra_space(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'LB_label()' - Display a label string. + */ + +void +LB_label(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + char *s; /* Pointer into string */ + + + if (num_params == 0) + return; + + Outputf("gsave\n"); + Outputf("currentmiterlimit 1.0 \n"); + Outputf("MP\n"); + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + + Outputf("("); + for (s = params[0].value.string; *s != '\0'; s ++) + if (strchr("()\\", *s) != NULL) + Outputf("\\%c", *s); + else + Outputf("%c", *s); + Outputf(") true charpath\n"); + + if (CharFillMode != 1) + Outputf("FI\n"); + if (CharFillMode == 1 || CharFillMode == 3) + { + Outputf("%.3f %.3f %.3f %.2f SP ST\n", Pens[CharPen].rgb[0], + Pens[CharPen].rgb[CharPen], Pens[CharPen].rgb[2], + Pens[CharPen].width * PenScaling); + Outputf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0], + Pens[PenNumber].rgb[PenNumber], Pens[PenNumber].rgb[2], + Pens[PenNumber].width * PenScaling); + } + + Outputf("setmiterlimit\n"); + Outputf("grestore\n"); +} + + +/* + * 'LO_label_origin()' - Set the label origin. + */ + +void +LO_label_origin(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'SA_select_alternate()' - Select the alternate font. + */ + +void +SA_select_alternate(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; + + if (PageDirty) + puts("SA"); + + CharFont = 1; +} + + +/* + * 'SD_define_standard()' - Define the standard font... + */ + +void +SD_define_standard(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + int i; /* Looping var */ + + + /* + * Set default font attributes... + */ + + StandardFont.typeface = 48; + StandardFont.posture = 0; + StandardFont.weight = 0; + StandardFont.height = 11.5; + StandardFont.x = 1.0; + StandardFont.y = 0.0; + + /* + * Loop through parameter value pairs... + */ + + for (i = 0; i < (num_params - 1); i += 2) + switch ((int)params[i].value.number) + { + case 4 : + StandardFont.height = params[i + 1].value.number; + break; + case 5 : + StandardFont.posture = (int)params[i + 1].value.number; + break; + case 6 : + StandardFont.weight = (int)params[i + 1].value.number; + break; + case 7 : + StandardFont.typeface = (int)params[i + 1].value.number; + break; + } + + /* + * Define the font... + */ + + if (PageDirty) + printf("/SS {\n" + " /%s%s%s%s findfont\n" + " [ %f %f %f %f 0.0 0.0 ] makefont\n" + " setfont\n" + "} bind def\n", + StandardFont.typeface == 48 ? "Courier" : "Helvetica", + (StandardFont.weight != 0 || StandardFont.posture != 0) ? "-" : "", + StandardFont.weight != 0 ? "Bold" : "", + StandardFont.posture != 0 ? "Oblique" : "", + StandardFont.x * StandardFont.height, + -StandardFont.y * StandardFont.height, + StandardFont.y * StandardFont.height, + StandardFont.x * StandardFont.height); + + CharHeight[0] = StandardFont.height; +} + + +/* + * 'SI_absolute_size()' - Set the absolute size of text. + */ + +void +SI_absolute_size(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'SL_character_slant()' - Set the slant of text. + */ + +void +SL_character_slant(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'SR_relative_size()' - Set the relative size of text. + */ + +void +SR_relative_size(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'SS_select_standard()' - Select the standard font for text. + */ + +void +SS_select_standard(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; + + if (PageDirty) + puts("SS"); + + CharFont = 0; +} + + +/* + * 'TD_transparent_data()' - Send transparent print data. + */ + +void +TD_transparent_data(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgl-config.c b/filter/hpgl-config.c new file mode 100644 index 0000000000..d4c76d7cef --- /dev/null +++ b/filter/hpgl-config.c @@ -0,0 +1,638 @@ +/* + * "$Id$" + * + * HP-GL/2 configuration routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * update_transform() - Update the page transformation matrix as needed. + * BP_begin_plot() - Start a plot... + * DF_default_values() - Set all state info to the default values. + * IN_initialize() - Initialize the plotter. + * IP_input_absolute() - Set P1 and P2 values for the plot. + * IR_input_relative() - Update P1 and P2. + * IW_input_window() - Setup an input window. + * PG_advance_page() - Eject the current page. + * PS_plot_size() - Set the plot size. + * RO_rotate() - Rotate the plot. + * RP_replot() - Replot the current page. + * SC_scale() - Set user-defined scaling. + */ + +/* + * Include necessary headers... + */ + +#include "hpgltops.h" + + +/* + * 'update_transform()' - Update the page transformation matrix as needed. + */ + +void +update_transform(void) +{ + float page_width, /* Actual page width */ + page_height; /* Actual page height */ + float scaling; /* Scaling factor */ + float left, right, /* Scaling window */ + bottom, top; + float width, height; /* Scaling width and height */ + float iw1[2], iw2[2]; /* Clipping window */ + + + /* + * Get the page and input window sizes... + */ + + if (FitPlot) + { + page_width = PageRight - PageLeft; + page_height = PageTop - PageBottom; + } + else + { + page_width = (P2[0] - P1[0]) * 72.0f / 1016.0f; + page_height = (P2[1] - P1[1]) * 72.0f / 1016.0f; + } + + fprintf(stderr, "DEBUG: page_width = %.0f, page_height = %.0f\n", + page_width, page_height); + + if (page_width == 0 || page_height == 0) + return; + + /* + * Set the scaling window... + */ + + switch (ScalingType) + { + default : /* No user scaling */ + left = P1[0]; + bottom = P1[1]; + right = P2[0]; + top = P2[1]; + break; + + case 0 : /* Anisotropic (non-uniform) scaling */ + left = Scaling1[0]; + bottom = Scaling1[1]; + right = Scaling2[0]; + top = Scaling2[1]; + break; + + case 1 : /* Isotropic (uniform) scaling */ + left = Scaling1[0]; + bottom = Scaling1[1]; + right = Scaling2[0]; + top = Scaling2[1]; + + width = right - left; + height = top - bottom; + + if (width == 0 || height == 0) + return; + + if ((width * page_height) != (height * page_width)) + { + scaling = height * page_width / page_height; + if (width < scaling) + { + width = scaling; + left = 0.5f * (left + right - width); + right = left + width; + } + else + { + height = width * page_height / page_width; + bottom = 0.5f * (bottom + top - height); + top = bottom + height; + } + } + break; + + case 2 : + left = Scaling1[0]; + bottom = Scaling1[1]; + right = left + page_width * Scaling2[0]; + top = bottom + page_height * Scaling2[1]; + break; + } + + width = right - left; + height = top - bottom; + + if (width == 0 || height == 0) + return; + + /* + * Scale the plot as needed... + */ + + if (Rotation == 0 || Rotation == 180) + scaling = page_width / width; + else + scaling = page_width / height; + + if (FitPlot) + { + if (Rotation == 0 || Rotation == 180) + scaling *= page_width / PlotSize[1]; + else + scaling *= page_width / PlotSize[0]; + } + + /* + * Offset for the current P1 location... + */ + + if (FitPlot) + { + left = 0; + bottom = 0; + } + else + { + left = P1[0] * 72.0f / 1016.0f; + bottom = P1[1] * 72.0f / 1016.0f; + } + + /* + * Generate a new transformation matrix... + */ + + switch (Rotation) + { + case 0 : + Transform[0][0] = scaling; + Transform[0][1] = 0.0; + Transform[0][2] = -left; + Transform[1][0] = 0.0; + Transform[1][1] = scaling; + Transform[1][2] = -bottom; + break; + + case 90 : + Transform[0][0] = 0.0; + Transform[0][1] = -scaling; + Transform[0][2] = PageLength - left; + Transform[1][0] = scaling; + Transform[1][1] = 0.0; + Transform[1][2] = -bottom; + break; + + case 180 : + Transform[0][0] = -scaling; + Transform[0][1] = 0.0; + Transform[0][2] = PageLength - left; + Transform[1][0] = 0.0; + Transform[1][1] = -scaling; + Transform[1][2] = PageWidth - bottom; + break; + + case 270 : + Transform[0][0] = 0.0; + Transform[0][1] = scaling; + Transform[0][2] = -left; + Transform[1][0] = -scaling; + Transform[1][1] = 0.0; + Transform[1][2] = PageWidth - bottom; + break; + } + + fprintf(stderr, "DEBUG: Transform = [ %.3f %.3f\n" + "DEBUG: %.3f %.3f\n" + "DEBUG: %.3f %.3f ]\n", + Transform[0][0], Transform[1][0], Transform[0][1], + Transform[1][1], Transform[0][2], Transform[1][2]); + + if (FitPlot) + { + if (Rotation == 0 || Rotation == 180) + PenScaling *= page_width / PlotSize[1]; + else + PenScaling *= page_width / PlotSize[0]; + } + else + PenScaling = 1.0; + + if (PenScaling < 0.0) + PenScaling = -PenScaling; + + if (PageDirty) + { + printf("%.2f setlinewidth\n", Pens[PenNumber].width * PenScaling); + + if (IW1[0] != IW2[0] && IW1[1] != IW2[1]) + { + iw1[0] = IW1[0] * 72.0f / 1016.0f; + iw1[1] = IW1[1] * 72.0f / 1016.0f; + iw2[0] = IW2[0] * 72.0f / 1016.0f; + iw2[1] = IW2[1] * 72.0f / 1016.0f; + + printf("initclip MP %.3f %.3f MO %.3f %.3f LI %.3f %.3f LI %.3f %.3f LI CP clip\n", + iw1[0], iw1[1], iw1[0], iw2[1], iw2[0], iw2[1], iw2[0], iw1[1]); + } + } +} + + +/* + * 'BP_begin_plot()' - Start a plot... + */ + +void +BP_begin_plot(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'DF_default_values()' - Set all state info to the default values. + */ + +void +DF_default_values(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; + + AC_anchor_corner(0, NULL); + AD_define_alternate(0, NULL); + SD_define_standard(0, NULL); + CF_character_fill(0, NULL); + DI_absolute_direction(0, NULL); + DT_define_label_term(0, NULL); + DV_define_variable_path(0, NULL); + ES_extra_space(0, NULL); + FT_fill_type(0, NULL); + IW_input_window(0, NULL); + LA_line_attributes(0, NULL); + LO_label_origin(0, NULL); + LT_line_type(0, NULL); + PA_plot_absolute(0, NULL); + PolygonMode = 0; + RF_raster_fill(0, NULL); + SC_scale(0, NULL); + SM_symbol_mode(0, NULL); + SS_select_standard(0, NULL); + TD_transparent_data(0, NULL); + UL_user_line_type(0, NULL); +} + + +/* + * 'IN_initialize()' - Initialize the plotter. + */ + +void +IN_initialize(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; + + DF_default_values(0, NULL); + PU_pen_up(0, NULL); + RO_rotate(0, NULL); + PS_plot_size(0, NULL); + WU_width_units(0, NULL); + PW_pen_width(0, NULL); + + PenWidth = 1; + + PenPosition[0] = PenPosition[1] = 0.0; +} + + +/* + * 'IP_input_absolute()' - Set P1 and P2 values for the plot. + */ + +void +IP_input_absolute(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + { + P1[0] = PageLeft / 72.0f * 1016.0f; + P1[1] = PageBottom / 72.0f * 1016.0f; + P2[0] = PageRight / 72.0f * 1016.0f; + P2[1] = PageTop / 72.0f * 1016.0f; + } + else if (num_params == 2) + { + P2[0] -= P1[0]; + P2[1] -= P1[1]; + P1[0] = params[0].value.number; + P1[1] = params[1].value.number; + P2[0] += P1[0]; + P2[1] += P1[1]; + } + else if (num_params == 4) + { + P1[0] = params[0].value.number; + P1[1] = params[1].value.number; + P2[0] = params[2].value.number; + P2[1] = params[3].value.number; + } + + IW1[0] = 0.0; + IW1[1] = 0.0; + IW2[0] = 0.0; + IW2[1] = 0.0; + + if (ScalingType < 0) + { + Scaling1[0] = P1[0]; + Scaling1[0] = P1[1]; + Scaling2[0] = P2[0]; + Scaling2[1] = P2[1]; + } + + update_transform(); +} + + +/* + * 'IR_input_relative()' - Update P1 and P2. + */ + +void +IR_input_relative(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + { + P1[0] = PageLeft / 72.0f * 1016.0f; + P1[1] = PageBottom / 72.0f * 1016.0f; + P2[0] = PageRight / 72.0f * 1016.0f; + P2[1] = PageTop / 72.0f * 1016.0f; + } + else if (num_params == 2) + { + P2[0] -= P1[0]; + P2[1] -= P1[1]; + P1[0] = params[0].value.number * PlotSize[0] / 72.0f * 1016.0f / 100.0f; + P1[1] = params[1].value.number * PlotSize[1] / 72.0f * 1016.0f / 100.0f; + P2[0] += P1[0]; + P2[1] += P1[1]; + } + else if (num_params == 4) + { + P1[0] = params[0].value.number * PlotSize[0] / 72.0f * 1016.0f / 100.0f; + P1[1] = params[1].value.number * PlotSize[1] / 72.0f * 1016.0f / 100.0f; + P2[0] = params[2].value.number * PlotSize[0] / 72.0f * 1016.0f / 100.0f; + P2[1] = params[3].value.number * PlotSize[1] / 72.0f * 1016.0f / 100.0f; + } + + IW1[0] = 0.0; + IW1[1] = 0.0; + IW2[0] = 0.0; + IW2[1] = 0.0; + + if (ScalingType < 0) + { + Scaling1[0] = P1[0]; + Scaling1[0] = P1[1]; + Scaling2[0] = P2[0]; + Scaling2[1] = P2[1]; + } + + update_transform(); +} + + +/* + * 'IW_input_window()' - Setup an input window. + */ + +void +IW_input_window(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + { + IW1[0] = PageLeft / 72.0f * 1016.0f; + IW1[1] = PageBottom / 72.0f * 1016.0f; + IW2[0] = PageRight / 72.0f * 1016.0f; + IW2[1] = PageTop / 72.0f * 1016.0f; + } + else if (num_params == 4) + { + + if (ScalingType < 0) + { + IW1[0] = params[0].value.number; + IW1[1] = params[1].value.number; + IW2[0] = params[2].value.number; + IW2[1] = params[3].value.number; + } + else + { + IW1[0] = (Transform[0][0] * params[0].value.number + + Transform[0][1] * params[1].value.number + + Transform[0][2]) / 72.0f * 1016.0f; + IW1[1] = (Transform[1][0] * params[0].value.number + + Transform[1][1] * params[1].value.number + + Transform[1][2]) / 72.0f * 1016.0f; + IW2[0] = (Transform[0][0] * params[2].value.number + + Transform[0][1] * params[3].value.number + + Transform[0][2]) / 72.0f * 1016.0f; + IW2[1] = (Transform[1][0] * params[2].value.number + + Transform[1][1] * params[3].value.number + + Transform[1][2]) / 72.0f * 1016.0f; + } + + fprintf(stderr, "DEBUG: IW%.0f,%.0f,%.0f,%.0f = [ %.0f %.0f %.0f %.0f ]\n", + params[0].value.number, params[1].value.number, + params[2].value.number, params[3].value.number, + IW1[0], IW1[1], IW2[0], IW2[1]); + } + + + update_transform(); +} + + +/* + * 'PG_advance_page()' - Eject the current page. + */ + +void +PG_advance_page(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; + + if (PageDirty) + { + puts("grestore"); + puts("showpage"); + + PageDirty = 0; + } +} + + +/* + * 'PS_plot_size()' - Set the plot size. + */ + +void +PS_plot_size(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + switch (num_params) + { + case 0 : /* PS ; */ + if (Rotation == 0 || Rotation == 180) + { + PlotSize[0] = PageWidth; + PlotSize[1] = PageLength; + } + else + { + PlotSize[0] = PageLength; + PlotSize[1] = PageWidth; + } + break; + case 1 : /* PS length ; */ + if (Rotation == 0 || Rotation == 180) + { + PlotSize[1] = 72.0f * params[0].value.number / 1016.0f; + PlotSize[0] = 0.75f * PlotSize[1]; + } + else + { + PlotSize[0] = 72.0f * params[0].value.number / 1016.0f; + PlotSize[1] = 0.75f * PlotSize[0]; + } + break; + case 2 : /* PS length, width ; */ + /* + * Unfortunately, it appears that NO application correctly + * sends a two-argument PS command as documented in the + * HP-GL/2 Reference Manual from HP. Instead, applications + * send the width before the length, which causes all sorts + * of problems. + * + * Rather than fight it, we now look for them as width,length + * instead of length,width. + * + * Don't like it? Send mail to the folks that make Ideas, Pro/E, + * AutoCAD, etc. + */ + + if (Rotation == 0 || Rotation == 180) + { + PlotSize[0] = 72.0f * params[0].value.number / 1016.0f; + PlotSize[1] = 72.0f * params[1].value.number / 1016.0f; + } + else + { + PlotSize[0] = 72.0f * params[1].value.number / 1016.0f; + PlotSize[1] = 72.0f * params[0].value.number / 1016.0f; + } + break; + } + + /* + * This is required for buggy files that don't set the input window. + */ + + IP_input_absolute(0, NULL); +} + + +/* + * 'RO_rotate()' - Rotate the plot. + */ + +void +RO_rotate(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + Rotation = 0; + else + Rotation = (int)params[0].value.number; + + update_transform(); +} + + +/* + * 'RP_replot()' - Replot the current page. + */ + +void +RP_replot(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; +} + + +/* + * 'SC_scale()' - Set user-defined scaling. + */ + +void +SC_scale(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0) + { + ScalingType = -1; + Scaling1[0] = P1[0]; + Scaling1[0] = P1[1]; + Scaling2[0] = P2[0]; + Scaling2[1] = P2[1]; + } + else if (num_params > 3) + { + Scaling1[0] = params[0].value.number; + Scaling2[0] = params[1].value.number; + Scaling1[1] = params[2].value.number; + Scaling2[1] = params[3].value.number; + + if (num_params > 4) + ScalingType = (int)params[4].value.number; + else + ScalingType = 1; + } + + update_transform(); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgl-input.c b/filter/hpgl-input.c new file mode 100644 index 0000000000..720122ee17 --- /dev/null +++ b/filter/hpgl-input.c @@ -0,0 +1,232 @@ +/* + * "$Id$" + * + * HP-GL/2 input processing for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ParseCommand() - Parse an HPGL/2 command. + * FreeParameters() - Free all string parameter values. + */ + +/* + * Include necessary headers... + */ + +#include "hpgltops.h" +#include + +#define MAX_PARAMS 16384 + + +/* + * 'ParseCommand()' - Parse an HPGL/2 command. + * + * Returns the number of parameters seen or -1 on EOF. + */ + +int /* O - -1 on EOF, # params otherwise */ +ParseCommand(FILE *fp, /* I - File to read from */ + char *name, /* O - Name of command */ + param_t **params) /* O - Parameter list */ +{ + int num_params, /* Number of parameters seen */ + ch, /* Current char */ + done, /* Non-zero when the current command is read */ + i; /* Looping var */ + char buf[262144]; /* String buffer */ + static param_t p[MAX_PARAMS]; /* Parameter buffer */ + + + num_params = 0; + done = 0; + + do + { + while ((ch = getc(fp)) != EOF) + if (strchr(" \t\r\n,;", ch) == NULL) + break; + + if (ch == EOF) + return (-1); + + if (ch == 0x1b) + switch (getc(fp)) + { + case '.' : /* HP-GL/2 job control */ + i = getc(fp); + + if (strchr(")Z", i) != NULL) + { + /* + * 'Printer Off' command - look for next 'Printer On' command... + */ + + for (;;) + { + while ((i = getc(fp)) != EOF && i != 0x1b); + + if (i == EOF) + return (-1); + + if (getc(fp) != '.') + continue; + + if ((i = getc(fp)) == '(' || + i == 'Y') + break; + } + } + else if (strchr("@HIMNTI\003", i) != NULL) + { + while ((i = getc(fp)) != EOF && i != ':'); + } + break; + + default : /* HP RTL/PCL control */ + while ((i = getc(fp)) != EOF && !isupper(i)); + break; + } + } while (ch == 0x1b); + + name[0] = ch; + name[1] = getc(fp); + name[2] = '\0'; + + if (strcasecmp(name, "LB") == 0) + { + for (i = 0; (ch = getc(fp)) != StringTerminator; i ++) + buf[i] = ch; + buf[i] = '\0'; + p[num_params].type = PARAM_STRING; + p[num_params].value.string = strdup(buf); + num_params ++; + } + else if (strcasecmp(name, "SM") == 0) + { + buf[0] = getc(fp); + buf[1] = '\0'; + p[num_params].type = PARAM_STRING; + p[num_params].value.string = strdup(buf); + num_params ++; + } + else if (strcasecmp(name, "DT") == 0) + { + if ((buf[0] = getc(fp)) != ';') + { + buf[1] = '\0'; + p[num_params].type = PARAM_STRING; + p[num_params].value.string = strdup(buf); + num_params ++; + } + } + else if (strcasecmp(name, "PE") == 0) + { + for (i = 0; i < (sizeof(buf) - 1); i ++) + if ((buf[i] = getc(fp)) == ';') + break; + + buf[i] = '\0'; + p[num_params].type = PARAM_STRING; + p[num_params].value.string = strdup(buf); + num_params ++; + } + + while (!done) + switch (ch = getc(fp)) + { + case ',' : + case ' ' : + case '\n' : + case '\r' : + case '\t' : + break; + + case '\"' : + fscanf(fp, "%262143[^\"]\"", buf); + if (num_params < MAX_PARAMS) + { + p[num_params].type = PARAM_STRING; + p[num_params].value.string = strdup(buf); + num_params ++; + }; + break; + + case '-' : + case '+' : + ungetc(ch, fp); + fscanf(fp, "%f", &(p[num_params].value.number)); + if (num_params < MAX_PARAMS) + { + p[num_params].type = PARAM_RELATIVE; + num_params ++; + } + break; + case '0' : + case '1' : + case '2' : + case '3' : + case '4' : + case '5' : + case '6' : + case '7' : + case '8' : + case '9' : + case '.' : + ungetc(ch, fp); + fscanf(fp, "%f", &(p[num_params].value.number)); + if (num_params < MAX_PARAMS) + { + p[num_params].type = PARAM_ABSOLUTE; + num_params ++; + } + break; + default : + ungetc(ch, fp); + done = 1; + break; + } + + *params = p; + return (num_params); +} + + +/* + * 'FreeParameters()' - Free all string parameter values. + */ + +void +FreeParameters(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameter values */ +{ + int i; /* Looping var */ + + + for (i = 0; i < num_params; i ++) + if (params[i].type == PARAM_STRING) + free(params[i].value.string); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgl-main.c b/filter/hpgl-main.c new file mode 100644 index 0000000000..117c21c9aa --- /dev/null +++ b/filter/hpgl-main.c @@ -0,0 +1,255 @@ +/* + * "$Id$" + * + * HP-GL/2 filter main entry for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry for HP-GL/2 filter. + * compare_names() - Compare two command names. + */ + +/* + * Include necessary headers... + */ + +/*#define DEBUG*/ +#define _HPGL_MAIN_C_ +#include "hpgltops.h" + + +/* + * HP-GL/2 command table... + */ + +typedef struct +{ + char name[4]; /* Name of command */ + void (*func)(int, param_t *); /* Function to call */ +} name_t; + +static name_t commands[] = +{ + { "BP", BP_begin_plot }, + { "DF", DF_default_values }, + { "IN", IN_initialize }, + { "IP", IP_input_absolute }, + { "IR", IR_input_relative }, + { "IW", IW_input_window }, + { "PG", PG_advance_page }, + { "RO", RO_rotate }, + { "RP", RP_replot }, + { "SC", SC_scale }, + { "AA", AA_arc_absolute }, + { "AR", AR_arc_relative }, + { "AT", AT_arc_absolute3 }, + { "CI", CI_circle }, + { "PA", PA_plot_absolute }, + { "PD", PD_pen_down }, + { "PE", PE_polyline_encoded }, + { "PR", PR_plot_relative }, + { "PS", PS_plot_size }, + { "PU", PU_pen_up }, + { "RT", RT_arc_relative3 }, + { "EA", EA_edge_rect_absolute }, + { "EP", EP_edge_polygon }, + { "ER", ER_edge_rect_relative }, + { "EW", EW_edge_wedge }, + { "FP", FP_fill_polygon }, + { "PM", PM_polygon_mode }, + { "RA", RA_fill_rect_absolute }, + { "RR", RR_fill_rect_relative }, + { "WG", WG_fill_wedge }, + { "AD", AD_define_alternate }, + { "CF", CF_character_fill }, + { "CP", CP_character_plot }, + { "DI", DI_absolute_direction }, + { "DR", DR_relative_direction }, + { "DT", DT_define_label_term }, + { "DV", DV_define_variable_path }, + { "ES", ES_extra_space }, + { "LB", LB_label }, + { "LO", LO_label_origin }, + { "SA", SA_select_alternate }, + { "SD", SD_define_standard }, + { "SI", SI_absolute_size }, + { "SL", SL_character_slant }, + { "SR", SR_relative_size }, + { "SS", SS_select_standard }, + { "TD", TD_transparent_data }, + { "AC", AC_anchor_corner }, + { "FT", FT_fill_type }, + { "LA", LA_line_attributes }, + { "LT", LT_line_type }, + { "NP", NP_number_pens }, + { "PC", PC_pen_color }, + { "CR", CR_color_range }, + { "PW", PW_pen_width }, + { "RF", RF_raster_fill }, + { "SM", SM_symbol_mode }, + { "SP", SP_select_pen }, + { "UL", UL_user_line_type }, + { "WU", WU_width_units } +}; +#define NUM_COMMANDS (sizeof(commands) / sizeof(name_t)) + + +/* + * Local functions... + */ + +static int compare_names(const void *p1, const void *p2); + + +/* + * 'main()' - Main entry for HP-GL/2 filter. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + FILE *fp; /* Input file */ + int num_params; /* Number of parameters */ + param_t *params; /* Command parameters */ + name_t *command, /* Command */ + name; /* Name of command */ + int num_options; /* Number of print options */ + cups_option_t *options; /* Print options */ + const char *val; /* Option value */ + int shading; /* -1 = black, 0 = grey, 1 = color */ + + + if (argc < 6 || argc > 7) + { + fputs("ERROR: hpgltops job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + fp = stdin; + else + { + /* + * Try to open the print file... + */ + + if ((fp = fopen(argv[6], "rb")) == NULL) + { + perror("ERROR: unable to open print file - "); + return (1); + } + } + + /* + * Process command-line options and write the prolog... + */ + + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + + PPD = SetCommonOptions(num_options, options, 1); + + PlotSize[0] = PageWidth; + PlotSize[1] = PageLength; + + shading = 1; + PenWidth = 1.0; + + if ((val = cupsGetOption("blackplot", num_options, options)) != NULL) + shading = 0; + + if ((val = cupsGetOption("fitplot", num_options, options)) != NULL) + FitPlot = 1; + + if ((val = cupsGetOption("penwidth", num_options, options)) != NULL) + PenWidth = (float)atoi(val) * 0.001f; + + /* + * Write the PostScript prolog and initialize the plotting "engine"... + */ + + OutputProlog(argv[3], argv[2], shading); + + IP_input_absolute(0, NULL); + + /* + * Sort the command array... + */ + + qsort(commands, NUM_COMMANDS, sizeof(name_t), + (int (*)(const void *, const void *))compare_names); + + /* + * Read commands until we reach the end of file. + */ + + while ((num_params = ParseCommand(fp, name.name, ¶ms)) >= 0) + { +#ifdef DEBUG + { + int i; + fprintf(stderr, "DEBUG: %s(%d)", name.name, num_params); + for (i = 0; i < num_params; i ++) + if (params[i].type == PARAM_STRING) + fprintf(stderr, " \'%s\'", params[i].value.string); + else + fprintf(stderr, " %f", params[i].value.number); + fputs("\n", stderr); + } +#endif /* DEBUG */ + + if ((command = bsearch(&name, commands, NUM_COMMANDS, sizeof(name_t), + (int (*)(const void *, const void *))compare_names)) != NULL) + (*command->func)(num_params, params); + + FreeParameters(num_params, params); + } + + OutputTrailer(); + + if (fp != stdin) + fclose(fp); + + return (0); +} + + +/* + * 'compare_names()' - Compare two command names. + */ + +static int /* O - Result of strcasecmp() on names */ +compare_names(const void *p1, /* I - First name */ + const void *p2) /* I - Second name */ +{ + return (strcasecmp(((name_t *)p1)->name, ((name_t *)p2)->name)); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgl-polygon.c b/filter/hpgl-polygon.c new file mode 100644 index 0000000000..c6646a6e55 --- /dev/null +++ b/filter/hpgl-polygon.c @@ -0,0 +1,380 @@ +/* + * "$Id$" + * + * HP-GL/2 polygon routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * EA_edge_rect_absolute() - Draw a rectangle. + * EP_edge_polygon() - Stroke the edges of a polygon. + * ER_edge_rect_relative() - Draw a rectangle relative to the current + * EW_edge_wedge() - Draw a pie wedge. + * FP_fill_polygon() - Fill a polygon. + * PM_polygon_mode() - Set the polygon drawing mode. + * RA_fill_rect_absolute() - Fill a rectangle. + * RR_fill_rect_relative() - Fill a rectangle relative to the current + * WG_fill_wedge() - Fill a pie wedge. + */ + +/* + * Include necessary headers... + */ + +#include "hpgltops.h" + + +/* + * 'EA_edge_rect_absolute()' - Draw a rectangle. + */ + +void +EA_edge_rect_absolute(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + float x, y; /* Transformed coordinates */ + + + if (num_params < 2) + return; + + x = Transform[0][0] * params[0].value.number + + Transform[0][1] * params[1].value.number + + Transform[0][2]; + y = Transform[1][0] * params[0].value.number + + Transform[1][1] * params[1].value.number + + Transform[1][2]; + + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + Outputf("%.3f %.3f LI\n", PenPosition[0], y); + Outputf("%.3f %.3f LI\n", x, y); + Outputf("%.3f %.3f LI\n", x, PenPosition[1]); + + Outputf("CP\n"); + if (!PolygonMode) + Outputf("ST\n"); +} + + +/* + * 'EP_edge_polygon()' - Stroke the edges of a polygon. + */ + +void +EP_edge_polygon(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; + + Outputf("ST\n"); +} + + +/* + * 'ER_edge_rect_relative()' - Draw a rectangle relative to the current + * pen position. + */ + +void +ER_edge_rect_relative(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + float x, y; /* Transformed coordinates */ + + + if (num_params < 2) + return; + + x = Transform[0][0] * params[0].value.number + + Transform[0][1] * params[1].value.number + + PenPosition[0]; + y = Transform[1][0] * params[0].value.number + + Transform[1][1] * params[1].value.number + + PenPosition[1]; + + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + Outputf("%.3f %.3f LI\n", PenPosition[0], y); + Outputf("%.3f %.3f LI\n", x, y); + Outputf("%.3f %.3f LI\n", x, PenPosition[1]); + + Outputf("CP\n"); + if (!PolygonMode) + Outputf("ST\n"); +} + + +/* + * 'EW_edge_wedge()' - Draw a pie wedge. + */ + +void +EW_edge_wedge(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + float x, y; /* Transformed coordinates */ + float start, end, /* Start and end of arc */ + theta, /* Current angle */ + dt, /* Step between points */ + radius; /* Radius of arc */ + + + if (num_params < 3) + return; + + radius = params[0].value.number; + start = params[1].value.number; + end = start + params[2].value.number; + + if (num_params > 3) + dt = (float)fabs(params[3].value.number); + else + dt = 5.0f; + + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + + if (start < end) + for (theta = start + dt; theta < end; theta += dt) + { + x = (float)(PenPosition[0] + + radius * cos(M_PI * theta / 180.0) * Transform[0][0] + + radius * sin(M_PI * theta / 180.0) * Transform[0][1]); + y = (float)(PenPosition[1] + + radius * cos(M_PI * theta / 180.0) * Transform[1][0] + + radius * sin(M_PI * theta / 180.0) * Transform[1][1]); + + Outputf("%.3f %.3f LI\n", x, y); + } + else + for (theta = start - dt; theta > end; theta -= dt) + { + x = (float)(PenPosition[0] + + radius * cos(M_PI * theta / 180.0) * Transform[0][0] + + radius * sin(M_PI * theta / 180.0) * Transform[0][1]); + y = (float)(PenPosition[1] + + radius * cos(M_PI * theta / 180.0) * Transform[1][0] + + radius * sin(M_PI * theta / 180.0) * Transform[1][1]); + + Outputf("%.3f %.3f LI\n", x, y); + } + + x = (float)(PenPosition[0] + + radius * cos(M_PI * end / 180.0) * Transform[0][0] + + radius * sin(M_PI * end / 180.0) * Transform[0][1]); + y = (float)(PenPosition[1] + + radius * cos(M_PI * end / 180.0) * Transform[1][0] + + radius * sin(M_PI * end / 180.0) * Transform[1][1]); + Outputf("%.3f %.3f LI\n", x, y); + + Outputf("CP\n"); + if (!PolygonMode) + Outputf("ST\n"); +} + + +/* + * 'FP_fill_polygon()' - Fill a polygon. + */ + +void +FP_fill_polygon(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + (void)num_params; + (void)params; + + Outputf("FI\n"); +} + + +/* + * 'PM_polygon_mode()' - Set the polygon drawing mode. + */ + +void +PM_polygon_mode(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params == 0 || + params[0].value.number == 0) + { + Outputf("MP\n"); + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + PolygonMode = 1; + } + else if (params[0].value.number == 2) + PolygonMode = 0; +} + + +/* + * 'RA_fill_rect_absolute()' - Fill a rectangle. + */ + +void +RA_fill_rect_absolute(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + float x, y; /* Transformed coordinates */ + + + if (num_params < 2) + return; + + x = Transform[0][0] * params[0].value.number + + Transform[0][1] * params[1].value.number + + Transform[0][2]; + y = Transform[1][0] * params[0].value.number + + Transform[1][1] * params[1].value.number + + Transform[1][2]; + + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + Outputf("%.3f %.3f LI\n", PenPosition[0], y); + Outputf("%.3f %.3f LI\n", x, y); + Outputf("%.3f %.3f LI\n", x, PenPosition[1]); + + Outputf("CP\n"); + if (!PolygonMode) + Outputf("FI\n"); +} + + +/* + * 'RR_fill_rect_relative()' - Fill a rectangle relative to the current + * pen position. + */ + +void +RR_fill_rect_relative(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + float x, y; /* Transformed coordinates */ + + + if (num_params < 2) + return; + + x = Transform[0][0] * params[0].value.number + + Transform[0][1] * params[1].value.number + + PenPosition[0]; + y = Transform[1][0] * params[0].value.number + + Transform[1][1] * params[1].value.number + + PenPosition[1]; + + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + Outputf("%.3f %.3f LI\n", PenPosition[0], y); + Outputf("%.3f %.3f LI\n", x, y); + Outputf("%.3f %.3f LI\n", x, PenPosition[1]); + + Outputf("CP\n"); + if (!PolygonMode) + Outputf("FI\n"); +} + + +/* + * 'WG_fill_wedge()' - Fill a pie wedge. + */ + +void +WG_fill_wedge(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + float x, y; /* Transformed coordinates */ + float start, end, /* Start and end angles */ + theta, /* Current angle */ + dt, /* Step between points */ + radius; /* Radius of arc */ + + + if (num_params < 3) + return; + + radius = params[0].value.number; + start = params[1].value.number; + end = start + params[2].value.number; + + if (num_params > 3) + dt = (float)fabs(params[3].value.number); + else + dt = 5.0; + + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + + if (start < end) + for (theta = start + dt; theta < end; theta += dt) + { + x = (float)(PenPosition[0] + + radius * cos(M_PI * theta / 180.0) * Transform[0][0] + + radius * sin(M_PI * theta / 180.0) * Transform[0][1]); + y = (float)(PenPosition[1] + + radius * cos(M_PI * theta / 180.0) * Transform[1][0] + + radius * sin(M_PI * theta / 180.0) * Transform[1][1]); + + Outputf("%.3f %.3f LI\n", x, y); + } + else + for (theta = start - dt; theta > end; theta -= dt) + { + x = (float)(PenPosition[0] + + radius * cos(M_PI * theta / 180.0) * Transform[0][0] + + radius * sin(M_PI * theta / 180.0) * Transform[0][1]); + y = (float)(PenPosition[1] + + radius * cos(M_PI * theta / 180.0) * Transform[1][0] + + radius * sin(M_PI * theta / 180.0) * Transform[1][1]); + + Outputf("%.3f %.3f LI\n", x, y); + } + + x = (float)(PenPosition[0] + + radius * cos(M_PI * end / 180.0) * Transform[0][0] + + radius * sin(M_PI * end / 180.0) * Transform[0][1]); + y = (float)(PenPosition[1] + + radius * cos(M_PI * end / 180.0) * Transform[1][0] + + radius * sin(M_PI * end / 180.0) * Transform[1][1]); + Outputf("%.3f %.3f LI\n", x, y); + + Outputf("CP\n"); + if (!PolygonMode) + Outputf("FI\n"); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgl-prolog.c b/filter/hpgl-prolog.c new file mode 100644 index 0000000000..a371763068 --- /dev/null +++ b/filter/hpgl-prolog.c @@ -0,0 +1,407 @@ +/* + * "$Id$" + * + * HP-GL/2 prolog routines for for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * OutputProlog() - Output the PostScript prolog... + * OutputTrailer() - Output the PostScript trailer... + * Outputf() - Write a formatted string to the output file, creating the + * page header as needed... + */ + +/* + * Include necessary headers... + */ + +#include "hpgltops.h" +#include + + +/* + * 'OutputProlog()' - Output the PostScript prolog... + */ + +void +OutputProlog(char *title, /* I - Job title */ + char *user, /* I - Username */ + int shading) /* I - Type of shading */ +{ + FILE *prolog; /* Prolog file */ + char line[255]; /* Line from prolog file */ + const char *datadir; /* CUPS_DATADIR environment variable */ + char filename[1024]; /* Name of prolog file */ + time_t curtime; /* Current time */ + struct tm *curtm; /* Current date */ + + + curtime = time(NULL); + curtm = localtime(&curtime); + + puts("%!PS-Adobe-3.0"); + printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", + PageLeft, PageBottom, PageRight, PageTop); + puts("%%Pages: (atend)"); + printf("%%%%LanguageLevel: %d\n", LanguageLevel); + puts("%%DocumentData: Clean7Bit"); + puts("%%DocumentSuppliedResources: procset hpgltops 1.1 0"); + puts("%%DocumentNeededResources: font Courier Helvetica"); + puts("%%Creator: hpgltops/" CUPS_SVERSION); + strftime(line, sizeof(line), "%%%%CreationDate: %c", curtm); + puts(line); + printf("%%%%Title: %s\n", title); + printf("%%%%For: %s\n", user); + if (Orientation & 1) + puts("%%Orientation: Landscape"); + puts("%%EndComments"); + puts("%%BeginProlog"); + printf("/DefaultPenWidth %.2f def\n", PenWidth * 72.0 / 25.4); + puts("3.0 setmiterlimit"); + if (!shading) /* Black only */ + puts("/setrgbcolor { pop pop pop } bind def"); + else if (!ColorDevice) /* Greyscale */ + puts("/setrgbcolor { 0.08 mul exch 0.61 mul add exch 0.31 mul add setgray } bind def\n"); + + if ((datadir = getenv("CUPS_DATADIR")) == NULL) + datadir = CUPS_DATADIR; + + snprintf(filename, sizeof(filename), "%s/data/HPGLprolog", datadir); + + if ((prolog = fopen(filename, "r")) == NULL) + { + fprintf(stderr, "ERROR: Unable to open HPGL prolog \"%s\" for reading - %s\n", + filename, strerror(errno)); + exit(1); + } + + while (fgets(line, sizeof(line), prolog) != NULL) + fputs(line, stdout); + + fclose(prolog); + + puts("%%EndProlog"); + + IN_initialize(0, NULL); +} + + +/* + * 'OutputTrailer()' - Output the PostScript trailer... + */ + +void +OutputTrailer(void) +{ + if (PageDirty) + PG_advance_page(0, NULL); + + puts("%%Trailer"); + printf("%%%%Pages: %d\n", PageCount); + puts("%%EOF"); +} + + +/* + * 'Outputf()' - Write a formatted string to the output file, creating the + * page header as needed... + */ + +int /* O - Number of bytes written */ +Outputf(const char *format, /* I - Printf-style string */ + ...) /* I - Additional args as needed */ +{ + va_list ap; /* Argument pointer */ + int bytes; /* Number of bytes written */ + float iw1[2], iw2[2]; /* Clipping window */ + int i; /* Looping var */ + ppd_size_t *size; /* Page size */ + ppd_option_t *option; /* Page size option */ + ppd_choice_t *choice; /* Page size choice */ + float width, length; /* Page dimensions */ + int landscape; /* Rotate for landscape orientation? */ + + + /* + * Write the page header as needed... + */ + + if (!PageDirty) + { + PageDirty = 1; + PageCount ++; + + printf("%%%%Page: %d %d\n", PageCount, PageCount); + + landscape = 0; + + if (!FitPlot) + { + /* + * Set the page size for this page... + */ + + if (PageRotation == 0 || PageRotation == 180) + { + width = PlotSize[0]; + length = PlotSize[1]; + } + else + { + width = PlotSize[1]; + length = PlotSize[0]; + } + + fprintf(stderr, "DEBUG: hpgltops setting page size (%.0f x %.0f)\n", + width, length); + + if (PPD != NULL) + { + fputs("DEBUG: hpgltops has a PPD file!\n", stderr); + + /* + * Lookup the closest PageSize and set it... + */ + + for (i = PPD->num_sizes, size = PPD->sizes; i > 0; i --, size ++) + if ((fabs(length - size->length) < 36.0 && size->width >= width) || + (fabs(length - size->width) < 36.0 && size->length >= width)) + break; + + if (i == 0 && PPD->variable_sizes) + { + for (i = PPD->num_sizes, size = PPD->sizes; i > 0; i --, size ++) + if (strcasecmp(size->name, "custom") == 0) + break; + } + + if (i > 0) + { + /* + * Found a matching size... + */ + + option = ppdFindOption(PPD, "PageSize"); + choice = ppdFindChoice(option, size->name); + + puts("%%BeginPageSetup"); + printf("%%%%BeginFeature: PageSize %s\n", size->name); + + if (strcasecmp(size->name, "custom") == 0) + { + PageLeft = PPD->custom_margins[0]; + PageRight = width - PPD->custom_margins[2]; + PageWidth = width; + PageBottom = PPD->custom_margins[1]; + PageTop = length - PPD->custom_margins[3]; + PageLength = length; + + printf("%.0f %.0f 0 0 0\n", width, length); + + if (choice->code == NULL) + { + /* + * This can happen with certain buggy PPD files that don't include + * a CustomPageSize command sequence... We just use a generic + * Level 2 command sequence... + */ + + puts("pop pop pop"); + puts("<>setpagedevice\n"); + } + else + { + /* + * Use the vendor-supplied command... + */ + + printf("%s\n", choice->code); + } + } + else + { + if (choice->code) + printf("%s\n", choice->code); + + if (fabs(length - size->width) < 36.0) + { + /* + * Do landscape orientation... + */ + + PageLeft = size->bottom; + PageRight = size->top; + PageWidth = size->length; + PageBottom = size->left; + PageTop = size->right; + PageLength = size->width; + + landscape = 1; + } + else + { + /* + * Do portrait orientation... + */ + + PageLeft = size->left; + PageRight = size->right; + PageWidth = size->width; + PageBottom = size->bottom; + PageTop = size->top; + PageLength = size->length; + } + } + + puts("%%EndFeature"); + puts("%%EndPageSetup"); + } + } + else + { + fputs("DEBUG: hpgltops does not have a PPD file!\n", stderr); + + puts("%%BeginPageSetup"); + printf("%%%%BeginFeature: PageSize w%.0fh%.0f\n", width, length); + printf("<>setpagedevice\n", + width, length); + puts("%%EndFeature"); + puts("%%EndPageSetup"); + + PageLeft = 0.0; + PageRight = width; + PageWidth = width; + PageBottom = 0.0; + PageTop = length; + PageLength = length; + } + } + + printf("/SA {\n" + " /%s%s%s%s findfont\n" + " [ %f %f %f %f 0.0 0.0 ] makefont\n" + " setfont\n" + "} bind def\n", + AlternateFont.typeface == 48 ? "Courier" : "Helvetica", + (AlternateFont.weight != 0 || AlternateFont.posture != 0) ? "-" : "", + AlternateFont.weight != 0 ? "Bold" : "", + AlternateFont.posture != 0 ? "Oblique" : "", + AlternateFont.x * AlternateFont.height, + -AlternateFont.y * AlternateFont.height, + AlternateFont.y * AlternateFont.height, + AlternateFont.x * AlternateFont.height); + + printf("/SS {\n" + " /%s%s%s%s findfont\n" + " [ %f %f %f %f 0.0 0.0 ] makefont\n" + " setfont\n" + "} bind def\n", + StandardFont.typeface == 48 ? "Courier" : "Helvetica", + (StandardFont.weight != 0 || StandardFont.posture != 0) ? "-" : "", + StandardFont.weight != 0 ? "Bold" : "", + StandardFont.posture != 0 ? "Oblique" : "", + StandardFont.x * StandardFont.height, + -StandardFont.y * StandardFont.height, + StandardFont.y * StandardFont.height, + StandardFont.x * StandardFont.height); + + if (CharFont) + puts("SA"); + else + puts("SS"); + + printf("%.1f setmiterlimit\n", MiterLimit); + printf("%d setlinecap\n", LineCap); + printf("%d setlinejoin\n", LineJoin); + + printf("%.3f %.3f %.3f %.2f SP\n", Pens[1].rgb[0], Pens[1].rgb[1], + Pens[1].rgb[2], Pens[1].width * PenScaling); + + puts("gsave"); + + if (Duplex && (PageCount & 1) == 0) + switch ((PageRotation / 90 + landscape) & 3) + { + case 0 : + printf("%.1f %.1f translate\n", PageWidth - PageRight, PageBottom); + break; + case 1 : + printf("%.0f 0 translate 90 rotate\n", PageLength); + printf("%.1f %.1f translate\n", PageLength - PageTop, + PageWidth - PageRight); + break; + case 2 : + printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength); + printf("%.1f %.1f translate\n", PageLeft, PageLength - PageTop); + break; + case 3 : + printf("0 %.0f translate -90 rotate\n", PageWidth); + printf("%.1f %.1f translate\n", PageBottom, PageLeft); + break; + } + else + switch ((PageRotation / 90 + landscape) & 3) + { + case 0 : + printf("%.1f %.1f translate\n", PageLeft, PageBottom); + break; + case 1 : + printf("%.0f 0 translate 90 rotate\n", PageLength); + printf("%.1f %.1f translate\n", PageBottom, PageWidth - PageRight); + break; + case 2 : + printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength); + printf("%.1f %.1f translate\n", PageWidth - PageRight, + PageLength - PageTop); + break; + case 3 : + printf("0 %.0f translate -90 rotate\n", PageWidth); + printf("%.1f %.1f translate\n", PageLength - PageTop, PageLeft); + break; + } + + if (IW1[0] != IW2[0] && IW1[1] != IW2[1]) + { + iw1[0] = IW1[0] * 72.0f / 1016.0f; + iw1[1] = IW1[1] * 72.0f / 1016.0f; + iw2[0] = IW2[0] * 72.0f / 1016.0f; + iw2[1] = IW2[1] * 72.0f / 1016.0f; + + printf("initclip MP %.3f %.3f MO %.3f %.3f LI %.3f %.3f LI %.3f %.3f LI CP clip\n", + iw1[0], iw1[1], iw1[0], iw2[1], iw2[0], iw2[1], iw2[0], iw1[1]); + } + } + + /* + * Write the string to the output file... + */ + + va_start(ap, format); + bytes = vprintf(format, ap); + va_end(ap); + + return (bytes); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgl-vector.c b/filter/hpgl-vector.c new file mode 100644 index 0000000000..dbe059f04c --- /dev/null +++ b/filter/hpgl-vector.c @@ -0,0 +1,731 @@ +/* + * "$Id$" + * + * HP-GL/2 vector routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * AA_arc_absolute() - Draw an arc. + * AR_arc_relative() - Draw an arc relative to the current pen + * AT_arc_absolute3() - Draw an arc using 3 points. + * CI_circle() - Draw a circle. + * PA_plot_absolute() - Plot a line using absolute coordinates. + * PD_pen_down() - Start drawing. + * PE_polygon_encoded() - Draw an encoded polyline. + * PR_plot_relative() - Plot a line using relative coordinates. + * PU_pen_up() - Stop drawing. + * RT_arc_relative3() - Draw an arc through 3 points relative to the + * decode_number() - Decode an encoded number. + * plot_points() - Plot the specified points. + */ + +/* + * Include necessary headers... + */ + +#include "hpgltops.h" + + +/* + * Local functions... + */ + +static double decode_number(unsigned char **, int, double); +static void plot_points(int, param_t *); + + +/* + * 'AA_arc_absolute()' - Draw an arc. + */ + +void +AA_arc_absolute(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + float x, y, /* Transformed coordinates */ + dx, dy; /* Distance from current pen */ + float start, end, /* Start and end angles */ + theta, /* Current angle */ + dt, /* Step between points */ + radius; /* Radius of arc */ + + + if (num_params < 3) + return; + + x = Transform[0][0] * params[0].value.number + + Transform[0][1] * params[1].value.number + + Transform[0][2]; + y = Transform[1][0] * params[0].value.number + + Transform[1][1] * params[1].value.number + + Transform[1][2]; + + dx = PenPosition[0] - x; + dy = PenPosition[1] - y; + + start = (float)(180.0 * atan2(dy, dx) / M_PI); + if (start < 0.0) + start += 360.0f; + + end = start + params[2].value.number; + radius = (float)hypot(dx, dy); + + if (PenDown) + { + if (num_params > 3 && params[3].value.number > 0.0) + dt = (float)fabs(params[3].value.number); + else + dt = 5.0; + + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + + if (start < end) + for (theta = start + dt; theta < end; theta += dt) + { + PenPosition[0] = (float)(x + radius * cos(M_PI * theta / 180.0)); + PenPosition[1] = (float)(y + radius * sin(M_PI * theta / 180.0)); + + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + } + else + for (theta = start - dt; theta > end; theta -= dt) + { + PenPosition[0] = (float)(x + radius * cos(M_PI * theta / 180.0)); + PenPosition[1] = (float)(y + radius * sin(M_PI * theta / 180.0)); + + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + } + } + + PenPosition[0] = (float)(x + radius * cos(M_PI * end / 180.0)); + PenPosition[1] = (float)(y + radius * sin(M_PI * end / 180.0)); + + if (PenDown) + { + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + + if (!PolygonMode) + Outputf("ST\n"); + } +} + + +/* + * 'AR_arc_relative()' - Draw an arc relative to the current pen + * position. + */ + +void +AR_arc_relative(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + float x, y, /* Transformed coordinates */ + dx, dy; /* Distance from current pen */ + float start, end, /* Start and end angles */ + theta, /* Current angle */ + dt, /* Step between points */ + radius; /* Radius of arc */ + + + if (num_params < 3) + return; + + x = Transform[0][0] * params[0].value.number + + Transform[0][1] * params[1].value.number + + PenPosition[0]; + y = Transform[1][0] * params[0].value.number + + Transform[1][1] * params[1].value.number + + PenPosition[1]; + + dx = PenPosition[0] - x; + dy = PenPosition[1] - y; + + start = (float)(180.0 * atan2(dy, dx) / M_PI); + if (start < 0.0) + start += 360.0f; + + end = start + params[2].value.number; + radius = (float)hypot(dx, dy); + + if (PenDown) + { + if (num_params > 3 && params[3].value.number > 0.0) + dt = (float)fabs(params[3].value.number); + else + dt = 5.0; + + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + + if (start < end) + for (theta = start + dt; theta < end; theta += dt) + { + PenPosition[0] = (float)(x + radius * cos(M_PI * theta / 180.0)); + PenPosition[1] = (float)(y + radius * sin(M_PI * theta / 180.0)); + + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + } + else + for (theta = start - dt; theta > end; theta -= dt) + { + PenPosition[0] = (float)(x + radius * cos(M_PI * theta / 180.0)); + PenPosition[1] = (float)(y + radius * sin(M_PI * theta / 180.0)); + + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + } + } + + PenPosition[0] = (float)(x + radius * cos(M_PI * end / 180.0)); + PenPosition[1] = (float)(y + radius * sin(M_PI * end / 180.0)); + + if (PenDown) + { + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + + if (!PolygonMode) + Outputf("ST\n"); + } +} + + +/* + * 'AT_arc_absolute3()' - Draw an arc using 3 points. + * + * Note: + * + * Currently this only draws two line segments through the + * specified points. + */ + +void +AT_arc_absolute3(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params < 4) + return; + + if (PenDown) + { + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + + PenPosition[0] = Transform[0][0] * params[0].value.number + + Transform[0][1] * params[1].value.number + + Transform[0][2]; + PenPosition[1] = Transform[1][0] * params[0].value.number + + Transform[1][1] * params[1].value.number + + Transform[1][2]; + + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + } + + PenPosition[0] = Transform[0][0] * params[2].value.number + + Transform[0][1] * params[3].value.number + + Transform[0][2]; + PenPosition[1] = Transform[1][0] * params[2].value.number + + Transform[1][1] * params[3].value.number + + Transform[1][2]; + + if (PenDown) + { + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + + if (!PolygonMode) + Outputf("ST\n"); + } +} + + +/* + * 'CI_circle()' - Draw a circle. + */ + +void +CI_circle(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + float x, y; /* Transformed coordinates */ + float theta, /* Current angle */ + dt, /* Step between points */ + radius; /* Radius of circle */ + + + if (num_params < 1) + return; + + if (!PenDown) + return; + + radius = params[0].value.number; + + if (num_params > 1) + dt = (float)fabs(params[1].value.number); + else + dt = 5.0; + + if (!PolygonMode) + Outputf("MP\n"); + + for (theta = 0.0; theta < 360.0; theta += dt) + { + x = (float)(PenPosition[0] + + radius * cos(M_PI * theta / 180.0) * Transform[0][0] + + radius * sin(M_PI * theta / 180.0) * Transform[0][1]); + y = (float)(PenPosition[1] + + radius * cos(M_PI * theta / 180.0) * Transform[1][0] + + radius * sin(M_PI * theta / 180.0) * Transform[1][1]); + + Outputf("%.3f %.3f %s\n", x, y, theta == 0.0 ? "MO" : "LI"); + } + + Outputf("CP\n"); + if (!PolygonMode) + Outputf("ST\n"); +} + + +/* + * 'PA_plot_absolute()' - Plot a line using absolute coordinates. + */ + +void +PA_plot_absolute(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + PenMotion = 0; + + if (num_params > 1) + plot_points(num_params, params); +} + + +/* + * 'PD_pen_down()' - Start drawing. + */ + +void +PD_pen_down(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + PenDown = 1; + + if (num_params > 1) + plot_points(num_params, params); +} + + +/* + * 'PE_polygon_encoded()' - Draw an encoded polyline. + */ + +void +PE_polyline_encoded(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + unsigned char *s; /* Pointer into string */ + int temp, /* Temporary value */ + base_bits, /* Data bits per byte */ + draw, /* Draw or move */ + abscoords; /* Use absolute coordinates */ + double tx, ty, /* Transformed coordinates */ + x, y, /* Raw coordinates */ + frac_bits; /* Multiplier for encoded number */ + + + base_bits = 6; + frac_bits = 1.0; + draw = 1; + abscoords = 0; + + if (num_params == 0) + return; + + if (!PolygonMode) + { + Outputf("MP\n"); + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + } + + for (s = (unsigned char *)params[0].value.string; *s != '\0';) + switch (*s) + { + case '7' : + s ++; + base_bits = 5; + +#ifdef DEBUG + fputs("DEBUG: 7-bit\n", stderr); +#endif /* DEBUG */ + break; + case ':' : /* Select pen */ + s ++; + PenNumber = (int)decode_number(&s, base_bits, 1.0); + if (PageDirty) + printf("%.3f %.3f %.3f %.2f SP\n", Pens[PenNumber].rgb[0], + Pens[PenNumber].rgb[PenNumber], Pens[PenNumber].rgb[2], + Pens[PenNumber].width * PenScaling); + +#ifdef DEBUG + fprintf(stderr, "DEBUG: set pen #%d\n", PenNumber); +#endif /* DEBUG */ + break; + case '<' : /* Next coords are a move-to */ + draw = 0; + s ++; + +#ifdef DEBUG + fputs("DEBUG: moveto\n", stderr); +#endif /* DEBUG */ + break; + case '>' : /* Set fractional bits */ + s ++; + temp = (int)decode_number(&s, base_bits, 1.0); + frac_bits = 1.0 / (1 << temp); + +#ifdef DEBUG + fprintf(stderr, "DEBUG: set fractional bits %d\n", temp); +#endif /* DEBUG */ + break; + case '=' : /* Next coords are absolute */ + s ++; + abscoords = 1; + +#ifdef DEBUG + fputs("DEBUG: absolute\n", stderr); +#endif /* DEBUG */ + break; + default : + if (*s >= 63) + { + /* + * Coordinate... + */ + + x = decode_number(&s, base_bits, frac_bits); + y = decode_number(&s, base_bits, frac_bits); + +#ifdef DEBUG + fprintf(stderr, "DEBUG: coords %.3f %.3f\n", x, y); +#endif /* DEBUG */ + + if (abscoords) + { + tx = Transform[0][0] * x + Transform[0][1] * y + + Transform[0][2]; + ty = Transform[1][0] * x + Transform[1][1] * y + + Transform[1][2]; + } + else if (x == 0.0 && y == 0.0) + { + draw = 1; + continue; + } + else + { + tx = Transform[0][0] * x + Transform[0][1] * y + + PenPosition[0]; + ty = Transform[1][0] * x + Transform[1][1] * y + + PenPosition[1]; + } + + if (draw) + Outputf("%.3f %.3f LI\n", tx, ty); + else + Outputf("%.3f %.3f MO\n", tx, ty); + + PenPosition[0] = (float)tx; + PenPosition[1] = (float)ty; + + draw = 1; + abscoords = 0; + } + else + { + /* + * Junk - ignore... + */ + + if (*s != '\n' && *s != '\r') + fprintf(stderr, "WARNING: ignoring illegal PE char \'%c\'...\n", *s); + s ++; + } + break; + } + + if (!PolygonMode) + Outputf("ST\n"); +} + + +/* + * 'PR_plot_relative()' - Plot a line using relative coordinates. + */ + +void +PR_plot_relative(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + PenMotion = 1; + + if (num_params > 1) + plot_points(num_params, params); +} + + +/* + * 'PU_pen_up()' - Stop drawing. + */ + +void +PU_pen_up(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + PenDown = 0; + + if (num_params > 1) + plot_points(num_params, params); +} + + +/* + * 'RT_arc_relative3()' - Draw an arc through 3 points relative to the + * current pen position. + * + * Note: + * + * This currently only draws two line segments through the specified + * points. + */ + +void +RT_arc_relative3(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + if (num_params < 4) + return; + + if (PenDown) + { + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + + PenPosition[0] = Transform[0][0] * params[0].value.number + + Transform[0][1] * params[1].value.number + + PenPosition[0]; + PenPosition[1] = Transform[1][0] * params[0].value.number + + Transform[1][1] * params[1].value.number + + PenPosition[1]; + + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + } + + PenPosition[0] = Transform[0][0] * params[2].value.number + + Transform[0][1] * params[3].value.number + + PenPosition[0]; + PenPosition[1] = Transform[1][0] * params[2].value.number + + Transform[1][1] * params[3].value.number + + PenPosition[1]; + + if (PenDown) + { + Outputf("%.3f %.3f LI\n", PenPosition[0], PenPosition[1]); + + if (!PolygonMode) + Outputf("ST\n"); + } +} + + +/* + * 'decode_number()' - Decode an encoded number. + */ + +static double /* O - Value */ +decode_number(unsigned char **s, /* IO - String to decode */ + int base_bits, /* I - Number of data bits per byte */ + double frac_bits) /* I - Multiplier for fractional data */ +{ + double temp, /* Current value */ + shift; /* Multiplier */ + int sign; /* Sign of result */ + + + sign = 0; + + if (base_bits == 5) + { + for (temp = 0.0, shift = frac_bits * 0.5; **s != '\0'; (*s) ++) + if (**s >= 95 && **s < 127) + { + if (sign == 0) + { + if ((**s - 95) & 1) + sign = -1; + else + sign = 1; + + temp += ((**s - 95) & ~1) * shift; + } + else + temp += (**s - 95) * shift; + break; + } + else if (**s < 63) + { + if (**s != '\r' && **s != '\n') + fprintf(stderr, "hpgl2ps: Bad PE character \'%c\'!\n", **s); + + continue; + } + else + { + if (sign == 0) + { + if ((**s - 63) & 1) + sign = -1; + else + sign = 1; + + temp += ((**s - 63) & ~1) * shift; + } + else + temp += (**s - 63) * shift; + + shift *= 32.0; + } + } + else + { + for (temp = 0.0, shift = frac_bits * 0.5; **s != '\0'; (*s) ++) + if (**s >= 191 && **s < 255) + { + if (sign == 0) + { + if ((**s - 191) & 1) + sign = -1; + else + sign = 1; + + temp += ((**s - 191) & ~1) * shift; + } + else + temp += (**s - 191) * shift; + break; + } + else if (**s < 63) + { + if (**s != '\r' && **s != '\n') + fprintf(stderr, "hpgl2ps: Bad PE character \'%c\'!\n", **s); + + continue; + } + else + { + if (sign == 0) + { + if ((**s - 63) & 1) + sign = -1; + else + sign = 1; + + temp += ((**s - 63) & ~1) * shift; + } + else + temp += (**s - 63) * shift; + + shift *= 64.0; + } + } + + (*s) ++; + + return (temp * sign); +} + + +/* + * 'plot_points()' - Plot the specified points. + */ + +static void +plot_points(int num_params, /* I - Number of parameters */ + param_t *params) /* I - Parameters */ +{ + int i; /* Looping var */ + float x, y; /* Transformed coordinates */ + + + if (PenDown) + { + if (!PolygonMode) + Outputf("MP\n"); + + Outputf("%.3f %.3f MO\n", PenPosition[0], PenPosition[1]); + } + + for (i = 0; i < num_params; i += 2) + { + if (PenMotion == 0) + { + x = Transform[0][0] * params[i + 0].value.number + + Transform[0][1] * params[i + 1].value.number + + Transform[0][2]; + y = Transform[1][0] * params[i + 0].value.number + + Transform[1][1] * params[i + 1].value.number + + Transform[1][2]; + } + else + { + x = Transform[0][0] * params[i + 0].value.number + + Transform[0][1] * params[i + 1].value.number + + PenPosition[0]; + y = Transform[1][0] * params[i + 0].value.number + + Transform[1][1] * params[i + 1].value.number + + PenPosition[1]; + } + + if (PenDown) + Outputf("%.3f %.3f LI\n", x, y); + + PenPosition[0] = x; + PenPosition[1] = y; + } + + if (PenDown) + { + if (!PolygonMode) + Outputf("ST\n"); + } +} + + +/* + * End of "$Id$". + */ diff --git a/filter/hpgltops.h b/filter/hpgltops.h new file mode 100644 index 0000000000..d1b65d2da9 --- /dev/null +++ b/filter/hpgltops.h @@ -0,0 +1,232 @@ +/* + * "$Id$" + * + * HP-GL/2 to PostScript filter for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +/* + * Include necessary headers... + */ + +#include "common.h" +#include + +#ifndef M_PI +# define M_PI 3.14159265358979323846 +#endif /* M_PI */ + +/* + * Parameter value structure... + */ + +typedef struct +{ + int type; + union + { + float number; + char *string; + } value; +} param_t; + +#define PARAM_ABSOLUTE 0 +#define PARAM_RELATIVE 1 +#define PARAM_STRING 2 + + +/* + * Font information... + */ + +typedef struct +{ + int typeface, /* Typeface number */ + posture, /* Posture number */ + weight; /* Weight number */ + float height; /* Height/size of font */ + float x, y; /* X and Y direction/scaling */ +} font_t; + + +/* + * Pen information... + */ + +typedef struct +{ + float rgb[3]; /* Pen color */ + float width; /* Pen width */ +} pen_t; + + +/* + * Globals... + */ + +#ifdef _HPGL_MAIN_C_ +# define VAR +# define VALUE(x) =x +# define VALUE2(x,y) ={x,y} +#else +# define VAR extern +# define VALUE(x) +# define VALUE2(x,y) +#endif /* _HPGL_MAIN_C_ */ + +VAR ppd_file_t *PPD VALUE(NULL); /* PPD file */ + +VAR float P1[2], /* Lower-lefthand physical limit */ + P2[2], /* Upper-righthand physical limit */ + IW1[2], /* Window lower-lefthand limit */ + IW2[2]; /* Window upper-righthand limit */ +VAR int Rotation VALUE(0); /* Page rotation */ +VAR int ScalingType VALUE(-1); /* Type of scaling (-1 for none) */ +VAR float Scaling1[2], /* Lower-lefthand user limit */ + Scaling2[2]; /* Upper-righthand user limit */ +VAR float Transform[2][3]; /* Transform matrix */ +VAR int PageRotation VALUE(0); /* Page/plot rotation */ + +VAR char StringTerminator VALUE('\003'); /* Terminator for labels */ +VAR font_t StandardFont, /* Standard font */ + AlternateFont; /* Alternate font */ +VAR float PenPosition[2] VALUE2(0.0f, 0.0f), + /* Current pen position */ + PenScaling VALUE(1.0f), /* Pen width scaling factor */ + PenWidth VALUE(1.0f); /* Default pen width */ +VAR pen_t Pens[1024]; /* State of each pen */ +VAR int PenMotion VALUE(0), /* 0 = absolute, 1 = relative */ + PenNumber VALUE(1), /* Current pen number */ + PenCount VALUE(8), /* Number of pens */ + PenDown VALUE(0), /* 0 = pen up, 1 = pen down */ + PolygonMode VALUE(0), /* Drawing polygons? */ + PageCount VALUE(0), /* Number of pages in plot */ + PageDirty VALUE(0), /* Current page written on? */ + WidthUnits VALUE(0); /* 0 = mm, 1 = proportionate */ +VAR float PlotSize[2] VALUE2(2592.0f, 3456.0f); + /* Plot size */ +VAR int CharFillMode VALUE(0), /* Where to draw labels */ + CharPen VALUE(0), /* Pen to use for labels */ + CharFont VALUE(0); /* Font to use for labels */ +VAR float CharHeight[2] VALUE2(11.5f,11.5f); + /* Size of font for labels */ +VAR int FitPlot VALUE(0); /* 1 = fit to page */ +VAR float ColorRange[3][2] /* Range of color values */ +#ifdef _HPGL_MAIN_C_ + = { + { 0.0, 255.0 }, + { 0.0, 255.0 }, + { 0.0, 255.0 } + } +#endif /* _HPGL_MAIN_C_ */ +; + +VAR int LineCap VALUE(0); /* Line capping */ +VAR int LineJoin VALUE(0); /* Line joining */ +VAR float MiterLimit VALUE(3.0f); /* Miter limit at joints */ + + +/* + * Prototypes... + */ + +/* hpgl-input.c */ +extern int ParseCommand(FILE *fp, char *name, param_t **params); +extern void FreeParameters(int num_params, param_t *params); + +/* hpgl-config.c */ +extern void update_transform(void); +extern void BP_begin_plot(int num_params, param_t *params); +extern void DF_default_values(int num_params, param_t *params); +extern void IN_initialize(int num_params, param_t *params); +extern void IP_input_absolute(int num_params, param_t *params); +extern void IR_input_relative(int num_params, param_t *params); +extern void IW_input_window(int num_params, param_t *params); +extern void PG_advance_page(int num_params, param_t *params); +extern void PS_plot_size(int num_params, param_t *params); +extern void RO_rotate(int num_params, param_t *params); +extern void RP_replot(int num_params, param_t *params); +extern void SC_scale(int num_params, param_t *params); + +/* hpgl-vector.c */ +extern void AA_arc_absolute(int num_params, param_t *params); +extern void AR_arc_relative(int num_params, param_t *params); +extern void AT_arc_absolute3(int num_params, param_t *params); +extern void CI_circle(int num_params, param_t *params); +extern void PA_plot_absolute(int num_params, param_t *params); +extern void PD_pen_down(int num_params, param_t *params); +extern void PE_polyline_encoded(int num_params, param_t *params); +extern void PR_plot_relative(int num_params, param_t *params); +extern void PU_pen_up(int num_params, param_t *params); +extern void RT_arc_relative3(int num_params, param_t *params); + +/* hpgl-polygon.c */ +extern void EA_edge_rect_absolute(int num_params, param_t *params); +extern void EP_edge_polygon(int num_params, param_t *params); +extern void ER_edge_rect_relative(int num_params, param_t *params); +extern void EW_edge_wedge(int num_params, param_t *params); +extern void FP_fill_polygon(int num_params, param_t *params); +extern void PM_polygon_mode(int num_params, param_t *params); +extern void RA_fill_rect_absolute(int num_params, param_t *params); +extern void RR_fill_rect_relative(int num_params, param_t *params); +extern void WG_fill_wedge(int num_params, param_t *params); + +/* hpgl-char.c */ +extern void AD_define_alternate(int num_params, param_t *params); +extern void CF_character_fill(int num_params, param_t *params); +extern void CP_character_plot(int num_params, param_t *params); +extern void DI_absolute_direction(int num_params, param_t *params); +extern void DR_relative_direction(int num_params, param_t *params); +extern void DT_define_label_term(int num_params, param_t *params); +extern void DV_define_variable_path(int num_params, param_t *params); +extern void ES_extra_space(int num_params, param_t *params); +extern void LB_label(int num_params, param_t *params); +extern void LO_label_origin(int num_params, param_t *params); +extern void SA_select_alternate(int num_params, param_t *params); +extern void SD_define_standard(int num_params, param_t *params); +extern void SI_absolute_size(int num_params, param_t *params); +extern void SL_character_slant(int num_params, param_t *params); +extern void SR_relative_size(int num_params, param_t *params); +extern void SS_select_standard(int num_params, param_t *params); +extern void TD_transparent_data(int num_params, param_t *params); + +/* hpgl-attr.c */ +extern void AC_anchor_corner(int num_params, param_t *params); +extern void CR_color_range(int num_params, param_t *params); +extern void FT_fill_type(int num_params, param_t *params); +extern void LA_line_attributes(int num_params, param_t *params); +extern void LT_line_type(int num_params, param_t *params); +extern void NP_number_pens(int num_params, param_t *params); +extern void PC_pen_color(int num_params, param_t *params); +extern void PW_pen_width(int num_params, param_t *params); +extern void RF_raster_fill(int num_params, param_t *params); +extern void SM_symbol_mode(int num_params, param_t *params); +extern void SP_select_pen(int num_params, param_t *params); +extern void UL_user_line_type(int num_params, param_t *params); +extern void WU_width_units(int num_params, param_t *params); + +/* hpgl-prolog.c */ +extern void OutputProlog(char *title, char *user, int shading); +extern void OutputTrailer(void); +extern int Outputf(const char *format, ...); + +/* + * End of "$Id$". + */ diff --git a/filter/image-bmp.c b/filter/image-bmp.c new file mode 100644 index 0000000000..aa7fa352d2 --- /dev/null +++ b/filter/image-bmp.c @@ -0,0 +1,499 @@ +/* + * "$Id$" + * + * BMP image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadBMP() - Read a BMP image file. + * read_word() - Read a 16-bit unsigned integer. + * read_dword() - Read a 32-bit unsigned integer. + * read_long() - Read a 32-bit signed integer. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + + +/* + * Constants for the bitmap compression... + */ + +# define BI_RGB 0 /* No compression - straight BGR data */ +# define BI_RLE8 1 /* 8-bit run-length compression */ +# define BI_RLE4 2 /* 4-bit run-length compression */ +# define BI_BITFIELDS 3 /* RGB bitmap with RGB masks */ + + +/* + * Local functions... + */ + +static unsigned short read_word(FILE *fp); +static unsigned int read_dword(FILE *fp); +static int read_long(FILE *fp); + + +/* + * 'ImageReadBMP()' - Read a BMP image file. + */ + +int /* O - Read status */ +ImageReadBMP(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + int offset, /* Offset to bitmap data */ + info_size, /* Size of info header */ + planes, /* Number of planes (always 1) */ + depth, /* Depth of image (bits) */ + compression, /* Type of compression */ + image_size, /* Size of image in bytes */ + colors_used, /* Number of colors used */ + colors_important, /* Number of important colors */ + bpp, /* Bytes per pixel */ + x, y, /* Looping vars */ + color, /* Color of RLE pixel */ + count, /* Number of times to repeat */ + temp, /* Temporary color */ + align; /* Alignment bytes */ + ib_t bit, /* Bit in image */ + byte; /* Byte in image */ + ib_t *in, /* Input pixels */ + *out, /* Output pixels */ + *ptr; /* Pointer into pixels */ + ib_t colormap[256][4]; /* Colormap */ + + + /* + * Get the header... + */ + + getc(fp); /* Skip "BM" sync chars */ + getc(fp); + read_dword(fp); /* Skip size */ + read_word(fp); /* Skip reserved stuff */ + read_word(fp); + offset = read_dword(fp); + + fprintf(stderr, "offset = %d\n", offset); + + /* + * Then the bitmap information... + */ + + info_size = read_dword(fp); + img->xsize = read_long(fp); + img->ysize = read_long(fp); + planes = read_word(fp); + depth = read_word(fp); + compression = read_dword(fp); + image_size = read_dword(fp); + img->xppi = read_long(fp) * 0.0254 + 0.5; + img->yppi = read_long(fp) * 0.0254 + 0.5; + colors_used = read_dword(fp); + colors_important = read_dword(fp); + + fprintf(stderr, "info_size = %d, xsize = %d, ysize = %d, planes = %d, depth = %d\n", + info_size, img->xsize, img->ysize, planes, depth); + fprintf(stderr, "compression = %d, image_size = %d, xppi = %d, yppi = %d\n", + compression, image_size, img->xppi, img->yppi); + fprintf(stderr, "colors_used = %d, colors_important = %d\n", colors_used, + colors_important); + + if (info_size > 40) + for (info_size -= 40; info_size > 0; info_size --) + getc(fp); + + /* + * Get colormap... + */ + + if (colors_used == 0 && depth <= 8) + colors_used = 1 << depth; + + fread(colormap, colors_used, 4, fp); + + /* + * Setup image and buffers... + */ + + img->colorspace = primary; + + ImageSetMaxTiles(img, 0); + + in = malloc(img->xsize * 3); + bpp = ImageGetDepth(img); + out = malloc(img->xsize * bpp); + + /* + * Read the image data... + */ + + color = 0; + count = 0; + align = 0; + + for (y = img->ysize - 1; y >= 0; y --) + { + if (img->colorspace == IMAGE_RGB) + ptr = out; + else + ptr = in; + + switch (depth) + { + case 1 : /* Bitmap */ + for (x = img->xsize, bit = 128; x > 0; x --) + { + if (bit == 128) + byte = getc(fp); + + if (byte & bit) + { + *ptr++ = colormap[1][2]; + *ptr++ = colormap[1][1]; + *ptr++ = colormap[1][0]; + } + else + { + *ptr++ = colormap[0][2]; + *ptr++ = colormap[0][1]; + *ptr++ = colormap[0][0]; + } + + if (bit > 1) + bit >>= 1; + else + bit = 128; + } + + /* + * Read remaining bytes to align to 32 bits... + */ + + for (temp = (img->xsize + 7) / 8; temp & 3; temp ++) + getc(fp); + break; + + case 4 : /* 16-color */ + for (x = img->xsize, bit = 0xf0; x > 0; x --) + { + /* + * Get a new count as needed... + */ + + if (compression != BI_RLE4 && count == 0) + { + count = 2; + color = -1; + } + + if (count == 0) + { + while (align > 0) + { + align --; + getc(fp); + } + + if ((count = getc(fp)) == 0) + { + if ((count = getc(fp)) == 0) + { + /* + * End of line... + */ + + x ++; + continue; + } + else if (count == 1) + { + /* + * End of image... + */ + + break; + } + else if (count == 2) + { + /* + * Delta... + */ + + count = getc(fp) * getc(fp) * img->xsize; + color = 0; + } + else + { + /* + * Absolute... + */ + + color = -1; + align = ((4 - (count & 3)) / 2) & 1; + } + } + else + color = getc(fp); + } + + /* + * Get a new color as needed... + */ + + count --; + + if (bit == 0xf0) + { + if (color < 0) + temp = getc(fp); + else + temp = color; + + /* + * Copy the color value... + */ + + *ptr++ = colormap[temp >> 4][2]; + *ptr++ = colormap[temp >> 4][1]; + *ptr++ = colormap[temp >> 4][0]; + bit = 0x0f; + } + else + { + /* + * Copy the color value... + */ + + *ptr++ = colormap[temp & 15][2]; + *ptr++ = colormap[temp & 15][1]; + *ptr++ = colormap[temp & 15][0]; + bit = 0xf0; + } + } + break; + + case 8 : /* 256-color */ + for (x = img->xsize; x > 0; x --) + { + /* + * Get a new count as needed... + */ + + if (compression != BI_RLE8) + { + count = 1; + color = -1; + } + + if (count == 0) + { + while (align > 0) + { + align --; + getc(fp); + } + + if ((count = getc(fp)) == 0) + { + if ((count = getc(fp)) == 0) + { + /* + * End of line... + */ + + x ++; + continue; + } + else if (count == 1) + { + /* + * End of image... + */ + + break; + } + else if (count == 2) + { + /* + * Delta... + */ + + count = getc(fp) * getc(fp) * img->xsize; + color = 0; + } + else + { + /* + * Absolute... + */ + + color = -1; + align = (2 - (count & 1)) & 1; + } + } + else + color = getc(fp); + } + + /* + * Get a new color as needed... + */ + + if (color < 0) + temp = getc(fp); + else + temp = color; + + count --; + + /* + * Copy the color value... + */ + + *ptr++ = colormap[temp][2]; + *ptr++ = colormap[temp][1]; + *ptr++ = colormap[temp][0]; + } + break; + + case 24 : /* 24-bit RGB */ + for (x = img->xsize; x > 0; x --, ptr += 3) + { + ptr[2] = getc(fp); + ptr[1] = getc(fp); + ptr[0] = getc(fp); + } + + /* + * Read remaining bytes to align to 32 bits... + */ + + for (temp = img->xsize * 3; temp & 3; temp ++) + getc(fp); + break; + } + + if (img->colorspace == IMAGE_RGB) + { + if (saturation != 100 || hue != 0) + ImageRGBAdjust(out, img->xsize, saturation, hue); + } + else + { + if (saturation != 100 || hue != 0) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->xsize); + break; + } + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + + fclose(fp); + free(in); + free(out); + + return (0); +} + + +/* + * 'read_word()' - Read a 16-bit unsigned integer. + */ + +static unsigned short /* O - 16-bit unsigned integer */ +read_word(FILE *fp) /* I - File to read from */ +{ + unsigned char b0, b1; /* Bytes from file */ + + b0 = getc(fp); + b1 = getc(fp); + + return ((b1 << 8) | b0); +} + + +/* + * 'read_dword()' - Read a 32-bit unsigned integer. + */ + +static unsigned int /* O - 32-bit unsigned integer */ +read_dword(FILE *fp) /* I - File to read from */ +{ + unsigned char b0, b1, b2, b3; /* Bytes from file */ + + b0 = getc(fp); + b1 = getc(fp); + b2 = getc(fp); + b3 = getc(fp); + + return ((((((b3 << 8) | b2) << 8) | b1) << 8) | b0); +} + + +/* + * 'read_long()' - Read a 32-bit signed integer. + */ + +static int /* O - 32-bit signed integer */ +read_long(FILE *fp) /* I - File to read from */ +{ + unsigned char b0, b1, b2, b3; /* Bytes from file */ + + b0 = getc(fp); + b1 = getc(fp); + b2 = getc(fp); + b3 = getc(fp); + + return ((int)(((((b3 << 8) | b2) << 8) | b1) << 8) | b0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-colorspace.c b/filter/image-colorspace.c new file mode 100644 index 0000000000..1a42458be9 --- /dev/null +++ b/filter/image-colorspace.c @@ -0,0 +1,882 @@ +/* + * "$Id$" + * + * Colorspace conversions for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageWhiteToWhite() - Convert luminance colors to device-dependent + * ImageWhiteToRGB() - Convert luminance data to RGB. + * ImageWhiteToBlack() - Convert luminance colors to black. + * ImageWhiteToCMY() - Convert luminance colors to CMY. + * ImageWhiteToCMYK() - Convert luminance colors to CMYK. + * ImageRGBToBlack() - Convert RGB data to black. + * ImageRGBToCMY() - Convert RGB colors to CMY. + * ImageRGBToCMYK() - Convert RGB colors to CMYK. + * ImageRGBToWhite() - Convert RGB colors to luminance. + * ImageRGBToRGB() - Convert RGB colors to device-dependent RGB. + * ImageLut() - Adjust all pixel values with the given LUT. + * ImageRGBAdjust() - Adjust the hue and saturation of the given RGB + * colors. + * huerotate() - Rotate the hue, maintaining luminance. + * ident() - Make an identity matrix. + * mult() - Multiply two matrices. + * saturate() - Make a saturation matrix. + * xform() - Transform a 3D point using a matrix... + * xrotate() - Rotate about the x (red) axis... + * yrotate() - Rotate about the y (green) axis... + * zrotate() - Rotate about the z (blue) axis... + * zshear() - Shear z using x and y... + */ + +/* + * Include necessary headers... + */ + +#include "image.h" +#include + + +/* + * Globals... + */ + +extern int ImageHaveProfile; +extern int ImageDensity[256]; +extern int ImageMatrix[3][3][256]; + +/* + * Local functions... + */ + +static void huerotate(float [3][3], float); +static void ident(float [3][3]); +static void mult(float [3][3], float [3][3], float [3][3]); +static void saturate(float [3][3], float); +static void xform(float [3][3], float, float, float, float *, float *, float *); +static void xrotate(float [3][3], float, float); +static void yrotate(float [3][3], float, float); +static void zrotate(float [3][3], float, float); +static void zshear(float [3][3], float, float); + + +/* + * 'ImageWhiteToWhite()' - Convert luminance colors to device-dependent + * luminance. + */ + +void +ImageWhiteToWhite(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (ImageHaveProfile) + while (count > 0) + { + *out++ = 255 - ImageDensity[255 - *in++]; + count --; + } + else if (in != out) + memcpy(out, in, count); +} + + +/* + * 'ImageWhiteToRGB()' - Convert luminance data to RGB. + */ + +void +ImageWhiteToRGB(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (ImageHaveProfile) + while (count > 0) + { + out[0] = 255 - ImageDensity[255 - *in++]; + out[1] = out[0]; + out[2] = out[0]; + out += 3; + count --; + } + else + while (count > 0) + { + *out++ = *in; + *out++ = *in; + *out++ = *in++; + count --; + } +} + + +/* + * 'ImageWhiteToBlack()' - Convert luminance colors to black. + */ + +void +ImageWhiteToBlack(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (ImageHaveProfile) + while (count > 0) + { + *out++ = ImageDensity[255 - *in++]; + count --; + } + else + while (count > 0) + { + *out++ = 255 - *in++; + count --; + } +} + + +/* + * 'ImageWhiteToCMY()' - Convert luminance colors to CMY. + */ + +void +ImageWhiteToCMY(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (ImageHaveProfile) + while (count > 0) + { + out[0] = ImageDensity[255 - *in++]; + out[1] = out[0]; + out[2] = out[0]; + out += 3; + count --; + } + else + while (count > 0) + { + *out++ = 255 - *in; + *out++ = 255 - *in; + *out++ = 255 - *in++; + count --; + } +} + + +/* + * 'ImageWhiteToCMYK()' - Convert luminance colors to CMYK. + */ + +void +ImageWhiteToCMYK(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (ImageHaveProfile) + while (count > 0) + { + *out++ = 0; + *out++ = 0; + *out++ = 0; + *out++ = ImageDensity[255 - *in++]; + count --; + } + else + while (count > 0) + { + *out++ = 0; + *out++ = 0; + *out++ = 0; + *out++ = 255 - *in++; + count --; + } +} + + +/* + * 'ImageRGBToBlack()' - Convert RGB data to black. + */ + +void +ImageRGBToBlack(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (ImageHaveProfile) + while (count > 0) + { + *out++ = ImageDensity[255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100]; + in += 3; + count --; + } + else + while (count > 0) + { + *out++ = 255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100; + in += 3; + count --; + } +} + + +/* + * 'ImageRGBToCMY()' - Convert RGB colors to CMY. + */ + +void +ImageRGBToCMY(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + int c, m, y, k; /* CMYK values */ + int cc, cm, cy; /* Calibrated CMY values */ + + + if (ImageHaveProfile) + while (count > 0) + { + c = 255 - *in++; + m = 255 - *in++; + y = 255 - *in++; + k = min(c, min(m, y)); + c -= k; + m -= k; + y -= k; + + cc = ImageMatrix[0][0][c] + + ImageMatrix[0][1][m] + + ImageMatrix[0][2][y] + k; + cm = ImageMatrix[1][0][c] + + ImageMatrix[1][1][m] + + ImageMatrix[1][2][y] + k; + cy = ImageMatrix[2][0][c] + + ImageMatrix[2][1][m] + + ImageMatrix[2][2][y] + k; + + if (cc < 0) + *out++ = 0; + else if (cc > 255) + *out++ = ImageDensity[255]; + else + *out++ = ImageDensity[cc]; + + if (cm < 0) + *out++ = 0; + else if (cm > 255) + *out++ = ImageDensity[255]; + else + *out++ = ImageDensity[cm]; + + if (cy < 0) + *out++ = 0; + else if (cy > 255) + *out++ = ImageDensity[255]; + else + *out++ = ImageDensity[cy]; + + count --; + } + else + while (count > 0) + { + c = 255 - in[0]; + m = 255 - in[1]; + y = 255 - in[2]; + k = min(c, min(m, y)); + + *out++ = (255 - in[1] / 4) * (c - k) / 255 + k; + *out++ = (255 - in[2] / 4) * (m - k) / 255 + k; + *out++ = (255 - in[0] / 4) * (y - k) / 255 + k; + in += 3; + count --; + } +} + + +/* + * 'ImageRGBToCMYK()' - Convert RGB colors to CMYK. + */ + +void +ImageRGBToCMYK(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count)/* I - Number of pixels */ +{ + int c, m, y, k, /* CMYK values */ + km; /* Maximum K value */ + int cc, cm, cy; /* Calibrated CMY values */ + + + if (ImageHaveProfile) + while (count > 0) + { + c = 255 - *in++; + m = 255 - *in++; + y = 255 - *in++; + k = min(c, min(m, y)); + + if ((km = max(c, max(m, y))) > k) + k = k * k / km; + + c -= k; + m -= k; + y -= k; + + cc = (ImageMatrix[0][0][c] + + ImageMatrix[0][1][m] + + ImageMatrix[0][2][y]); + cm = (ImageMatrix[1][0][c] + + ImageMatrix[1][1][m] + + ImageMatrix[1][2][y]); + cy = (ImageMatrix[2][0][c] + + ImageMatrix[2][1][m] + + ImageMatrix[2][2][y]); + + if (cc < 0) + *out++ = 0; + else if (cc > 255) + *out++ = ImageDensity[255]; + else + *out++ = ImageDensity[cc]; + + if (cm < 0) + *out++ = 0; + else if (cm > 255) + *out++ = ImageDensity[255]; + else + *out++ = ImageDensity[cm]; + + if (cy < 0) + *out++ = 0; + else if (cy > 255) + *out++ = ImageDensity[255]; + else + *out++ = ImageDensity[cy]; + + *out++ = ImageDensity[k]; + + count --; + } + else + while (count > 0) + { + c = 255 - *in++; + m = 255 - *in++; + y = 255 - *in++; + k = min(c, min(m, y)); + + if ((km = max(c, max(m, y))) > k) + k = k * k / km; + + c -= k; + m -= k; + y -= k; + + *out++ = c; + *out++ = m; + *out++ = y; + *out++ = k; + + count --; + } +} + + +/* + * 'ImageRGBToWhite()' - Convert RGB colors to luminance. + */ + +void +ImageRGBToWhite(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + if (ImageHaveProfile) + while (count > 0) + { + *out++ = 255 - ImageDensity[255 - (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100]; + in += 3; + count --; + } + else + while (count > 0) + { + *out++ = (31 * in[0] + 61 * in[1] + 8 * in[2]) / 100; + in += 3; + count --; + } +} + + +/* + * 'ImageRGBToRGB()' - Convert RGB colors to device-dependent RGB. + */ + +void +ImageRGBToRGB(const ib_t *in, /* I - Input pixels */ + ib_t *out, /* I - Output pixels */ + int count) /* I - Number of pixels */ +{ + int c, m, y, k; /* CMYK values */ + int cr, cg, cb; /* Calibrated RGB values */ + + + if (ImageHaveProfile) + while (count > 0) + { + c = 255 - *in++; + m = 255 - *in++; + y = 255 - *in++; + k = min(c, min(m, y)); + c -= k; + m -= k; + y -= k; + + cr = ImageMatrix[0][0][c] + + ImageMatrix[0][1][m] + + ImageMatrix[0][2][y] + k; + cg = ImageMatrix[1][0][c] + + ImageMatrix[1][1][m] + + ImageMatrix[1][2][y] + k; + cb = ImageMatrix[2][0][c] + + ImageMatrix[2][1][m] + + ImageMatrix[2][2][y] + k; + + if (cr < 0) + *out++ = 255; + else if (cr > 255) + *out++ = 255 - ImageDensity[255]; + else + *out++ = 255 - ImageDensity[cr]; + + if (cg < 0) + *out++ = 255; + else if (cg > 255) + *out++ = 255 - ImageDensity[255]; + else + *out++ = 255 - ImageDensity[cg]; + + if (cb < 0) + *out++ = 255; + else if (cb > 255) + *out++ = 255 - ImageDensity[255]; + else + *out++ = 255 - ImageDensity[cb]; + + count --; + } + else if (in != out) + memcpy(out, in, count * 3); +} + + +/* + * 'ImageLut()' - Adjust all pixel values with the given LUT. + */ + +void +ImageLut(ib_t *pixels, /* IO - Input/output pixels */ + int count, /* I - Number of pixels/bytes to adjust */ + const ib_t *lut) /* I - Lookup table */ +{ + while (count > 0) + { + *pixels = lut[*pixels]; + pixels ++; + count --; + } +} + + +/* + * 'ImageRGBAdjust()' - Adjust the hue and saturation of the given RGB colors. + */ + +void +ImageRGBAdjust(ib_t *pixels, /* IO - Input/output pixels */ + int count, /* I - Number of pixels to adjust */ + int saturation, /* I - Color saturation (%) */ + int hue) /* I - Color hue (degrees) */ +{ + int i, j, k; /* Looping vars */ + float mat[3][3]; /* Color adjustment matrix */ + static int last_sat = 100, /* Last saturation used */ + last_hue = 0; /* Last hue used */ + static int lut[3][3][256]; /* Lookup table for matrix */ + + + if (saturation != last_sat || + hue != last_hue) + { + /* + * Build the color adjustment matrix... + */ + + ident(mat); + saturate(mat, saturation * 0.01); + huerotate(mat, (float)hue); + + /* + * Convert the matrix into a 3x3 array of lookup tables... + */ + + for (i = 0; i < 3; i ++) + for (j = 0; j < 3; j ++) + for (k = 0; k < 256; k ++) + lut[i][j][k] = mat[i][j] * k + 0.5; + + /* + * Save the saturation and hue to compare later... + */ + + last_sat = saturation; + last_hue = hue; + } + + /* + * Adjust each pixel in the given buffer. + */ + + while (count > 0) + { + i = lut[0][0][pixels[0]] + + lut[1][0][pixels[1]] + + lut[2][0][pixels[2]]; + if (i < 0) + pixels[0] = 0; + else if (i > 255) + pixels[0] = 255; + else + pixels[0] = i; + + i = lut[0][1][pixels[0]] + + lut[1][1][pixels[1]] + + lut[2][1][pixels[2]]; + if (i < 0) + pixels[1] = 0; + else if (i > 255) + pixels[1] = 255; + else + pixels[1] = i; + + i = lut[0][2][pixels[0]] + + lut[1][2][pixels[1]] + + lut[2][2][pixels[2]]; + if (i < 0) + pixels[2] = 0; + else if (i > 255) + pixels[2] = 255; + else + pixels[2] = i; + + count --; + pixels += 3; + } +} + + +/* + * The color saturation/hue matrix stuff is provided thanks to Mr. Paul + * Haeberli at "http://www.sgi.com/grafica/matrix/index.html". + */ + +/* + * 'huerotate()' - Rotate the hue, maintaining luminance. + */ + +static void +huerotate(float mat[3][3], /* I - Matrix to append to */ + float rot) /* I - Hue rotation in degrees */ +{ + float hmat[3][3]; /* Hue matrix */ + float lx, ly, lz; /* Luminance vector */ + float xrs, xrc; /* X rotation sine/cosine */ + float yrs, yrc; /* Y rotation sine/cosine */ + float zrs, zrc; /* Z rotation sine/cosine */ + float zsx, zsy; /* Z shear x/y */ + + + /* + * Load the identity matrix... + */ + + ident(hmat); + + /* + * Rotate the grey vector into positive Z... + */ + + xrs = M_SQRT1_2; + xrc = M_SQRT1_2; + xrotate(hmat,xrs,xrc); + + yrs = -1.0 / sqrt(3.0); + yrc = -M_SQRT2 * yrs; + yrotate(hmat,yrs,yrc); + + /* + * Shear the space to make the luminance plane horizontal... + */ + + xform(hmat, 0.3086, 0.6094, 0.0820, &lx, &ly, &lz); + zsx = lx / lz; + zsy = ly / lz; + zshear(hmat, zsx, zsy); + + /* + * Rotate the hue... + */ + + zrs = sin(rot * M_PI / 180.0); + zrc = cos(rot * M_PI / 180.0); + + zrotate(hmat, zrs, zrc); + + /* + * Unshear the space to put the luminance plane back... + */ + + zshear(hmat, -zsx, -zsy); + + /* + * Rotate the grey vector back into place... + */ + + yrotate(hmat, -yrs, yrc); + xrotate(hmat, -xrs, xrc); + + /* + * Append it to the current matrix... + */ + + mult(hmat, mat, mat); +} + + +/* + * 'ident()' - Make an identity matrix. + */ + +static void +ident(float mat[3][3]) /* I - Matrix to identify */ +{ + mat[0][0] = 1.0; + mat[0][1] = 0.0; + mat[0][2] = 0.0; + mat[1][0] = 0.0; + mat[1][1] = 1.0; + mat[1][2] = 0.0; + mat[2][0] = 0.0; + mat[2][1] = 0.0; + mat[2][2] = 1.0; +} + + +/* + * 'mult()' - Multiply two matrices. + */ + +static void +mult(float a[3][3], /* I - First matrix */ + float b[3][3], /* I - Second matrix */ + float c[3][3]) /* I - Destination matrix */ +{ + int x, y; /* Looping vars */ + float temp[3][3]; /* Temporary matrix */ + + + /* + * Multiply a and b, putting the result in temp... + */ + + for (y = 0; y < 3; y ++) + for (x = 0; x < 3; x ++) + temp[y][x] = b[y][0] * a[0][x] + + b[y][1] * a[1][x] + + b[y][2] * a[2][x]; + + /* + * Copy temp to c (that way c can be a pointer to a or b). + */ + + memcpy(c, temp, sizeof(temp)); +} + + +/* + * 'saturate()' - Make a saturation matrix. + */ + +static void +saturate(float mat[3][3], /* I - Matrix to append to */ + float sat) /* I - Desired color saturation */ +{ + float smat[3][3]; /* Saturation matrix */ + + + smat[0][0] = (1.0 - sat) * 0.3086 + sat; + smat[0][1] = (1.0 - sat) * 0.3086; + smat[0][2] = (1.0 - sat) * 0.3086; + smat[1][0] = (1.0 - sat) * 0.6094; + smat[1][1] = (1.0 - sat) * 0.6094 + sat; + smat[1][2] = (1.0 - sat) * 0.6094; + smat[2][0] = (1.0 - sat) * 0.0820; + smat[2][1] = (1.0 - sat) * 0.0820; + smat[2][2] = (1.0 - sat) * 0.0820 + sat; + + mult(smat, mat, mat); +} + + +/* + * 'xform()' - Transform a 3D point using a matrix... + */ + +static void +xform(float mat[3][3], /* I - Matrix */ + float x, /* I - Input X coordinate */ + float y, /* I - Input Y coordinate */ + float z, /* I - Input Z coordinate */ + float *tx, /* O - Output X coordinate */ + float *ty, /* O - Output Y coordinate */ + float *tz) /* O - Output Z coordinate */ +{ + *tx = x * mat[0][0] + y * mat[1][0] + z * mat[2][0]; + *ty = x * mat[0][1] + y * mat[1][1] + z * mat[2][1]; + *tz = x * mat[0][2] + y * mat[1][2] + z * mat[2][2]; +} + + +/* + * 'xrotate()' - Rotate about the x (red) axis... + */ + +static void +xrotate(float mat[3][3], /* I - Matrix */ + float rs, /* I - Rotation angle sine */ + float rc) /* I - Rotation angle cosine */ +{ + float rmat[3][3]; /* I - Rotation matrix */ + + + rmat[0][0] = 1.0; + rmat[0][1] = 0.0; + rmat[0][2] = 0.0; + + rmat[1][0] = 0.0; + rmat[1][1] = rc; + rmat[1][2] = rs; + + rmat[2][0] = 0.0; + rmat[2][1] = -rs; + rmat[2][2] = rc; + + mult(rmat, mat, mat); +} + + +/* + * 'yrotate()' - Rotate about the y (green) axis... + */ + +static void +yrotate(float mat[3][3], /* I - Matrix */ + float rs, /* I - Rotation angle sine */ + float rc) /* I - Rotation angle cosine */ +{ + float rmat[3][3]; /* I - Rotation matrix */ + + + rmat[0][0] = rc; + rmat[0][1] = 0.0; + rmat[0][2] = -rs; + + rmat[1][0] = 0.0; + rmat[1][1] = 1.0; + rmat[1][2] = 0.0; + + rmat[2][0] = rs; + rmat[2][1] = 0.0; + rmat[2][2] = rc; + + mult(rmat,mat,mat); +} + + +/* + * 'zrotate()' - Rotate about the z (blue) axis... + */ + +static void +zrotate(float mat[3][3], /* I - Matrix */ + float rs, /* I - Rotation angle sine */ + float rc) /* I - Rotation angle cosine */ +{ + float rmat[3][3]; /* I - Rotation matrix */ + + + rmat[0][0] = rc; + rmat[0][1] = rs; + rmat[0][2] = 0.0; + + rmat[1][0] = -rs; + rmat[1][1] = rc; + rmat[1][2] = 0.0; + + rmat[2][0] = 0.0; + rmat[2][1] = 0.0; + rmat[2][2] = 1.0; + + mult(rmat,mat,mat); +} + + +/* + * 'zshear()' - Shear z using x and y... + */ + +static void +zshear(float mat[3][3], /* I - Matrix */ + float dx, /* I - X shear */ + float dy) /* I - Y shear */ +{ + float smat[3][3]; /* Shear matrix */ + + + smat[0][0] = 1.0; + smat[0][1] = 0.0; + smat[0][2] = dx; + + smat[1][0] = 0.0; + smat[1][1] = 1.0; + smat[1][2] = dy; + + smat[2][0] = 0.0; + smat[2][1] = 0.0; + smat[2][2] = 1.0; + + mult(smat, mat, mat); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-gif.c b/filter/image-gif.c new file mode 100644 index 0000000000..d1d5c6e977 --- /dev/null +++ b/filter/image-gif.c @@ -0,0 +1,644 @@ +/* + * "$Id$" + * + * GIF image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadGIF() - Read a GIF image file. + * gif_read_cmap() - Read the colormap from a GIF file... + * gif_get_block() - Read a GIF data block... + * gif_get_code() - Get a LZW code from the file... + * gif_read_lzw() - Read a byte from the LZW stream... + * gif_read_image() - Read a GIF image stream... + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + + +/* + * GIF definitions... + */ + +#define GIF_INTERLACE 0x40 +#define GIF_COLORMAP 0x80 + +typedef ib_t gif_cmap_t[256][4]; + + +/* + * Local globals... + */ + +static int gif_eof = 0; /* Did we hit EOF? */ + + +/* + * Local functions... + */ + +static int gif_read_cmap(FILE *fp, int ncolors, gif_cmap_t cmap, + int *gray); +static int gif_get_block(FILE *fp, unsigned char *buffer); +static int gif_get_code (FILE *fp, int code_size, int first_time); +static int gif_read_lzw(FILE *fp, int first_time, int input_code_size); +static int gif_read_image(FILE *fp, image_t *img, gif_cmap_t cmap, + int interlace); + + +/* + * 'ImageReadGIF()' - Read a GIF image file. + */ + +int /* O - Read status */ +ImageReadGIF(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + unsigned char buf[1024]; /* Input buffer */ + gif_cmap_t cmap; /* Colormap */ + int i, /* Looping var */ + bpp, /* Bytes per pixel */ + gray, /* Grayscale image? */ + ncolors, /* Bits per pixel */ + transparent; /* Transparent color index */ + + + /* + * Read the header; we already know it is a GIF file... + */ + + fread(buf, 13, 1, fp); + + img->xsize = (buf[7] << 8) | buf[6]; + img->ysize = (buf[9] << 8) | buf[8]; + ncolors = 2 << (buf[10] & 0x07); + gray = primary == IMAGE_BLACK || primary == IMAGE_WHITE; + + if (buf[10] & GIF_COLORMAP) + if (gif_read_cmap(fp, ncolors, cmap, &gray)) + { + fclose(fp); + return (-1); + } + + transparent = -1; + + for (;;) + { + switch (getc(fp)) + { + case ';' : /* End of image */ + fclose(fp); + return (-1); /* Early end of file */ + + case '!' : /* Extension record */ + buf[0] = getc(fp); + if (buf[0] == 0xf9) /* Graphic Control Extension */ + { + gif_get_block(fp, buf); + if (buf[0] & 1) /* Get transparent color index */ + transparent = buf[3]; + } + + while (gif_get_block(fp, buf) != 0); + break; + + case ',' : /* Image data */ + fread(buf, 9, 1, fp); + + if (buf[8] & GIF_COLORMAP) + { + ncolors = 2 << (buf[8] & 0x07); + gray = primary == IMAGE_BLACK || primary == IMAGE_WHITE; + + if (gif_read_cmap(fp, ncolors, cmap, &gray)) + { + fclose(fp); + return (-1); + } + } + + if (transparent >= 0) + { + /* + * Make transparent color white... + */ + + cmap[transparent][0] = 255; + cmap[transparent][1] = 255; + cmap[transparent][2] = 255; + } + + if (gray) + { + switch (secondary) + { + case IMAGE_CMYK : + for (i = ncolors - 1; i >= 0; i --) + ImageWhiteToCMYK(cmap[i], cmap[i], 1); + break; + case IMAGE_CMY : + for (i = ncolors - 1; i >= 0; i --) + ImageWhiteToCMY(cmap[i], cmap[i], 1); + break; + case IMAGE_BLACK : + for (i = ncolors - 1; i >= 0; i --) + ImageWhiteToBlack(cmap[i], cmap[i], 1); + break; + case IMAGE_WHITE : + break; + case IMAGE_RGB : + for (i = ncolors - 1; i >= 0; i --) + ImageWhiteToRGB(cmap[i], cmap[i], 1); + break; + } + + img->colorspace = secondary; + } + else + { + if (hue != 0 || saturation != 100) + for (i = ncolors - 1; i >= 0; i --) + ImageRGBAdjust(cmap[i], 1, saturation, hue); + + switch (primary) + { + case IMAGE_CMYK : + for (i = ncolors - 1; i >= 0; i --) + ImageRGBToCMYK(cmap[i], cmap[i], 1); + break; + case IMAGE_CMY : + for (i = ncolors - 1; i >= 0; i --) + ImageRGBToCMY(cmap[i], cmap[i], 1); + break; + case IMAGE_BLACK : + for (i = ncolors - 1; i >= 0; i --) + ImageRGBToBlack(cmap[i], cmap[i], 1); + break; + case IMAGE_WHITE : + for (i = ncolors - 1; i >= 0; i --) + ImageRGBToWhite(cmap[i], cmap[i], 1); + break; + case IMAGE_RGB : + break; + } + + img->colorspace = primary; + } + + if (lut) + { + bpp = ImageGetDepth(img); + + for (i = ncolors - 1; i >= 0; i --) + ImageLut(cmap[i], bpp, lut); + } + + img->xsize = (buf[5] << 8) | buf[4]; + img->ysize = (buf[7] << 8) | buf[6]; + + i = gif_read_image(fp, img, cmap, buf[8] & GIF_INTERLACE); + fclose(fp); + return (i); + } + } +} + + +/* + * 'gif_read_cmap()' - Read the colormap from a GIF file... + */ + +static int /* O - -1 on error, 0 on success */ +gif_read_cmap(FILE *fp, /* I - File to read from */ + int ncolors, /* I - Number of colors in file */ + gif_cmap_t cmap, /* O - Colormap information */ + int *gray) /* IO - Is the image grayscale? */ +{ + int i; /* Looping var */ + + + /* + * Read the colormap... + */ + + for (i = 0; i < ncolors; i ++) + if (fread(cmap[i], 3, 1, fp) < 1) + return (-1); + + /* + * Check to see if the colormap is a grayscale ramp... + */ + + for (i = 0; i < ncolors; i ++) + if (cmap[i][0] != cmap[i][1] || cmap[i][1] != cmap[i][2]) + break; + + if (i == ncolors) + { + *gray = 1; + return (0); + } + + /* + * If this needs to be a grayscale image, convert the RGB values to + * luminance values... + */ + + if (*gray) + for (i = 0; i < ncolors; i ++) + cmap[i][0] = (cmap[i][0] * 31 + cmap[i][1] * 61 + cmap[i][2] * 8) / 100; + + return (0); +} + + +/* + * 'gif_get_block()' - Read a GIF data block... + */ + +static int /* O - Number characters read */ +gif_get_block(FILE *fp, /* I - File to read from */ + unsigned char *buf) /* I - Input buffer */ +{ + int count; /* Number of character to read */ + + + /* + * Read the count byte followed by the data from the file... + */ + + if ((count = getc(fp)) == EOF) + { + gif_eof = 1; + return (-1); + } + else if (count == 0) + gif_eof = 1; + else if (fread(buf, 1, count, fp) < count) + { + gif_eof = 1; + return (-1); + } + else + gif_eof = 0; + + return (count); +} + + +/* + * 'gif_get_code()' - Get a LZW code from the file... + */ + +static int /* O - LZW code */ +gif_get_code(FILE *fp, /* I - File to read from */ + int code_size, /* I - Size of code in bits */ + int first_time) /* I - 1 = first time, 0 = not first time */ +{ + unsigned i, j, /* Looping vars */ + ret; /* Return value */ + int count; /* Number of bytes read */ + static unsigned char buf[280]; /* Input buffer */ + static unsigned curbit, /* Current bit */ + lastbit, /* Last bit in buffer */ + done, /* Done with this buffer? */ + last_byte; /* Last byte in buffer */ + static unsigned char bits[8] = /* Bit masks for codes */ + { + 0x01, 0x02, 0x04, 0x08, + 0x10, 0x20, 0x40, 0x80 + }; + + + if (first_time) + { + /* + * Just initialize the input buffer... + */ + + curbit = 0; + lastbit = 0; + done = 0; + + return (0); + } + + + if ((curbit + code_size) >= lastbit) + { + /* + * Don't have enough bits to hold the code... + */ + + if (done) + return (-1); /* Sorry, no more... */ + + /* + * Move last two bytes to front of buffer... + */ + + buf[0] = buf[last_byte - 2]; + buf[1] = buf[last_byte - 1]; + + /* + * Read in another buffer... + */ + + if ((count = gif_get_block (fp, buf + 2)) <= 0) + { + /* + * Whoops, no more data! + */ + + done = 1; + return (-1); + } + + /* + * Update buffer state... + */ + + last_byte = 2 + count; + curbit = (curbit - lastbit) + 16; + lastbit = last_byte * 8; + } + + ret = 0; + for (ret = 0, i = curbit + code_size - 1, j = code_size; + j > 0; + i --, j --) + ret = (ret << 1) | ((buf[i / 8] & bits[i & 7]) != 0); + + curbit += code_size; + + return ret; +} + + +/* + * 'gif_read_lzw()' - Read a byte from the LZW stream... + */ + +static int /* I - Byte from stream */ +gif_read_lzw(FILE *fp, /* I - File to read from */ + int first_time, /* I - 1 = first time, 0 = not first time */ + int input_code_size) /* I - Code size in bits */ +{ + int i, /* Looping var */ + code, /* Current code */ + incode; /* Input code */ + static short fresh = 0, /* 1 = empty buffers */ + code_size, /* Current code size */ + set_code_size, /* Initial code size set */ + max_code, /* Maximum code used */ + max_code_size, /* Maximum code size */ + firstcode, /* First code read */ + oldcode, /* Last code read */ + clear_code, /* Clear code for LZW input */ + end_code, /* End code for LZW input */ + table[2][4096], /* String table */ + stack[8192], /* Output stack */ + *sp; /* Current stack pointer */ + + + if (first_time) + { + /* + * Setup LZW state... + */ + + set_code_size = input_code_size; + code_size = set_code_size + 1; + clear_code = 1 << set_code_size; + end_code = clear_code + 1; + max_code_size = 2 * clear_code; + max_code = clear_code + 2; + + /* + * Initialize input buffers... + */ + + gif_get_code(fp, 0, 1); + + /* + * Wipe the decompressor table... + */ + + fresh = 1; + + for (i = 0; i < clear_code; i ++) + { + table[0][i] = 0; + table[1][i] = i; + } + + for (; i < 4096; i ++) + table[0][i] = table[1][0] = 0; + + sp = stack; + + return (0); + } + else if (fresh) + { + fresh = 0; + + do + firstcode = oldcode = gif_get_code(fp, code_size, 0); + while (firstcode == clear_code); + + return (firstcode); + } + + if (sp > stack) + return (*--sp); + + while ((code = gif_get_code (fp, code_size, 0)) >= 0) + { + if (code == clear_code) + { + for (i = 0; i < clear_code; i ++) + { + table[0][i] = 0; + table[1][i] = i; + } + + for (; i < 4096; i ++) + table[0][i] = table[1][i] = 0; + + code_size = set_code_size + 1; + max_code_size = 2 * clear_code; + max_code = clear_code + 2; + + sp = stack; + + firstcode = oldcode = gif_get_code(fp, code_size, 0); + + return (firstcode); + } + else if (code == end_code) + { + unsigned char buf[260]; + + + if (!gif_eof) + while (gif_get_block(fp, buf) > 0); + + return (-2); + } + + incode = code; + + if (code >= max_code) + { + *sp++ = firstcode; + code = oldcode; + } + + while (code >= clear_code) + { + *sp++ = table[1][code]; + if (code == table[0][code]) + return (255); + + code = table[0][code]; + } + + *sp++ = firstcode = table[1][code]; + code = max_code; + + if (code < 4096) + { + table[0][code] = oldcode; + table[1][code] = firstcode; + max_code ++; + + if (max_code >= max_code_size && max_code_size < 4096) + { + max_code_size *= 2; + code_size ++; + } + } + + oldcode = incode; + + if (sp > stack) + return (*--sp); + } + + return (code); +} + + +/* + * 'gif_read_image()' - Read a GIF image stream... + */ + +static int /* I - 0 = success, -1 = failure */ +gif_read_image(FILE *fp, /* I - Input file */ + image_t *img, /* I - Image pointer */ + gif_cmap_t cmap, /* I - Colormap */ + int interlace) /* I - Non-zero = interlaced image */ +{ + unsigned char code_size; /* Code size */ + ib_t *pixels, /* Pixel buffer */ + *temp; /* Current pixel */ + int xpos, /* Current X position */ + ypos, /* Current Y position */ + pass; /* Current pass */ + int pixel; /* Current pixel */ + int bpp; /* Bytes per pixel */ + static int xpasses[4] = { 8, 8, 4, 2 }, + ypasses[5] = { 0, 4, 2, 1, 999999 }; + + + bpp = ImageGetDepth(img); + pixels = calloc(bpp, img->xsize); + xpos = 0; + ypos = 0; + pass = 0; + code_size = getc(fp); + + if (gif_read_lzw(fp, 1, code_size) < 0) + return (-1); + + temp = pixels; + while ((pixel = gif_read_lzw(fp, 0, code_size)) >= 0) + { + switch (bpp) + { + case 4 : + temp[3] = cmap[pixel][3]; + case 3 : + temp[2] = cmap[pixel][2]; + case 2 : + temp[1] = cmap[pixel][1]; + default : + temp[0] = cmap[pixel][0]; + } + + xpos ++; + temp += bpp; + if (xpos == img->xsize) + { + ImagePutRow(img, 0, ypos, img->xsize, pixels); + + xpos = 0; + temp = pixels; + + if (interlace) + { + ypos += xpasses[pass]; + + if (ypos >= img->ysize) + { + pass ++; + + ypos = ypasses[pass]; + } + } + else + ypos ++; + } + + if (ypos >= img->ysize) + break; + } + + free(pixels); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-jpeg.c b/filter/image-jpeg.c new file mode 100644 index 0000000000..2f92dc263f --- /dev/null +++ b/filter/image-jpeg.c @@ -0,0 +1,194 @@ +/* + * "$Id$" + * + * JPEG image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadJPEG() - Read a JPEG image file. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + +#ifdef HAVE_LIBJPEG +# include /* JPEG/JFIF image definitions */ + + +/* + * 'ImageReadJPEG()' - Read a JPEG image file. + */ + +int /* O - Read status */ +ImageReadJPEG(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + struct jpeg_decompress_struct cinfo; /* Decompressor info */ + struct jpeg_error_mgr jerr; /* Error handler info */ + ib_t *in, /* Input pixels */ + *out; /* Output pixels */ + + + (void)secondary; + + cinfo.err = jpeg_std_error(&jerr); + jpeg_create_decompress(&cinfo); + jpeg_stdio_src(&cinfo, fp); + jpeg_read_header(&cinfo, 1); + + cinfo.quantize_colors = 0; + + if (cinfo.num_components == 1) + { + cinfo.out_color_space = JCS_GRAYSCALE; + cinfo.out_color_components = 1; + cinfo.output_components = 1; + } + else + { + cinfo.out_color_space = JCS_RGB; + cinfo.out_color_components = 3; + cinfo.output_components = 3; + } + + jpeg_calc_output_dimensions(&cinfo); + + img->xsize = cinfo.output_width; + img->ysize = cinfo.output_height; + img->colorspace = primary; + + if (cinfo.X_density > 0 && cinfo.Y_density > 0 && cinfo.density_unit > 0) + { + if (cinfo.density_unit == 1) + { + img->xppi = cinfo.X_density; + img->yppi = cinfo.Y_density; + } + else + { + img->xppi = (int)((float)cinfo.X_density * 2.54); + img->yppi = (int)((float)cinfo.Y_density * 2.54); + } + } + + fprintf(stderr, "DEBUG: JPEG image %dx%dx%d, %dx%d PPI\n", + img->xsize, img->colorspace, cinfo.output_components, + img->xppi, img->yppi); + + ImageSetMaxTiles(img, 0); + + in = malloc(img->xsize * cinfo.output_components); + if (primary < 0) + out = malloc(-img->xsize * primary); + else + out = malloc(img->xsize * primary); + + jpeg_start_decompress(&cinfo); + + while (cinfo.output_scanline < cinfo.output_height) + { + jpeg_read_scanlines(&cinfo, (JSAMPROW *)&in, (JDIMENSION)1); + + if ((saturation != 100 || hue != 0) && cinfo.output_components > 1) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + if ((primary == IMAGE_WHITE && cinfo.out_color_space == JCS_GRAYSCALE) || + (primary == IMAGE_RGB && cinfo.out_color_space == JCS_RGB)) + { + if (lut) + ImageLut(in, img->xsize * ImageGetDepth(img), lut); + + ImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, in); + } + else if (cinfo.out_color_space == JCS_GRAYSCALE) + { + switch (primary) + { + case IMAGE_BLACK : + ImageWhiteToBlack(in, out, img->xsize); + break; + case IMAGE_RGB : + ImageWhiteToRGB(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageWhiteToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * ImageGetDepth(img), lut); + + ImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out); + } + else + { + switch (primary) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * ImageGetDepth(img), lut); + + ImagePutRow(img, 0, cinfo.output_scanline - 1, img->xsize, out); + } + } + + free(in); + free(out); + + jpeg_finish_decompress(&cinfo); + jpeg_destroy_decompress(&cinfo); + + fclose(fp); + + return (0); +} + + +#endif /* HAVE_LIBJPEG */ + + +/* + * End of "$Id$". + */ diff --git a/filter/image-photocd.c b/filter/image-photocd.c new file mode 100644 index 0000000000..9df3044dee --- /dev/null +++ b/filter/image-photocd.c @@ -0,0 +1,323 @@ +/* + * "$Id$" + * + * PhotoCD routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadPhotoCD() - Read a PhotoCD image file. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + + +/* + * PhotoCD support is currently limited to the 768x512 base image, which + * is only YCC encoded. Support for the higher resolution images will + * require a lot of extra code... + */ + +/* + * 'ImageReadPhotoCD()' - Read a PhotoCD image file. + */ + +int /* O - Read status */ +ImageReadPhotoCD(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + int x, y; /* Looping vars */ + int xdir, /* X direction */ + xstart; /* X starting point */ + int bpp; /* Bytes per pixel */ + int pass; /* Pass number */ + int rotation; /* 0 for 768x512, 1 for 512x768 */ + int temp, /* Adjusted luminance */ + temp2, /* Red, green, and blue values */ + cb, cr; /* Adjusted chroma values */ + ib_t *in, /* Input (YCC) pixels */ + *iy, /* Luminance */ + *icb, /* Blue chroma */ + *icr, /* Red chroma */ + *rgb, /* RGB */ + *rgbptr, /* Pointer into RGB data */ + *out; /* Output pixels */ + + + (void)secondary; + + /* + * Get the image orientation... + */ + + fseek(fp, 72, SEEK_SET); + rotation = (getc(fp) & 63) != 8; + + /* + * Seek to the start of the base image... + */ + + fseek(fp, 0x30000, SEEK_SET); + + /* + * Allocate and initialize... + */ + + img->colorspace = primary; + img->xppi = 128; + img->yppi = 128; + + if (rotation) + { + img->xsize = 512; + img->ysize = 768; + } + else + { + img->xsize = 768; + img->ysize = 512; + } + + ImageSetMaxTiles(img, 0); + + bpp = ImageGetDepth(img); + in = malloc(768 * 3); + out = malloc(768 * bpp); + + if (bpp > 1) + rgb = malloc(768 * 3); + else + rgb = NULL; + + if (rotation) + { + xstart = 767 * bpp; + xdir = -2 * bpp; + } + else + { + xstart = 0; + xdir = 0; + } + + /* + * Read the image file... + */ + + for (y = 0; y < 512; y += 2) + { + /* + * Grab the next two scanlines: + * + * YYYYYYYYYYYYYYY... + * YYYYYYYYYYYYYYY... + * CbCbCb...CrCrCr... + */ + + if (fread(in, 1, 768 * 3, fp) < (768 * 3)) + { + /* + * Couldn't read a row of data - return an error! + */ + + free(in); + free(out); + + return (-1); + } + + /* + * Process the two scanlines... + */ + + for (pass = 0, iy = in; pass < 2; pass ++) + { + if (bpp == 1) + { + /* + * Just extract the luminance channel from the line and put it + * in the image... + */ + + if (primary == IMAGE_BLACK) + { + if (rotation) + { + for (rgbptr = out + xstart, x = 0; x < 768; x ++) + *rgbptr-- = 255 - *iy++; + + if (lut) + ImageLut(out, 768, lut); + + ImagePutCol(img, 511 - y - pass, 0, 768, out); + } + else + { + ImageWhiteToBlack(iy, out, 768); + + if (lut) + ImageLut(out, 768, lut); + + ImagePutRow(img, 0, y + pass, 768, out); + iy += 768; + } + } + else if (rotation) + { + for (rgbptr = out + xstart, x = 0; x < 768; x ++) + *rgbptr-- = 255 - *iy++; + + if (lut) + ImageLut(out, 768, lut); + + ImagePutCol(img, 511 - y - pass, 0, 768, out); + } + else + { + if (lut) + ImageLut(iy, 768, lut); + + ImagePutRow(img, 0, y + pass, 768, iy); + iy += 768; + } + } + else + { + /* + * Convert YCbCr to RGB... While every pixel gets a luminance + * value, adjacent pixels share chroma information. + */ + + cb = cr = 0.0f; + + for (x = 0, rgbptr = rgb + xstart, icb = in + 1536, icr = in + 1920; + x < 768; + x ++, iy ++, rgbptr += xdir) + { + if (!(x & 1)) + { + cb = (float)(*icb - 156); + cr = (float)(*icr - 137); + } + + temp = 92241 * (*iy); + + temp2 = (temp + 86706 * cr) / 65536; + if (temp2 < 0) + *rgbptr++ = 0; + else if (temp2 > 255) + *rgbptr++ = 255; + else + *rgbptr++ = temp2; + + temp2 = (temp - 25914 * cb - 44166 * cr) / 65536; + if (temp2 < 0) + *rgbptr++ = 0; + else if (temp2 > 255) + *rgbptr++ = 255; + else + *rgbptr++ = temp2; + + temp2 = (temp + 133434 * cb) / 65536; + if (temp2 < 0) + *rgbptr++ = 0; + else if (temp2 > 255) + *rgbptr++ = 255; + else + *rgbptr++ = temp2; + + if (x & 1) + { + icb ++; + icr ++; + } + } + + /* + * Adjust the hue and saturation if needed... + */ + + if (saturation != 100 || hue != 0) + ImageRGBAdjust(rgb, 768, saturation, hue); + + /* + * Then convert the RGB data to the appropriate colorspace and + * put it in the image... + */ + + if (img->colorspace == IMAGE_RGB) + { + if (lut) + ImageLut(rgb, 768 * 3, lut); + + if (rotation) + ImagePutCol(img, 511 - y - pass, 0, 768, rgb); + else + ImagePutRow(img, 0, y + pass, 768, rgb); + } + else + { + switch (img->colorspace) + { + case IMAGE_CMY : + ImageRGBToCMY(rgb, out, 768); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(rgb, out, 768); + break; + } + + if (lut) + ImageLut(out, 768 * bpp, lut); + + if (rotation) + ImagePutCol(img, 511 - y - pass, 0, 768, out); + else + ImagePutRow(img, 0, y + pass, 768, out); + } + } + } + } + + /* + * Free memory and return... + */ + + free(in); + free(out); + if (bpp > 1) + free(rgb); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-pix.c b/filter/image-pix.c new file mode 100644 index 0000000000..4cb742e8ff --- /dev/null +++ b/filter/image-pix.c @@ -0,0 +1,223 @@ +/* + * "$Id$" + * + * Alias PIX image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadPIX() - Read a PIX image file. + * read_short() - Read a 16-bit integer. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + + +/* + * Local functions... + */ + +static short read_short(FILE *fp); + + +/* + * 'ImageReadPIX()' - Read a PIX image file. + */ + +int /* O - Read status */ +ImageReadPIX(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + short width, /* Width of image */ + height, /* Height of image */ + depth; /* Depth of image (bits) */ + int count, /* Repetition count */ + bpp, /* Bytes per pixel */ + x, y; /* Looping vars */ + ib_t r, g, b; /* Red, green/gray, blue values */ + ib_t *in, /* Input pixels */ + *out, /* Output pixels */ + *ptr; /* Pointer into pixels */ + + + /* + * Get the image dimensions and setup the image... + */ + + width = read_short(fp); + height = read_short(fp); + read_short(fp); + read_short(fp); + depth = read_short(fp); + + if (depth == 8) + img->colorspace = secondary; + else + img->colorspace = primary; + + img->xsize = width; + img->ysize = height; + + ImageSetMaxTiles(img, 0); + + in = malloc(img->xsize * (depth / 8)); + bpp = ImageGetDepth(img); + out = malloc(img->xsize * bpp); + + /* + * Read the image data... + */ + + if (depth == 8) + { + for (count = 0, y = 0; y < img->ysize; y ++) + { + if (img->colorspace == IMAGE_WHITE) + ptr = out; + else + ptr = in; + + for (x = img->xsize; x > 0; x --, count --) + { + if (count == 0) + { + count = getc(fp); + g = getc(fp); + } + + *ptr++ = g; + } + + if (img->colorspace != IMAGE_WHITE) + switch (img->colorspace) + { + case IMAGE_RGB : + ImageWhiteToRGB(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageWhiteToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageWhiteToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + else + { + for (count = 0, y = 0; y < img->ysize; y ++) + { + if (img->colorspace == IMAGE_RGB) + ptr = out; + else + ptr = in; + + for (x = img->xsize; x > 0; x --, count --) + { + if (count == 0) + { + count = getc(fp); + b = getc(fp); + g = getc(fp); + r = getc(fp); + } + + *ptr++ = r; + *ptr++ = g; + *ptr++ = b; + } + + if (img->colorspace == IMAGE_RGB) + { + if (saturation != 100 || hue != 0) + ImageRGBAdjust(out, img->xsize, saturation, hue); + } + else + { + if (saturation != 100 || hue != 0) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->xsize); + break; + } + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + + fclose(fp); + free(in); + free(out); + + return (0); +} + + +/* + * 'read_short()' - Read a 16-bit integer. + */ + +static short /* O - Value from file */ +read_short(FILE *fp) /* I - File to read from */ +{ + int ch; /* Character from file */ + + + ch = getc(fp); + return ((ch << 8) | getc(fp)); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-png.c b/filter/image-png.c new file mode 100644 index 0000000000..996e1726a9 --- /dev/null +++ b/filter/image-png.c @@ -0,0 +1,250 @@ +/* + * "$Id$" + * + * PNG image routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadPNG() - Read a PNG image file. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + +#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) +#include /* Portable Network Graphics (PNG) definitions */ + + +/* + * 'ImageReadPNG()' - Read a PNG image file. + */ + +int /* O - Read status */ +ImageReadPNG(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + int y; /* Looping var */ + png_structp pp; /* PNG read pointer */ + png_infop info; /* PNG info pointers */ + int bpp; /* Bytes per pixel */ + int pass, /* Current pass */ + passes; /* Number of passes required */ + ib_t *in, /* Input pixels */ + *inptr, /* Pointer into pixels */ + *out; /* Output pixels */ + png_color_16 bg; /* Background color */ + + /* + * Setup the PNG data structures... + */ + + pp = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + info = png_create_info_struct(pp); + + /* + * Initialize the PNG read "engine"... + */ + + png_init_io(pp, fp); + + /* + * Get the image dimensions and load the output image... + */ + + png_read_info(pp, info); + + if (info->color_type == PNG_COLOR_TYPE_PALETTE) + png_set_expand(pp); + + if (info->color_type == PNG_COLOR_TYPE_GRAY || + info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + img->colorspace = secondary; + else + img->colorspace = primary; + + img->xsize = info->width; + img->ysize = info->height; + + if (info->valid & PNG_INFO_pHYs && + info->phys_unit_type == PNG_RESOLUTION_METER) + { + img->xppi = (int)((float)info->x_pixels_per_unit * 0.0254); + img->yppi = (int)((float)info->y_pixels_per_unit * 0.0254); + } + + ImageSetMaxTiles(img, 0); + + if (info->bit_depth < 8) + { + png_set_packing(pp); + + if (info->valid & PNG_INFO_sBIT) + png_set_shift(pp, &(info->sig_bit)); + } + else if (info->bit_depth == 16) + png_set_strip_16(pp); + + passes = png_set_interlace_handling(pp); + + /* + * Handle transparency... + */ + + if (png_get_valid(pp, info, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(pp); + + bg.red = 65535; + bg.green = 65535; + bg.blue = 65535; + + png_set_background(pp, &bg, PNG_BACKGROUND_GAMMA_SCREEN, 0, 1.0); + + if (passes == 1) + { + /* + * Load one row at a time... + */ + + if (info->color_type == PNG_COLOR_TYPE_GRAY || + info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + in = malloc(img->xsize); + else + in = malloc(img->xsize * 3); + } + else + { + /* + * Interlaced images must be loaded all at once... + */ + + if (info->color_type == PNG_COLOR_TYPE_GRAY || + info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + in = malloc(img->xsize * img->ysize); + else + in = malloc(img->xsize * img->ysize * 3); + } + + bpp = ImageGetDepth(img); + out = malloc(img->xsize * bpp); + + /* + * Read the image, interlacing as needed... + */ + + for (pass = 1; pass <= passes; pass ++) + for (inptr = in, y = 0; y < img->ysize; y ++) + { + png_read_row(pp, (png_bytep)inptr, NULL); + + if (pass == passes) + { + /* + * Output this row... + */ + + if (info->color_type == PNG_COLOR_TYPE_GRAY || + info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + switch (img->colorspace) + { + case IMAGE_WHITE : + memcpy(out, inptr, img->xsize); + break; + case IMAGE_RGB : + ImageWhiteToRGB(inptr, out, img->xsize); + break; + case IMAGE_BLACK : + ImageWhiteToBlack(inptr, out, img->xsize); + break; + case IMAGE_CMY : + ImageWhiteToCMY(inptr, out, img->xsize); + break; + case IMAGE_CMYK : + ImageWhiteToCMYK(inptr, out, img->xsize); + break; + } + } + else + { + if ((saturation != 100 || hue != 0) && bpp > 1) + ImageRGBAdjust(inptr, img->xsize, saturation, hue); + + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(inptr, out, img->xsize); + break; + case IMAGE_RGB : + memcpy(out, inptr, img->xsize * 3); + break; + case IMAGE_BLACK : + ImageRGBToBlack(inptr, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(inptr, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(inptr, out, img->xsize); + break; + } + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + + if (passes > 1) + { + if (info->color_type == PNG_COLOR_TYPE_GRAY || + info->color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + inptr += img->xsize; + else + inptr += img->xsize * 3; + } + } + + png_read_end(pp, info); + png_read_destroy(pp, info, NULL); + + fclose(fp); + free(in); + free(out); + + return (0); +} + + +#endif /* HAVE_LIBPNG && HAVE_LIBZ */ + + +/* + * End of "$Id$". + */ diff --git a/filter/image-pnm.c b/filter/image-pnm.c new file mode 100644 index 0000000000..dbc956c61c --- /dev/null +++ b/filter/image-pnm.c @@ -0,0 +1,288 @@ +/* + * "$Id$" + * + * Portable Any Map file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadPNM() - Read a PNM image file. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" +#include + + +/* + * 'ImageReadPNM()' - Read a PNM image file. + */ + +int /* O - Read status */ +ImageReadPNM(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + int x, y; /* Looping vars */ + int bpp; /* Bytes per pixel */ + ib_t *in, /* Input pixels */ + *inptr, /* Current input pixel */ + *out, /* Output pixels */ + *outptr, /* Current output pixel */ + bit; /* Bit in input line */ + char line[255], /* Input line */ + *lineptr; /* Pointer in line */ + int format, /* Format of PNM file */ + val, /* Pixel value */ + maxval; /* Maximum pixel value */ + + + /* + * Read the file header in the format: + * + * Pformat + * # comment1 + * # comment2 + * ... + * # commentN + * width + * height + * max sample + */ + + lineptr = fgets(line, sizeof(line), fp); + lineptr ++; + + format = atoi(lineptr); + while (isdigit(*lineptr)) + lineptr ++; + + while (lineptr != NULL && img->xsize == 0) + { + if (*lineptr == '\0' || *lineptr == '#') + lineptr = fgets(line, sizeof(line), fp); + else if (isdigit(*lineptr)) + { + img->xsize = atoi(lineptr); + while (isdigit(*lineptr)) + lineptr ++; + } + else + lineptr ++; + } + + while (lineptr != NULL && img->ysize == 0) + { + if (*lineptr == '\0' || *lineptr == '#') + lineptr = fgets(line, sizeof(line), fp); + else if (isdigit(*lineptr)) + { + img->ysize = atoi(lineptr); + while (isdigit(*lineptr)) + lineptr ++; + } + else + lineptr ++; + } + + if (format != 1 && format != 4) + { + maxval = 0; + + while (lineptr != NULL && maxval == 0) + { + if (*lineptr == '\0' || *lineptr == '#') + lineptr = fgets(line, sizeof(line), fp); + else if (isdigit(*lineptr)) + { + maxval = atoi(lineptr); + while (isdigit(*lineptr)) + lineptr ++; + } + else + lineptr ++; + } + } + else + maxval = 1; + + if (format == 1 || format == 2 || format == 4 || format == 5) + img->colorspace = secondary; + else + img->colorspace = primary; + + ImageSetMaxTiles(img, 0); + + bpp = ImageGetDepth(img); + in = malloc(img->xsize * 3); + out = malloc(img->xsize * bpp); + + /* + * Read the image file... + */ + + for (y = 0; y < img->ysize; y ++) + { + switch (format) + { + case 1 : + case 2 : + for (x = img->xsize, inptr = in; x > 0; x --, inptr ++) + if (fscanf(fp, "%d", &val) == 1) + *inptr = 255 * val / maxval; + break; + + case 3 : + for (x = img->xsize, inptr = in; x > 0; x --, inptr += 3) + { + if (fscanf(fp, "%d", &val) == 1) + inptr[0] = 255 * val / maxval; + if (fscanf(fp, "%d", &val) == 1) + inptr[1] = 255 * val / maxval; + if (fscanf(fp, "%d", &val) == 1) + inptr[2] = 255 * val / maxval; + } + break; + + case 4 : + fread(out, (img->xsize + 7) / 8, 1, fp); + for (x = img->xsize, inptr = in, outptr = out, bit = 128; + x > 0; + x --, inptr ++) + { + if (*outptr & bit) + *inptr = 255; + else + *inptr = 0; + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + inptr ++; + } + } + break; + + case 5 : + fread(in, img->xsize, 1, fp); + break; + + case 6 : + fread(in, img->xsize, 3, fp); + break; + } + + switch (format) + { + case 1 : + case 2 : + case 4 : + case 5 : + if (img->colorspace == IMAGE_WHITE) + { + if (lut) + ImageLut(in, img->xsize, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_RGB : + ImageWhiteToRGB(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageWhiteToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageWhiteToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + break; + + default : + if ((saturation != 100 || hue != 0) && bpp > 1) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + if (img->colorspace == IMAGE_RGB) + { + if (lut) + ImageLut(in, img->xsize * 3, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + break; + } + } + + free(in); + free(out); + + fclose(fp); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-sgi.c b/filter/image-sgi.c new file mode 100644 index 0000000000..8aa11321a8 --- /dev/null +++ b/filter/image-sgi.c @@ -0,0 +1,267 @@ +/* + * "$Id$" + * + * SGI image file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadSGI() - Read a SGI image file. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" +#include "image-sgi.h" + + +/* + * 'ImageReadSGI()' - Read a SGI image file. + */ + +int /* O - Read status */ +ImageReadSGI(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + int i, y; /* Looping vars */ + int bpp; /* Bytes per pixel */ + sgi_t *sgip; /* SGI image file */ + ib_t *in, /* Input pixels */ + *inptr, /* Current input pixel */ + *out; /* Output pixels */ + unsigned short *rows[4], /* Row pointers for image data */ + *red, + *green, + *blue, + *gray, + *alpha; + + + /* + * Setup the SGI file... + */ + + sgip = sgiOpenFile(fp, SGI_READ, 0, 0, 0, 0, 0); + + /* + * Get the image dimensions and load the output image... + */ + + if (sgip->zsize < 3) + img->colorspace = secondary; + else + img->colorspace = primary; + + img->xsize = sgip->xsize; + img->ysize = sgip->ysize; + + ImageSetMaxTiles(img, 0); + + bpp = ImageGetDepth(img); + in = malloc(img->xsize * sgip->zsize); + out = malloc(img->xsize * bpp); + + rows[0] = calloc(img->xsize * sgip->zsize, sizeof(unsigned short)); + for (i = 1; i < sgip->zsize; i ++) + rows[i] = rows[0] + i * img->xsize; + + /* + * Read the SGI image file... + */ + + for (y = 0; y < img->ysize; y ++) + { + for (i = 0; i < sgip->zsize; i ++) + sgiGetRow(sgip, rows[i], img->ysize - 1 - y, i); + + switch (sgip->zsize) + { + case 1 : + if (sgip->bpp == 1) + for (i = img->xsize - 1, gray = rows[0], inptr = in; + i >= 0; + i --) + { + *inptr++ = *gray++; + } + else + for (i = img->xsize - 1, gray = rows[0], inptr = in; + i >= 0; + i --) + { + *inptr++ = (*gray++) / 256 + 128; + } + break; + case 2 : + if (sgip->bpp == 1) + for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in; + i >= 0; + i --) + { + *inptr++ = (*gray++) * (*alpha++) / 255; + } + else + for (i = img->xsize - 1, gray = rows[0], alpha = rows[1], inptr = in; + i >= 0; + i --) + { + *inptr++ = ((*gray++) / 256 + 128) * (*alpha++) / 32767; + } + break; + case 3 : + if (sgip->bpp == 1) + for (i = img->xsize - 1, red = rows[0], green = rows[1], + blue = rows[2], inptr = in; + i >= 0; + i --) + { + *inptr++ = *red++; + *inptr++ = *green++; + *inptr++ = *blue++; + } + else + for (i = img->xsize - 1, red = rows[0], green = rows[1], + blue = rows[2], inptr = in; + i >= 0; + i --) + { + *inptr++ = (*red++) / 256 + 128; + *inptr++ = (*green++) / 256 + 128; + *inptr++ = (*blue++) / 256 + 128; + } + break; + case 4 : + if (sgip->bpp == 1) + for (i = img->xsize - 1, red = rows[0], green = rows[1], + blue = rows[2], alpha = rows[3], inptr = in; + i >= 0; + i --) + { + *inptr++ = (*red++) * (*alpha) / 255; + *inptr++ = (*green++) * (*alpha) / 255; + *inptr++ = (*blue++) * (*alpha++) / 255; + } + else + for (i = img->xsize - 1, red = rows[0], green = rows[1], + blue = rows[2], alpha = rows[3], inptr = in; + i >= 0; + i --) + { + *inptr++ = ((*red++) / 256 + 128) * (*alpha) / 32767; + *inptr++ = ((*green++) / 256 + 128) * (*alpha) / 32767; + *inptr++ = ((*blue++) / 256 + 128) * (*alpha++) / 32767; + } + break; + } + + if (sgip->zsize < 3) + { + if (img->colorspace == IMAGE_WHITE) + { + if (lut) + ImageLut(in, img->xsize, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_RGB : + ImageWhiteToRGB(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageWhiteToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageWhiteToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + else + { + if (img->colorspace == IMAGE_RGB) + { + if (saturation != 100 || hue != 0) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + if (lut) + ImageLut(in, img->xsize * 3, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + if ((saturation != 100 || hue != 0) && bpp > 1) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + } + + free(in); + free(out); + free(rows[0]); + + sgiClose(sgip); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-sgi.h b/filter/image-sgi.h new file mode 100644 index 0000000000..ad8aa9e61a --- /dev/null +++ b/filter/image-sgi.h @@ -0,0 +1,94 @@ +/* + * "$Id$" + * + * SGI image file format library definitions for the Common UNIX Printing + * System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +#ifndef _SGI_H_ +# define _SGI_H_ + +# include +# include +# include + +# ifdef __cplusplus +extern "C" { +# endif + + +/* + * Constants... + */ + +# define SGI_MAGIC 474 /* Magic number in image file */ + +# define SGI_READ 0 /* Read from an SGI image file */ +# define SGI_WRITE 1 /* Write to an SGI image file */ + +# define SGI_COMP_NONE 0 /* No compression */ +# define SGI_COMP_RLE 1 /* Run-length encoding */ +# define SGI_COMP_ARLE 2 /* Agressive run-length encoding */ + + +/* + * Image structure... + */ + +typedef struct +{ + FILE *file; /* Image file */ + int mode, /* File open mode */ + bpp, /* Bytes per pixel/channel */ + comp; /* Compression */ + unsigned short xsize, /* Width in pixels */ + ysize, /* Height in pixels */ + zsize; /* Number of channels */ + long firstrow, /* File offset for first row */ + nextrow, /* File offset for next row */ + **table, /* Offset table for compression */ + **length; /* Length table for compression */ + unsigned short *arle_row; /* Advanced RLE compression buffer */ + long arle_offset, /* Advanced RLE buffer offset */ + arle_length; /* Advanced RLE buffer length */ +} sgi_t; + + +/* + * Prototypes... + */ + +extern int sgiClose(sgi_t *sgip); +extern int sgiGetRow(sgi_t *sgip, unsigned short *row, int y, int z); +extern sgi_t *sgiOpen(char *filename, int mode, int comp, int bpp, + int xsize, int ysize, int zsize); +extern sgi_t *sgiOpenFile(FILE *file, int mode, int comp, int bpp, + int xsize, int ysize, int zsize); +extern int sgiPutRow(sgi_t *sgip, unsigned short *row, int y, int z); + +# ifdef __cplusplus +} +# endif +#endif /* !_SGI_H_ */ + +/* + * End of "$Id$". + */ diff --git a/filter/image-sgilib.c b/filter/image-sgilib.c new file mode 100644 index 0000000000..c6b6d9c22b --- /dev/null +++ b/filter/image-sgilib.c @@ -0,0 +1,857 @@ +/* + * "$Id$" + * + * SGI image file format library routines for the Common UNIX Printing + * System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * sgiClose() - Close an SGI image file. + * sgiGetRow() - Get a row of image data from a file. + * sgiOpen() - Open an SGI image file for reading or writing. + * sgiOpenFile() - Open an SGI image file for reading or writing. + * sgiPutRow() - Put a row of image data to a file. + * getlong() - Get a 32-bit big-endian integer. + * getshort() - Get a 16-bit big-endian integer. + * putlong() - Put a 32-bit big-endian integer. + * putshort() - Put a 16-bit big-endian integer. + * read_rle8() - Read 8-bit RLE data. + * read_rle16() - Read 16-bit RLE data. + * write_rle8() - Write 8-bit RLE data. + * write_rle16() - Write 16-bit RLE data. + */ + +#include "image-sgi.h" + + +/* + * Local functions... + */ + +static int getlong(FILE *); +static int getshort(FILE *); +static int putlong(long, FILE *); +static int putshort(unsigned short, FILE *); +static int read_rle8(FILE *, unsigned short *, int); +static int read_rle16(FILE *, unsigned short *, int); +static int write_rle8(FILE *, unsigned short *, int); +static int write_rle16(FILE *, unsigned short *, int); + + +/* + * 'sgiClose()' - Close an SGI image file. + */ + +int +sgiClose(sgi_t *sgip) /* I - SGI image */ +{ + int i; /* Return status */ + long *offset; /* Looping var for offset table */ + + + if (sgip == NULL) + return (-1); + + if (sgip->mode == SGI_WRITE && sgip->comp != SGI_COMP_NONE) + { + /* + * Write the scanline offset table to the file... + */ + + fseek(sgip->file, 512, SEEK_SET); + + for (i = sgip->ysize * sgip->zsize, offset = sgip->table[0]; + i > 0; + i --, offset ++) + if (putlong(offset[0], sgip->file) < 0) + return (-1); + + for (i = sgip->ysize * sgip->zsize, offset = sgip->length[0]; + i > 0; + i --, offset ++) + if (putlong(offset[0], sgip->file) < 0) + return (-1); + } + + if (sgip->table != NULL) + { + free(sgip->table[0]); + free(sgip->table); + } + + if (sgip->length != NULL) + { + free(sgip->length[0]); + free(sgip->length); + } + + if (sgip->comp == SGI_COMP_ARLE) + free(sgip->arle_row); + + i = fclose(sgip->file); + free(sgip); + + return (i); +} + + +/* + * 'sgiGetRow()' - Get a row of image data from a file. + */ + +int +sgiGetRow(sgi_t *sgip, /* I - SGI image */ + unsigned short *row, /* O - Row to read */ + int y, /* I - Line to read */ + int z) /* I - Channel to read */ +{ + int x; /* X coordinate */ + long offset; /* File offset */ + + + if (sgip == NULL || + row == NULL || + y < 0 || y >= sgip->ysize || + z < 0 || z >= sgip->zsize) + return (-1); + + switch (sgip->comp) + { + case SGI_COMP_NONE : + /* + * Seek to the image row - optimize buffering by only seeking if + * necessary... + */ + + offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp; + if (offset != ftell(sgip->file)) + fseek(sgip->file, offset, SEEK_SET); + + if (sgip->bpp == 1) + { + for (x = sgip->xsize; x > 0; x --, row ++) + *row = getc(sgip->file); + } + else + { + for (x = sgip->xsize; x > 0; x --, row ++) + *row = getshort(sgip->file); + } + break; + + case SGI_COMP_RLE : + offset = sgip->table[z][y]; + if (offset != ftell(sgip->file)) + fseek(sgip->file, offset, SEEK_SET); + + if (sgip->bpp == 1) + return (read_rle8(sgip->file, row, sgip->xsize)); + else + return (read_rle16(sgip->file, row, sgip->xsize)); + } + + return (0); +} + + +/* + * 'sgiOpen()' - Open an SGI image file for reading or writing. + */ + +sgi_t * +sgiOpen(char *filename, /* I - File to open */ + int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */ + int comp, /* I - Type of compression */ + int bpp, /* I - Bytes per pixel */ + int xsize, /* I - Width of image in pixels */ + int ysize, /* I - Height of image in pixels */ + int zsize) /* I - Number of channels */ +{ + sgi_t *sgip; /* New SGI image file */ + FILE *file; /* Image file pointer */ + + + if (mode == SGI_READ) + file = fopen(filename, "rb"); + else + file = fopen(filename, "wb+"); + + if (file == NULL) + return (NULL); + + if ((sgip = sgiOpenFile(file, mode, comp, bpp, xsize, ysize, zsize)) == NULL) + fclose(file); + + return (sgip); +} + + +/* + * 'sgiOpenFile()' - Open an SGI image file for reading or writing. + */ + +sgi_t * +sgiOpenFile(FILE *file, /* I - File to open */ + int mode, /* I - Open mode (SGI_READ or SGI_WRITE) */ + int comp, /* I - Type of compression */ + int bpp, /* I - Bytes per pixel */ + int xsize, /* I - Width of image in pixels */ + int ysize, /* I - Height of image in pixels */ + int zsize) /* I - Number of channels */ +{ + int i, j; /* Looping var */ + char name[80]; /* Name of file in image header */ + short magic; /* Magic number */ + sgi_t *sgip; /* New image pointer */ + + + if ((sgip = calloc(sizeof(sgi_t), 1)) == NULL) + return (NULL); + + sgip->file = file; + + switch (mode) + { + case SGI_READ : + sgip->mode = SGI_READ; + + magic = getshort(sgip->file); + if (magic != SGI_MAGIC) + { + free(sgip); + return (NULL); + } + + sgip->comp = getc(sgip->file); + sgip->bpp = getc(sgip->file); + getshort(sgip->file); /* Dimensions */ + sgip->xsize = getshort(sgip->file); + sgip->ysize = getshort(sgip->file); + sgip->zsize = getshort(sgip->file); + getlong(sgip->file); /* Minimum pixel */ + getlong(sgip->file); /* Maximum pixel */ + + if (sgip->comp) + { + /* + * This file is compressed; read the scanline tables... + */ + + fseek(sgip->file, 512, SEEK_SET); + + sgip->table = calloc(sgip->zsize, sizeof(long *)); + sgip->table[0] = calloc(sgip->ysize * sgip->zsize, sizeof(long)); + for (i = 1; i < sgip->zsize; i ++) + sgip->table[i] = sgip->table[0] + i * sgip->ysize; + + for (i = 0; i < sgip->zsize; i ++) + for (j = 0; j < sgip->ysize; j ++) + sgip->table[i][j] = getlong(sgip->file); + } + break; + + case SGI_WRITE : + if (xsize < 1 || + ysize < 1 || + zsize < 1 || + bpp < 1 || bpp > 2 || + comp < SGI_COMP_NONE || comp > SGI_COMP_ARLE) + { + free(sgip); + return (NULL); + } + + sgip->mode = SGI_WRITE; + + putshort(SGI_MAGIC, sgip->file); + putc((sgip->comp = comp) != 0, sgip->file); + putc(sgip->bpp = bpp, sgip->file); + putshort(3, sgip->file); /* Dimensions */ + putshort(sgip->xsize = xsize, sgip->file); + putshort(sgip->ysize = ysize, sgip->file); + putshort(sgip->zsize = zsize, sgip->file); + if (bpp == 1) + { + putlong(0, sgip->file); /* Minimum pixel */ + putlong(255, sgip->file); /* Maximum pixel */ + } + else + { + putlong(-32768, sgip->file); /* Minimum pixel */ + putlong(32767, sgip->file); /* Maximum pixel */ + } + putlong(0, sgip->file); /* Reserved */ + + memset(name, 0, sizeof(name)); + fwrite(name, sizeof(name), 1, sgip->file); + + for (i = 0; i < 102; i ++) + putlong(0, sgip->file); + + switch (comp) + { + case SGI_COMP_NONE : /* No compression */ + /* + * This file is uncompressed. To avoid problems with sparse files, + * we need to write blank pixels for the entire image... + */ + + if (bpp == 1) + { + for (i = xsize * ysize * zsize; i > 0; i --) + putc(0, sgip->file); + } + else + { + for (i = xsize * ysize * zsize; i > 0; i --) + putshort(0, sgip->file); + } + break; + + case SGI_COMP_ARLE : /* Aggressive RLE */ + sgip->arle_row = calloc(xsize, sizeof(unsigned short)); + sgip->arle_offset = 0; + + case SGI_COMP_RLE : /* Run-Length Encoding */ + /* + * This file is compressed; write the (blank) scanline tables... + */ + + for (i = 2 * ysize * zsize; i > 0; i --) + putlong(0, sgip->file); + + sgip->firstrow = ftell(sgip->file); + sgip->nextrow = ftell(sgip->file); + sgip->table = calloc(sgip->zsize, sizeof(long *)); + sgip->table[0] = calloc(sgip->ysize * sgip->zsize, sizeof(long)); + for (i = 1; i < sgip->zsize; i ++) + sgip->table[i] = sgip->table[0] + i * sgip->ysize; + sgip->length = calloc(sgip->zsize, sizeof(long *)); + sgip->length[0] = calloc(sgip->ysize * sgip->zsize, sizeof(long)); + for (i = 1; i < sgip->zsize; i ++) + sgip->length[i] = sgip->length[0] + i * sgip->ysize; + break; + } + break; + + default : + free(sgip); + return (NULL); + } + + return (sgip); +} + + +/* + * 'sgiPutRow()' - Put a row of image data to a file. + */ + +int +sgiPutRow(sgi_t *sgip, /* I - SGI image */ + unsigned short *row, /* I - Row to write */ + int y, /* I - Line to write */ + int z) /* I - Channel to write */ +{ + int x; /* X coordinate */ + long offset; /* File offset */ + + + if (sgip == NULL || + row == NULL || + y < 0 || y >= sgip->ysize || + z < 0 || z >= sgip->zsize) + return (-1); + + switch (sgip->comp) + { + case SGI_COMP_NONE : + /* + * Seek to the image row - optimize buffering by only seeking if + * necessary... + */ + + offset = 512 + (y + z * sgip->ysize) * sgip->xsize * sgip->bpp; + if (offset != ftell(sgip->file)) + fseek(sgip->file, offset, SEEK_SET); + + if (sgip->bpp == 1) + { + for (x = sgip->xsize; x > 0; x --, row ++) + putc(*row, sgip->file); + } + else + { + for (x = sgip->xsize; x > 0; x --, row ++) + putshort(*row, sgip->file); + } + break; + + case SGI_COMP_ARLE : + if (sgip->table[z][y] != 0) + return (-1); + + /* + * First check the last row written... + */ + + if (sgip->arle_offset > 0) + { + for (x = 0; x < sgip->xsize; x ++) + if (row[x] != sgip->arle_row[x]) + break; + + if (x == sgip->xsize) + { + sgip->table[z][y] = sgip->arle_offset; + sgip->length[z][y] = sgip->arle_length; + return (0); + } + } + + /* + * If that didn't match, search all the previous rows... + */ + + fseek(sgip->file, sgip->firstrow, SEEK_SET); + + if (sgip->bpp == 1) + { + for (;;) + { + sgip->arle_offset = ftell(sgip->file); + if ((sgip->arle_length = read_rle8(sgip->file, sgip->arle_row, sgip->xsize)) < 0) + { + x = 0; + break; + } + + if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0) + { + x = sgip->xsize; + break; + } + } + } + else + { + for (;;) + { + sgip->arle_offset = ftell(sgip->file); + if ((sgip->arle_length = read_rle16(sgip->file, sgip->arle_row, sgip->xsize)) < 0) + { + x = 0; + break; + } + + if (memcmp(row, sgip->arle_row, sgip->xsize * sizeof(unsigned short)) == 0) + { + x = sgip->xsize; + break; + } + } + } + + if (x == sgip->xsize) + { + sgip->table[z][y] = sgip->arle_offset; + sgip->length[z][y] = sgip->arle_length; + return (0); + } + else + fseek(sgip->file, 0, SEEK_END); /* Clear EOF */ + + case SGI_COMP_RLE : + if (sgip->table[z][y] != 0) + return (-1); + + offset = sgip->table[z][y] = sgip->nextrow; + + if (offset != ftell(sgip->file)) + fseek(sgip->file, offset, SEEK_SET); + + if (sgip->bpp == 1) + x = write_rle8(sgip->file, row, sgip->xsize); + else + x = write_rle16(sgip->file, row, sgip->xsize); + + if (sgip->comp == SGI_COMP_ARLE) + { + sgip->arle_offset = offset; + sgip->arle_length = x; + memcpy(sgip->arle_row, row, sgip->xsize * sizeof(unsigned short)); + } + + sgip->nextrow = ftell(sgip->file); + sgip->length[z][y] = x; + + return (x); + } + + return (0); +} + + +/* + * 'getlong()' - Get a 32-bit big-endian integer. + */ + +static int +getlong(FILE *fp) /* I - File to read from */ +{ + unsigned char b[4]; + + + fread(b, 4, 1, fp); + return ((b[0] << 24) | (b[1] << 16) | (b[2] << 8) | b[3]); +} + + +/* + * 'getshort()' - Get a 16-bit big-endian integer. + */ + +static int +getshort(FILE *fp) /* I - File to read from */ +{ + unsigned char b[2]; + + + fread(b, 2, 1, fp); + return ((b[0] << 8) | b[1]); +} + + +/* + * 'putlong()' - Put a 32-bit big-endian integer. + */ + +static int +putlong(long n, /* I - Long to write */ + FILE *fp) /* I - File to write to */ +{ + if (putc(n >> 24, fp) == EOF) + return (EOF); + if (putc(n >> 16, fp) == EOF) + return (EOF); + if (putc(n >> 8, fp) == EOF) + return (EOF); + if (putc(n, fp) == EOF) + return (EOF); + else + return (0); +} + + +/* + * 'putshort()' - Put a 16-bit big-endian integer. + */ + +static int +putshort(unsigned short n, /* I - Short to write */ + FILE *fp) /* I - File to write to */ +{ + if (putc(n >> 8, fp) == EOF) + return (EOF); + if (putc(n, fp) == EOF) + return (EOF); + else + return (0); +} + + +/* + * 'read_rle8()' - Read 8-bit RLE data. + */ + +static int +read_rle8(FILE *fp, /* I - File to read from */ + unsigned short *row, /* O - Data */ + int xsize) /* I - Width of data in pixels */ +{ + int i, /* Looping var */ + ch, /* Current character */ + count, /* RLE count */ + length; /* Number of bytes read... */ + + + length = 0; + + while (xsize > 0) + { + if ((ch = getc(fp)) == EOF) + return (-1); + length ++; + + count = ch & 127; + if (count == 0) + break; + + if (ch & 128) + { + for (i = 0; i < count; i ++, row ++, xsize --, length ++) + *row = getc(fp); + } + else + { + ch = getc(fp); + length ++; + for (i = 0; i < count; i ++, row ++, xsize --) + *row = ch; + } + } + + return (xsize > 0 ? -1 : length); +} + + +/* + * 'read_rle16()' - Read 16-bit RLE data. + */ + +static int +read_rle16(FILE *fp, /* I - File to read from */ + unsigned short *row, /* O - Data */ + int xsize)/* I - Width of data in pixels */ +{ + int i, /* Looping var */ + ch, /* Current character */ + count, /* RLE count */ + length; /* Number of bytes read... */ + + + length = 0; + + while (xsize > 0) + { + if ((ch = getshort(fp)) == EOF) + return (-1); + length ++; + + count = ch & 127; + if (count == 0) + break; + + if (ch & 128) + { + for (i = 0; i < count; i ++, row ++, xsize --, length ++) + *row = getshort(fp); + } + else + { + ch = getshort(fp); + length ++; + for (i = 0; i < count; i ++, row ++, xsize --) + *row = ch; + } + } + + return (xsize > 0 ? -1 : length * 2); +} + + +/* + * 'write_rle8()' - Write 8-bit RLE data. + */ + +static int +write_rle8(FILE *fp, /* I - File to write to */ + unsigned short *row, /* I - Data */ + int xsize)/* I - Width of data in pixels */ +{ + int length, + count, + i, + x; + unsigned short *start, + repeat; + + + for (x = xsize, length = 0; x > 0;) + { + start = row; + row += 2; + x -= 2; + + while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0])) + { + row ++; + x --; + } + + row -= 2; + x += 2; + + count = row - start; + while (count > 0) + { + i = count > 126 ? 126 : count; + count -= i; + + if (putc(128 | i, fp) == EOF) + return (-1); + length ++; + + while (i > 0) + { + if (putc(*start, fp) == EOF) + return (-1); + start ++; + i --; + length ++; + } + } + + if (x <= 0) + break; + + start = row; + repeat = row[0]; + + row ++; + x --; + + while (x > 0 && *row == repeat) + { + row ++; + x --; + } + + count = row - start; + while (count > 0) + { + i = count > 126 ? 126 : count; + count -= i; + + if (putc(i, fp) == EOF) + return (-1); + length ++; + + if (putc(repeat, fp) == EOF) + return (-1); + length ++; + } + } + + length ++; + + if (putc(0, fp) == EOF) + return (-1); + else + return (length); +} + + +/* + * 'write_rle16()' - Write 16-bit RLE data. + */ + +static int +write_rle16(FILE *fp, /* I - File to write to */ + unsigned short *row, /* I - Data */ + int xsize)/* I - Width of data in pixels */ +{ + int length, + count, + i, + x; + unsigned short *start, + repeat; + + + for (x = xsize, length = 0; x > 0;) + { + start = row; + row += 2; + x -= 2; + + while (x > 0 && (row[-2] != row[-1] || row[-1] != row[0])) + { + row ++; + x --; + } + + row -= 2; + x += 2; + + count = row - start; + while (count > 0) + { + i = count > 126 ? 126 : count; + count -= i; + + if (putshort(128 | i, fp) == EOF) + return (-1); + length ++; + + while (i > 0) + { + if (putshort(*start, fp) == EOF) + return (-1); + start ++; + i --; + length ++; + } + } + + if (x <= 0) + break; + + start = row; + repeat = row[0]; + + row ++; + x --; + + while (x > 0 && *row == repeat) + { + row ++; + x --; + } + + count = row - start; + while (count > 0) + { + i = count > 126 ? 126 : count; + count -= i; + + if (putshort(i, fp) == EOF) + return (-1); + length ++; + + if (putshort(repeat, fp) == EOF) + return (-1); + length ++; + } + } + + length ++; + + if (putshort(0, fp) == EOF) + return (-1); + else + return (2 * length); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-sun.c b/filter/image-sun.c new file mode 100644 index 0000000000..ada20b5bbc --- /dev/null +++ b/filter/image-sun.c @@ -0,0 +1,377 @@ +/* + * "$Id$" + * + * Sun Raster image file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadSunRaster() - Read a SunRaster image file. + * read_unsigned() - Read a 32-bit unsigned integer. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + + +#define RAS_MAGIC 0x59a66a95 + + /* Sun supported ras_type's */ +#define RT_OLD 0 /* Raw pixrect image in 68000 byte order */ +#define RT_STANDARD 1 /* Raw pixrect image in 68000 byte order */ +#define RT_BYTE_ENCODED 2 /* Run-length compression of bytes */ +#define RT_FORMAT_RGB 3 /* XRGB or RGB instead of XBGR or BGR */ +#define RT_EXPERIMENTAL 0xffff /* Reserved for testing */ + + /* Sun registered ras_maptype's */ +#define RMT_RAW 2 + /* Sun supported ras_maptype's */ +#define RMT_NONE 0 /* ras_maplength is expected to be 0 */ +#define RMT_EQUAL_RGB 1 /* red[ras_maplength/3],green[],blue[] */ + +#define RAS_RLE 0x80 + +/* + * NOTES: + * Each line of the image is rounded out to a multiple of 16 bits. + * This corresponds to the rounding convention used by the memory pixrect + * package (/usr/include/pixrect/memvar.h) of the SunWindows system. + * The ras_encoding field (always set to 0 by Sun's supported software) + * was renamed to ras_length in release 2.0. As a result, rasterfiles + * of type 0 generated by the old software claim to have 0 length; for + * compatibility, code reading rasterfiles must be prepared to compute the + * true length from the width, height, and depth fields. + */ + +/* + * Local functions... + */ + +static unsigned read_unsigned(FILE *fp); + + +/* + * 'ImageReadSunRaster()' - Read a SunRaster image file. + */ + +int /* O - Read status */ +ImageReadSunRaster(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary,/* I - Secondary choice for colorspace */ + int saturation,/* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + int i, x, y, + bpp, /* Bytes per pixel */ + scanwidth, + run_count, + run_value; + ib_t *in, + *out, + *scanline, + *scanptr, + *p, + bit; + unsigned ras_depth, /* depth (1, 8, or 24 bits) of pixel */ + ras_type, /* type of file; see RT_* below */ + ras_maplength; /* length (bytes) of following map */ + unsigned char cmap[3][256]; /* colormap */ + + + /* + * Read the header; we already know that this is a raster file (ImageOpen + * checks this) so we don't need to check the magic number again. + */ + + read_unsigned(fp); /* Skip magic */ + img->xsize = read_unsigned(fp); + img->ysize = read_unsigned(fp); + ras_depth = read_unsigned(fp); + /* ras_length */read_unsigned(fp); + ras_type = read_unsigned(fp); + /* ras_maptype*/read_unsigned(fp); + ras_maplength = read_unsigned(fp); + + if (ras_maplength > 0) + { + fread(cmap[0], 1, ras_maplength / 3, fp); + fread(cmap[1], 1, ras_maplength / 3, fp); + fread(cmap[2], 1, ras_maplength / 3, fp); + } + + /* + * Compute the width of each line and allocate memory as needed... + */ + + scanwidth = (img->xsize * ras_depth + 7) / 8; + if (scanwidth & 1) + scanwidth ++; + + if (ras_depth < 24 && ras_maplength == 0) + { + img->colorspace = secondary; + in = malloc(img->xsize + 1); + } + else + { + img->colorspace = primary; + in = malloc(img->xsize * 3 + 1); + } + + bpp = ImageGetDepth(img); + out = malloc(img->xsize * bpp); + scanline = malloc(scanwidth); + run_count = 0; + run_value = 0; + + for (y = 0; y < img->ysize; y ++) + { + if (ras_depth != 8 || ras_maplength > 0) + p = scanline; + else + p = in; + + if (ras_type != RT_BYTE_ENCODED) + fread(p, scanwidth, 1, fp); + else + { + for (i = scanwidth; i > 0; i --, p ++) + { + if (run_count > 0) + { + *p = run_value; + run_count --; + } + else + { + run_value = getc(fp); + + if (run_value == RAS_RLE) + { + run_count = getc(fp); + if (run_count == 0) + *p = RAS_RLE; + else + run_value = *p = getc(fp); + } + else + *p = run_value; + } + } + } + + if (ras_depth == 1 && ras_maplength == 0) + { + /* + * 1-bit B&W image... + */ + + for (x = img->xsize, bit = 128, scanptr = scanline, p = in; + x > 0; + x --, p ++) + { + if (*scanptr & bit) + *p = 255; + else + *p = 0; + + if (bit > 1) + { + bit = 128; + scanptr ++; + } + else + bit >>= 1; + } + } + else if (ras_depth == 1) + { + /* + * 1-bit colormapped image... + */ + + for (x = img->xsize, bit = 128, scanptr = scanline, p = in; + x > 0; + x --) + { + if (*scanptr & bit) + { + *p++ = cmap[0][1]; + *p++ = cmap[1][1]; + *p++ = cmap[2][1]; + } + else + { + *p++ = cmap[0][0]; + *p++ = cmap[1][0]; + *p++ = cmap[2][0]; + } + + if (bit > 1) + { + bit = 128; + scanptr ++; + } + else + bit >>= 1; + } + } + else if (ras_depth == 8 && ras_maplength > 0) + { + /* + * 8-bit colormapped image. + */ + + for (x = img->xsize, scanptr = scanline, p = in; + x > 0; + x --) + { + *p++ = cmap[0][*scanptr]; + *p++ = cmap[1][*scanptr]; + *p++ = cmap[2][*scanptr++]; + } + } + else if (ras_depth == 24 && ras_type != RT_FORMAT_RGB) + { + /* + * Convert BGR to RGB... + */ + + for (x = img->xsize, scanptr = scanline, p = in; + x > 0; + x --, scanptr += 3) + { + *p++ = scanptr[2]; + *p++ = scanptr[1]; + *p++ = scanptr[0]; + } + } + + if (bpp == 1) + { + if (img->colorspace == IMAGE_WHITE) + { + if (lut) + ImageLut(in, img->xsize, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_RGB : + ImageWhiteToRGB(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageWhiteToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageWhiteToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + else + { + if (img->colorspace == IMAGE_RGB) + { + if (saturation != 100 || hue != 0) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + if (lut) + ImageLut(in, img->xsize * 3, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + if ((saturation != 100 || hue != 0) && bpp > 1) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + } + + free(scanline); + free(in); + free(out); + + fclose(fp); + + return (0); +} + + +/* + * 'read_unsigned()' - Read a 32-bit unsigned integer. + */ + +static unsigned /* O - Integer from file */ +read_unsigned(FILE *fp) /* I - File to read from */ +{ + unsigned v; /* Integer from file */ + + + v = getc(fp); + v = (v << 8) | getc(fp); + v = (v << 8) | getc(fp); + v = (v << 8) | getc(fp); + + return (v); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image-tiff.c b/filter/image-tiff.c new file mode 100644 index 0000000000..8d15ffd604 --- /dev/null +++ b/filter/image-tiff.c @@ -0,0 +1,1631 @@ +/* + * "$Id$" + * + * TIFF file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageReadTIFF() - Read a TIFF image file. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + +#ifdef HAVE_LIBTIFF +# include /* TIFF image definitions */ +# include +# include + + +/* + * 'ImageReadTIFF()' - Read a TIFF image file. + */ + +int /* O - Read status */ +ImageReadTIFF(image_t *img, /* IO - Image */ + FILE *fp, /* I - Image file */ + int primary, /* I - Primary choice for colorspace */ + int secondary, /* I - Secondary choice for colorspace */ + int saturation, /* I - Color saturation (%) */ + int hue, /* I - Color hue (degrees) */ + const ib_t *lut) /* I - Lookup table for gamma/brightness */ +{ + TIFF *tif; /* TIFF file */ + uint32 width, height; /* Size of image */ + uint16 photometric, /* Colorspace */ + compression, /* Type of compression */ + orientation, /* Orientation */ + resunit, /* Units for resolution */ + samples, /* Number of samples/pixel */ + bits, /* Number of bits/pixel */ + inkset; /* Ink set for color separations */ + float xres, /* Horizontal resolution */ + yres; /* Vertical resolution */ + uint16 *redcmap, /* Red colormap information */ + *greencmap, /* Green colormap information */ + *bluecmap; /* Blue colormap information */ + int c, /* Color index */ + num_colors, /* Number of colors */ + bpp, /* Bytes per pixel */ + x, y, /* Current x & y */ + xstart, ystart, /* Starting x & y */ + xdir, ydir, /* X & y direction */ + xcount, ycount, /* X & Y counters */ + pstep, /* Pixel step (= bpp or -2 * bpp) */ + scanwidth, /* Width of scanline */ + r, g, b, k, /* Red, green, blue, and black values */ + alpha; /* Image includes alpha? */ + ib_t *in, /* Input buffer */ + *out, /* Output buffer */ + *p, /* Pointer into buffer */ + *scanline, /* Scanline buffer */ + *scanptr, /* Pointer into scanline buffer */ + bit, /* Current bit */ + pixel, /* Current pixel */ + zero, /* Zero value (bitmaps) */ + one; /* One value (bitmaps) */ + + + /* + * Open the TIFF file and get the required parameters... + */ + + lseek(fileno(fp), 0, SEEK_SET); /* Work around "feature" in some stdio's */ + + if ((tif = TIFFFdOpen(fileno(fp), "", "r")) == NULL) + { + fclose(fp); + return (-1); + } + + if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width) || + !TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height) || + !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric) || + !TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression) || + !TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samples) || + !TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits)) + { + TIFFClose(tif); + fclose(fp); + return (-1); + } + + /* + * Get the image orientation... + */ + + if (!TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation)) + orientation = 0; + + /* + * Get the image resolution... + */ + + if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) && + TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) && + TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resunit)) + { + if (resunit == RESUNIT_INCH) + { + img->xppi = xres; + img->yppi = yres; + } + else if (resunit == RESUNIT_CENTIMETER) + { + img->xppi = xres * 2.54; + img->yppi = yres * 2.54; + } + else + { + img->xppi = 128; + img->yppi = 128; + } + + fprintf(stderr, "DEBUG: TIFF resolution = %fx%f, units=%d\n", + xres, yres, resunit); + fprintf(stderr, "DEBUG: Stored resolution = %dx%d PPI\n", + img->xppi, img->yppi); + } + + /* + * See if the image has an alpha channel... + */ + + if (samples == 2 || (samples == 4 && photometric == PHOTOMETRIC_RGB)) + alpha = 1; + else + alpha = 0; + + /* + * Setup the image size and colorspace... + */ + + img->xsize = width; + img->ysize = height; + if (photometric == PHOTOMETRIC_MINISBLACK || + photometric == PHOTOMETRIC_MINISWHITE) + img->colorspace = secondary; + else + img->colorspace = primary; + + bpp = ImageGetDepth(img); + + ImageSetMaxTiles(img, 0); + + /* + * Set the X & Y start and direction according to the image orientation... + */ + + switch (orientation) + { + case ORIENTATION_TOPRIGHT : + case ORIENTATION_RIGHTTOP : + xstart = img->xsize - 1; + xdir = -1; + ystart = 0; + ydir = 1; + break; + default : + case ORIENTATION_TOPLEFT : + case ORIENTATION_LEFTTOP : + xstart = 0; + xdir = 1; + ystart = 0; + ydir = 1; + break; + case ORIENTATION_BOTLEFT : + case ORIENTATION_LEFTBOT : + xstart = 0; + xdir = 1; + ystart = img->ysize - 1; + ydir = -1; + break; + case ORIENTATION_BOTRIGHT : + case ORIENTATION_RIGHTBOT : + xstart = img->xsize - 1; + xdir = -1; + ystart = img->ysize - 1; + ydir = -1; + break; + } + + /* + * Allocate a scanline buffer... + */ + + scanwidth = TIFFScanlineSize(tif); + scanline = _TIFFmalloc(scanwidth); + + /* + * Allocate input and output buffers... + */ + + if (orientation < ORIENTATION_LEFTTOP) + { + if (samples > 1 || photometric == PHOTOMETRIC_PALETTE) + pstep = xdir * 3; + else + pstep = xdir; + + in = malloc(img->xsize * 3 + 3); + out = malloc(img->xsize * bpp); + } + else + { + if (samples > 1 || photometric == PHOTOMETRIC_PALETTE) + pstep = ydir * 3; + else + pstep = ydir; + + in = malloc(img->ysize * 3 + 3); + out = malloc(img->ysize * bpp); + } + + /* + * Read the image. This is greatly complicated by the fact that TIFF + * supports literally hundreds of different colorspaces and orientations, + * each which must be handled separately... + */ + + fprintf(stderr, "DEBUG: photometric = %d\n", photometric); + fprintf(stderr, "DEBUG: compression = %d\n", compression); + + switch (photometric) + { + case PHOTOMETRIC_MINISWHITE : + case PHOTOMETRIC_MINISBLACK : + if (photometric == PHOTOMETRIC_MINISWHITE) + { + zero = 255; + one = 0; + } + else + { + zero = 0; + one = 255; + } + + if (orientation < ORIENTATION_LEFTTOP) + { + /* + * Row major order... + */ + + for (y = ystart, ycount = img->ysize; + ycount > 0; + ycount --, y += ydir) + { + if (bits == 1) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 128; + xcount > 0; + xcount --, p += pstep) + { + if (*scanptr & bit) + *p = one; + else + *p = zero; + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + scanptr ++; + } + } + } + else if (bits == 2) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xc0; + xcount > 0; + xcount --, p += pstep) + { + pixel = *scanptr & bit; + while (pixel > 3) + pixel >>= 2; + *p = (255 * pixel / 3) ^ zero; + + if (bit > 3) + bit >>= 2; + else + { + bit = 0xc0; + scanptr ++; + } + } + } + else if (bits == 4) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xf0; + xcount > 0; + xcount --, p += pstep) + { + if (bit == 0xf0) + { + *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero; + bit = 0x0f; + } + else + { + *p = (255 * (*scanptr & 0x0f) / 15) ^ zero; + bit = 0xf0; + scanptr ++; + } + } + } + else if (xdir < 0 || zero || alpha) + { + TIFFReadScanline(tif, scanline, y, 0); + + if (alpha) + { + if (zero) + { + for (xcount = img->xsize, p = in + xstart, scanptr = scanline; + xcount > 0; + xcount --, p += pstep, scanptr += 2) + *p = (scanptr[1] * (255 - scanptr[0]) + + (255 - scanptr[1]) * 255) / 255; + } + else + { + for (xcount = img->xsize, p = in + xstart, scanptr = scanline; + xcount > 0; + xcount --, p += pstep, scanptr += 2) + *p = (scanptr[1] * scanptr[0] + + (255 - scanptr[1]) * 255) / 255; + } + } + else + { + if (zero) + { + for (xcount = img->xsize, p = in + xstart, scanptr = scanline; + xcount > 0; + xcount --, p += pstep, scanptr ++) + *p = 255 - *scanptr; + } + else + { + for (xcount = img->xsize, p = in + xstart, scanptr = scanline; + xcount > 0; + xcount --, p += pstep, scanptr ++) + *p = *scanptr; + } + } + } + else + TIFFReadScanline(tif, in, y, 0); + + if (img->colorspace == IMAGE_WHITE) + { + if (lut) + ImageLut(in, img->xsize, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_RGB : + ImageWhiteToRGB(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageWhiteToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageWhiteToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageWhiteToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + } + else + { + /* + * Column major order... + */ + + for (x = xstart, xcount = img->xsize; + xcount > 0; + xcount --, x += xdir) + { + if (bits == 1) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 128; + ycount > 0; + ycount --, p += ydir) + { + if (*scanptr & bit) + *p = one; + else + *p = zero; + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + scanptr ++; + } + } + } + else if (bits == 2) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xc0; + ycount > 0; + ycount --, p += ydir) + { + pixel = *scanptr & 0xc0; + while (pixel > 3) + pixel >>= 2; + + *p = (255 * pixel / 3) ^ zero; + + if (bit > 3) + bit >>= 2; + else + { + bit = 0xc0; + scanptr ++; + } + } + } + else if (bits == 4) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xf0; + ycount > 0; + ycount --, p += ydir) + { + if (bit == 0xf0) + { + *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero; + bit = 0x0f; + } + else + { + *p = (255 * (*scanptr & 0x0f) / 15) ^ zero; + bit = 0xf0; + scanptr ++; + } + } + } + else if (ydir < 0 || zero || alpha) + { + TIFFReadScanline(tif, scanline, x, 0); + + if (alpha) + { + if (zero) + { + for (ycount = img->ysize, p = in + ystart, scanptr = scanline; + ycount > 0; + ycount --, p += ydir, scanptr += 2) + *p = (scanptr[1] * (255 - scanptr[0]) + + (255 - scanptr[1]) * 255) / 255; + } + else + { + for (ycount = img->ysize, p = in + ystart, scanptr = scanline; + ycount > 0; + ycount --, p += ydir, scanptr += 2) + *p = (scanptr[1] * scanptr[0] + + (255 - scanptr[1]) * 255) / 255; + } + } + else + { + if (zero) + { + for (ycount = img->ysize, p = in + ystart, scanptr = scanline; + ycount > 0; + ycount --, p += ydir, scanptr ++) + *p = 255 - *scanptr; + } + else + { + for (ycount = img->ysize, p = in + ystart, scanptr = scanline; + ycount > 0; + ycount --, p += ydir, scanptr ++) + *p = *scanptr; + } + } + } + else + TIFFReadScanline(tif, in, x, 0); + + if (img->colorspace == IMAGE_WHITE) + { + if (lut) + ImageLut(in, img->ysize, lut); + + ImagePutCol(img, x, 0, img->ysize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_RGB : + ImageWhiteToRGB(in, out, img->ysize); + break; + case IMAGE_BLACK : + ImageWhiteToBlack(in, out, img->ysize); + break; + case IMAGE_CMY : + ImageWhiteToCMY(in, out, img->ysize); + break; + case IMAGE_CMYK : + ImageWhiteToCMYK(in, out, img->ysize); + break; + } + + if (lut) + ImageLut(out, img->ysize * bpp, lut); + + ImagePutCol(img, x, 0, img->ysize, out); + } + } + } + break; + + case PHOTOMETRIC_PALETTE : + if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &redcmap, &greencmap, &bluecmap)) + { + fclose(fp); + return (-1); + } + + num_colors = 1 << bits; + + for (c = 0; c < num_colors; c ++) + { + redcmap[c] >>= 8; + greencmap[c] >>= 8; + bluecmap[c] >>= 8; + } + + if (orientation < ORIENTATION_LEFTTOP) + { + /* + * Row major order... + */ + + for (y = ystart, ycount = img->ysize; + ycount > 0; + ycount --, y += ydir) + { + if (bits == 1) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, + p = in + xstart * 3, bit = 128; + xcount > 0; + xcount --, p += pstep) + { + if (*scanptr & bit) + { + p[0] = redcmap[1]; + p[1] = greencmap[1]; + p[2] = bluecmap[1]; + } + else + { + p[0] = redcmap[0]; + p[1] = greencmap[0]; + p[2] = bluecmap[0]; + } + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + scanptr ++; + } + } + } + else if (bits == 2) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, + p = in + xstart * 3, bit = 0xc0; + xcount > 0; + xcount --, p += pstep) + { + pixel = *scanptr & bit; + while (pixel > 3) + pixel >>= 2; + + p[0] = redcmap[pixel]; + p[1] = greencmap[pixel]; + p[2] = bluecmap[pixel]; + + if (bit > 3) + bit >>= 2; + else + { + bit = 0xc0; + scanptr ++; + } + } + } + else if (bits == 4) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, + p = in + 3 * xstart, bit = 0xf0; + xcount > 0; + xcount --, p += pstep) + { + if (bit == 0xf0) + { + pixel = (*scanptr & 0xf0) >> 4; + p[0] = redcmap[pixel]; + p[1] = greencmap[pixel]; + p[2] = bluecmap[pixel]; + bit = 0x0f; + } + else + { + pixel = *scanptr++ & 0x0f; + p[0] = redcmap[pixel]; + p[1] = greencmap[pixel]; + p[2] = bluecmap[pixel]; + bit = 0xf0; + } + } + } + else + { + TIFFReadScanline(tif, scanline, y, 0); + + for (xcount = img->xsize, p = in + 3 * xstart, scanptr = scanline; + xcount > 0; + xcount --, p += pstep) + { + p[0] = redcmap[*scanptr]; + p[1] = greencmap[*scanptr]; + p[2] = bluecmap[*scanptr++]; + } + } + + if (img->colorspace == IMAGE_RGB) + { + if (lut) + ImageLut(in, img->xsize * 3, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + } + else + { + /* + * Column major order... + */ + + for (x = xstart, xcount = img->xsize; + xcount > 0; + xcount --, x += xdir) + { + if (bits == 1) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, + p = in + 3 * ystart, bit = 128; + ycount > 0; + ycount --, p += ydir) + { + if (*scanptr & bit) + { + p[0] = redcmap[1]; + p[1] = greencmap[1]; + p[2] = bluecmap[1]; + } + else + { + p[0] = redcmap[0]; + p[1] = greencmap[0]; + p[2] = bluecmap[0]; + } + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + scanptr ++; + } + } + } + else if (bits == 2) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, + p = in + 3 * ystart, bit = 0xc0; + ycount > 0; + ycount --, p += ydir) + { + pixel = *scanptr & 0xc0; + while (pixel > 3) + pixel >>= 2; + + p[0] = redcmap[pixel]; + p[1] = greencmap[pixel]; + p[2] = bluecmap[pixel]; + + if (bit > 3) + bit >>= 2; + else + { + bit = 0xc0; + scanptr ++; + } + } + } + else if (bits == 4) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, + p = in + 3 * ystart, bit = 0xf0; + ycount > 0; + ycount --, p += ydir) + { + if (bit == 0xf0) + { + pixel = (*scanptr & 0xf0) >> 4; + p[0] = redcmap[pixel]; + p[1] = greencmap[pixel]; + p[2] = bluecmap[pixel]; + bit = 0x0f; + } + else + { + pixel = *scanptr++ & 0x0f; + p[0] = redcmap[pixel]; + p[1] = greencmap[pixel]; + p[2] = bluecmap[pixel]; + bit = 0xf0; + } + } + } + else + { + TIFFReadScanline(tif, scanline, x, 0); + + for (ycount = img->ysize, p = in + 3 * ystart, scanptr = scanline; + ycount > 0; + ycount --, p += ydir) + { + p[0] = redcmap[*scanptr]; + p[1] = greencmap[*scanptr]; + p[2] = bluecmap[*scanptr++]; + } + } + + if (img->colorspace == IMAGE_RGB) + { + if (lut) + ImageLut(in, img->ysize * 3, lut); + + ImagePutCol(img, x, 0, img->ysize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->ysize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->ysize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->ysize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->ysize); + break; + } + + if (lut) + ImageLut(out, img->ysize * bpp, lut); + + ImagePutCol(img, x, 0, img->ysize, out); + } + } + } + break; + + case PHOTOMETRIC_RGB : + if (orientation < ORIENTATION_LEFTTOP) + { + /* + * Row major order... + */ + + for (y = ystart, ycount = img->ysize; + ycount > 0; + ycount --, y += ydir) + { + if (bits == 1) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0; + xcount > 0; + xcount --, p += pstep) + { + if (*scanptr & bit & 0x88) + p[0] = 255; + else + p[0] = 0; + + if (*scanptr & bit & 0x44) + p[1] = 255; + else + p[1] = 0; + + if (*scanptr & bit & 0x22) + p[2] = 255; + else + p[2] = 0; + + if (bit == 0xf0) + bit = 0x0f; + else + { + bit = 0xf0; + scanptr ++; + } + } + } + else if (bits == 2) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; + xcount > 0; + xcount --, p += pstep, scanptr ++) + { + pixel = *scanptr >> 2; + p[0] = 255 * (pixel & 3) / 3; + pixel >>= 2; + p[1] = 255 * (pixel & 3) / 3; + pixel >>= 2; + p[2] = 255 * (pixel & 3) / 3; + } + } + else if (bits == 4) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; + xcount > 0; + xcount -= 2, p += 2 * pstep, scanptr += 3) + { + pixel = scanptr[0]; + p[1] = 255 * (pixel & 15) / 15; + pixel >>= 4; + p[0] = 255 * (pixel & 15) / 15; + pixel = scanptr[1]; + p[2] = 255 * ((pixel >> 4) & 15) / 15; + + if (xcount > 1) + { + p[pstep + 0] = 255 * (pixel & 15) / 15; + pixel = scanptr[2]; + p[pstep + 2] = 255 * (pixel & 15) / 15; + pixel >>= 4; + p[pstep + 1] = 255 * (pixel & 15) / 15; + } + } + } + else if (xdir < 0 || alpha) + { + TIFFReadScanline(tif, scanline, y, 0); + + if (alpha) + { + for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline; + xcount > 0; + xcount --, p += pstep, scanptr += 4) + { + p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; + p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; + p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; + } + } + else + { + for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline; + xcount > 0; + xcount --, p += pstep, scanptr += 3) + { + p[0] = scanptr[0]; + p[1] = scanptr[1]; + p[2] = scanptr[2]; + } + } + } + else + TIFFReadScanline(tif, in, y, 0); + + if ((saturation != 100 || hue != 0) && bpp > 1) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + if (img->colorspace == IMAGE_RGB) + { + if (lut) + ImageLut(in, img->xsize * 3, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * bpp, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + } + else + { + /* + * Column major order... + */ + + for (x = xstart, xcount = img->xsize; + xcount > 0; + xcount --, x += xdir) + { + if (bits == 1) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3, bit = 0xf0; + ycount > 0; + ycount --, p += pstep) + { + if (*scanptr & bit & 0x88) + p[0] = 255; + else + p[0] = 0; + + if (*scanptr & bit & 0x44) + p[1] = 255; + else + p[1] = 0; + + if (*scanptr & bit & 0x22) + p[2] = 255; + else + p[2] = 0; + + if (bit == 0xf0) + bit = 0x0f; + else + { + bit = 0xf0; + scanptr ++; + } + } + } + else if (bits == 2) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3; + ycount > 0; + ycount --, p += pstep, scanptr ++) + { + pixel = *scanptr >> 2; + p[0] = 255 * (pixel & 3) / 3; + pixel >>= 2; + p[1] = 255 * (pixel & 3) / 3; + pixel >>= 2; + p[2] = 255 * (pixel & 3) / 3; + } + } + else if (bits == 4) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3; + ycount > 0; + ycount -= 2, p += 2 * pstep, scanptr += 3) + { + pixel = scanptr[0]; + p[1] = 255 * (pixel & 15) / 15; + pixel >>= 4; + p[0] = 255 * (pixel & 15) / 15; + pixel = scanptr[1]; + p[2] = 255 * ((pixel >> 4) & 15) / 15; + + if (ycount > 1) + { + p[pstep + 0] = 255 * (pixel & 15) / 15; + pixel = scanptr[2]; + p[pstep + 2] = 255 * (pixel & 15) / 15; + pixel >>= 4; + p[pstep + 1] = 255 * (pixel & 15) / 15; + } + } + } + else if (ydir < 0 || alpha) + { + TIFFReadScanline(tif, scanline, x, 0); + + if (alpha) + { + for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline; + ycount > 0; + ycount --, p += pstep, scanptr += 4) + { + p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; + p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; + p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; + } + } + else + { + for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline; + ycount > 0; + ycount --, p += pstep, scanptr += 3) + { + p[0] = scanptr[0]; + p[1] = scanptr[1]; + p[2] = scanptr[2]; + } + } + } + else + TIFFReadScanline(tif, in, x, 0); + + if ((saturation != 100 || hue != 0) && bpp > 1) + ImageRGBAdjust(in, img->ysize, saturation, hue); + + if (img->colorspace == IMAGE_RGB) + { + if (lut) + ImageLut(in, img->ysize * 3, lut); + + ImagePutCol(img, x, 0, img->ysize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->ysize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->ysize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->ysize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->ysize); + break; + } + + if (lut) + ImageLut(out, img->ysize * bpp, lut); + + ImagePutCol(img, x, 0, img->ysize, out); + } + } + } + break; + + case PHOTOMETRIC_SEPARATED : + TIFFGetField(tif, TIFFTAG_INKSET, &inkset); + + if (inkset == INKSET_CMYK) + { + if (orientation < ORIENTATION_LEFTTOP) + { + /* + * Row major order... + */ + + for (y = ystart, ycount = img->ysize; + ycount > 0; + ycount --, y += ydir) + { + if (bits == 1) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0; + xcount > 0; + xcount --, p += pstep) + { + if (*scanptr & bit & 0x11) + { + p[0] = 0; + p[1] = 0; + p[2] = 0; + } + else + { + if (*scanptr & bit & 0x88) + p[0] = 0; + else + p[0] = 255; + + if (*scanptr & bit & 0x44) + p[1] = 0; + else + p[1] = 255; + + if (*scanptr & bit & 0x22) + p[2] = 0; + else + p[2] = 255; + } + + if (bit == 0xf0) + bit = 0x0f; + else + { + bit = 0xf0; + scanptr ++; + } + } + } + else if (bits == 2) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; + xcount > 0; + xcount --, p += pstep, scanptr ++) + { + pixel = *scanptr; + k = 255 * (pixel & 3) / 3; + if (k == 255) + { + p[0] = 0; + p[1] = 0; + p[2] = 0; + } + else + { + pixel >>= 2; + b = 255 - 255 * (pixel & 3) / 3 - k; + if (b < 0) + p[2] = 0; + else if (b < 256) + p[2] = b; + else + p[2] = 255; + + pixel >>= 2; + g = 255 - 255 * (pixel & 3) / 3 - k; + if (g < 0) + p[1] = 0; + else if (g < 256) + p[1] = g; + else + p[1] = 255; + + pixel >>= 2; + r = 255 - 255 * (pixel & 3) / 3 - k; + if (r < 0) + p[0] = 0; + else if (r < 256) + p[0] = r; + else + p[0] = 255; + } + } + } + else if (bits == 4) + { + TIFFReadScanline(tif, scanline, y, 0); + for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; + xcount > 0; + xcount --, p += pstep, scanptr += 2) + { + pixel = scanptr[1]; + k = 255 * (pixel & 15) / 15; + if (k == 255) + { + p[0] = 0; + p[1] = 0; + p[2] = 0; + } + else + { + pixel >>= 4; + b = 255 - 255 * (pixel & 15) / 15 - k; + if (b < 0) + p[2] = 0; + else if (b < 256) + p[2] = b; + else + p[2] = 255; + + pixel = scanptr[0]; + g = 255 - 255 * (pixel & 15) / 15 - k; + if (g < 0) + p[1] = 0; + else if (g < 256) + p[1] = g; + else + p[1] = 255; + + pixel >>= 4; + r = 255 - 255 * (pixel & 15) / 15 - k; + if (r < 0) + p[0] = 0; + else if (r < 256) + p[0] = r; + else + p[0] = 255; + } + } + } + else + { + TIFFReadScanline(tif, scanline, y, 0); + + for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline; + xcount > 0; + xcount --, p += pstep, scanptr += 4) + { + k = scanptr[3]; + if (k == 255) + { + p[0] = 0; + p[1] = 0; + p[2] = 0; + } + else + { + r = 255 - scanptr[0] - k; + if (r < 0) + p[0] = 0; + else if (r < 256) + p[0] = r; + else + p[0] = 255; + + g = 255 - scanptr[1] - k; + if (g < 0) + p[1] = 0; + else if (g < 256) + p[1] = g; + else + p[1] = 255; + + b = 255 - scanptr[2] - k; + if (b < 0) + p[2] = 0; + else if (b < 256) + p[2] = b; + else + p[2] = 255; + } + } + } + + if ((saturation != 100 || hue != 0) && bpp > 1) + ImageRGBAdjust(in, img->xsize, saturation, hue); + + if (img->colorspace == IMAGE_RGB) + { + if (lut) + ImageLut(in, img->xsize * 3, lut); + + ImagePutRow(img, 0, y, img->xsize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->xsize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->xsize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->xsize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->xsize); + break; + } + + if (lut) + ImageLut(out, img->xsize * 3, lut); + + ImagePutRow(img, 0, y, img->xsize, out); + } + } + } + else + { + /* + * Column major order... + */ + + for (x = xstart, xcount = img->xsize; + xcount > 0; + xcount --, x += xdir) + { + if (bits == 1) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0; + ycount > 0; + ycount --, p += pstep) + { + if (*scanptr & bit & 0x11) + { + p[0] = 0; + p[1] = 0; + p[2] = 0; + } + else + { + if (*scanptr & bit & 0x88) + p[0] = 0; + else + p[0] = 255; + + if (*scanptr & bit & 0x44) + p[1] = 0; + else + p[1] = 255; + + if (*scanptr & bit & 0x22) + p[2] = 0; + else + p[2] = 255; + } + + if (bit == 0xf0) + bit = 0x0f; + else + { + bit = 0xf0; + scanptr ++; + } + } + } + else if (bits == 2) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3; + ycount > 0; + ycount --, p += pstep, scanptr ++) + { + pixel = *scanptr; + k = 255 * (pixel & 3) / 3; + if (k == 255) + { + p[0] = 0; + p[1] = 0; + p[2] = 0; + } + else + { + pixel >>= 2; + b = 255 - 255 * (pixel & 3) / 3 - k; + if (b < 0) + p[2] = 0; + else if (b < 256) + p[2] = b; + else + p[2] = 255; + + pixel >>= 2; + g = 255 - 255 * (pixel & 3) / 3 - k; + if (g < 0) + p[1] = 0; + else if (g < 256) + p[1] = g; + else + p[1] = 255; + + pixel >>= 2; + r = 255 - 255 * (pixel & 3) / 3 - k; + if (r < 0) + p[0] = 0; + else if (r < 256) + p[0] = r; + else + p[0] = 255; + } + } + } + else if (bits == 4) + { + TIFFReadScanline(tif, scanline, x, 0); + for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3; + ycount > 0; + ycount --, p += pstep, scanptr += 2) + { + pixel = scanptr[1]; + k = 255 * (pixel & 15) / 15; + if (k == 255) + { + p[0] = 0; + p[1] = 0; + p[2] = 0; + } + else + { + pixel >>= 4; + b = 255 - 255 * (pixel & 15) / 15 - k; + if (b < 0) + p[2] = 0; + else if (b < 256) + p[2] = b; + else + p[2] = 255; + + pixel = scanptr[0]; + g = 255 - 255 * (pixel & 15) / 15 - k; + if (g < 0) + p[1] = 0; + else if (g < 256) + p[1] = g; + else + p[1] = 255; + + pixel >>= 4; + r = 255 - 255 * (pixel & 15) / 15 - k; + if (r < 0) + p[0] = 0; + else if (r < 256) + p[0] = r; + else + p[0] = 255; + } + } + } + else + { + TIFFReadScanline(tif, scanline, x, 0); + + for (ycount = img->ysize, p = in + xstart * 3, scanptr = scanline; + ycount > 0; + ycount --, p += pstep, scanptr += 4) + { + k = scanptr[3]; + if (k == 255) + { + p[0] = 0; + p[1] = 0; + p[2] = 0; + } + else + { + r = 255 - scanptr[0] - k; + if (r < 0) + p[0] = 0; + else if (r < 256) + p[0] = r; + else + p[0] = 255; + + g = 255 - scanptr[1] - k; + if (g < 0) + p[1] = 0; + else if (g < 256) + p[1] = g; + else + p[1] = 255; + + b = 255 - scanptr[2] - k; + if (b < 0) + p[2] = 0; + else if (b < 256) + p[2] = b; + else + p[2] = 255; + } + } + } + + if ((saturation != 100 || hue != 0) && bpp > 1) + ImageRGBAdjust(in, img->ysize, saturation, hue); + + if (img->colorspace == IMAGE_RGB) + { + if (lut) + ImageLut(in, img->ysize * 3, lut); + + ImagePutCol(img, x, 0, img->ysize, in); + } + else + { + switch (img->colorspace) + { + case IMAGE_WHITE : + ImageRGBToWhite(in, out, img->ysize); + break; + case IMAGE_BLACK : + ImageRGBToBlack(in, out, img->ysize); + break; + case IMAGE_CMY : + ImageRGBToCMY(in, out, img->ysize); + break; + case IMAGE_CMYK : + ImageRGBToCMYK(in, out, img->ysize); + break; + } + + if (lut) + ImageLut(out, img->ysize * bpp, lut); + + ImagePutCol(img, x, 0, img->ysize, out); + } + } + } + + break; + } + + default : + _TIFFfree(scanline); + free(in); + free(out); + + TIFFClose(tif); + return (-1); + } + + /* + * Free temporary buffers, close the TIFF file, and return. + */ + + _TIFFfree(scanline); + free(in); + free(out); + + TIFFClose(tif); + return (0); +} + + +#endif /* HAVE_LIBTIFF */ + + +/* + * End of "$Id$". + */ diff --git a/filter/image-zoom.c b/filter/image-zoom.c new file mode 100644 index 0000000000..fe15632f1d --- /dev/null +++ b/filter/image-zoom.c @@ -0,0 +1,310 @@ +/* + * "$Id$" + * + * Image zoom routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageZoomAlloc() - Allocate a pixel zoom record... + * ImageZoomFill() - Fill a zoom record with image data utilizing bilinear + * interpolation. + * ImageZoomQFill() - Fill a zoom record quickly using nearest-neighbor + * sampling. + * ImageZoomFree() - Free a zoom record... + */ + +/* + * Include necessary headers... + */ + +#include "image.h" + + +/* + * 'ZoomAlloc()' - Allocate a pixel zoom record... + */ + +izoom_t * +ImageZoomAlloc(image_t *img, /* I - Image to zoom */ + int x0, /* I - Upper-lefthand corner */ + int y0, /* I - ... */ + int x1, /* I - Lower-righthand corner */ + int y1, /* I - ... */ + int xsize, /* I - Final width of image */ + int ysize, /* I - Final height of image */ + int rotated) /* I - Non-zero if image is rotated 90 degs */ +{ + izoom_t *z; /* New zoom record */ + + + if ((z = (izoom_t *)calloc(1, sizeof(izoom_t))) == NULL) + return (NULL); + + z->img = img; + z->row = 0; + z->depth = ImageGetDepth(img); + z->rotated = rotated; + + if (rotated) + { + z->xorig = x1; + z->yorig = y0; + z->width = y1 - y0 + 1; + z->height = x1 - x0 + 1; + z->xsize = xsize; + z->ysize = ysize; + z->xmod = z->width % z->xsize; + z->xstep = z->width / z->xsize; + z->xincr = 1; + z->ymod = z->height % z->ysize; + z->ystep = z->height / z->ysize; + z->yincr = 1; + z->instep = z->xstep * z->depth; + z->inincr = z->xincr * z->depth; + + if (z->width < img->ysize) + z->xmax = z->width; + else + z->xmax = z->width - 1; + + if (z->height < img->xsize) + z->ymax = z->height; + else + z->ymax = z->height - 1; + } + else + { + z->xorig = x0; + z->yorig = y0; + z->width = x1 - x0 + 1; + z->height = y1 - y0 + 1; + z->xsize = xsize; + z->ysize = ysize; + z->xmod = z->width % z->xsize; + z->xstep = z->width / z->xsize; + z->xincr = 1; + z->ymod = z->height % z->ysize; + z->ystep = z->height / z->ysize; + z->yincr = 1; + z->instep = z->xstep * z->depth; + z->inincr = z->xincr * z->depth; + + if (z->width < img->xsize) + z->xmax = z->width; + else + z->xmax = z->width - 1; + + if (z->height < img->ysize) + z->ymax = z->height; + else + z->ymax = z->height - 1; + } + + if ((z->rows[0] = (ib_t *)malloc(z->xsize * z->depth)) == NULL) + { + free(z); + return (NULL); + } + + if ((z->rows[1] = (ib_t *)malloc(z->xsize * z->depth)) == NULL) + { + free(z->rows[0]); + free(z); + return (NULL); + } + + if ((z->in = (ib_t *)malloc(z->width * z->depth)) == NULL) + { + free(z->rows[0]); + free(z->rows[1]); + free(z); + return (NULL); + } + + return (z); +} + + +/* + * 'ImageZoomFill()' - Fill a zoom record with image data utilizing bilinear + * interpolation. + */ + +void +ImageZoomFill(izoom_t *z, /* I - Zoom record to fill */ + int iy) /* I - Zoom image row */ +{ + ib_t *r, /* Row pointer */ + *inptr; /* Pixel pointer */ + int xerr0, /* X error counter */ + xerr1; /* ... */ + int ix, + x, + count, + z_depth, + z_xstep, + z_xincr, + z_instep, + z_inincr, + z_xmax, + z_xmod, + z_xsize; + + + if (iy > z->ymax) + iy = z->ymax; + + z->row ^= 1; + + z_depth = z->depth; + z_xsize = z->xsize; + z_xmax = z->xmax; + z_xmod = z->xmod; + z_xstep = z->xstep; + z_xincr = z->xincr; + z_instep = z->instep; + z_inincr = z->inincr; + + if (z->rotated) + ImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in); + else + ImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in); + + if (z_inincr < 0) + inptr = z->in + (z->width - 1) * z_depth; + else + inptr = z->in; + + for (x = z_xsize, xerr0 = z_xsize, xerr1 = 0, ix = 0, r = z->rows[z->row]; + x > 0; + x --) + { + if (ix < z_xmax) + { + for (count = 0; count < z_depth; count ++) + *r++ = (inptr[count] * xerr0 + inptr[z_depth + count] * xerr1) / z_xsize; + } + else + { + for (count = 0; count < z_depth; count ++) + *r++ = inptr[count]; + } + + ix += z_xstep; + inptr += z_instep; + xerr0 -= z_xmod; + xerr1 += z_xmod; + + if (xerr0 <= 0) + { + xerr0 += z_xsize; + xerr1 -= z_xsize; + ix += z_xincr; + inptr += z_inincr; + } + } +} + + +/* + * 'ImageZoomQFill()' - Fill a zoom record quickly using nearest-neighbor sampling. + */ + +void +ImageZoomQFill(izoom_t *z, /* I - Zoom record to fill */ + int iy) /* I - Zoom image row */ +{ + ib_t *r, /* Row pointer */ + *inptr; /* Pixel pointer */ + int xerr0; /* X error counter */ + int ix, + x, + count, + z_depth, + z_xstep, + z_xincr, + z_instep, + z_inincr, + z_xmod, + z_xsize; + + + if (iy > z->ymax) + iy = z->ymax; + + z->row ^= 1; + + z_depth = z->depth; + z_xsize = z->xsize; + z_xmod = z->xmod; + z_xstep = z->xstep; + z_xincr = z->xincr; + z_instep = z->instep; + z_inincr = z->inincr; + + if (z->rotated) + ImageGetCol(z->img, z->xorig - iy, z->yorig, z->width, z->in); + else + ImageGetRow(z->img, z->xorig, z->yorig + iy, z->width, z->in); + + if (z_inincr < 0) + inptr = z->in + (z->width - 1) * z_depth; + else + inptr = z->in; + + for (x = z_xsize, xerr0 = z_xsize, ix = 0, r = z->rows[z->row]; + x > 0; + x --) + { + for (count = 0; count < z_depth; count ++) + *r++ = inptr[count]; + + ix += z_xstep; + inptr += z_instep; + xerr0 -= z_xmod; + + if (xerr0 <= 0) + { + xerr0 += z_xsize; + ix += z_xincr; + inptr += z_inincr; + } + } +} + + +/* + * 'ImageZoomFree()' - Free a zoom record... + */ + +void +ImageZoomFree(izoom_t *z) /* I - Zoom record to free */ +{ + free(z->rows[0]); + free(z->rows[1]); + free(z->in); + free(z); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image.c b/filter/image.c new file mode 100644 index 0000000000..0bc6cceffe --- /dev/null +++ b/filter/image.c @@ -0,0 +1,800 @@ +/* + * "$Id$" + * + * Base image support for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * ImageOpen() - Open an image file and read it into memory. + * ImageClose() - Close an image file. + * ImageSetMaxTiles() - Set the maximum number of tiles to cache. + * ImageSetProfile() - Set the device color profile. + * ImageGetCol() - Get a column of pixels from an image. + * ImageGetRow() - Get a row of pixels from an image. + * ImagePutCol() - Put a column of pixels to an image. + * ImagePutRow() - Put a row of pixels to an image. + * get_tile() - Get a cached tile. + * flush_tile() - Flush the least-recently-used tile in the cache. + */ + +/* + * Include necessary headers... + */ + +#include "image.h" +#include +#include +#include +#include + + +/* + * Globals... + */ + +int ImageHaveProfile = 0; /* Do we have a color profile? */ +int ImageDensity[256]; /* Ink/marker density LUT */ +int ImageMatrix[3][3][256]; /* Color transform matrix LUT */ + + +/* + * Local functions... + */ + +static ib_t *get_tile(image_t *img, int x, int y); +static void flush_tile(image_t *img); + + +/* + * 'ImageOpen()' - Open an image file and read it into memory. + */ + +image_t * /* O - New image */ +ImageOpen(char *filename, /* I - Filename of image */ + int primary, /* I - Primary colorspace needed */ + int secondary, /* I - Secondary colorspace if primary no good */ + int saturation,/* I - Color saturation level */ + int hue, /* I - Color hue adjustment */ + const ib_t *lut) /* I - RGB gamma/brightness LUT */ +{ + FILE *fp; /* File pointer */ + unsigned char header[16], /* First 16 bytes of file */ + header2[16]; /* Bytes 2048-2064 (PhotoCD) */ + image_t *img; /* New image buffer */ + int status; /* Status of load... */ + + + fprintf(stderr, "DEBUG: ImageOpen(\"%s\", %d, %d, %d, %d, %p)\n", + filename ? filename : "(null)", primary, secondary, + saturation, hue, lut); + + /* + * Range check... + */ + + if (filename == NULL) + { + fputs("ERROR: Image filename == NULL!\n", stderr); + return (NULL); + } + + /* + * Figure out the file type... + */ + + if ((fp = fopen(filename, "r")) == NULL) + { + perror("ERROR: Unable to open image file"); + return (NULL); + } + + if (fread(header, 1, sizeof(header), fp) == 0) + { + perror("ERROR: Unable to read image file header"); + + fclose(fp); + return (NULL); + } + + fseek(fp, 2048, SEEK_SET); + memset(header2, 0, sizeof(header2)); + fread(header2, 1, sizeof(header2), fp); + fseek(fp, 0, SEEK_SET); + + /* + * Allocate memory... + */ + + img = calloc(sizeof(image_t), 1); + + if (img == NULL) + { + perror("ERROR: Unable to allocate memory for image file"); + fclose(fp); + return (NULL); + } + + /* + * Load the image as appropriate... + */ + + img->max_ics = TILE_MINIMUM; + img->xppi = 128; + img->yppi = 128; + + if (memcmp(header, "GIF87a", 6) == 0 || + memcmp(header, "GIF89a", 6) == 0) + status = ImageReadGIF(img, fp, primary, secondary, saturation, hue, lut); + else if (memcmp(header, "BM", 2) == 0) + status = ImageReadBMP(img, fp, primary, secondary, saturation, hue, lut); + else if (header[0] == 0x01 && header[1] == 0xda) + status = ImageReadSGI(img, fp, primary, secondary, saturation, hue, lut); + else if (header[0] == 0x59 && header[1] == 0xa6 && + header[2] == 0x6a && header[3] == 0x95) + status = ImageReadSunRaster(img, fp, primary, secondary, saturation, hue, lut); + else if (header[0] == 'P' && header[1] >= '1' && header[1] <= '6') + status = ImageReadPNM(img, fp, primary, secondary, saturation, hue, lut); + else if (memcmp(header2, "PCD_IPI", 7) == 0) + status = ImageReadPhotoCD(img, fp, primary, secondary, saturation, hue, lut); + else if (memcmp(header + 8, "\000\010", 2) == 0 || + memcmp(header + 8, "\000\030", 2) == 0) + status = ImageReadPIX(img, fp, primary, secondary, saturation, hue, lut); +#if defined(HAVE_LIBPNG) && defined(HAVE_LIBZ) + else if (memcmp(header, "\211PNG", 4) == 0) + status = ImageReadPNG(img, fp, primary, secondary, saturation, hue, lut); +#endif /* HAVE_LIBPNG && HAVE_LIBZ */ +#ifdef HAVE_LIBJPEG + else if (memcmp(header, "\377\330\377", 3) == 0 && /* Start-of-Image */ + header[3] >= 0xe0 && header[3] <= 0xef) /* APPn */ + status = ImageReadJPEG(img, fp, primary, secondary, saturation, hue, lut); +#endif /* HAVE_LIBJPEG */ +#ifdef HAVE_LIBTIFF + else if (memcmp(header, "MM", 2) == 0 || + memcmp(header, "II", 2) == 0) + status = ImageReadTIFF(img, fp, primary, secondary, saturation, hue, lut); +#endif /* HAVE_LIBTIFF */ + else + { + fputs("ERROR: Unknown image file format!\n", stderr); + fclose(fp); + status = -1; + } + + if (status) + { + free(img); + return (NULL); + } + else + return (img); +} + + +/* + * 'ImageClose()' - Close an image file. + */ + +void +ImageClose(image_t *img) /* I - Image to close */ +{ + ic_t *current, /* Current cached tile */ + *next; /* Next cached tile */ + + + /* + * Wipe the tile cache file (if any)... + */ + + if (img->cachefile != NULL) + { + fprintf(stderr, "DEBUG: Closing and removing swap file \"%s\"...\n", + img->cachename); + + fclose(img->cachefile); + unlink(img->cachename); + } + + /* + * Free the image cache... + */ + + fputs("DEBUG: Freeing memory...\n", stderr); + + for (current = img->first, next = NULL; current != NULL; current = next) + { + fprintf(stderr, "DEBUG: Freeing cache (%p, next = %p)...\n", + current, next); + + next = current->next; + free(current); + } + + /* + * Free the rest of memory... + */ + + if (img->tiles != NULL) + { + fprintf(stderr, "DEBUG: Freeing tiles (%p)...\n", img->tiles[0]); + + free(img->tiles[0]); + + fprintf(stderr, "DEBUG: Freeing tile pointers (%p)...\n", img->tiles); + + free(img->tiles); + } + + free(img); +} + + +/* + * 'ImageSetMaxTiles()' - Set the maximum number of tiles to cache. + * + * If the "max_tiles" argument is 0 then the maximum number of tiles is + * computed from the image size or the RIP_CACHE environment variable. + */ + +void +ImageSetMaxTiles(image_t *img, /* I - Image to set */ + int max_tiles) /* I - Number of tiles to cache */ +{ + int cache_size, /* Size of tile cache in bytes */ + min_tiles, /* Minimum number of tiles to cache */ + max_size; /* Maximum cache size in bytes */ + char *cache_env, /* Cache size environment variable */ + cache_units[255]; /* Cache size units */ + + + min_tiles = max(TILE_MINIMUM, + 1 + max((img->xsize + TILE_SIZE - 1) / TILE_SIZE, + (img->ysize + TILE_SIZE - 1) / TILE_SIZE)); + + if (max_tiles == 0) + max_tiles = ((img->xsize + TILE_SIZE - 1) / TILE_SIZE) * + ((img->ysize + TILE_SIZE - 1) / TILE_SIZE); + + cache_size = max_tiles * TILE_SIZE * TILE_SIZE * ImageGetDepth(img); + + if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL) + { + switch (sscanf(cache_env, "%d%254s", &max_size, cache_units)) + { + case 0 : + max_size = 32 * 1024 * 1024; + break; + case 1 : + max_size *= 4 * TILE_SIZE * TILE_SIZE; + break; + case 2 : + if (tolower(cache_units[0]) == 'g') + max_size *= 1024 * 1024 * 1024; + else if (tolower(cache_units[0]) == 'm') + max_size *= 1024 * 1024; + else if (tolower(cache_units[0]) == 'k') + max_size *= 1024; + else if (tolower(cache_units[0]) == 't') + max_size *= 4 * TILE_SIZE * TILE_SIZE; + break; + } + } + else + max_size = 32 * 1024 * 1024; + + if (cache_size > max_size) + max_tiles = max_size / TILE_SIZE / TILE_SIZE / ImageGetDepth(img); + + if (max_tiles < min_tiles) + max_tiles = min_tiles; + + img->max_ics = max_tiles; + + fprintf(stderr, "DEBUG: max_ics=%d...\n", img->max_ics); +} + + +/* + * 'ImageSetProfile()' - Set the device color profile. + */ + +void +ImageSetProfile(float d, /* I - Ink/marker density */ + float g, /* I - Ink/marker gamma */ + float matrix[3][3]) /* I - Color transform matrix */ +{ + int i, j, k; /* Looping vars */ + float m; /* Current matrix value */ + int *im; /* Pointer into ImageMatrix */ + + ImageHaveProfile = 1; + + for (i = 0, im = ImageMatrix[0][0]; i < 3; i ++) + for (j = 0; j < 3; j ++) + for (k = 0, m = matrix[i][j]; k < 256; k ++) + *im++ = (int)(k * m + 0.5); + + for (k = 0, im = ImageDensity; k < 256; k ++) + *im++ = 255.0 * d * pow((float)k / 255.0, g) + 0.5; +} + + +/* + * 'ImageGetCol()' - Get a column of pixels from an image. + */ + +int /* O - -1 on error, 0 on success */ +ImageGetCol(image_t *img, /* I - Image */ + int x, /* I - Column */ + int y, /* I - Start row */ + int height, /* I - Column height */ + ib_t *pixels) /* O - Pixel data */ +{ + int bpp, /* Bytes per pixel */ + twidth, /* Tile width */ + count; /* Number of pixels to get */ + const ib_t *ib; /* Pointer into tile */ + + + if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize) + return (-1); + + if (y < 0) + { + height += y; + y = 0; + } + + if ((y + height) > img->ysize) + height = img->ysize - y; + + if (height < 1) + return (-1); + + bpp = ImageGetDepth(img); + twidth = bpp * (TILE_SIZE - 1); + + while (height > 0) + { + ib = get_tile(img, x, y); + + if (ib == NULL) + return (-1); + + count = TILE_SIZE - (y & (TILE_SIZE - 1)); + if (count > height) + count = height; + + y += count; + height -= count; + + for (; count > 0; count --, ib += twidth) + switch (bpp) + { + case 4 : + *pixels++ = *ib++; + case 3 : + *pixels++ = *ib++; + *pixels++ = *ib++; + case 1 : + *pixels++ = *ib++; + break; + } + } + + return (0); +} + + +/* + * 'ImageGetRow()' - Get a row of pixels from an image. + */ + +int /* O - -1 on error, 0 on success */ +ImageGetRow(image_t *img, /* I - Image */ + int x, /* I - Start column */ + int y, /* I - Row */ + int width, /* I - Width of row */ + ib_t *pixels) /* O - Pixel data */ +{ + int bpp, /* Bytes per pixel */ + count; /* Number of pixels to get */ + const ib_t *ib; /* Pointer to pixels */ + + + if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize) + return (-1); + + if (x < 0) + { + width += x; + x = 0; + } + + if ((x + width) > img->xsize) + width = img->xsize - x; + + if (width < 1) + return (-1); + + bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace; + + while (width > 0) + { + ib = get_tile(img, x, y); + + if (ib == NULL) + return (-1); + + count = TILE_SIZE - (x & (TILE_SIZE - 1)); + if (count > width) + count = width; + memcpy(pixels, ib, count * bpp); + pixels += count * bpp; + x += count; + width -= count; + } + + return (0); +} + + +/* + * 'ImagePutCol()' - Put a column of pixels to an image. + */ + +int /* O - -1 on error, 0 on success */ +ImagePutCol(image_t *img, /* I - Image */ + int x, /* I - Column */ + int y, /* I - Start row */ + int height, /* I - Column height */ + const ib_t *pixels) /* I - Pixels to put */ +{ + int bpp, /* Bytes per pixel */ + twidth, /* Width of tile */ + count; /* Number of pixels to put */ + int tilex, /* Column within tile */ + tiley; /* Row within tile */ + ib_t *ib; /* Pointer to pixels in tile */ + + + if (img == NULL || x < 0 || x >= img->xsize || y >= img->ysize) + return (-1); + + if (y < 0) + { + height += y; + y = 0; + } + + if ((y + height) > img->ysize) + height = img->ysize - y; + + if (height < 1) + return (-1); + + bpp = ImageGetDepth(img); + twidth = bpp * (TILE_SIZE - 1); + tilex = x / TILE_SIZE; + tiley = y / TILE_SIZE; + + while (height > 0) + { + ib = get_tile(img, x, y); + + if (ib == NULL) + return (-1); + + img->tiles[tiley][tilex].dirty = 1; + tiley ++; + + count = TILE_SIZE - (y & (TILE_SIZE - 1)); + if (count > height) + count = height; + + y += count; + height -= count; + + for (; count > 0; count --, ib += twidth) + switch (bpp) + { + case 4 : + *ib++ = *pixels++; + case 3 : + *ib++ = *pixels++; + *ib++ = *pixels++; + case 1 : + *ib++ = *pixels++; + break; + } + } + + return (0); +} + + +/* + * 'ImagePutRow()' - Put a row of pixels to an image. + */ + +int /* O - -1 on error, 0 on success */ +ImagePutRow(image_t *img, /* I - Image */ + int x, /* I - Start column */ + int y, /* I - Row */ + int width, /* I - Row width */ + const ib_t *pixels) /* I - Pixel data */ +{ + int bpp, /* Bytes per pixel */ + count; /* Number of pixels to put */ + int tilex, /* Column within tile */ + tiley; /* Row within tile */ + ib_t *ib; /* Pointer to pixels in tile */ + + + if (img == NULL || y < 0 || y >= img->ysize || x >= img->xsize) + return (-1); + + if (x < 0) + { + width += x; + x = 0; + } + + if ((x + width) > img->xsize) + width = img->xsize - x; + + if (width < 1) + return (-1); + + bpp = img->colorspace < 0 ? -img->colorspace : img->colorspace; + tilex = x / TILE_SIZE; + tiley = y / TILE_SIZE; + + while (width > 0) + { + ib = get_tile(img, x, y); + + if (ib == NULL) + return (-1); + + img->tiles[tiley][tilex].dirty = 1; + + count = TILE_SIZE - (x & (TILE_SIZE - 1)); + if (count > width) + count = width; + memcpy(ib, pixels, count * bpp); + pixels += count * bpp; + x += count; + width -= count; + tilex ++; + } + + return (0); +} + + +/* + * 'get_tile()' - Get a cached tile. + */ + +static ib_t * /* O - Pointer to tile or NULL */ +get_tile(image_t *img, /* I - Image */ + int x, /* I - Column in image */ + int y) /* I - Row in image */ +{ + int bpp, /* Bytes per pixel */ + tilex, /* Column within tile */ + tiley, /* Row within tile */ + xtiles, /* Number of tiles horizontally */ + ytiles; /* Number of tiles vertically */ + ic_t *ic; /* Cache pointer */ + itile_t *tile; /* Tile pointer */ + + + if (x >= img->xsize || y >= img->ysize) + { + fprintf(stderr, "ERROR: Internal image RIP error - %d,%d is outside of %dx%d\n", + x, y, img->xsize, img->ysize); + return (NULL); + } + + if (img->tiles == NULL) + { + xtiles = (img->xsize + TILE_SIZE - 1) / TILE_SIZE; + ytiles = (img->ysize + TILE_SIZE - 1) / TILE_SIZE; + + fprintf(stderr, "DEBUG: Creating tile array (%dx%d)\n", xtiles, ytiles); + + img->tiles = calloc(sizeof(itile_t *), ytiles); + tile = calloc(sizeof(itile_t), xtiles * ytiles); + + for (tiley = 0; tiley < ytiles; tiley ++) + { + img->tiles[tiley] = tile; + for (tilex = xtiles; tilex > 0; tilex --, tile ++) + tile->pos = -1; + } + } + + bpp = ImageGetDepth(img); + tilex = x / TILE_SIZE; + tiley = y / TILE_SIZE; + x &= (TILE_SIZE - 1); + y &= (TILE_SIZE - 1); + + tile = img->tiles[tiley] + tilex; + + if ((ic = tile->ic) == NULL) + { + if (img->num_ics < img->max_ics) + { + ic = calloc(sizeof(ic_t) + bpp * TILE_SIZE * TILE_SIZE, 1); + ic->pixels = ((ib_t *)ic) + sizeof(ic_t); + + img->num_ics ++; + + fprintf(stderr, "DEBUG: Allocated cache tile %d (%p)...\n", + img->num_ics, ic); + } + else + { + fprintf(stderr, "DEBUG: Flushing old cache tile (%p)...\n", + img->first); + + flush_tile(img); + ic = img->first; + } + + ic->tile = tile; + tile->ic = ic; + + if (tile->pos >= 0) + { + fprintf(stderr, "DEBUG: Loading cache tile from file position %ld...\n", + tile->pos); + + if (ftell(img->cachefile) != tile->pos) + if (fseek(img->cachefile, tile->pos, SEEK_SET)) + perror("get_tile:"); + + fread(ic->pixels, bpp, TILE_SIZE * TILE_SIZE, img->cachefile); + } + else + { + fputs("DEBUG: Clearing cache tile...\n", stderr); + + memset(ic->pixels, 0, bpp * TILE_SIZE * TILE_SIZE); + } + } + + if (ic == img->first) + { + if (ic->next != NULL) + ic->next->prev = NULL; + + img->first = ic->next; + ic->next = NULL; + ic->prev = NULL; + } + else if (img->first == NULL) + img->first = ic; + + if (ic != img->last) + { + /* + * Remove the cache entry from the list... + */ + + if (ic->prev != NULL) + ic->prev->next = ic->next; + if (ic->next != NULL) + ic->next->prev = ic->prev; + + /* + * And add it to the end... + */ + + if (img->last != NULL) + img->last->next = ic; + + ic->prev = img->last; + img->last = ic; + } + + ic->next = NULL; + + return (ic->pixels + bpp * (y * TILE_SIZE + x)); +} + + +/* + * 'flush_tile()' - Flush the least-recently-used tile in the cache. + */ + +static void +flush_tile(image_t *img) /* I - Image */ +{ + int bpp; /* Bytes per pixel */ + itile_t *tile; /* Pointer to tile */ + + + + bpp = ImageGetDepth(img); + tile = img->first->tile; + + if (!tile->dirty) + { + tile->ic = NULL; + return; + } + + if (img->cachefile == NULL) + { + cupsTempFile(img->cachename, sizeof(img->cachename)); + + fprintf(stderr, "DEBUG: Creating swap file \"%s\"...\n", img->cachename); + + if ((img->cachefile = fopen(img->cachename, "wb+")) == NULL) + { + perror("ERROR: Unable to create image swap file"); + tile->ic = NULL; + tile->dirty = 0; + return; + } + } + + if (tile->pos >= 0) + { + if (ftell(img->cachefile) != tile->pos) + if (fseek(img->cachefile, tile->pos, SEEK_SET)) + { + perror("ERROR: Unable to seek in swap file"); + tile->ic = NULL; + tile->dirty = 0; + return; + } + } + else + { + if (fseek(img->cachefile, 0, SEEK_END)) + { + perror("ERROR: Unable to append to swap file"); + tile->ic = NULL; + tile->dirty = 0; + return; + } + + tile->pos = ftell(img->cachefile); + } + + + if (fwrite(tile->ic->pixels, bpp, TILE_SIZE * TILE_SIZE, img->cachefile) < 1) + perror("ERROR: Unable to write tile to swap file"); + else + fprintf(stderr, "DEBUG: Wrote tile at position %ld...\n", tile->pos); + + tile->ic = NULL; + tile->dirty = 0; +} + + +/* + * End of "$Id$". + */ diff --git a/filter/image.h b/filter/image.h new file mode 100644 index 0000000000..858926d6ea --- /dev/null +++ b/filter/image.h @@ -0,0 +1,231 @@ +/* + * "$Id$" + * + * Image library definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +#ifndef _IMAGE_H_ +# define _IMAGE_H_ + +/* + * Include necessary headers... + */ + +# include +# include +# include +# include +# include + + +/* + * Colorspaces... + */ + +# define IMAGE_CMYK -4 /* Cyan, magenta, yellow, and black */ +# define IMAGE_CMY -3 /* Cyan, magenta, and yellow */ +# define IMAGE_BLACK -1 /* Black */ +# define IMAGE_WHITE 1 /* White (luminance) */ +# define IMAGE_RGB 3 /* Red, green, and blue */ + +/* + * Tile definitions... + */ + +# define TILE_SIZE 256 /* 256x256 pixel tiles */ +# define TILE_MINIMUM 10 /* Minimum number of tiles */ + +/* + * min/max/abs macros... + */ + +#ifndef max +# define max(a,b) ((a) > (b) ? (a) : (b)) +#endif /* !max */ +#ifndef min +# define min(a,b) ((a) < (b) ? (a) : (b)) +#endif /* !min */ +#ifndef abs +# define abs(a) ((a) < 0 ? -(a) : (a)) +#endif /* !abs */ + + +/* + * Image byte type... + */ + +typedef unsigned char ib_t; + +/* + * Tile cache structure... + */ + +typedef struct ic_str +{ + struct ic_str *prev, /* Previous tile in cache */ + *next; /* Next tile in cache */ + void *tile; /* Tile this is attached to */ + ib_t *pixels; /* Pixel data */ +} ic_t; + +/* + * Tile structure... + */ + +typedef struct +{ + int dirty; /* True if tile is dirty */ + long pos; /* Position of tile on disk (-1 if not written) */ + ic_t *ic; /* Pixel data */ +} itile_t; + +/* + * Image structure... + */ + +typedef struct +{ + int colorspace; /* Colorspace of image */ + unsigned xsize, /* Width of image in pixels */ + ysize, /* Height of image in pixels */ + xppi, /* X resolution in pixels-per-inch */ + yppi, /* Y resolution in pixels-per-inch */ + num_ics, /* Number of cached tiles */ + max_ics; /* Maximum number of cached tiles */ + itile_t **tiles; /* Tiles in image */ + ic_t *first, /* First cached tile in image */ + *last; /* Last cached tile in image */ + FILE *cachefile; /* Tile cache file */ + char cachename[256]; /* Tile cache filename */ +} image_t; + +/* + * Image row zooming structure... + */ + +typedef struct +{ + image_t *img; /* Image to zoom */ + unsigned xorig, + yorig, + width, /* Width of input area */ + height, /* Height of input area */ + depth, /* Number of bytes per pixel */ + rotated, /* Non-zero if image needs to be rotated */ + xsize, /* Width of output image */ + ysize, /* Height of output image */ + xmax, /* Maximum input image X position */ + ymax, /* Maximum input image Y position */ + xmod, /* Threshold for Bresenheim rounding */ + ymod; /* ... */ + int xstep, /* Amount to step for each pixel along X */ + xincr, + instep, /* Amount to step pixel pointer along X */ + inincr, + ystep, /* Amount to step for each pixel along Y */ + yincr, + row; /* Current row */ + ib_t *rows[2], /* Horizontally scaled pixel data */ + *in; /* Unscaled input pixel data */ +} izoom_t; + + +/* + * Basic image functions... + */ + +extern image_t *ImageOpen(char *filename, int primary, int secondary, + int saturation, int hue, const ib_t *lut); +extern void ImageClose(image_t *img); +extern void ImageSetMaxTiles(image_t *img, int max_tiles); +extern void ImageSetProfile(float d, float g, float matrix[3][3]); + +#define ImageGetDepth(img) ((img)->colorspace < 0 ? -(img)->colorspace : (img)->colorspace) +extern int ImageGetCol(image_t *img, int x, int y, int height, ib_t *pixels); +extern int ImageGetRow(image_t *img, int x, int y, int width, ib_t *pixels); +extern int ImagePutCol(image_t *img, int x, int y, int height, const ib_t *pixels); +extern int ImagePutRow(image_t *img, int x, int y, int width, const ib_t *pixels); + +/* + * File formats... + */ + +extern int ImageReadBMP(image_t *img, FILE *fp, int primary, int secondary, + int saturation, int hue, const ib_t *lut); +extern int ImageReadFPX(image_t *img, FILE *fp, int primary, int secondary, + int saturation, int hue, const ib_t *lut); +extern int ImageReadGIF(image_t *img, FILE *fp, int primary, int secondary, + int saturation, int hue, const ib_t *lut); +extern int ImageReadJPEG(image_t *img, FILE *fp, int primary, int secondary, + int saturation, int hue, const ib_t *lut); +extern int ImageReadPIX(image_t *img, FILE *fp, int primary, int secondary, + int saturation, int hue, const ib_t *lut); +extern int ImageReadPNG(image_t *img, FILE *fp, int primary, int secondary, + int saturation, int hue, const ib_t *lut); +extern int ImageReadPNM(image_t *img, FILE *fp, int primary, int secondary, + int saturation, int hue, const ib_t *lut); +extern int ImageReadPhotoCD(image_t *img, FILE *fp, int primary, + int secondary, int saturation, int hue, + const ib_t *lut); +extern int ImageReadSGI(image_t *img, FILE *fp, int primary, int secondary, + int saturation, int hue, const ib_t *lut); +extern int ImageReadSunRaster(image_t *img, FILE *fp, int primary, + int secondary, int saturation, int hue, + const ib_t *lut); +extern int ImageReadTIFF(image_t *img, FILE *fp, int primary, int secondary, + int saturation, int hue, const ib_t *lut); + +/* + * Colorspace conversions... + */ + +extern void ImageWhiteToWhite(const ib_t *in, ib_t *out, int count); +extern void ImageWhiteToRGB(const ib_t *in, ib_t *out, int count); +extern void ImageWhiteToBlack(const ib_t *in, ib_t *out, int count); +extern void ImageWhiteToCMY(const ib_t *in, ib_t *out, int count); +extern void ImageWhiteToCMYK(const ib_t *in, ib_t *out, int count); + +extern void ImageRGBToWhite(const ib_t *in, ib_t *out, int count); +extern void ImageRGBToRGB(const ib_t *in, ib_t *out, int count); +extern void ImageRGBToBlack(const ib_t *in, ib_t *out, int count); +extern void ImageRGBToCMY(const ib_t *in, ib_t *out, int count); +extern void ImageRGBToCMYK(const ib_t *in, ib_t *out, int count); + +extern void ImageRGBAdjust(ib_t *pixels, int count, int saturation, int hue); + +extern void ImageLut(ib_t *pixels, int count, const ib_t *lut); + +/* + * Image scaling operations... + */ + +extern izoom_t *ImageZoomAlloc(image_t *img, int x0, int y0, int x1, int y1, + int xsize, int ysize, int rotated); +extern void ImageZoomFill(izoom_t *z, int iy); +extern void ImageZoomQFill(izoom_t *z, int iy); +extern void ImageZoomFree(izoom_t *z); + + +#endif /* !_IMAGE_H_ */ + +/* + * End of "$Id$". + */ diff --git a/filter/imagetops.c b/filter/imagetops.c new file mode 100644 index 0000000000..823425b71f --- /dev/null +++ b/filter/imagetops.c @@ -0,0 +1,685 @@ +/* + * "$Id$" + * + * Image file to PostScript filter for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry... + * ps_hex() - Print binary data as a series of hexadecimal numbers. + * ps_ascii85() - Print binary data as a series of base-85 numbers. + */ + +/* + * Include necessary headers... + */ + +#include "common.h" +#include "image.h" +#include + + +/* + * Globals... + */ + +int Flip = 0, /* Flip/mirror pages */ + XPosition = 0, /* Horizontal position on page */ + YPosition = 0, /* Vertical position on page */ + Collate = 0, /* Collate copies? */ + Copies = 1; /* Number of copies */ + + +/* + * Local functions... + */ + +static void ps_hex(ib_t *, int); +static void ps_ascii85(ib_t *, int, int); + + +/* + * 'main()' - Main entry... + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + image_t *img; /* Image to print */ + float xprint, /* Printable area */ + yprint, + xinches, /* Total size in inches */ + yinches; + float xsize, /* Total size in points */ + ysize, + xsize2, + ysize2; + float aspect; /* Aspect ratio */ + int xpages, /* # x pages */ + ypages, /* # y pages */ + xpage, /* Current x page */ + ypage, /* Current y page */ + page; /* Current page number */ + int x0, y0, /* Corners of the page in image coords */ + x1, y1; + ib_t *row; /* Current row */ + int y; /* Current Y coordinate in image */ + int colorspace; /* Output colorspace */ + int out_offset, /* Offset into output buffer */ + out_length; /* Length of output buffer */ + ppd_file_t *ppd; /* PPD file */ + int num_options; /* Number of print options */ + cups_option_t *options; /* Print options */ + const char *val; /* Option value */ + int slowcollate; /* Collate copies the slow way */ + float g; /* Gamma correction value */ + float b; /* Brightness factor */ + float zoom; /* Zoom facter */ + int xppi, yppi; /* Pixels-per-inch */ + int hue, sat; /* Hue and saturation adjustment */ + int realcopies; /* Real copies being printed */ + float left, top; /* Left and top of image */ + + + if (argc != 7) + { + fputs("ERROR: imagetops job-id user title copies options file\n", stderr); + return (1); + } + + /* + * Process command-line options and write the prolog... + */ + + zoom = 0.0; + xppi = 0; + yppi = 0; + hue = 0; + sat = 100; + g = 1.0; + b = 1.0; + + Copies = atoi(argv[4]); + + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + + ppd = SetCommonOptions(num_options, options, 1); + + if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL) + { + /* + * This IPP attribute is unnecessarily complicated... + * + * single-document, separate-documents-collated-copies, and + * single-document-new-sheet all require collated copies. + * + * separate-documents-collated-copies allows for uncollated copies. + */ + + Collate = strcasecmp(val, "separate-documents-collated-copies") != 0; + } + + if ((val = cupsGetOption("Collate", num_options, options)) != NULL && + strcasecmp(val, "True") == 0) + Collate = 1; + + if ((val = cupsGetOption("gamma", num_options, options)) != NULL) + g = atoi(val) * 0.001f; + + if ((val = cupsGetOption("brightness", num_options, options)) != NULL) + b = atoi(val) * 0.01f; + + if ((val = cupsGetOption("scaling", num_options, options)) != NULL) + zoom = atoi(val) * 0.01; + + if ((val = cupsGetOption("ppi", num_options, options)) != NULL) + if (sscanf(val, "%dx%d", &xppi, &yppi) < 2) + yppi = xppi; + + if ((val = cupsGetOption("position", num_options, options)) != NULL) + { + if (strcasecmp(val, "center") == 0) + { + XPosition = 0; + YPosition = 0; + } + else if (strcasecmp(val, "top") == 0) + { + XPosition = 0; + YPosition = 1; + } + else if (strcasecmp(val, "left") == 0) + { + XPosition = -1; + YPosition = 0; + } + else if (strcasecmp(val, "right") == 0) + { + XPosition = 1; + YPosition = 0; + } + else if (strcasecmp(val, "top-left") == 0) + { + XPosition = -1; + YPosition = 1; + } + else if (strcasecmp(val, "top-right") == 0) + { + XPosition = 1; + YPosition = 1; + } + else if (strcasecmp(val, "bottom") == 0) + { + XPosition = 0; + YPosition = -1; + } + else if (strcasecmp(val, "bottom-left") == 0) + { + XPosition = -1; + YPosition = -1; + } + else if (strcasecmp(val, "bottom-right") == 0) + { + XPosition = 1; + YPosition = -1; + } + } + + if ((val = cupsGetOption("saturation", num_options, options)) != NULL) + sat = atoi(val); + + if ((val = cupsGetOption("hue", num_options, options)) != NULL) + hue = atoi(val); + + /* + * Open the input image to print... + */ + + colorspace = ColorDevice ? IMAGE_RGB : IMAGE_WHITE; + + if ((img = ImageOpen(argv[6], colorspace, IMAGE_WHITE, sat, hue, NULL)) == NULL) + { + fputs("ERROR: Unable to open image file for printing!\n", stderr); + ppdClose(ppd); + return (1); + } + + colorspace = img->colorspace; + + /* + * Scale as necessary... + */ + + xprint = (PageRight - PageLeft) / 72.0; + yprint = (PageTop - PageBottom) / 72.0; + + if (zoom == 0.0 && xppi == 0) + { + xppi = img->xppi; + yppi = img->yppi; + } + + if (yppi == 0) + yppi = xppi; + + if (xppi > 0) + { + /* + * Scale the image as neccesary to match the desired pixels-per-inch. + */ + + xinches = (float)img->xsize / (float)xppi; + yinches = (float)img->ysize / (float)yppi; + + if (cupsGetOption("orientation", num_options, options) == NULL && + cupsGetOption("landscape", num_options, options) == NULL) + { + /* + * Rotate the image if it will fit landscape but not portrait... + */ + + if ((xinches > xprint || yinches > yprint) && + xinches <= yprint && yinches <= xprint) + { + /* + * Rotate the image as needed... + */ + + Orientation = (Orientation + 1) & 3; + xsize = yprint; + yprint = xprint; + xprint = xsize; + + xsize = PageLeft; + PageLeft = PageBottom; + PageBottom = PageWidth - PageRight; + PageRight = PageTop; + PageTop = PageLength - xsize; + + xsize = PageWidth; + PageWidth = PageLength; + PageLength = xsize; + } + } + } + else + { + /* + * Scale percentage of page size... + */ + + aspect = (float)img->yppi / (float)img->xppi; + + fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n", + img->xppi, img->yppi, aspect); + + xsize = xprint * zoom; + ysize = xsize * img->ysize / img->xsize / aspect; + + if (ysize > (yprint * zoom)) + { + ysize = yprint * zoom; + xsize = ysize * img->xsize * aspect / img->ysize; + } + + xsize2 = yprint * zoom; + ysize2 = xsize2 * img->ysize / img->xsize / aspect; + + if (ysize2 > (xprint * zoom)) + { + ysize2 = xprint * zoom; + xsize2 = ysize2 * img->xsize * aspect / img->ysize; + } + + fprintf(stderr, "DEBUG: xsize = %.0f, ysize = %.0f\n", xsize, ysize); + fprintf(stderr, "DEBUG: xsize2 = %.0f, ysize2 = %.0f\n", xsize2, ysize2); + + if (cupsGetOption("orientation", num_options, options) == NULL && + cupsGetOption("landscape", num_options, options) == NULL) + { + /* + * Choose the rotation with the largest area, but prefer + * portrait if they are equal... + */ + + if ((xsize * ysize) < (xsize2 * xsize2)) + { + /* + * Do landscape orientation... + */ + + Orientation = 1; + xinches = xsize2; + yinches = ysize2; + xprint = (PageTop - PageBottom) / 72.0; + yprint = (PageRight - PageLeft) / 72.0; + + xsize = PageLeft; + PageLeft = PageBottom; + PageBottom = PageWidth - PageRight; + PageRight = PageTop; + PageTop = PageLength - xsize; + + xsize = PageWidth; + PageWidth = PageLength; + PageLength = xsize; + } + else + { + /* + * Do portrait orientation... + */ + + Orientation = 0; + xinches = xsize; + yinches = ysize; + } + } + else if (Orientation & 1) + { + xinches = xsize2; + yinches = ysize2; + xprint = (PageTop - PageBottom) / 72.0; + yprint = (PageRight - PageLeft) / 72.0; + + xsize = PageLeft; + PageLeft = PageBottom; + PageBottom = PageWidth - PageRight; + PageRight = PageTop; + PageTop = PageLength - xsize; + + xsize = PageWidth; + PageWidth = PageLength; + PageLength = xsize; + } + } + + xpages = ceil(xinches / xprint); + ypages = ceil(yinches / yprint); + + /* + * See if we need to collate, and if so how we need to do it... + */ + + if (xpages == 1 && ypages == 1) + Collate = 0; + + slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL; + + /* + * Write any "exit server" options that have been selected... + */ + + ppdEmit(ppd, stdout, PPD_ORDER_EXIT); + + /* + * Write any JCL commands that are needed to print PostScript code... + */ + + if (ppd != NULL && ppd->jcl_begin && ppd->jcl_ps) + { + fputs(ppd->jcl_begin, stdout); + ppdEmit(ppd, stdout, PPD_ORDER_JCL); + fputs(ppd->jcl_ps, stdout); + } + + /* + * Start sending the document with any commands needed... + */ + + puts("%!"); + + if (ppd != NULL && ppd->patches != NULL) + puts(ppd->patches); + + ppdEmit(ppd, stdout, PPD_ORDER_DOCUMENT); + ppdEmit(ppd, stdout, PPD_ORDER_ANY); + ppdEmit(ppd, stdout, PPD_ORDER_PROLOG); + + if (g != 1.0 || b != 1.0) + printf("{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } " + "ifelse %.3f mul } bind settransfer\n", g, b); + + if (Copies > 1 && !slowcollate) + { + printf("/#copies %d def\n", Copies); + realcopies = Copies; + Copies = 1; + } + else + realcopies = 1; + + /* + * Output the pages... + */ + + xprint = xinches / xpages; + yprint = yinches / ypages; + row = malloc(img->xsize * abs(colorspace) + 3); + + for (page = 1; Copies > 0; Copies --) + for (xpage = 0; xpage < xpages; xpage ++) + for (ypage = 0; ypage < ypages; ypage ++, page ++) + { + fprintf(stderr, "PAGE: %d %d\n", page, realcopies); + fprintf(stderr, "INFO: Printing page %d...\n", page); + + ppdEmit(ppd, stdout, PPD_ORDER_PAGE); + + puts("gsave"); + + if (Flip) + printf("%.0f 0 translate -1 1 scale\n", PageWidth); + + switch (Orientation) + { + case 1 : /* Landscape */ + printf("%.0f 0 translate 90 rotate\n", PageLength); + break; + case 2 : /* Reverse Portrait */ + printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength); + break; + case 3 : /* Reverse Landscape */ + printf("0 %.0f translate -90 rotate\n", PageWidth); + break; + } + + x0 = img->xsize * xpage / xpages; + x1 = img->xsize * (xpage + 1) / xpages - 1; + y0 = img->ysize * ypage / ypages; + y1 = img->ysize * (ypage + 1) / ypages - 1; + + switch (XPosition) + { + case -1 : + left = PageLeft; + break; + case 0 : + left = (PageWidth - xprint * 72.0) * 0.5; + break; + case 1 : + left = PageRight - xprint * 72.0; + break; + } + + switch (YPosition) + { + case -1 : + top = PageBottom + 72.0 * yprint; + break; + case 0 : + top = (PageLength + yprint * 72.0) * 0.5; + break; + case 1 : + top = PageTop; + break; + } + + printf("%.1f %.1f translate\n", left, top); + + printf("%.3f %.3f scale\n\n", + xprint * 72.0 / (x1 - x0 + 1), + yprint * 72.0 / (y1 - y0 + 1)); + + if (LanguageLevel == 1) + { + printf("/picture %d string def\n", (x1 - x0 + 1) * abs(colorspace)); + printf("%d %d 8[1 0 0 -1 0 1]", (x1 - x0 + 1), (y1 - y0 + 1)); + + if (colorspace == IMAGE_WHITE) + puts("{currentfile picture readhexstring pop} image"); + else + puts("{currentfile picture readhexstring pop} false 3 colorimage"); + + for (y = y0; y <= y1; y ++) + { + ImageGetRow(img, x0, y, x1 - x0 + 1, row); + ps_hex(row, (x1 - x0 + 1) * abs(colorspace)); + } + } + else + { + if (colorspace == IMAGE_WHITE) + puts("/DeviceGray setcolorspace"); + else + puts("/DeviceRGB setcolorspace"); + + printf("<<" + "/ImageType 1" + "/Width %d" + "/Height %d" + "/BitsPerComponent 8", + x1 - x0 + 1, y1 - y0 + 1); + + if (colorspace == IMAGE_WHITE) + fputs("/Decode[0 1]", stdout); + else + fputs("/Decode[0 1 0 1 0 1]", stdout); + + fputs("/DataSource currentfile /ASCII85Decode filter", stdout); + + if (((x1 - x0 + 1) / xprint) < 100.0) + fputs("/Interpolate true", stdout); + + puts("/ImageMatrix[1 0 0 -1 0 1]>>image"); + + for (y = y0, out_offset = 0; y <= y1; y ++) + { + ImageGetRow(img, x0, y, x1 - x0 + 1, row + out_offset); + + out_length = (x1 - x0 + 1) * abs(colorspace) + out_offset; + out_offset = out_length & 3; + + ps_ascii85(row, out_length, y == y1); + + if (out_offset > 0) + memcpy(row, row + out_length - out_offset, out_offset); + } + } + + puts("grestore"); + puts("showpage"); + } + + /* + * End the job with the appropriate JCL command or CTRL-D otherwise. + */ + + if (ppd != NULL && ppd->jcl_end) + fputs(ppd->jcl_end, stdout); + else + putchar(0x04); + + /* + * Close files... + */ + + ImageClose(img); + ppdClose(ppd); + + return (0); +} + + +/* + * 'ps_hex()' - Print binary data as a series of hexadecimal numbers. + */ + +static void +ps_hex(ib_t *data, /* I - Data to print */ + int length) /* I - Number of bytes to print */ +{ + int col; + static char *hex = "0123456789ABCDEF"; + + + col = 0; + + while (length > 0) + { + /* + * Put the hex chars out to the file; note that we don't use printf() + * for speed reasons... + */ + + putchar(hex[*data >> 4]); + putchar(hex[*data & 15]); + + data ++; + length --; + + col = (col + 1) & 31; + if (col == 0 && length > 0) + putchar('\n'); + } + + putchar('\n'); +} + + +/* + * 'ps_ascii85()' - Print binary data as a series of base-85 numbers. + */ + +static void +ps_ascii85(ib_t *data, /* I - Data to print */ + int length, /* I - Number of bytes to print */ + int last_line) /* I - Last line of raster data? */ +{ + unsigned b; /* Binary data word */ + unsigned char c[5]; /* ASCII85 encoded chars */ + + + while (length > 3) + { + b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]; + + if (b == 0) + putchar('z'); + else + { + c[4] = (b % 85) + '!'; + b /= 85; + c[3] = (b % 85) + '!'; + b /= 85; + c[2] = (b % 85) + '!'; + b /= 85; + c[1] = (b % 85) + '!'; + b /= 85; + c[0] = b + '!'; + + fwrite(c, 5, 1, stdout); + } + + data += 4; + length -= 4; + } + + if (last_line) + { + if (length > 0) + { + memset(data + length, 0, 4 - length); + b = (((((data[0] << 8) | data[1]) << 8) | data[2]) << 8) | data[3]; + + c[4] = (b % 85) + '!'; + b /= 85; + c[3] = (b % 85) + '!'; + b /= 85; + c[2] = (b % 85) + '!'; + b /= 85; + c[1] = (b % 85) + '!'; + b /= 85; + c[0] = b + '!'; + + fwrite(c, length + 1, 1, stdout); + } + + puts("~>"); + } +} + + +/* + * End of "$Id$". + */ diff --git a/filter/imagetoraster.c b/filter/imagetoraster.c new file mode 100644 index 0000000000..f1ad73aecb --- /dev/null +++ b/filter/imagetoraster.c @@ -0,0 +1,4260 @@ +/* + * "$Id$" + * + * Image file to raster filter for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry... + * format_CMY() - Convert image data to CMY. + * format_CMYK() - Convert image data to CMYK. + * format_K() - Convert image data to black. + * format_KCMY() - Convert image data to KCMY. + * format_KCMYcm() - Convert image data to KCMYcm. + * format_RGBA() - Convert image data to RGBA. + * format_W() - Convert image data to luminance. + * format_YMC() - Convert image data to YMC. + * format_YMCK() - Convert image data to YMCK. + * make_lut() - Make a lookup table given gamma and brightness values. + */ + +/* + * Include necessary headers... + */ + +/* + * Include necessary headers... + */ + +#include "common.h" +#include "image.h" +#include "raster.h" +#include + + +/* + * Globals... + */ + +int Flip = 0, /* Flip/mirror pages */ + XPosition = 0, /* Horizontal position on page */ + YPosition = 0, /* Vertical position on page */ + Collate = 0, /* Collate copies? */ + Copies = 1; /* Number of copies */ +int Floyd16x16[16][16] = /* Traditional Floyd ordered dither */ + { + { 0, 128, 32, 160, 8, 136, 40, 168, + 2, 130, 34, 162, 10, 138, 42, 170 }, + { 192, 64, 224, 96, 200, 72, 232, 104, + 194, 66, 226, 98, 202, 74, 234, 106 }, + { 48, 176, 16, 144, 56, 184, 24, 152, + 50, 178, 18, 146, 58, 186, 26, 154 }, + { 240, 112, 208, 80, 248, 120, 216, 88, + 242, 114, 210, 82, 250, 122, 218, 90 }, + { 12, 140, 44, 172, 4, 132, 36, 164, + 14, 142, 46, 174, 6, 134, 38, 166 }, + { 204, 76, 236, 108, 196, 68, 228, 100, + 206, 78, 238, 110, 198, 70, 230, 102 }, + { 60, 188, 28, 156, 52, 180, 20, 148, + 62, 190, 30, 158, 54, 182, 22, 150 }, + { 252, 124, 220, 92, 244, 116, 212, 84, + 254, 126, 222, 94, 246, 118, 214, 86 }, + { 3, 131, 35, 163, 11, 139, 43, 171, + 1, 129, 33, 161, 9, 137, 41, 169 }, + { 195, 67, 227, 99, 203, 75, 235, 107, + 193, 65, 225, 97, 201, 73, 233, 105 }, + { 51, 179, 19, 147, 59, 187, 27, 155, + 49, 177, 17, 145, 57, 185, 25, 153 }, + { 243, 115, 211, 83, 251, 123, 219, 91, + 241, 113, 209, 81, 249, 121, 217, 89 }, + { 15, 143, 47, 175, 7, 135, 39, 167, + 13, 141, 45, 173, 5, 133, 37, 165 }, + { 207, 79, 239, 111, 199, 71, 231, 103, + 205, 77, 237, 109, 197, 69, 229, 101 }, + { 63, 191, 31, 159, 55, 183, 23, 151, + 61, 189, 29, 157, 53, 181, 21, 149 }, + { 254, 127, 223, 95, 247, 119, 215, 87, + 253, 125, 221, 93, 245, 117, 213, 85 } + }; +int Floyd8x8[8][8] = + { + { 0, 32, 8, 40, 2, 34, 10, 42 }, + { 48, 16, 56, 24, 50, 18, 58, 26 }, + { 12, 44, 4, 36, 14, 46, 6, 38 }, + { 60, 28, 52, 20, 62, 30, 54, 22 }, + { 3, 35, 11, 43, 1, 33, 9, 41 }, + { 51, 19, 59, 27, 49, 17, 57, 25 }, + { 15, 47, 7, 39, 13, 45, 5, 37 }, + { 63, 31, 55, 23, 61, 29, 53, 21 } + }; +int Floyd4x4[4][4] = + { + { 0, 8, 2, 10 }, + { 12, 4, 14, 6 }, + { 3, 11, 1, 9 }, + { 15, 7, 13, 5 } + }; + +ib_t OnPixels[256], /* On-pixel LUT */ + OffPixels[256]; /* Off-pixel LUT */ +int Planes[] = /* Number of planes for each colorspace */ + { 1, 3, 4, 1, 3, 3, 4, 4, 4, 6, 4, 4, 1, 1, 1 }; + + +/* + * Local functions... + */ + +static void exec_choice(cups_page_header_t *header, ppd_choice_t *choice); +static void format_CMY(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1); +static void format_CMYK(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1); +static void format_K(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1); +static void format_KCMYcm(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1); +static void format_KCMY(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1); +#define format_RGB format_CMY +static void format_RGBA(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1); +static void format_W(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1); +static void format_YMC(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1); +static void format_YMCK(cups_page_header_t *header, unsigned char *row, int y, int z, int xsize, int ysize, int yerr0, int yerr1, ib_t *r0, ib_t *r1); +static void make_lut(ib_t *, int, float, float); + + +/* + * 'main()' - Main entry... + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int i; /* Looping var */ + image_t *img; /* Image to print */ + float xprint, /* Printable area */ + yprint, + xinches, /* Total size in inches */ + yinches; + float xsize, /* Total size in points */ + ysize, + xsize2, + ysize2; + float aspect; /* Aspect ratio */ + int xpages, /* # x pages */ + ypages, /* # y pages */ + xpage, /* Current x page */ + ypage, /* Current y page */ + xtemp, /* Bitmap width in pixels */ + ytemp, /* Bitmap height in pixels */ + page; /* Current page number */ + int x0, y0, /* Corners of the page in image coords */ + x1, y1; + ppd_file_t *ppd; /* PPD file */ + ppd_choice_t *choice; /* PPD option choice */ + char *resolution, /* Output resolution */ + *media_type; /* Media type */ + ppd_profile_t *profile; /* Color profile */ + ppd_profile_t userprofile; /* User-specified profile */ + cups_raster_t *ras; /* Raster stream */ + cups_page_header_t header; /* Page header */ + int num_options; /* Number of print options */ + cups_option_t *options; /* Print options */ + const char *val; /* Option value */ + int slowcollate, /* Collate copies the slow way */ + slowcopies; /* Make copies the "slow" way? */ + float g; /* Gamma correction value */ + float b; /* Brightness factor */ + float zoom; /* Zoom facter */ + int xppi, yppi; /* Pixels-per-inch */ + int hue, sat; /* Hue and saturation adjustment */ + izoom_t *z; /* ImageZoom buffer */ + int primary, /* Primary image colorspace */ + secondary; /* Secondary image colorspace */ + ib_t *row, /* Current row */ + *r0, /* Top row */ + *r1; /* Bottom row */ + int y, /* Current Y coordinate on page */ + iy, /* Current Y coordinate in image */ + last_iy, /* Previous Y coordinate in image */ + yerr0, /* Top Y error value */ + yerr1, /* Bottom Y error value */ + blank; /* Blank value */ + ib_t lut[256]; /* Gamma/brightness LUT */ + int plane, /* Current color plane */ + num_planes; /* Number of color planes */ + + + if (argc != 7) + { + fputs("ERROR: imagetoraster job-id user title copies options file\n", stderr); + return (1); + } + + fprintf(stderr, "INFO: %s %s %s %s %s %s %s\n", argv[0], argv[1], argv[2], + argv[3], argv[4], argv[5], argv[6]); + + /* + * Process command-line options and write the prolog... + */ + + zoom = 0.0; + xppi = 0; + yppi = 0; + hue = 0; + sat = 100; + g = 1.0; + b = 1.0; + + Copies = atoi(argv[4]); + + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + + ppd = SetCommonOptions(num_options, options, 0); + + if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL) + { + /* + * This IPP attribute is unnecessarily complicated... + * + * single-document, separate-documents-collated-copies, and + * single-document-new-sheet all require collated copies. + * + * separate-documents-collated-copies allows for uncollated copies. + */ + + Collate = strcasecmp(val, "separate-documents-collated-copies") != 0; + } + + if ((val = cupsGetOption("Collate", num_options, options)) != NULL && + strcasecmp(val, "True") == 0) + Collate = 1; + + if ((val = cupsGetOption("gamma", num_options, options)) != NULL) + g = atoi(val) * 0.001f; + + if ((val = cupsGetOption("brightness", num_options, options)) != NULL) + b = atoi(val) * 0.01f; + + if ((val = cupsGetOption("scaling", num_options, options)) != NULL) + zoom = atoi(val) * 0.01; + + if ((val = cupsGetOption("ppi", num_options, options)) != NULL) + if (sscanf(val, "%dx%d", &xppi, &yppi) < 2) + yppi = xppi; + + if ((val = cupsGetOption("position", num_options, options)) != NULL) + { + if (strcasecmp(val, "center") == 0) + { + XPosition = 0; + YPosition = 0; + } + else if (strcasecmp(val, "top") == 0) + { + XPosition = 0; + YPosition = 1; + } + else if (strcasecmp(val, "left") == 0) + { + XPosition = -1; + YPosition = 0; + } + else if (strcasecmp(val, "right") == 0) + { + XPosition = 1; + YPosition = 0; + } + else if (strcasecmp(val, "top-left") == 0) + { + XPosition = -1; + YPosition = 1; + } + else if (strcasecmp(val, "top-right") == 0) + { + XPosition = 1; + YPosition = 1; + } + else if (strcasecmp(val, "bottom") == 0) + { + XPosition = 0; + YPosition = -1; + } + else if (strcasecmp(val, "bottom-left") == 0) + { + XPosition = -1; + YPosition = -1; + } + else if (strcasecmp(val, "bottom-right") == 0) + { + XPosition = 1; + YPosition = -1; + } + } + + if ((val = cupsGetOption("saturation", num_options, options)) != NULL) + sat = atoi(val); + + if ((val = cupsGetOption("hue", num_options, options)) != NULL) + hue = atoi(val); + + /* + * Set the needed options in the page header... + */ + + memset(&header, 0, sizeof(header)); + header.HWResolution[0] = 100; + header.HWResolution[1] = 100; + header.cupsBitsPerColor = 1; + header.cupsColorOrder = CUPS_ORDER_CHUNKED; + header.cupsColorSpace = CUPS_CSPACE_K; + + if ((choice = ppdFindMarkedChoice(ppd, "ColorModel")) != NULL) + exec_choice(&header, choice); + + if ((choice = ppdFindMarkedChoice(ppd, "CutMedia")) != NULL) + exec_choice(&header, choice); + + if ((choice = ppdFindMarkedChoice(ppd, "ESPFinishing")) != NULL) + exec_choice(&header, choice); + + if ((choice = ppdFindMarkedChoice(ppd, "InputSlot")) != NULL) + exec_choice(&header, choice); + + if ((choice = ppdFindMarkedChoice(ppd, "MediaType")) != NULL) + { + exec_choice(&header, choice); + + media_type = choice->choice; + } + else + media_type = ""; + + if ((choice = ppdFindMarkedChoice(ppd, "Resolution")) != NULL) + { + exec_choice(&header, choice); + + resolution = choice->choice; + } + else + resolution = ""; + + /* + * Choose the appropriate colorspace... + */ + + switch (header.cupsColorSpace) + { + case CUPS_CSPACE_W : + primary = IMAGE_WHITE; + secondary = IMAGE_WHITE; + header.cupsBitsPerPixel = header.cupsBitsPerColor; + break; + + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_RGBA : + primary = IMAGE_RGB; + secondary = IMAGE_RGB; + + if (header.cupsColorOrder == CUPS_ORDER_CHUNKED) + { + if (header.cupsBitsPerColor >= 8) + header.cupsBitsPerPixel = header.cupsBitsPerColor * 3; + else + header.cupsBitsPerPixel = header.cupsBitsPerColor * 4; + } + else + header.cupsBitsPerPixel = header.cupsBitsPerColor; + break; + + case CUPS_CSPACE_K : + case CUPS_CSPACE_WHITE : + case CUPS_CSPACE_GOLD : + case CUPS_CSPACE_SILVER : + primary = IMAGE_BLACK; + secondary = IMAGE_BLACK; + header.cupsBitsPerPixel = header.cupsBitsPerColor; + break; + + default : + primary = IMAGE_CMYK; + secondary = IMAGE_CMYK; + + if (header.cupsColorOrder == CUPS_ORDER_CHUNKED) + header.cupsBitsPerPixel = header.cupsBitsPerColor * 4; + else + header.cupsBitsPerPixel = header.cupsBitsPerColor; + break; + + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + primary = IMAGE_CMY; + secondary = IMAGE_CMY; + + if (header.cupsColorOrder == CUPS_ORDER_CHUNKED) + { + if (header.cupsBitsPerColor >= 8) + header.cupsBitsPerPixel = 24; + else + header.cupsBitsPerPixel = header.cupsBitsPerColor * 4; + } + else + header.cupsBitsPerPixel = header.cupsBitsPerColor; + break; + + case CUPS_CSPACE_KCMYcm : + if (header.cupsBitsPerPixel == 1) + { + primary = IMAGE_CMY; + secondary = IMAGE_CMY; + + if (header.cupsColorOrder == CUPS_ORDER_CHUNKED) + header.cupsBitsPerPixel = 8; + else + header.cupsBitsPerPixel = 1; + } + else + { + primary = IMAGE_CMYK; + secondary = IMAGE_CMYK; + + if (header.cupsColorOrder == CUPS_ORDER_CHUNKED) + header.cupsBitsPerPixel = header.cupsBitsPerColor * 4; + else + header.cupsBitsPerPixel = header.cupsBitsPerColor; + } + break; + } + + /* + * Find a color profile matching the current options... + */ + + if ((val = cupsGetOption("profile", num_options, options)) != NULL) + { + profile = &userprofile; + sscanf(val, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", + &(userprofile.density), &(userprofile.gamma), + userprofile.matrix[0] + 0, userprofile.matrix[0] + 1, + userprofile.matrix[0] + 2, + userprofile.matrix[1] + 0, userprofile.matrix[1] + 1, + userprofile.matrix[1] + 2, + userprofile.matrix[2] + 0, userprofile.matrix[2] + 1, + userprofile.matrix[2] + 2); + + userprofile.density *= 0.001f; + userprofile.gamma *= 0.001f; + userprofile.matrix[0][0] *= 0.001f; + userprofile.matrix[0][1] *= 0.001f; + userprofile.matrix[0][2] *= 0.001f; + userprofile.matrix[1][0] *= 0.001f; + userprofile.matrix[1][1] *= 0.001f; + userprofile.matrix[1][2] *= 0.001f; + userprofile.matrix[2][0] *= 0.001f; + userprofile.matrix[2][1] *= 0.001f; + userprofile.matrix[2][2] *= 0.001f; + } + else if (ppd != NULL) + { + fprintf(stderr, "DEBUG: Searching for profile \"%s/%s\"...\n", + resolution, media_type); + + for (i = 0, profile = ppd->profiles; i < ppd->num_profiles; i ++, profile ++) + { + fprintf(stderr, "DEBUG: \"%s/%s\" = ", profile->resolution, + profile->media_type); + + if ((strcmp(profile->resolution, resolution) == 0 || + profile->resolution[0] == '-') && + (strcmp(profile->media_type, media_type) == 0 || + profile->media_type[0] == '-')) + { + fputs("MATCH!\n", stderr); + break; + } + else + fputs("no.\n", stderr); + } + + /* + * If we found a color profile, use it! + */ + + if (i >= ppd->num_profiles) + profile = NULL; + } + else + profile = NULL; + + if (profile) + ImageSetProfile(profile->density, profile->gamma, profile->matrix); + + /* + * Create a gamma/brightness LUT... + */ + + make_lut(lut, primary, g, b); + + /* + * Open the input image to print... + */ + + fputs("INFO: Loading image file...\n", stderr); + + if ((img = ImageOpen(argv[6], primary, secondary, sat, hue, lut)) == NULL) + { + fputs("ERROR: Unable to open image file for printing!\n", stderr); + ppdClose(ppd); + return (1); + } + + /* + * Scale as necessary... + */ + + if (zoom == 0.0 && xppi == 0) + { + xppi = img->xppi; + yppi = img->yppi; + } + + if (yppi == 0) + yppi = xppi; + + if (xppi > 0) + { + /* + * Scale the image as neccesary to match the desired pixels-per-inch. + */ + + if (Orientation & 1) + { + xprint = (PageTop - PageBottom) / 72.0; + yprint = (PageRight - PageLeft) / 72.0; + } + else + { + xprint = (PageRight - PageLeft) / 72.0; + yprint = (PageTop - PageBottom) / 72.0; + } + + xinches = (float)img->xsize / (float)xppi; + yinches = (float)img->ysize / (float)yppi; + + if (cupsGetOption("orientation", num_options, options) == NULL && + cupsGetOption("landscape", num_options, options) == NULL) + { + /* + * Rotate the image if it will fit landscape but not portrait... + */ + + if ((xinches > xprint || yinches > yprint) && + xinches <= yprint && yinches <= xprint) + { + /* + * Rotate the image as needed... + */ + + Orientation = (Orientation + 1) & 3; + xsize = yprint; + yprint = xprint; + xprint = xsize; + } + } + } + else + { + /* + * Scale percentage of page size... + */ + + xprint = (PageRight - PageLeft) / 72.0; + yprint = (PageTop - PageBottom) / 72.0; + aspect = (float)img->yppi / (float)img->xppi; + + fprintf(stderr, "DEBUG: img->xppi = %d, img->yppi = %d, aspect = %f\n", + img->xppi, img->yppi, aspect); + + xsize = xprint * zoom; + ysize = xsize * img->ysize / img->xsize / aspect; + + if (ysize > (yprint * zoom)) + { + ysize = yprint * zoom; + xsize = ysize * img->xsize * aspect / img->ysize; + } + + xsize2 = yprint * zoom; + ysize2 = xsize2 * img->ysize / img->xsize / aspect; + + if (ysize2 > (xprint * zoom)) + { + ysize2 = xprint * zoom; + xsize2 = ysize2 * img->xsize * aspect / img->ysize; + } + + fprintf(stderr, "DEBUG: xsize = %.0f, ysize = %.0f\n", xsize, ysize); + fprintf(stderr, "DEBUG: xsize2 = %.0f, ysize2 = %.0f\n", xsize2, ysize2); + + if (cupsGetOption("orientation", num_options, options) == NULL && + cupsGetOption("landscape", num_options, options) == NULL) + { + /* + * Choose the rotation with the largest area, but prefer + * portrait if they are equal... + */ + + if ((xsize * ysize) < (xsize2 * xsize2)) + { + /* + * Do landscape orientation... + */ + + Orientation = 1; + xinches = xsize2; + yinches = ysize2; + xprint = (PageTop - PageBottom) / 72.0; + yprint = (PageRight - PageLeft) / 72.0; + } + else + { + /* + * Do portrait orientation... + */ + + Orientation = 0; + xinches = xsize; + yinches = ysize; + } + } + else if (Orientation & 1) + { + xinches = xsize2; + yinches = ysize2; + xprint = (PageTop - PageBottom) / 72.0; + yprint = (PageRight - PageLeft) / 72.0; + + xsize = PageLeft; + PageLeft = PageBottom; + PageBottom = PageWidth - PageRight; + PageRight = PageTop; + PageTop = PageLength - xsize; + + xsize = PageWidth; + PageWidth = PageLength; + PageLength = xsize; + } + } + + xpages = ceil(xinches / xprint); + ypages = ceil(yinches / yprint); + + fprintf(stderr, "DEBUG: xpages = %d, ypages = %d\n", xpages, ypages); + + /* + * Compute the bitmap size... + */ + + xprint = xinches / xpages; + yprint = yinches / ypages; + + if ((choice = ppdFindMarkedChoice(ppd, "PageSize")) != NULL && + strcasecmp(choice->choice, "Custom") == 0) + { + if (Orientation & 1) + { + header.cupsWidth = yprint * header.HWResolution[0]; + header.cupsHeight = xprint * header.HWResolution[1]; + header.PageSize[0] = yprint * 72.0; + header.PageSize[1] = xprint * 72.0; + } + else + { + header.cupsWidth = xprint * header.HWResolution[0]; + header.cupsHeight = yprint * header.HWResolution[1]; + header.PageSize[0] = xprint * 72.0; + header.PageSize[1] = yprint * 72.0; + } + } + else + { + header.cupsWidth = (PageRight - PageLeft) * header.HWResolution[0] / 72.0; + header.cupsHeight = (PageTop - PageBottom) * header.HWResolution[1] / 72.0; + header.PageSize[0] = PageWidth; + header.PageSize[1] = PageLength; + } + + header.Margins[0] = PageLeft; + header.Margins[1] = PageBottom; + + switch (Orientation) + { + case 0 : + switch (XPosition) + { + case -1 : + header.ImagingBoundingBox[0] = PageLeft; + header.ImagingBoundingBox[2] = PageLeft + xprint * 72; + break; + case 0 : + header.ImagingBoundingBox[0] = (PageRight + PageLeft - xprint * 72) / 2; + header.ImagingBoundingBox[2] = (PageRight + PageLeft + xprint * 72) / 2; + break; + case 1 : + header.ImagingBoundingBox[0] = PageRight - xprint * 72; + header.ImagingBoundingBox[2] = PageRight; + break; + } + + switch (YPosition) + { + case -1 : + header.ImagingBoundingBox[1] = PageBottom; + header.ImagingBoundingBox[3] = PageBottom + yprint * 72; + break; + case 0 : + header.ImagingBoundingBox[1] = (PageTop + PageBottom - yprint * 72) / 2; + header.ImagingBoundingBox[3] = (PageTop + PageBottom + yprint * 72) / 2; + break; + case 1 : + header.ImagingBoundingBox[1] = PageTop - yprint * 72; + header.ImagingBoundingBox[3] = PageTop; + break; + } + break; + + case 1 : + switch (XPosition) + { + case -1 : + header.ImagingBoundingBox[0] = PageBottom; + header.ImagingBoundingBox[2] = PageBottom + yprint * 72; + break; + case 0 : + header.ImagingBoundingBox[0] = (PageTop + PageBottom - yprint * 72) / 2; + header.ImagingBoundingBox[2] = (PageTop + PageBottom + yprint * 72) / 2; + break; + case 1 : + header.ImagingBoundingBox[0] = PageTop - yprint * 72; + header.ImagingBoundingBox[2] = PageTop; + break; + } + + switch (YPosition) + { + case -1 : + header.ImagingBoundingBox[1] = PageLeft; + header.ImagingBoundingBox[3] = PageLeft + xprint * 72; + break; + case 0 : + header.ImagingBoundingBox[1] = (PageRight + PageLeft - xprint * 72) / 2; + header.ImagingBoundingBox[3] = (PageRight + PageLeft + xprint * 72) / 2; + break; + case 1 : + header.ImagingBoundingBox[1] = PageRight - xprint * 72; + header.ImagingBoundingBox[3] = PageRight; + break; + } + break; + + case 2 : + switch (XPosition) + { + case 1 : + header.ImagingBoundingBox[0] = PageLeft; + header.ImagingBoundingBox[2] = PageLeft + xprint * 72; + break; + case 0 : + header.ImagingBoundingBox[0] = (PageRight + PageLeft - xprint * 72) / 2; + header.ImagingBoundingBox[2] = (PageRight + PageLeft + xprint * 72) / 2; + break; + case -1 : + header.ImagingBoundingBox[0] = PageRight - xprint * 72; + header.ImagingBoundingBox[2] = PageRight; + break; + } + + switch (YPosition) + { + case 1 : + header.ImagingBoundingBox[1] = PageBottom; + header.ImagingBoundingBox[3] = PageBottom + yprint * 72; + break; + case 0 : + header.ImagingBoundingBox[1] = (PageTop + PageBottom - yprint * 72) / 2; + header.ImagingBoundingBox[3] = (PageTop + PageBottom + yprint * 72) / 2; + break; + case -1 : + header.ImagingBoundingBox[1] = PageTop - yprint * 72; + header.ImagingBoundingBox[3] = PageTop; + break; + } + break; + + case 3 : + switch (XPosition) + { + case 1 : + header.ImagingBoundingBox[0] = PageBottom; + header.ImagingBoundingBox[2] = PageBottom + yprint * 72; + break; + case 0 : + header.ImagingBoundingBox[0] = (PageTop + PageBottom - yprint * 72) / 2; + header.ImagingBoundingBox[2] = (PageTop + PageBottom + yprint * 72) / 2; + break; + case -1 : + header.ImagingBoundingBox[0] = PageTop - yprint * 72; + header.ImagingBoundingBox[2] = PageTop; + break; + } + + switch (YPosition) + { + case 1 : + header.ImagingBoundingBox[1] = PageLeft; + header.ImagingBoundingBox[3] = PageLeft + xprint * 72; + break; + case 0 : + header.ImagingBoundingBox[1] = (PageRight + PageLeft - xprint * 72) / 2; + header.ImagingBoundingBox[3] = (PageRight + PageLeft + xprint * 72) / 2; + break; + case -1 : + header.ImagingBoundingBox[1] = PageRight - xprint * 72; + header.ImagingBoundingBox[3] = PageRight; + break; + } + break; + } + + switch (header.cupsColorOrder) + { + default : + header.cupsBytesPerLine = (header.cupsBitsPerPixel * + header.cupsWidth + 7) / 8; + num_planes = 1; + break; + + case CUPS_ORDER_BANDED : + if (header.cupsColorSpace == CUPS_CSPACE_KCMYcm && + header.cupsBitsPerColor > 1) + header.cupsBytesPerLine = (header.cupsBitsPerPixel * + header.cupsWidth + 7) / 8 * 4; + else + header.cupsBytesPerLine = (header.cupsBitsPerPixel * + header.cupsWidth + 7) / 8 * + Planes[header.cupsColorSpace]; + num_planes = 1; + break; + + case CUPS_ORDER_PLANAR : + header.cupsBytesPerLine = (header.cupsBitsPerPixel * + header.cupsWidth + 7) / 8; + num_planes = Planes[header.cupsColorSpace]; + break; + } + + /* + * See if we need to collate, and if so how we need to do it... + */ + + if (xpages == 1 && ypages == 1) + Collate = 0; + + slowcollate = Collate && ppdFindOption(ppd, "Collate") == NULL; + if (ppd != NULL) + slowcopies = ppd->manual_copies; + else + slowcopies = 1; + + if (Copies > 1 && !slowcollate && !slowcopies) + { + header.Collate = (cups_bool_t)Collate; + header.NumCopies = Copies; + + Copies = 1; + } + else + header.NumCopies = 1; + + /* + * Create the dithering lookup tables... + */ + + OnPixels[0] = 0x00; + OnPixels[255] = 0xff; + OffPixels[0] = 0x00; + OffPixels[255] = 0xff; + + switch (header.cupsBitsPerColor) + { + case 2 : + for (i = 1; i < 255; i ++) + { + OnPixels[i] = 0x55 * (i / 85 + 1); + OffPixels[i] = 0x55 * (i / 64); + } + break; + case 4 : + for (i = 1; i < 255; i ++) + { + OnPixels[i] = 17 * (i / 17 + 1); + OffPixels[i] = 17 * (i / 16); + } + + OnPixels[255] = OffPixels[255] = 0xff; + break; + } + + /* + * Output the pages... + */ + + fprintf(stderr, "DEBUG: cupsWidth = %d\n", header.cupsWidth); + fprintf(stderr, "DEBUG: cupsHeight = %d\n", header.cupsHeight); + fprintf(stderr, "DEBUG: cupsBitsPerColor = %d\n", header.cupsBitsPerColor); + fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d\n", header.cupsBitsPerPixel); + fprintf(stderr, "DEBUG: cupsBytesPerLine = %d\n", header.cupsBytesPerLine); + fprintf(stderr, "DEBUG: cupsColorOrder = %d\n", header.cupsColorOrder); + fprintf(stderr, "DEBUG: cupsColorSpace = %d\n", header.cupsColorSpace); + fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace); + + row = malloc(2 * header.cupsBytesPerLine); + ras = cupsRasterOpen(1, CUPS_RASTER_WRITE); + blank = img->colorspace < 0 ? 0 : ~0; + + for (i = 0, page = 1; i < Copies; i ++) + for (xpage = 0; xpage < xpages; xpage ++) + for (ypage = 0; ypage < ypages; ypage ++, page ++) + { + fprintf(stderr, "INFO: Formatting page %d...\n", page); + + if (Orientation & 1) + { + x0 = img->xsize * ypage / ypages; + x1 = img->xsize * (ypage + 1) / ypages - 1; + y0 = img->ysize * xpage / xpages; + y1 = img->ysize * (xpage + 1) / xpages - 1; + + xtemp = header.HWResolution[0] * yprint; + ytemp = header.HWResolution[1] * xprint; + } + else + { + x0 = img->xsize * xpage / xpages; + x1 = img->xsize * (xpage + 1) / xpages - 1; + y0 = img->ysize * ypage / ypages; + y1 = img->ysize * (ypage + 1) / ypages - 1; + + xtemp = header.HWResolution[0] * xprint; + ytemp = header.HWResolution[1] * yprint; + } + + cupsRasterWriteHeader(ras, &header); + + for (plane = 0; plane < num_planes; plane ++) + { + /* + * Initialize the image "zoom" engine... + */ + + z = ImageZoomAlloc(img, x0, y0, x1, y1, xtemp, ytemp, Orientation & 1); + + /* + * Write leading blank space as needed... + */ + + if (header.cupsHeight > z->ysize && YPosition <= 0) + { + memset(row, blank, header.cupsBytesPerLine); + + y = header.cupsHeight - z->ysize; + if (YPosition == 0) + y /= 2; + + for (; y > 0; y --) + { + if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) < + header.cupsBytesPerLine) + { + fputs("ERROR: Unable to write raster data to driver!\n", stderr); + ImageClose(img); + exit(1); + } + } + } + + /* + * Then write image data... + */ + + for (y = z->ysize, yerr0 = 0, yerr1 = z->ysize, iy = 0, last_iy = -2; + y > 0; + y --) + { + if (iy != last_iy) + { + if (header.cupsBitsPerColor >= 8) + { + /* + * Do bilinear interpolation for 8+ bpp images... + */ + + if ((iy - last_iy) > 1) + ImageZoomFill(z, iy); + + ImageZoomFill(z, iy + z->yincr); + } + else + { + /* + * Just do nearest-neighbor sampling for < 8 bpp images... + */ + + ImageZoomQFill(z, iy); + } + + last_iy = iy; + } + + /* + * Format this line of raster data for the printer... + */ + + memset(row, blank, header.cupsBytesPerLine); + + r0 = z->rows[z->row]; + r1 = z->rows[1 - z->row]; + + switch (header.cupsColorSpace) + { + case CUPS_CSPACE_W : + format_W(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + case CUPS_CSPACE_RGB : + format_RGB(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + case CUPS_CSPACE_RGBA : + format_RGBA(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + case CUPS_CSPACE_K : + case CUPS_CSPACE_WHITE : + case CUPS_CSPACE_GOLD : + case CUPS_CSPACE_SILVER : + format_K(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + case CUPS_CSPACE_CMY : + format_CMY(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + case CUPS_CSPACE_YMC : + format_YMC(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + case CUPS_CSPACE_CMYK : + format_CMYK(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_GMCK : + case CUPS_CSPACE_GMCS : + format_YMCK(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + case CUPS_CSPACE_KCMY : + format_KCMY(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + case CUPS_CSPACE_KCMYcm : + format_KCMYcm(&header, row, y, plane, z->xsize, z->ysize, + yerr0, yerr1, r0, r1); + break; + } + + /* + * Write the raster data to the driver... + */ + + if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) < + header.cupsBytesPerLine) + { + fputs("ERROR: Unable to write raster data to driver!\n", stderr); + ImageClose(img); + exit(1); + } + + /* + * Compute the next scanline in the image... + */ + + iy += z->ystep; + yerr0 += z->ymod; + yerr1 -= z->ymod; + if (yerr1 <= 0) + { + yerr0 -= z->ysize; + yerr1 += z->ysize; + iy += z->yincr; + } + } + + /* + * Write trailing blank space as needed... + */ + + if (header.cupsHeight > z->ysize && YPosition >= 0) + { + memset(row, blank, header.cupsBytesPerLine); + + y = header.cupsHeight - z->ysize; + if (YPosition == 0) + y = y - y / 2; + + for (; y > 0; y --) + { + if (cupsRasterWritePixels(ras, row, header.cupsBytesPerLine) < + header.cupsBytesPerLine) + { + fputs("ERROR: Unable to write raster data to driver!\n", stderr); + ImageClose(img); + exit(1); + } + } + } + + /* + * Free memory used for the "zoom" engine... + */ + + ImageZoomFree(z); + } + } + + /* + * Close files... + */ + + free(row); + cupsRasterClose(ras); + ImageClose(img); + ppdClose(ppd); + + return (0); +} + + +/* + * 'exec_choice()' - Execute PostScript setpagedevice commands as appropriate. + */ + +static void +exec_choice(cups_page_header_t *header, /* I - Page header */ + ppd_choice_t *choice) /* I - Option choice to execute */ +{ + char *code, /* Pointer into code string */ + *ptr, /* Pointer into name/value string */ + name[255], /* Name of pagedevice entry */ + value[1024]; /* Value of pagedevice entry */ + + + for (code = choice->code; *code != '\0';) + { + /* + * Search for the start of a dictionary name... + */ + + while (*code != '/' && *code != '\0') + code ++; + + if (*code == '\0') + break; + + /* + * Get the name... + */ + + code ++; + for (ptr = name; isalnum(*code) && (ptr - name) < (sizeof(name) - 1);) + *ptr++ = *code++; + *ptr = '\0'; + + /* + * The parse the value as needed... + */ + + while (isspace(*code)) + code ++; + + if (*code == '\0') + break; + + if (*code == '[') + { + /* + * Read array of values... + */ + + code ++; + for (ptr = value; + *code != ']' && *code != '\0' && + (ptr - value) < (sizeof(value) - 1);) + *ptr++ = *code++; + *ptr = '\0'; + } + else if (*code == '(') + { + /* + * Read string value... + */ + + code ++; + for (ptr = value; + *code != ')' && *code != '\0' && + (ptr - value) < (sizeof(value) - 1);) + if (*code == '\\') + { + code ++; + if (isdigit(*code)) + *ptr++ = (char)strtol(code, &code, 8); + else + *ptr++ = *code++; + } + else + *ptr++ = *code++; + + *ptr = '\0'; + } + else if (isdigit(*code) || *code == '-') + { + /* + * Read single number... + */ + + for (ptr = value; + (isdigit(*code) || *code == '-') && + (ptr - value) < (sizeof(value) - 1);) + *ptr++ = *code++; + *ptr = '\0'; + } + else + continue; + + /* + * Assign the value as needed... + */ + + if (strcmp(name, "cupsMediaType") == 0) + header->cupsMediaType = atoi(value); + else if (strcmp(name, "cupsBitsPerColor") == 0) + header->cupsBitsPerColor = atoi(value); + else if (strcmp(name, "cupsColorOrder") == 0) + header->cupsColorOrder = (cups_order_t)atoi(value); + else if (strcmp(name, "cupsColorSpace") == 0) + header->cupsColorSpace = (cups_cspace_t)atoi(value); + else if (strcmp(name, "cupsCompression") == 0) + header->cupsCompression = atoi(value); + else if (strcmp(name, "cupsRowCount") == 0) + header->cupsRowCount = atoi(value); + else if (strcmp(name, "cupsRowFeed") == 0) + header->cupsRowFeed = atoi(value); + else if (strcmp(name, "cupsRowStep") == 0) + header->cupsRowStep = atoi(value); + else if (strcmp(name, "CutMedia") == 0) + header->CutMedia = (cups_cut_t)atoi(value); + else if (strcmp(name, "HWResolution") == 0) + sscanf(value, "%d%d", header->HWResolution + 0, header->HWResolution + 1); + else if (strcmp(name, "cupsMediaPosition") == 0 || /* Compatibility */ + strcmp(name, "MediaPosition") == 0) + header->MediaPosition = atoi(value); + else if (strcmp(name, "MediaType") == 0) + strncpy(header->MediaType, value, sizeof(header->MediaType) - 1); + else if (strcmp(name, "OutputType") == 0) + strncpy(header->OutputType, value, sizeof(header->OutputType) - 1); + } +} + + +/* + * 'format_CMY()' - Convert image data to CMY. + */ + +static void +format_CMY(cups_page_header_t *header, /* I - Page header */ + unsigned char *row, /* IO - Bitmap data for device */ + int y, /* I - Current row */ + int z, /* I - Current plane */ + int xsize, /* I - Width of image data */ + int ysize, /* I - Height of image data */ + int yerr0, /* I - Top Y error */ + int yerr1, /* I - Bottom Y error */ + ib_t *r0, /* I - Primary image data */ + ib_t *r1) /* I - Image data for interpolation */ +{ + ib_t *ptr, /* Pointer into row */ + *cptr, /* Pointer into cyan */ + *mptr, /* Pointer into magenta */ + *yptr, /* Pointer into yellow */ + bitmask; /* Current mask for pixel */ + int bitoffset; /* Current offset in line */ + int bandwidth; /* Width of a color band */ + int x, /* Current X coordinate on page */ + *dither; /* Pointer into dither array */ + + + switch (XPosition) + { + case -1 : + bitoffset = 0; + break; + case 0 : + bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); + break; + case 1 : + bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); + break; + } + + ptr = row + bitoffset / 8; + bandwidth = header->cupsBytesPerLine / 3; + + switch (header->cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 64 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize ; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 2; + else + { + bitmask = 64; + ptr ++; + } + } + break; + + case 2 : + dither = Floyd8x8[y & 7]; + + for (x = xsize ; x > 0; x --, r0 += 3) + { + if ((r0[0] & 63) > dither[x & 7]) + *ptr ^= (0x30 & OnPixels[r0[0]]); + else + *ptr ^= (0x30 & OffPixels[r0[0]]); + + if ((r0[1] & 63) > dither[x & 7]) + *ptr ^= (0x0c & OnPixels[r0[1]]); + else + *ptr ^= (0x0c & OffPixels[r0[1]]); + + if ((r0[2] & 63) > dither[x & 7]) + *ptr++ ^= (0x03 & OnPixels[r0[2]]); + else + *ptr++ ^= (0x03 & OffPixels[r0[2]]); + } + break; + + case 4 : + dither = Floyd4x4[y & 3]; + + for (x = xsize ; x > 0; x --, r0 += 3) + { + if ((r0[0] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[0]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[0]]); + + if ((r0[1] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[1]]); + else + *ptr ^= (0xf0 & OffPixels[r0[1]]); + + if ((r0[2] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[2]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[2]]); + } + break; + + case 8 : + for (x = xsize * 3; x > 0; x --, r0 ++, r1 ++) + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + break; + } + break; + + case CUPS_ORDER_BANDED : + cptr = ptr; + mptr = ptr + bandwidth; + yptr = ptr + 2 * bandwidth; + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *cptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *mptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *yptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + cptr ++; + mptr ++; + yptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 63) > dither[x & 7]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + cptr ++; + mptr ++; + yptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 15) > dither[x & 3]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + cptr ++; + mptr ++; + yptr ++; + } + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) + { + if (r0[0] == r1[0]) + *cptr++ = r0[0]; + else + *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *mptr++ = r0[1]; + else + *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *yptr++ = r0[2]; + else + *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_PLANAR : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + switch (z) + { + case 0 : + for (x = xsize; x > 0; x --, r0 += 3) + { + if (r0[0] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 1 : + for (x = xsize; x > 0; x --, r0 += 3) + { + if (r0[1] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 2 : + for (x = xsize; x > 0; x --, r0 += 3) + { + if (r0[2] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 3) + { + if ((*r0 & 63) > dither[x & 7]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + ptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 3) + { + if ((*r0 & 15) > dither[x & 3]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + ptr ++; + } + } + break; + + case 8 : + r0 += z; + r1 += z; + + for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) + { + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + } + break; + } + break; + } +} + + +/* + * 'format_CMYK()' - Convert image data to CMYK. + */ + +static void +format_CMYK(cups_page_header_t *header, /* I - Page header */ + unsigned char *row, /* IO - Bitmap data for device */ + int y, /* I - Current row */ + int z, /* I - Current plane */ + int xsize, /* I - Width of image data */ + int ysize, /* I - Height of image data */ + int yerr0, /* I - Top Y error */ + int yerr1, /* I - Bottom Y error */ + ib_t *r0, /* I - Primary image data */ + ib_t *r1) /* I - Image data for interpolation */ +{ + ib_t *ptr, /* Pointer into row */ + *cptr, /* Pointer into cyan */ + *mptr, /* Pointer into magenta */ + *yptr, /* Pointer into yellow */ + *kptr, /* Pointer into black */ + bitmask; /* Current mask for pixel */ + int bitoffset; /* Current offset in line */ + int bandwidth; /* Width of a color band */ + int x, /* Current X coordinate on page */ + *dither; /* Pointer into dither array */ + + + switch (XPosition) + { + case -1 : + bitoffset = 0; + break; + case 0 : + bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); + break; + case 1 : + bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); + break; + } + + ptr = row + bitoffset / 8; + bandwidth = header->cupsBytesPerLine / 4; + + switch (header->cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 128 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize ; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 128; + ptr ++; + } + } + break; + + case 2 : + dither = Floyd8x8[y & 7]; + + for (x = xsize ; x > 0; x --, r0 += 4) + { + if ((r0[0] & 63) > dither[x & 7]) + *ptr ^= (0xc0 & OnPixels[r0[0]]); + else + *ptr ^= (0xc0 & OffPixels[r0[0]]); + + if ((r0[1] & 63) > dither[x & 7]) + *ptr ^= (0x30 & OnPixels[r0[1]]); + else + *ptr ^= (0x30 & OffPixels[r0[1]]); + + if ((r0[2] & 63) > dither[x & 7]) + *ptr ^= (0x0c & OnPixels[r0[2]]); + else + *ptr ^= (0x0c & OffPixels[r0[2]]); + + if ((r0[3] & 63) > dither[x & 7]) + *ptr++ ^= (0x03 & OnPixels[r0[3]]); + else + *ptr++ ^= (0x03 & OffPixels[r0[3]]); + } + break; + + case 4 : + dither = Floyd4x4[y & 3]; + + for (x = xsize ; x > 0; x --, r0 += 4) + { + if ((r0[0] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[0]]); + else + *ptr ^= (0xf0 & OffPixels[r0[0]]); + + if ((r0[1] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[1]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[1]]); + + if ((r0[2] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[2]]); + else + *ptr ^= (0xf0 & OffPixels[r0[2]]); + + if ((r0[3] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[3]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[3]]); + } + break; + + case 8 : + for (x = xsize * 4; x > 0; x --, r0 ++, r1 ++) + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + break; + } + break; + + case CUPS_ORDER_BANDED : + cptr = ptr; + mptr = ptr + bandwidth; + yptr = ptr + 2 * bandwidth; + kptr = ptr + 3 * bandwidth; + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *cptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *mptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *yptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *kptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + cptr ++; + mptr ++; + yptr ++; + kptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 63) > dither[x & 7]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *kptr ^= (bitmask & OnPixels[*r0++]); + else + *kptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + cptr ++; + mptr ++; + yptr ++; + kptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 15) > dither[x & 3]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *kptr ^= (bitmask & OnPixels[*r0++]); + else + *kptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + cptr ++; + mptr ++; + yptr ++; + kptr ++; + } + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (r0[0] == r1[0]) + *cptr++ = r0[0]; + else + *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *mptr++ = r0[1]; + else + *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *yptr++ = r0[2]; + else + *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + + if (r0[3] == r1[3]) + *kptr++ = r0[3]; + else + *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_PLANAR : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 4) + { + if (*r0 > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 4) + { + if ((*r0 & 63) > dither[x & 7]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + ptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 4) + { + if ((*r0 & 15) > dither[x & 3]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + ptr ++; + } + } + break; + + case 8 : + r0 += z; + r1 += z; + + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + } + break; + } + break; + } +} + + +/* + * 'format_K()' - Convert image data to black. + */ + +static void +format_K(cups_page_header_t *header, /* I - Page header */ + unsigned char *row, /* IO - Bitmap data for device */ + int y, /* I - Current row */ + int z, /* I - Current plane */ + int xsize, /* I - Width of image data */ + int ysize, /* I - Height of image data */ + int yerr0, /* I - Top Y error */ + int yerr1, /* I - Bottom Y error */ + ib_t *r0, /* I - Primary image data */ + ib_t *r1) /* I - Image data for interpolation */ +{ + ib_t *ptr, /* Pointer into row */ + bitmask; /* Current mask for pixel */ + int bitoffset; /* Current offset in line */ + int x, /* Current X coordinate on page */ + *dither; /* Pointer into dither array */ + + + switch (XPosition) + { + case -1 : + bitoffset = 0; + break; + case 0 : + bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); + break; + case 1 : + bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); + break; + } + + ptr = row + bitoffset / 8; + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 63) > dither[x & 7]) + *ptr ^= (bitmask & OnPixels[*r0++]); + else + *ptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + ptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 15) > dither[x & 3]) + *ptr ^= (bitmask & OnPixels[*r0++]); + else + *ptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + ptr ++; + } + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 ++, r1 ++) + { + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + } + break; + } +} + + +/* + * 'format_KCMY()' - Convert image data to KCMY. + */ + +static void +format_KCMY(cups_page_header_t *header, /* I - Page header */ + unsigned char *row, /* IO - Bitmap data for device */ + int y, /* I - Current row */ + int z, /* I - Current plane */ + int xsize, /* I - Width of image data */ + int ysize, /* I - Height of image data */ + int yerr0, /* I - Top Y error */ + int yerr1, /* I - Bottom Y error */ + ib_t *r0, /* I - Primary image data */ + ib_t *r1) /* I - Image data for interpolation */ +{ + ib_t *ptr, /* Pointer into row */ + *cptr, /* Pointer into cyan */ + *mptr, /* Pointer into magenta */ + *yptr, /* Pointer into yellow */ + *kptr, /* Pointer into black */ + bitmask; /* Current mask for pixel */ + int bitoffset; /* Current offset in line */ + int bandwidth; /* Width of a color band */ + int x, /* Current X coordinate on page */ + *dither; /* Pointer into dither array */ + + + switch (XPosition) + { + case -1 : + bitoffset = 0; + break; + case 0 : + bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); + break; + case 1 : + bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); + break; + } + + ptr = row + bitoffset / 8; + bandwidth = header->cupsBytesPerLine / 4; + + switch (header->cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 128 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize ; x > 0; x --, r0 += 4) + { + if (r0[3] > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (r0[0] > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (r0[1] > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (r0[2] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 128; + ptr ++; + } + } + break; + + case 2 : + dither = Floyd8x8[y & 7]; + + for (x = xsize ; x > 0; x --, r0 += 4) + { + if ((r0[3] & 63) > dither[x & 7]) + *ptr ^= (0xc0 & OnPixels[r0[3]]); + else + *ptr ^= (0xc0 & OffPixels[r0[3]]); + + if ((r0[0] & 63) > dither[x & 7]) + *ptr ^= (0x30 & OnPixels[r0[0]]); + else + *ptr ^= (0x30 & OffPixels[r0[0]]); + + if ((r0[1] & 63) > dither[x & 7]) + *ptr ^= (0x0c & OnPixels[r0[1]]); + else + *ptr ^= (0x0c & OffPixels[r0[1]]); + + if ((r0[2] & 63) > dither[x & 7]) + *ptr++ ^= (0x03 & OnPixels[r0[2]]); + else + *ptr++ ^= (0x03 & OffPixels[r0[2]]); + } + break; + + case 4 : + dither = Floyd4x4[y & 3]; + + for (x = xsize ; x > 0; x --, r0 += 4) + { + if ((r0[3] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[3]]); + else + *ptr ^= (0xf0 & OffPixels[r0[3]]); + + if ((r0[0] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[0]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[0]]); + + if ((r0[1] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[1]]); + else + *ptr ^= (0xf0 & OffPixels[r0[1]]); + + if ((r0[2] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[2]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[2]]); + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (r0[3] == r1[3]) + *ptr++ = r0[3]; + else + *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; + + if (r0[0] == r1[0]) + *ptr++ = r0[0]; + else + *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *ptr++ = r0[1]; + else + *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *ptr++ = r0[2]; + else + *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_BANDED : + kptr = ptr; + cptr = ptr + bandwidth; + mptr = ptr + 2 * bandwidth; + yptr = ptr + 3 * bandwidth; + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *cptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *mptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *yptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *kptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + cptr ++; + mptr ++; + yptr ++; + kptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 63) > dither[x & 7]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *kptr ^= (bitmask & OnPixels[*r0++]); + else + *kptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + cptr ++; + mptr ++; + yptr ++; + kptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 15) > dither[x & 3]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *kptr ^= (bitmask & OnPixels[*r0++]); + else + *kptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + cptr ++; + mptr ++; + yptr ++; + kptr ++; + } + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (r0[0] == r1[0]) + *cptr++ = r0[0]; + else + *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *mptr++ = r0[1]; + else + *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *yptr++ = r0[2]; + else + *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + + if (r0[3] == r1[3]) + *kptr++ = r0[3]; + else + *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_PLANAR : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + if (z == 0) + r0 += 3; + else + r0 += z - 1; + + for (x = xsize; x > 0; x --, r0 += 4) + { + if (*r0 > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + if (z == 0) + r0 += 3; + else + r0 += z - 1; + + for (x = xsize; x > 0; x --, r0 += 4) + { + if ((*r0 & 63) > dither[x & 7]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + ptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + if (z == 0) + r0 += 3; + else + r0 += z - 1; + + for (x = xsize; x > 0; x --, r0 += 4) + { + if ((*r0 & 15) > dither[x & 3]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + ptr ++; + } + } + break; + + case 8 : + if (z == 0) + { + r0 += 3; + r1 += 3; + } + else + { + r0 += z - 1; + r1 += z - 1; + } + + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + } + break; + } + break; + } +} + + +/* + * 'format_KCMYcm()' - Convert image data to KCMYcm. + */ + +static void +format_KCMYcm(cups_page_header_t *header,/* I - Page header */ + unsigned char *row, /* IO - Bitmap data for device */ + int y, /* I - Current row */ + int z, /* I - Current plane */ + int xsize, /* I - Width of image data */ + int ysize, /* I - Height of image data */ + int yerr0, /* I - Top Y error */ + int yerr1, /* I - Bottom Y error */ + ib_t *r0, /* I - Primary image data */ + ib_t *r1) /* I - Image data for interpolation */ +{ + int pc, pm, py, pk; /* Cyan, magenta, yellow, and black values */ + ib_t *ptr, /* Pointer into row */ + *cptr, /* Pointer into cyan */ + *mptr, /* Pointer into magenta */ + *yptr, /* Pointer into yellow */ + *kptr, /* Pointer into black */ + *lcptr, /* Pointer into light cyan */ + *lmptr, /* Pointer into light magenta */ + bitmask; /* Current mask for pixel */ + int bitoffset; /* Current offset in line */ + int bandwidth; /* Width of a color band */ + int x, /* Current X coordinate on page */ + *dither; /* Pointer into dither array */ + + + switch (XPosition) + { + case -1 : + bitoffset = 0; + break; + case 0 : + bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); + break; + case 1 : + bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); + break; + } + + ptr = row + bitoffset / 8; + if (header->cupsBitsPerColor == 1) + bandwidth = header->cupsBytesPerLine / 6; + else + bandwidth = header->cupsBytesPerLine / 4; + + switch (header->cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + switch (header->cupsBitsPerColor) + { + case 1 : + dither = Floyd16x16[y & 15]; + + for (x = xsize ; x > 0; x --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + pk = *r0++ > dither[x & 15]; + + if (pk) + *ptr++ ^= 32; /* Black */ + else if (pc && pm) + *ptr++ ^= 17; /* Blue (cyan + light magenta) */ + else if (pc && py) + *ptr++ ^= 6; /* Green (light cyan + yellow) */ + else if (pm && py) + *ptr++ ^= 12; /* Red (magenta + yellow) */ + else if (pc) + *ptr++ ^= 16; + else if (pm) + *ptr++ ^= 8; + else if (py) + *ptr++ ^= 4; + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (r0[3] == r1[3]) + *ptr++ = r0[3]; + else + *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; + + if (r0[0] == r1[0]) + *ptr++ = r0[0]; + else + *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *ptr++ = r0[1]; + else + *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *ptr++ = r0[2]; + else + *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_BANDED : + kptr = ptr; + cptr = ptr + bandwidth; + mptr = ptr + 2 * bandwidth; + yptr = ptr + 3 * bandwidth; + lcptr = ptr + 4 * bandwidth; + lmptr = ptr + 5 * bandwidth; + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize; x > 0; x --) + { + pc = *r0++ > dither[x & 15]; + pm = *r0++ > dither[x & 15]; + py = *r0++ > dither[x & 15]; + pk = *r0++ > dither[x & 15]; + + if (pk) + *kptr ^= bitmask; /* Black */ + else if (pc && pm) + { + *cptr ^= bitmask; /* Blue (cyan + light magenta) */ + *lmptr ^= bitmask; + } + else if (pc && py) + { + *lcptr ^= bitmask; /* Green (light cyan + yellow) */ + *yptr ^= bitmask; + } + else if (pm && py) + { + *mptr ^= bitmask; /* Red (magenta + yellow) */ + *yptr ^= bitmask; + } + else if (pc) + *cptr ^= bitmask; + else if (pm) + *mptr ^= bitmask; + else if (py) + *yptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + cptr ++; + mptr ++; + yptr ++; + kptr ++; + lcptr ++; + lmptr ++; + } + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (r0[0] == r1[0]) + *cptr++ = r0[0]; + else + *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *mptr++ = r0[1]; + else + *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *yptr++ = r0[2]; + else + *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + + if (r0[3] == r1[3]) + *kptr++ = r0[3]; + else + *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_PLANAR : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + switch (z) + { + case 0 : + for (x = xsize; x > 0; x --, r0 += 4) + { + if (r0[3] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 1 : + for (x = xsize; x > 0; x --, r0 += 4) + { + if (r0[0] > dither[x & 15] && + r0[2] < dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 2 : + for (x = xsize; x > 0; x --, r0 += 4) + { + if (r0[1] > dither[x & 15] && + (r0[0] < dither[x & 15] || + r0[2] > dither[x & 15])) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 3 : + for (x = xsize; x > 0; x --, r0 += 4) + { + if (r0[2] > dither[x & 15] && + (r0[0] < dither[x & 15] || + r0[1] < dither[x & 15])) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 4 : + for (x = xsize; x > 0; x --, r0 += 4) + { + if (r0[0] > dither[x & 15] && + r0[2] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 5 : + for (x = xsize; x > 0; x --, r0 += 4) + { + if (r0[0] > dither[x & 15] && + r0[1] > dither[x & 15] && + r0[2] < dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + } + break; + + case 8 : + if (z == 0) + { + r0 += 3; + r1 += 3; + } + else + { + r0 += z - 1; + r1 += z - 1; + } + + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + } + break; + } + break; + } +} + + +/* + * 'format_RGBA()' - Convert image data to RGBA. + */ + +static void +format_RGBA(cups_page_header_t *header, /* I - Page header */ + unsigned char *row, /* IO - Bitmap data for device */ + int y, /* I - Current row */ + int z, /* I - Current plane */ + int xsize, /* I - Width of image data */ + int ysize, /* I - Height of image data */ + int yerr0, /* I - Top Y error */ + int yerr1, /* I - Bottom Y error */ + ib_t *r0, /* I - Primary image data */ + ib_t *r1) /* I - Image data for interpolation */ +{ + ib_t *ptr, /* Pointer into row */ + *cptr, /* Pointer into cyan */ + *mptr, /* Pointer into magenta */ + *yptr, /* Pointer into yellow */ + bitmask; /* Current mask for pixel */ + int bitoffset; /* Current offset in line */ + int bandwidth; /* Width of a color band */ + int x, /* Current X coordinate on page */ + *dither; /* Pointer into dither array */ + + + switch (XPosition) + { + case -1 : + bitoffset = 0; + break; + case 0 : + bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); + break; + case 1 : + bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); + break; + } + + ptr = row + bitoffset / 8; + bandwidth = header->cupsBytesPerLine / 4; + + switch (header->cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 128 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize ; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 2) + { + *ptr ^= 16; + bitmask >>= 2; + } + else + { + bitmask = 128; + *ptr++ ^= 1; + } + } + break; + + case 2 : + dither = Floyd8x8[y & 7]; + + for (x = xsize ; x > 0; x --, r0 += 3) + { + if ((r0[0] & 63) > dither[x & 7]) + *ptr ^= (0xc0 & OnPixels[r0[0]]); + else + *ptr ^= (0xc0 & OffPixels[r0[0]]); + + if ((r0[1] & 63) > dither[x & 7]) + *ptr ^= (0x30 & OnPixels[r0[1]]); + else + *ptr ^= (0x30 & OffPixels[r0[1]]); + + if ((r0[2] & 63) > dither[x & 7]) + *ptr ^= (0x0c & OnPixels[r0[2]]); + else + *ptr ^= (0x0c & OffPixels[r0[2]]); + + *ptr++ ^= 0x03; + } + break; + + case 4 : + dither = Floyd4x4[y & 3]; + + for (x = xsize ; x > 0; x --, r0 += 3) + { + if ((r0[0] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[0]]); + else + *ptr ^= (0xf0 & OffPixels[r0[0]]); + + if ((r0[1] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[1]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[1]]); + + if ((r0[2] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[2]]); + else + *ptr ^= (0xf0 & OffPixels[r0[2]]); + + *ptr++ ^= 0x0f; + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) + { + if (r0[0] == r1[0]) + *ptr++ = r0[0]; + else + *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *ptr++ = r0[1]; + else + *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *ptr++ = r0[2]; + else + *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + + *ptr++ = 255; + } + break; + } + break; + + case CUPS_ORDER_BANDED : + cptr = ptr; + mptr = ptr + bandwidth; + yptr = ptr + 2 * bandwidth; + + memset(ptr + 3 * bandwidth, 255, bandwidth); + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *cptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *mptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *yptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + cptr ++; + mptr ++; + yptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 63) > dither[x & 7]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + cptr ++; + mptr ++; + yptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 15) > dither[x & 3]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + cptr ++; + mptr ++; + yptr ++; + } + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) + { + if (r0[0] == r1[0]) + *cptr++ = r0[0]; + else + *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *mptr++ = r0[1]; + else + *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *yptr++ = r0[2]; + else + *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_PLANAR : + if (z == 3) + { + memset(row, 255, header->cupsBytesPerLine); + break; + } + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + switch (z) + { + case 0 : + for (x = xsize; x > 0; x --, r0 += 3) + { + if (r0[0] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 1 : + for (x = xsize; x > 0; x --, r0 += 3) + { + if (r0[1] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 2 : + for (x = xsize; x > 0; x --, r0 += 3) + { + if (r0[2] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 3) + { + if ((*r0 & 63) > dither[x & 7]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + ptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 3) + { + if ((*r0 & 15) > dither[x & 3]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + ptr ++; + } + } + break; + + case 8 : + r0 += z; + r1 += z; + + for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) + { + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + } + break; + } + break; + } +} + + +/* + * 'format_W()' - Convert image data to luminance. + */ + +static void +format_W(cups_page_header_t *header, /* I - Page header */ + unsigned char *row, /* IO - Bitmap data for device */ + int y, /* I - Current row */ + int z, /* I - Current plane */ + int xsize, /* I - Width of image data */ + int ysize, /* I - Height of image data */ + int yerr0, /* I - Top Y error */ + int yerr1, /* I - Bottom Y error */ + ib_t *r0, /* I - Primary image data */ + ib_t *r1) /* I - Image data for interpolation */ +{ + ib_t *ptr, /* Pointer into row */ + bitmask; /* Current mask for pixel */ + int bitoffset; /* Current offset in line */ + int x, /* Current X coordinate on page */ + *dither; /* Pointer into dither array */ + + + switch (XPosition) + { + case -1 : + bitoffset = 0; + break; + case 0 : + bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); + break; + case 1 : + bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); + break; + } + + ptr = row + bitoffset / 8; + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 63) > dither[x & 7]) + *ptr ^= (bitmask & OnPixels[*r0++]); + else + *ptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + ptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 15) > dither[x & 3]) + *ptr ^= (bitmask & OnPixels[*r0++]); + else + *ptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + ptr ++; + } + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 ++, r1 ++) + { + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + } + break; + } +} + + +/* + * 'format_YMC()' - Convert image data to YMC. + */ + +static void +format_YMC(cups_page_header_t *header, /* I - Page header */ + unsigned char *row, /* IO - Bitmap data for device */ + int y, /* I - Current row */ + int z, /* I - Current plane */ + int xsize, /* I - Width of image data */ + int ysize, /* I - Height of image data */ + int yerr0, /* I - Top Y error */ + int yerr1, /* I - Bottom Y error */ + ib_t *r0, /* I - Primary image data */ + ib_t *r1) /* I - Image data for interpolation */ +{ + ib_t *ptr, /* Pointer into row */ + *cptr, /* Pointer into cyan */ + *mptr, /* Pointer into magenta */ + *yptr, /* Pointer into yellow */ + bitmask; /* Current mask for pixel */ + int bitoffset; /* Current offset in line */ + int bandwidth; /* Width of a color band */ + int x, /* Current X coordinate on page */ + *dither; /* Pointer into dither array */ + + + switch (XPosition) + { + case -1 : + bitoffset = 0; + break; + case 0 : + bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); + break; + case 1 : + bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); + break; + } + + ptr = row + bitoffset / 8; + bandwidth = header->cupsBytesPerLine / 3; + + switch (header->cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 64 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize ; x > 0; x --, r0 += 3) + { + if (r0[2] > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (r0[1] > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (r0[0] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 2; + else + { + bitmask = 64; + ptr ++; + } + } + break; + + case 2 : + dither = Floyd8x8[y & 7]; + + for (x = xsize ; x > 0; x --, r0 += 3) + { + if ((r0[2] & 63) > dither[x & 7]) + *ptr ^= (0x30 & OnPixels[r0[2]]); + else + *ptr ^= (0x30 & OffPixels[r0[2]]); + + if ((r0[1] & 63) > dither[x & 7]) + *ptr ^= (0x0c & OnPixels[r0[1]]); + else + *ptr ^= (0x0c & OffPixels[r0[1]]); + + if ((r0[0] & 63) > dither[x & 7]) + *ptr++ ^= (0x03 & OnPixels[r0[0]]); + else + *ptr++ ^= (0x03 & OffPixels[r0[0]]); + } + break; + + case 4 : + dither = Floyd4x4[y & 3]; + + for (x = xsize ; x > 0; x --, r0 += 3) + { + if ((r0[2] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[2]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[2]]); + + if ((r0[1] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[1]]); + else + *ptr ^= (0xf0 & OffPixels[r0[1]]); + + if ((r0[0] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[0]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[0]]); + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) + { + if (r0[2] == r1[2]) + *ptr++ = r0[2]; + else + *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *ptr++ = r0[1]; + else + *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[0] == r1[0]) + *ptr++ = r0[0]; + else + *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_BANDED : + yptr = ptr; + mptr = ptr + bandwidth; + cptr = ptr + 2 * bandwidth; + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *cptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *mptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *yptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + cptr ++; + mptr ++; + yptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 63) > dither[x & 7]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + cptr ++; + mptr ++; + yptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 15) > dither[x & 3]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + cptr ++; + mptr ++; + yptr ++; + } + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) + { + if (r0[0] == r1[0]) + *cptr++ = r0[0]; + else + *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *mptr++ = r0[1]; + else + *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *yptr++ = r0[2]; + else + *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_PLANAR : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + switch (z) + { + case 2 : + for (x = xsize; x > 0; x --, r0 += 3) + { + if (r0[0] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 1 : + for (x = xsize; x > 0; x --, r0 += 3) + { + if (r0[1] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 0 : + for (x = xsize; x > 0; x --, r0 += 3) + { + if (r0[2] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + z = 2 - z; + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 3) + { + if ((*r0 & 63) > dither[x & 7]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + ptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + z = 2 - z; + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 3) + { + if ((*r0 & 15) > dither[x & 3]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + ptr ++; + } + } + break; + + case 8 : + z = 2 - z; + r0 += z; + r1 += z; + + for (x = xsize; x > 0; x --, r0 += 3, r1 += 3) + { + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + } + break; + } + break; + } +} + + +/* + * 'format_YMCK()' - Convert image data to YMCK. + */ + +static void +format_YMCK(cups_page_header_t *header, /* I - Page header */ + unsigned char *row, /* IO - Bitmap data for device */ + int y, /* I - Current row */ + int z, /* I - Current plane */ + int xsize, /* I - Width of image data */ + int ysize, /* I - Height of image data */ + int yerr0, /* I - Top Y error */ + int yerr1, /* I - Bottom Y error */ + ib_t *r0, /* I - Primary image data */ + ib_t *r1) /* I - Image data for interpolation */ +{ + ib_t *ptr, /* Pointer into row */ + *cptr, /* Pointer into cyan */ + *mptr, /* Pointer into magenta */ + *yptr, /* Pointer into yellow */ + *kptr, /* Pointer into black */ + bitmask; /* Current mask for pixel */ + int bitoffset; /* Current offset in line */ + int bandwidth; /* Width of a color band */ + int x, /* Current X coordinate on page */ + *dither; /* Pointer into dither array */ + + + switch (XPosition) + { + case -1 : + bitoffset = 0; + break; + case 0 : + bitoffset = header->cupsBitsPerPixel * ((header->cupsWidth - xsize) / 2); + break; + case 1 : + bitoffset = header->cupsBitsPerPixel * (header->cupsWidth - xsize); + break; + } + + ptr = row + bitoffset / 8; + bandwidth = header->cupsBytesPerLine / 4; + + switch (header->cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 128 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize ; x > 0; x --, r0 += 4) + { + if (r0[2] > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (r0[1] > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (r0[0] > dither[x & 15]) + *ptr ^= bitmask; + bitmask >>= 1; + + if (r0[3] > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 128; + + ptr ++; + } + } + break; + + case 2 : + dither = Floyd8x8[y & 7]; + + for (x = xsize ; x > 0; x --, r0 += 4) + { + if ((r0[2] & 63) > dither[x & 7]) + *ptr ^= (0xc0 & OnPixels[r0[2]]); + else + *ptr ^= (0xc0 & OffPixels[r0[2]]); + + if ((r0[1] & 63) > dither[x & 7]) + *ptr ^= (0x30 & OnPixels[r0[1]]); + else + *ptr ^= (0x30 & OffPixels[r0[1]]); + + if ((r0[0] & 63) > dither[x & 7]) + *ptr ^= (0x0c & OnPixels[r0[0]]); + else + *ptr ^= (0x0c & OffPixels[r0[0]]); + + if ((r0[3] & 63) > dither[x & 7]) + *ptr++ ^= (0x03 & OnPixels[r0[3]]); + else + *ptr++ ^= (0x03 & OffPixels[r0[3]]); + } + break; + + case 4 : + dither = Floyd4x4[y & 3]; + + for (x = xsize ; x > 0; x --, r0 += 4) + { + if ((r0[2] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[2]]); + else + *ptr ^= (0xf0 & OffPixels[r0[2]]); + + if ((r0[1] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[1]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[1]]); + + if ((r0[0] & 15) > dither[x & 3]) + *ptr ^= (0xf0 & OnPixels[r0[0]]); + else + *ptr ^= (0xf0 & OffPixels[r0[0]]); + + if ((r0[3] & 15) > dither[x & 3]) + *ptr++ ^= (0x0f & OnPixels[r0[3]]); + else + *ptr++ ^= (0x0f & OffPixels[r0[3]]); + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (r0[2] == r1[2]) + *ptr++ = r0[2]; + else + *ptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *ptr++ = r0[1]; + else + *ptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[0] == r1[0]) + *ptr++ = r0[0]; + else + *ptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[3] == r1[3]) + *ptr++ = r0[3]; + else + *ptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_BANDED : + yptr = ptr; + mptr = ptr + bandwidth; + cptr = ptr + 2 * bandwidth; + kptr = ptr + 3 * bandwidth; + + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + for (x = xsize; x > 0; x --) + { + if (*r0++ > dither[x & 15]) + *cptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *mptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *yptr ^= bitmask; + if (*r0++ > dither[x & 15]) + *kptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + + cptr ++; + mptr ++; + yptr ++; + kptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 63) > dither[x & 7]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 63) > dither[x & 7]) + *kptr ^= (bitmask & OnPixels[*r0++]); + else + *kptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + cptr ++; + mptr ++; + yptr ++; + kptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + + for (x = xsize; x > 0; x --) + { + if ((*r0 & 15) > dither[x & 3]) + *cptr ^= (bitmask & OnPixels[*r0++]); + else + *cptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *mptr ^= (bitmask & OnPixels[*r0++]); + else + *mptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *yptr ^= (bitmask & OnPixels[*r0++]); + else + *yptr ^= (bitmask & OffPixels[*r0++]); + + if ((*r0 & 15) > dither[x & 3]) + *kptr ^= (bitmask & OnPixels[*r0++]); + else + *kptr ^= (bitmask & OffPixels[*r0++]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + cptr ++; + mptr ++; + yptr ++; + kptr ++; + } + } + break; + + case 8 : + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (r0[0] == r1[0]) + *cptr++ = r0[0]; + else + *cptr++ = (r0[0] * yerr0 + r1[0] * yerr1) / ysize; + + if (r0[1] == r1[1]) + *mptr++ = r0[1]; + else + *mptr++ = (r0[1] * yerr0 + r1[1] * yerr1) / ysize; + + if (r0[2] == r1[2]) + *yptr++ = r0[2]; + else + *yptr++ = (r0[2] * yerr0 + r1[2] * yerr1) / ysize; + + if (r0[3] == r1[3]) + *kptr++ = r0[3]; + else + *kptr++ = (r0[3] * yerr0 + r1[3] * yerr1) / ysize; + } + break; + } + break; + + case CUPS_ORDER_PLANAR : + switch (header->cupsBitsPerColor) + { + case 1 : + bitmask = 0x80 >> (bitoffset & 7); + dither = Floyd16x16[y & 15]; + + if (z < 3) + r0 += 2 - z; + else + r0 += z; + + for (x = xsize; x > 0; x --, r0 += 4) + { + if (*r0 > dither[x & 15]) + *ptr ^= bitmask; + + if (bitmask > 1) + bitmask >>= 1; + else + { + bitmask = 0x80; + ptr ++; + } + } + break; + + case 2 : + bitmask = 0xc0 >> (bitoffset & 7); + dither = Floyd8x8[y & 7]; + if (z == 3) + r0 += 3; + else + r0 += 2 - z; + + for (x = xsize; x > 0; x --, r0 += 4) + { + if ((*r0 & 63) > dither[x & 7]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask > 3) + bitmask >>= 2; + else + { + bitmask = 0xc0; + + ptr ++; + } + } + break; + + case 4 : + bitmask = 0xf0 >> (bitoffset & 7); + dither = Floyd4x4[y & 3]; + if (z == 3) + r0 += 3; + else + r0 += 2 - z; + + for (x = xsize; x > 0; x --, r0 += 4) + { + if ((*r0 & 15) > dither[x & 3]) + *ptr ^= (bitmask & OnPixels[*r0]); + else + *ptr ^= (bitmask & OffPixels[*r0]); + + if (bitmask == 0xf0) + bitmask = 0x0f; + else + { + bitmask = 0xf0; + + ptr ++; + } + } + break; + + case 8 : + if (z == 3) + { + r0 += 3; + r1 += 3; + } + else + { + r0 += 2 - z; + r1 += 2 - z; + } + + for (x = xsize; x > 0; x --, r0 += 4, r1 += 4) + { + if (*r0 == *r1) + *ptr++ = *r0; + else + *ptr++ = (*r0 * yerr0 + *r1 * yerr1) / ysize; + } + break; + } + break; + } +} + + +/* + * 'make_lut()' - Make a lookup table given gamma and brightness values. + */ + +static void +make_lut(ib_t *lut, /* I - Lookup table */ + int colorspace, /* I - Colorspace */ + float g, /* I - Image gamma */ + float b) /* I - Image brightness */ +{ + int i; /* Looping var */ + int v; /* Current value */ + + + g = 1.0 / g; + b = 1.0 / b; + + for (i = 0; i < 256; i ++) + { + if (colorspace < 0) + v = 255.0 * b * (1.0 - pow(1.0 - (float)i / 255.0, g)) + 0.5; + else + v = 255.0 * (1.0 - b * (1.0 - pow((float)i / 255.0, g))) + 0.5; + + if (v < 0) + *lut++ = 0; + else if (v > 255) + *lut++ = 255; + else + *lut++ = v; + } +} + + +/* + * End of "$Id$". + */ diff --git a/filter/pstops.c b/filter/pstops.c new file mode 100644 index 0000000000..0c7a2fa63b --- /dev/null +++ b/filter/pstops.c @@ -0,0 +1,912 @@ +/* + * "$Id$" + * + * PostScript filter for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry... + * check_range() - Check to see if the current page is selected for + * copy_bytes() - Copy bytes from the input file to stdout... + * end_nup() - End processing for N-up printing... + * psgets() - Get a line from a file. + * start_nup() - Start processing for N-up printing... + */ + +/* + * Include necessary headers... + */ + +#include "common.h" + + +/* + * Constants... + */ + +#define MAX_PAGES 10000 + + +/* + * Globals... + */ + +int NumPages = 0; /* Number of pages in file */ +long Pages[MAX_PAGES]; /* Offsets to each page */ +char PageLabels[MAX_PAGES][64]; + /* Page labels */ +const char *PageRanges = NULL; /* Range of pages selected */ +const char *PageSet = NULL; /* All, Even, Odd pages */ +int Order = 0, /* 0 = normal, 1 = reverse pages */ + Flip = 0, /* Flip/mirror pages */ + NUp = 1, /* Number of pages on each sheet (1, 2, 4) */ + Collate = 0, /* Collate copies? */ + Copies = 1; /* Number of copies */ + + +/* + * Local functions... + */ + +static int check_range(int page); +static void copy_bytes(FILE *fp, size_t length); +static void end_nup(int number); +static char *psgets(char *buf, size_t len, FILE *fp); +static void start_nup(int number); + + +/* + * 'main()' - Main entry... + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + FILE *fp; /* Print file */ + ppd_file_t *ppd; /* PPD file */ + int num_options; /* Number of print options */ + cups_option_t *options; /* Print options */ + const char *val; /* Option value */ + char tempfile[255]; /* Temporary file name */ + FILE *temp; /* Temporary file */ + int number; /* Page number */ + int slowcollate; /* 1 if we need to collate manually */ + int sloworder; /* 1 if we need to order manually */ + char line[8192]; /* Line buffer */ + float g; /* Gamma correction value */ + float b; /* Brightness factor */ + int level; /* Nesting level for embedded files */ + int nbytes, /* Number of bytes read */ + tbytes; /* Total bytes to read for binary data */ + int page; /* Current page sequence number */ + int page_count; /* Page count for NUp */ + int subpage; /* Sub-page number */ + int copy; /* Current copy */ + int saweof; /* Did we see a %%EOF tag? */ + + + /* + * Check arguments... + */ + + if (argc < 6 || argc > 7) + { + fputs("ERROR: pstops job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + fp = stdin; + else + { + /* + * Try to open the print file... + */ + + if ((fp = fopen(argv[6], "rb")) == NULL) + { + perror("ERROR: unable to open print file - "); + return (1); + } + } + + /* + * Process command-line options and write the prolog... + */ + + g = 1.0; + b = 1.0; + + Copies = atoi(argv[4]); + + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + + ppd = SetCommonOptions(num_options, options, 1); + + if ((val = cupsGetOption("page-ranges", num_options, options)) != NULL) + PageRanges = val; + + if ((val = cupsGetOption("page-set", num_options, options)) != NULL) + PageSet = val; + + if ((val = cupsGetOption("multiple-document-handling", num_options, options)) != NULL) + { + /* + * This IPP attribute is unnecessarily complicated... + * + * single-document, separate-documents-collated-copies, and + * single-document-new-sheet all require collated copies. + * + * separate-documents-collated-copies allows for uncollated copies. + */ + + Collate = strcasecmp(val, "separate-documents-collated-copies") != 0; + } + + if ((val = cupsGetOption("Collate", num_options, options)) != NULL && + strcasecmp(val, "True") == 0) + Collate = 1; + + if ((val = cupsGetOption("OutputOrder", num_options, options)) != NULL && + strcasecmp(val, "Reverse") == 0) + Order = 1; + + if ((val = cupsGetOption("number-up", num_options, options)) != NULL) + NUp = atoi(val); + + if ((val = cupsGetOption("gamma", num_options, options)) != NULL) + g = atoi(val) * 0.001f; + + if ((val = cupsGetOption("brightness", num_options, options)) != NULL) + b = atoi(val) * 0.01f; + + /* + * See if we have to filter the fast or slow way... + */ + + if (ppdFindOption(ppd, "Collate") == NULL && Collate && Copies > 1) + slowcollate = 1; + else + slowcollate = 0; + + if (ppdFindOption(ppd, "OutputOrder") == NULL && Order) + sloworder = 1; + else + sloworder = 0; + + /* + * If we need to filter slowly, then create a temporary file for page data... + * + * If the temp file can't be created, then we'll ignore the collating/output + * order options... + */ + + if (sloworder || slowcollate) + { + temp = fopen(cupsTempFile(tempfile, sizeof(tempfile)), "wb+"); + + if (temp == NULL) + slowcollate = sloworder = 0; + } + else + temp = NULL; + + /* + * Write any "exit server" options that have been selected... + */ + + ppdEmit(ppd, stdout, PPD_ORDER_EXIT); + + /* + * Write any JCL commands that are needed to print PostScript code... + */ + + if (ppd != NULL && ppd->jcl_begin && ppd->jcl_ps) + { + fputs(ppd->jcl_begin, stdout); + ppdEmit(ppd, stdout, PPD_ORDER_JCL); + + if (strncmp(ppd->jcl_ps, "@PJL", 4) == 0) + { + /* + * Send other PJL commands before we enter PostScript mode... + */ + + printf("@PJL JOB NAME = \"%s\" DISPLAY = \"%s %s %s\"\n", argv[3], + argv[1], argv[2], argv[3]); + } + + fputs(ppd->jcl_ps, stdout); + } + + /* + * Read the first line to see if we have DSC comments... + */ + + if (psgets(line, sizeof(line), fp) == NULL) + { + fputs("ERROR: Empty print file!\n", stderr); + ppdClose(ppd); + return (1); + } + + /* + * Start sending the document with any commands needed... + */ + + puts(line); + + saweof = 0; + + if (ppd != NULL && ppd->patches != NULL) + puts(ppd->patches); + + ppdEmit(ppd, stdout, PPD_ORDER_DOCUMENT); + ppdEmit(ppd, stdout, PPD_ORDER_ANY); + ppdEmit(ppd, stdout, PPD_ORDER_PROLOG); + + if (NUp > 1) + puts("userdict begin\n" + "/ESPshowpage /showpage load def\n" + "/showpage { } def\n" + "end"); + + if (g != 1.0 || b != 1.0) + printf("{ neg 1 add dup 0 lt { pop 1 } { %.3f exp neg 1 add } " + "ifelse %.3f mul } bind settransfer\n", g, b); + + if (Copies > 1 && (!Collate || !slowcollate)) + printf("/#copies %d def\n", Copies); + + if (strncmp(line, "%!PS-Adobe-", 11) == 0) + { + /* + * OK, we have DSC comments; read until we find a %%Page comment... + */ + + level = 0; + + while (psgets(line, sizeof(line), fp) != NULL) + if (strncmp(line, "%%BeginDocument:", 16) == 0 || + strncmp(line, "%%BeginDocument ", 16) == 0) /* Adobe Acrobat BUG */ + level ++; + else if (strcmp(line, "%%EndDocument") == 0 && level > 0) + level --; + else if (strncmp(line, "%%Page:", 7) == 0 && level == 0) + break; + else if (strncmp(line, "%%BeginBinary:", 14) == 0 || + (strncmp(line, "%%BeginData:", 12) == 0 && + strstr(line, "Binary") != NULL)) + { + /* + * Copy binary data... + */ + + tbytes = atoi(strchr(line, ':') + 1); + while (tbytes > 0) + { + if (tbytes > sizeof(line)) + nbytes = fread(line, 1, sizeof(line), fp); + else + nbytes = fread(line, 1, tbytes, fp); + + fwrite(line, 1, nbytes, stdout); + tbytes -= nbytes; + } + } + else + puts(line); + + /* + * Then read all of the pages, filtering as needed... + */ + + for (page = 1;;) + { + if (strncmp(line, "%%BeginDocument:", 16) == 0 || + strncmp(line, "%%BeginDocument ", 16) == 0) /* Adobe Acrobat BUG */ + level ++; + else if (strcmp(line, "%%EndDocument") == 0 && level > 0) + level --; + else if (strcmp(line, "%%EOF") == 0 && level == 0) + saweof = 1; + else if (strncmp(line, "%%Page:", 7) == 0 && level == 0) + { + if (sscanf(line, "%*s%*s%d", &number) == 1) + { + if (!check_range(number)) + { + while (psgets(line, sizeof(line), fp) != NULL) + if (strncmp(line, "%%BeginDocument:", 16) == 0 || + strncmp(line, "%%BeginDocument ", 16) == 0) /* Adobe Acrobat BUG */ + level ++; + else if (strcmp(line, "%%EndDocument") == 0 && level > 0) + level --; + else if (strncmp(line, "%%Page:", 7) == 0 && level == 0) + break; + + continue; + } + + if (!sloworder && NumPages > 0) + end_nup(NumPages - 1); + + if (slowcollate || sloworder) + Pages[NumPages] = ftell(temp); + + if (!sloworder) + { + if ((NumPages & (NUp - 1)) == 0) + { + if (ppd == NULL || ppd->num_filters == 0) + fprintf(stderr, "PAGE: %d %d\n", page, Copies); + + printf("%%%%Page: %d %d\n", page, page); + page ++; + ppdEmit(ppd, stdout, PPD_ORDER_PAGE); + } + + start_nup(NumPages); + } + + NumPages ++; + } + } + else if (strncmp(line, "%%BeginBinary:", 14) == 0 || + (strncmp(line, "%%BeginData:", 12) == 0 && + strstr(line, "Binary") != NULL)) + { + /* + * Copy binary data... + */ + + tbytes = atoi(strchr(line, ':') + 1); + while (tbytes > 0) + { + if (tbytes > sizeof(line)) + nbytes = fread(line, 1, sizeof(line), fp); + else + nbytes = fread(line, 1, tbytes, fp); + + if (!sloworder) + fwrite(line, 1, nbytes, stdout); + + if (slowcollate || sloworder) + fwrite(line, 1, nbytes, stdout); + + tbytes -= nbytes; + } + } + else if (strcmp(line, "%%Trailer") == 0 && level == 0) + { + /* + * Assume that a file with a %%Trailer will likely also have %%EOF... + */ + + saweof = 1; + break; + } + else + { + if (!sloworder) + puts(line); + + if (slowcollate || sloworder) + { + fputs(line, temp); + putc('\n', temp); + } + } + + if (psgets(line, sizeof(line), fp) == NULL) + break; + } + + if (!sloworder) + { + end_nup(NumPages - 1); + + if (NumPages & (NUp - 1)) + { + start_nup(NUp - 1); + end_nup(NUp - 1); + } + } + + if (slowcollate || sloworder) + { + Pages[NumPages] = ftell(temp); + page = 1; + + if (!sloworder) + { + while (Copies > 0) + { + rewind(temp); + + for (number = 0; number < NumPages; number ++) + { + if ((number & (NUp - 1)) == 0) + { + if (ppd == NULL || ppd->num_filters == 0) + fprintf(stderr, "PAGE: %d 1\n", page); + + printf("%%%%Page: %d %d\n", page, page); + page ++; + ppdEmit(ppd, stdout, PPD_ORDER_PAGE); + } + + start_nup(number); + copy_bytes(temp, Pages[number + 1] - Pages[number]); + end_nup(number); + } + + if (NumPages & (NUp - 1)) + { + start_nup(NUp - 1); + end_nup(NUp - 1); + } + + Copies --; + } + } + else + { + page_count = (NumPages + NUp - 1) / NUp; + copy = 0; + + do + { + for (page = page_count - 1; page >= 0; page --) + { + if (ppd == NULL || ppd->num_filters == 0) + fprintf(stderr, "PAGE: %d %d\n", page + 1, + slowcollate ? 1 : Copies); + + if (slowcollate) + printf("%%%%Page: %d %d\n", page + 1, + page_count - page + copy * page_count); + else + printf("%%%%Page: %d %d\n", page + 1, page_count - page); + + ppdEmit(ppd, stdout, PPD_ORDER_PAGE); + + for (subpage = 0, number = page * NUp; + subpage < NUp && number < NumPages; + subpage ++, number ++) + { + start_nup(number); + fseek(temp, Pages[number], SEEK_SET); + copy_bytes(temp, Pages[number + 1] - Pages[number]); + end_nup(number); + } + + if (number & (NUp - 1)) + { + start_nup(NUp - 1); + end_nup(NUp - 1); + } + } + + copy ++; + } + while (copy < Copies && slowcollate); + } + } + + /* + * Copy the trailer, if any... + */ + + while ((nbytes = fread(line, 1, sizeof(line), fp)) > 0) + fwrite(line, 1, nbytes, stdout); + } + else + { + /* + * No DSC comments - write any page commands and then the rest of the file... + */ + + if (ppd == NULL || ppd->num_filters == 0) + fprintf(stderr, "PAGE: 1 %d\n", slowcollate ? 1 : Copies); + + ppdEmit(ppd, stdout, PPD_ORDER_PAGE); + + while (psgets(line, sizeof(line), fp) != NULL) + { + puts(line); + + if (slowcollate) + { + fputs(line, temp); + putc('\n', temp); + } + } + + if (slowcollate) + { + while (Copies > 1) + { + if (ppd == NULL || ppd->num_filters == 0) + fputs("PAGE: 1 1\n", stderr); + + ppdEmit(ppd, stdout, PPD_ORDER_PAGE); + rewind(temp); + copy_bytes(temp, 0); + Copies --; + } + } + } + + /* + * Send %%EOF if needed... + */ + + if (!saweof) + puts("%%EOF"); + + /* + * End the job with the appropriate JCL command or CTRL-D otherwise. + */ + + if (ppd != NULL && ppd->jcl_end) + fputs(ppd->jcl_end, stdout); + else + putchar(0x04); + + /* + * Close files and remove the temporary file if needed... + */ + + if (slowcollate || sloworder) + { + fclose(temp); + unlink(tempfile); + } + + ppdClose(ppd); + + if (fp != stdin) + fclose(fp); + + return (0); +} + + +/* + * 'check_range()' - Check to see if the current page is selected for + * printing. + */ + +static int /* O - 1 if selected, 0 otherwise */ +check_range(int page) /* I - Page number */ +{ + const char *range; /* Pointer into range string */ + int lower, upper; /* Lower and upper page numbers */ + + + if (PageSet != NULL) + { + /* + * See if we only print even or odd pages... + */ + + if (strcasecmp(PageSet, "even") == 0 && (page & 1)) + return (0); + if (strcasecmp(PageSet, "odd") == 0 && !(page & 1)) + return (0); + } + + if (PageRanges == NULL) + return (1); /* No range, print all pages... */ + + for (range = PageRanges; *range != '\0';) + { + if (*range == '-') + { + lower = 1; + range ++; + upper = strtol(range, (char **)&range, 10); + } + else + { + lower = strtol(range, (char **)&range, 10); + + if (*range == '-') + { + range ++; + if (!isdigit(*range)) + upper = 65535; + else + upper = strtol(range, (char **)&range, 10); + } + else + upper = lower; + } + + if (page >= lower && page <= upper) + return (1); + + if (*range == ',') + range ++; + else + break; + } + + return (0); +} + + +/* + * 'copy_bytes()' - Copy bytes from the input file to stdout... + */ + +static void +copy_bytes(FILE *fp, /* I - File to read from */ + size_t length) /* I - Length of page data */ +{ + char buffer[8192]; /* Data buffer */ + size_t nbytes, /* Number of bytes read */ + nleft; /* Number of bytes left/remaining */ + + + nleft = length; + + while (nleft > 0 || length == 0) + { + if (nleft > sizeof(buffer)) + nbytes = sizeof(buffer); + else + nbytes = nleft; + + if ((nbytes = fread(buffer, 1, nbytes, fp)) < 1) + return; + + nleft -= nbytes; + + fwrite(buffer, 1, nbytes, stdout); + } +} + + +/* + * 'end_nup()' - End processing for N-up printing... + */ + +static void +end_nup(int number) /* I - Page number */ +{ + if (Flip || Orientation || NUp > 1) + puts("ESPsave restore"); + + switch (NUp) + { + case 2 : + if ((number & 1) == 1) + puts("ESPshowpage"); + break; + + case 4 : + if ((number & 3) == 3) + puts("ESPshowpage"); + break; + } +} + + +/* + * 'psgets()' - Get a line from a file. + * + * Note: + * + * This function differs from the gets() function in that it + * handles any combination of CR, LF, or CR LF to end input + * lines. + */ + +static char * /* O - String or NULL if EOF */ +psgets(char *buf, /* I - Buffer to read into */ + size_t len, /* I - Length of buffer */ + FILE *fp) /* I - File to read from */ +{ + char *bufptr; /* Pointer into buffer */ + int ch; /* Character from file */ + + + len --; + bufptr = buf; + ch = EOF; + + while ((bufptr - buf) < len) + { + if ((ch = getc(fp)) == EOF) + break; + + if (ch == 0x0d) + { + /* + * Got a CR; see if there is a LF as well... + */ + + ch = getc(fp); + if (ch != EOF && ch != 0x0a) + ungetc(ch, fp); /* Nope, save it for later... */ + + break; + } + else if (ch == 0x0a) + break; + else + *bufptr++ = ch; + } + + /* + * Nul-terminate the string and return it (or NULL for EOF). + */ + + *bufptr = '\0'; + + if (ch == EOF && bufptr == buf) + return (NULL); + else + return (buf); +} + + +/* + * 'start_nup()' - Start processing for N-up printing... + */ + +static void +start_nup(int number) /* I - Page number */ +{ + int x, y; /* Relative position of subpage */ + float w, l, /* Width and length of subpage */ + tx, ty; /* Translation values for subpage */ + float pw, pl; /* Printable width and length of full page */ + + + if (Flip || Orientation || NUp > 1) + puts("/ESPsave save def"); + + if (Flip) + printf("%.0f 0 translate -1 1 scale\n", PageWidth); + + pw = PageRight - PageLeft; + pl = PageTop - PageBottom; + + switch (Orientation) + { + case 1 : /* Landscape */ + printf("%.0f 0 translate 90 rotate\n", PageLength); + break; + case 2 : /* Reverse Portrait */ + printf("%.0f %.0f translate 180 rotate\n", PageWidth, PageLength); + break; + case 3 : /* Reverse Landscape */ + printf("0 %.0f translate -90 rotate\n", PageWidth); + break; + } + + switch (NUp) + { + case 2 : + x = number & 1; + + if (Orientation & 1) + { + x = 1 - x; + w = pl; + l = w * PageLength / PageWidth; + + if (l > (pw * 0.5)) + { + l = pw * 0.5; + w = l * PageWidth / PageLength; + } + + tx = pw * 0.5 - l; + ty = (pl - w) * 0.5; + } + else + { + l = pw; + w = l * PageWidth / PageLength; + + if (w > (pl * 0.5)) + { + w = pl * 0.5; + l = w * PageLength / PageWidth; + } + + tx = pl * 0.5 - w; + ty = (pw - l) * 0.5; + } + + if (Duplex && (number & 2)) + printf("%.0f %.0f translate\n", PageWidth - PageRight, PageBottom); + else + printf("%.0f %.0f translate\n", PageLeft, PageBottom); + + if (Orientation & 1) + { + printf("0 %.0f translate -90 rotate\n", pl); + printf("%.0f %.0f translate %.3f %.3f scale\n", + ty, tx + l * x, w / pw, l / pl); + } + else + { + printf("%.0f 0 translate 90 rotate\n", pw); + printf("%.0f %.0f translate %.3f %.3f scale\n", + tx + w * x, ty, w / pw, l / pl); + } + + printf("newpath\n" + "0 0 moveto\n" + "%.0f 0 lineto\n" + "%.0f %.0f lineto\n" + "0 %.0f lineto\n" + "closepath clip newpath\n", + PageWidth, PageWidth, PageLength, PageLength); + break; + + case 4 : + x = number & 1; + y = 1 - ((number & 2) != 0); + + w = pw * 0.5; + l = w * PageLength / PageWidth; + + if (l > (pl * 0.5)) + { + l = pl * 0.5; + w = l * PageWidth / PageLength; + } + + if (Duplex && (number & 4)) + printf("%.0f %.0f translate\n", PageWidth - PageRight, PageBottom); + else + printf("%.0f %.0f translate\n", PageLeft, PageBottom); + + printf("%.0f %.0f translate %.3f %.3f scale\n", x * w, y * l, + w / PageWidth, l / PageLength); + printf("newpath\n" + "0 0 moveto\n" + "%.0f 0 lineto\n" + "%.0f %.0f lineto\n" + "0 %.0f lineto\n" + "closepath clip newpath\n", + PageWidth, PageWidth, PageLength, PageLength); + break; + } +} + + +/* + * End of "$Id$". + */ diff --git a/filter/raster.c b/filter/raster.c new file mode 100644 index 0000000000..be4f466234 --- /dev/null +++ b/filter/raster.c @@ -0,0 +1,252 @@ +/* + * "$Id$" + * + * Raster file routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights for the CUPS Raster source + * files are outlined in the GNU Library General Public License, located + * in the "pstoraster" directory. If this file is missing or damaged + * please contact Easy Software Products at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * This code and any derivative of it may be used and distributed + * freely under the terms of the GNU General Public License when + * used with GNU Ghostscript or its derivatives. Use of the code + * (or any derivative of it) with software other than GNU + * GhostScript (or its derivatives) is governed by the CUPS license + * agreement. + * + * Contents: + * + * cupsRasterClose() - Close a raster stream. + * cupsRasterOpen() - Open a raster stream. + * cupsRasterReadHeader() - Read a raster page header. + * cupsRasterReadPixels() - Read raster pixels. + * cupsRasterWriteHeader() - Write a raster page header. + * cupsRasterWritePixels() - Write raster pixels. + */ + +/* + * Include necessary headers... + */ + +#include "raster.h" +#include +#include +#include + +#if defined(WIN32) || defined(__EMX__) +# include +#else +# include +#endif /* WIN32 || __EMX__ */ + + +/* + * 'cupsRasterClose()' - Close a raster stream. + */ + +void +cupsRasterClose(cups_raster_t *r) /* I - Stream to close */ +{ + if (r != NULL) + free(r); +} + + +/* + * 'cupsRasterOpen()' - Open a raster stream. + */ + +cups_raster_t * /* O - New stream */ +cupsRasterOpen(int fd, /* I - File descriptor */ + cups_mode_t mode) /* I - Mode */ +{ + cups_raster_t *r; /* New stream */ + + + if ((r = calloc(sizeof(cups_raster_t), 1)) == NULL) + return (NULL); + + r->fd = fd; + r->mode = mode; + + if (mode == CUPS_RASTER_READ) + { + /* + * Open for read - get sync word... + */ + + if (read(fd, &(r->sync), sizeof(r->sync)) < sizeof(r->sync)) + { + free(r); + return (NULL); + } + + if (r->sync != CUPS_RASTER_SYNC && + r->sync != CUPS_RASTER_REVSYNC) + { + free(r); + return (NULL); + } + } + else + { + /* + * Open for write - put sync word... + */ + + r->sync = CUPS_RASTER_SYNC; + if (write(fd, &(r->sync), sizeof(r->sync)) < sizeof(r->sync)) + { + free(r); + return (NULL); + } + } + + return (r); +} + + +/* + * 'cupsRasterReadHeader()' - Read a raster page header. + */ + +unsigned /* O - 1 on success, 0 on fail */ +cupsRasterReadHeader(cups_raster_t *r, /* I - Raster stream */ + cups_page_header_t *h) /* I - Pointer to header data */ +{ + int len; /* Number of words to swap */ + union swap_s /* Swapping structure */ + { + unsigned char b[4]; + unsigned v; + } *s; + + + if (r == NULL || r->mode != CUPS_RASTER_READ) + return (0); + + if (cupsRasterReadPixels(r, (unsigned char *)h, sizeof(cups_page_header_t)) < + sizeof(cups_page_header_t)) + return (0); + + if (r->sync == CUPS_RASTER_REVSYNC) + for (len = (sizeof(cups_page_header_t) - 256) / 4, + s = (union swap_s *)&(h->AdvanceDistance); + len > 0; + len --, s ++) + s->v = (((((s->b[3] << 8) | s->b[2]) << 8) | s->b[1]) << 8) | s->b[0]; + + return (1); +} + + +/* + * 'cupsRasterReadPixels()' - Read raster pixels. + */ + +unsigned /* O - Number of bytes read */ +cupsRasterReadPixels(cups_raster_t *r, /* I - Raster stream */ + unsigned char *p, /* I - Pointer to pixel buffer */ + unsigned len) /* I - Number of bytes to read */ +{ + int bytes; /* Bytes read */ + unsigned remaining; /* Bytes remaining */ + + + if (r == NULL || r->mode != CUPS_RASTER_READ) + return (0); + + remaining = len; + + while (remaining > 0) + { + bytes = read(r->fd, p, remaining); + + if (bytes <= 0) + { + if (errno != EAGAIN && errno != EINTR) + return (0); + else + continue; + } + + remaining -= bytes; + p += bytes; + } + + return (len); +} + + +/* + * 'cupsRasterWriteHeader()' - Write a raster page header. + */ + +unsigned +cupsRasterWriteHeader(cups_raster_t *r, + cups_page_header_t *h) +{ + if (r == NULL || r->mode != CUPS_RASTER_WRITE) + return (0); + + return (cupsRasterWritePixels(r, (unsigned char *)h, + sizeof(cups_page_header_t)) == + sizeof(cups_page_header_t)); +} + + +/* + * 'cupsRasterWritePixels()' - Write raster pixels. + */ + +unsigned /* O - Number of bytes written */ +cupsRasterWritePixels(cups_raster_t *r, /* I - Raster stream */ + unsigned char *p, /* I - Bytes to write */ + unsigned len)/* I - Number of bytes to write */ +{ + int bytes; /* Bytes read */ + unsigned remaining; /* Bytes remaining */ + + + if (r == NULL || r->mode != CUPS_RASTER_WRITE) + return (0); + + remaining = len; + + while (remaining > 0) + { + bytes = write(r->fd, p, remaining); + + if (bytes <= 0) + { + if (errno != EAGAIN && errno != EINTR) + return (0); + else + continue; + } + + remaining -= bytes; + p += bytes; + } + + return (len); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/raster.h b/filter/raster.h new file mode 100644 index 0000000000..2c4052d569 --- /dev/null +++ b/filter/raster.h @@ -0,0 +1,233 @@ +/* + * "$Id$" + * + * Raster file definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights for the CUPS Raster source + * files are outlined in the GNU Library General Public License, located + * in the "pstoraster" directory. If this file is missing or damaged + * please contact Easy Software Products at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * This code and any derivative of it may be used and distributed + * freely under the terms of the GNU General Public License when + * used with GNU Ghostscript or its derivatives. Use of the code + * (or any derivative of it) with software other than GNU + * GhostScript (or its derivatives) is governed by the CUPS license + * agreement. + */ + +#ifndef _CUPS_RASTER_H_ +# define _CUPS_RASTER_H_ + +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ + +/* + * Every non-PostScript printer driver that supports raster images should + * use the application/vnd.cups-raster image file format. Since both the + * PostScript RIP (pstoraster, based on GNU Ghostscript 4.03) and Image RIP + * (imagetoraster, located in the filter directory) use it, using this format + * saves you a lot of work. Also, the PostScript RIP passes any printer + * options that are in a PS file to your driver this way as well... + */ + +/* + * Constants... + */ + +# define CUPS_RASTER_SYNC 0x52615374 /* RaSt */ +# define CUPS_RASTER_REVSYNC 0x74536152 /* tSaR */ + + +/* + * Types... + */ + +typedef enum +{ + CUPS_RASTER_READ, /* Open stream for reading */ + CUPS_RASTER_WRITE /* Open stream for writing */ +} cups_mode_t; + +typedef enum +{ + CUPS_FALSE, /* Logical false */ + CUPS_TRUE /* Logical true */ +} cups_bool_t; + +typedef enum +{ + CUPS_JOG_NONE, /* Never move pages */ + CUPS_JOG_FILE, /* Move pages after this file */ + CUPS_JOG_JOB, /* Move pages after this job */ + CUPS_JOG_SET /* Move pages after this set */ +} cups_jog_t; + +typedef enum +{ + CUPS_ORIENT_0, /* Don't rotate the page */ + CUPS_ORIENT_90, /* Rotate the page counter-clockwise */ + CUPS_ORIENT_180, /* Turn the page upside down */ + CUPS_ORIENT_270 /* Rotate the page clockwise */ +} cups_orient_t; + +typedef enum +{ + CUPS_CUT_NONE, /* Never cut the roll */ + CUPS_CUT_FILE, /* Cut the roll after this file */ + CUPS_CUT_JOB, /* Cut the roll after this job */ + CUPS_CUT_SET, /* Cut the roll after this set */ + CUPS_CUT_PAGE /* Cut the roll after this page */ +} cups_cut_t; + +typedef enum +{ + CUPS_ADVANCE_NONE, /* Never advance the roll */ + CUPS_ADVANCE_FILE, /* Advance the roll after this file */ + CUPS_ADVANCE_JOB, /* Advance the roll after this job */ + CUPS_ADVANCE_SET, /* Advance the roll after this set */ + CUPS_ADVANCE_PAGE /* Advance the roll after this page */ +} cups_adv_t; + +typedef enum +{ + CUPS_EDGE_TOP, /* Leading edge is the top of the page */ + CUPS_EDGE_RIGHT, /* Leading edge is the right of the page */ + CUPS_EDGE_BOTTOM, /* Leading edge is the bottom of the page */ + CUPS_EDGE_LEFT /* Leading edge is the left of the page */ +} cups_edge_t; + +typedef enum +{ + CUPS_ORDER_CHUNKED, /* CMYK CMYK CMYK ... */ + CUPS_ORDER_BANDED, /* CCC MMM YYY KKK ... */ + CUPS_ORDER_PLANAR /* CCC ... MMM ... YYY ... KKK ... */ +} cups_order_t; + +typedef enum +{ + CUPS_CSPACE_W, /* Luminance */ + CUPS_CSPACE_RGB, /* Red, green, blue */ + CUPS_CSPACE_RGBA, /* Red, green, blue, alpha */ + CUPS_CSPACE_K, /* Black */ + CUPS_CSPACE_CMY, /* Cyan, magenta, yellow */ + CUPS_CSPACE_YMC, /* Yellow, magenta, cyan */ + CUPS_CSPACE_CMYK, /* Cyan, magenta, yellow, black */ + CUPS_CSPACE_YMCK, /* Yellow, magenta, cyan, black */ + CUPS_CSPACE_KCMY, /* Black, cyan, magenta, yellow */ + CUPS_CSPACE_KCMYcm, /* Black, cyan, magenta, yellow, * + * light-cyan, light-magenta */ + CUPS_CSPACE_GMCK, /* Gold, magenta, yellow, black */ + CUPS_CSPACE_GMCS, /* Gold, magenta, yellow, silver */ + CUPS_CSPACE_WHITE, /* White ink (as black) */ + CUPS_CSPACE_GOLD, /* Gold foil */ + CUPS_CSPACE_SILVER /* Silver foil */ +} cups_cspace_t; + + +/* + * The page header structure contains the standard PostScript page device + * dictionary, along with some CUPS-specific parameters that are provided + * by the RIPs... + */ + +typedef struct +{ + /**** Standard Page Device Dictionary String Values ****/ + char MediaClass[64]; /* MediaClass string */ + char MediaColor[64]; /* MediaColor string */ + char MediaType[64]; /* MediaType string */ + char OutputType[64]; /* OutputType string */ + + /**** Standard Page Device Dictionary Integer Values ****/ + unsigned AdvanceDistance; /* AdvanceDistance value in points */ + cups_adv_t AdvanceMedia; /* AdvanceMedia value (see above) */ + cups_bool_t Collate; /* Collated copies value */ + cups_cut_t CutMedia; /* CutMedia value (see above) */ + cups_bool_t Duplex; /* Duplexed (double-sided) value */ + unsigned HWResolution[2]; /* Resolution in dots-per-inch */ + unsigned ImagingBoundingBox[4]; /* Pixel region that is painted (points) */ + cups_bool_t InsertSheet; /* InsertSheet value */ + cups_jog_t Jog; /* Jog value (see above) */ + cups_edge_t LeadingEdge; /* LeadingEdge value (see above) */ + unsigned Margins[2]; /* Lower-lefthand margins in points */ + cups_bool_t ManualFeed; /* ManualFeed value */ + unsigned MediaPosition; /* MediaPosition value */ + unsigned MediaWeight; /* MediaWeight value in grams/m^2 */ + cups_bool_t MirrorPrint; /* MirrorPrint value */ + cups_bool_t NegativePrint; /* NegativePrint value */ + unsigned NumCopies; /* Number of copies to produce */ + cups_orient_t Orientation; /* Orientation value (see above) */ + cups_bool_t OutputFaceUp; /* OutputFaceUp value */ + unsigned PageSize[2]; /* Width and length of page in points */ + cups_bool_t Separations; /* Separations value */ + cups_bool_t TraySwitch; /* TraySwitch value */ + cups_bool_t Tumble; /* Tumble value */ + + /**** CUPS Page Device Dictionary Values ****/ + unsigned cupsWidth; /* Width of page image in pixels */ + unsigned cupsHeight; /* Height of page image in pixels */ + unsigned cupsMediaType; /* Media type code */ + unsigned cupsBitsPerColor; /* Number of bits for each color */ + unsigned cupsBitsPerPixel; /* Number of bits for each pixel */ + unsigned cupsBytesPerLine; /* Number of bytes per line */ + cups_order_t cupsColorOrder; /* Order of colors */ + cups_cspace_t cupsColorSpace; /* True colorspace */ + unsigned cupsCompression; /* Device compression to use */ + unsigned cupsRowCount; /* Rows per band */ + unsigned cupsRowFeed; /* Feed between bands */ + unsigned cupsRowStep; /* Spacing between lines */ +} cups_page_header_t; + + +/* + * The raster structure maintains information about a raster data + * stream... + */ + +typedef struct +{ + unsigned sync; /* Sync word from start of stream */ + int fd; /* File descriptor */ + cups_mode_t mode; /* Read/write mode */ +} cups_raster_t; + + +/* + * Prototypes... + */ + +extern void cupsRasterClose(cups_raster_t *r); +extern cups_raster_t *cupsRasterOpen(int fd, cups_mode_t mode); +extern unsigned cupsRasterReadHeader(cups_raster_t *r, + cups_page_header_t *h); +extern unsigned cupsRasterReadPixels(cups_raster_t *r, + unsigned char *p, unsigned len); +extern unsigned cupsRasterWriteHeader(cups_raster_t *r, + cups_page_header_t *h); +extern unsigned cupsRasterWritePixels(cups_raster_t *r, + unsigned char *p, unsigned len); + +# ifdef __cplusplus +} +# endif /* __cplusplus */ + +#endif /* !_CUPS_RASTER_H_ */ + +/* + * End of "$Id$". + */ diff --git a/filter/rastertoepson.c b/filter/rastertoepson.c new file mode 100644 index 0000000000..bcad2eacf7 --- /dev/null +++ b/filter/rastertoepson.c @@ -0,0 +1,955 @@ +/* + * "$Id$" + * + * EPSON ESC/P and ESC/P2 filter for the Common UNIX Printing System + * (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * Setup() - Prepare the printer for printing. + * StartPage() - Start a page of graphics. + * EndPage() - Finish a page of graphics. + * Shutdown() - Shutdown the printer. + * CompressData() - Compress a line of graphics. + * OutputLine() - Output a line of graphics. + * main() - Main entry and processing of driver. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include "raster.h" +#include +#include +#include + + +/* + * Model numbers... + */ + +#define EPSON_9PIN 0 +#define EPSON_24PIN 1 +#define EPSON_COLOR 2 +#define EPSON_PHOTO 3 + + +/* + * Macros... + */ + +#define pwrite(s,n) fwrite((s), 1, (n), stdout) + + +/* + * Globals... + */ + +unsigned char *Planes[6], /* Output buffers */ + *CompBuffer, /* Compression buffer */ + *LineBuffers[2]; /* Line bitmap buffers */ +int NumPlanes, /* Number of color planes */ + Feed; /* Number of lines to skip */ +int DotBit, /* Bit in buffers */ + DotBytes, /* # bytes in a dot column */ + DotColumns, /* # columns in 1/60 inch */ + LineCount, /* # of lines processed */ + EvenOffset, /* Offset into 'even' buffers */ + OddOffset, /* Offset into 'odd' buffers */ + Shingling; /* Shingle output? */ + + +/* + * Prototypes... + */ + +void Setup(void); +void StartPage(const ppd_file_t *ppd, const cups_page_header_t *header); +void EndPage(const cups_page_header_t *header); +void Shutdown(void); + +void CompressData(const unsigned char *line, int length, int plane, + int type, int xstep, int ystep); +void OutputLine(const cups_page_header_t *header); +void OutputRows(const cups_page_header_t *header, int row); + + +/* + * 'Setup()' - Prepare the printer for printing. + */ + +void +Setup(void) +{ + /* + * Send a reset sequence. + */ + + printf("\033@"); +} + + +/* + * 'StartPage()' - Start a page of graphics. + */ + +void +StartPage(const ppd_file_t *ppd, /* I - PPD file */ + const cups_page_header_t *header) /* I - Page header */ +{ + int n, t; /* Numbers */ + int plane; /* Looping var */ + + + /* + * Send a reset sequence. + */ + + printf("\033@"); + + /* + * See which type of printer we are using... + */ + + switch (ppd->model_number) + { + case EPSON_9PIN : + case EPSON_24PIN : + printf("\033P"); /* Set 10 CPI */ + + if (header->HWResolution[0] == 360 || header->HWResolution[0] == 240) + { + printf("\033x1"); /* LQ printing */ + printf("\033U1"); /* Unidirectional */ + } + else + { + printf("\033x0"); /* Draft printing */ + printf("\033U0"); /* Bidirectional */ + } + + printf("\033l%c\033Q%c", 0, /* Side margins */ + (int)(10.0 * header->PageSize[0] / 72.0 + 0.5)); + printf("\033C%c%c", 0, /* Page length */ + (int)(header->PageSize[1] / 72.0 + 0.5)); + printf("\033N%c", 0); /* Bottom margin */ + + /* + * Setup various buffer limits... + */ + + DotBytes = header->cupsRowCount / 8; + DotColumns = header->HWResolution[0] / 60; + Shingling = 0; + + if (ppd->model_number == EPSON_9PIN) + printf("\033\063\030"); /* Set line feed */ + else + switch (header->HWResolution[0]) + { + case 60: + case 120 : + printf("\033\063\030"); /* Set line feed */ + break; + + case 180 : + case 360 : + Shingling = 1; + + if (header->HWResolution[1] == 180) + printf("\033\063\010");/* Set line feed */ + else + printf("\033+\010"); /* Set line feed */ + break; + } + break; + + case EPSON_COLOR : + case EPSON_PHOTO : + /* + * Set graphics mode... + */ + + pwrite("\033(G\001\000\001", 6); /* Graphics mode */ + + /* + * Set the media size... + */ + + pwrite("\033(U\001\000", 5); /* Resolution/units */ + putchar(3600 / header->HWResolution[1]); + + n = header->PageSize[1] * header->HWResolution[1] / 72.0; + + pwrite("\033(C\002\000", 5); /* Page length */ + putchar(n); + putchar(n >> 8); + + t = (ppd->sizes[1].length - ppd->sizes[1].top) * + header->HWResolution[1] / 72.0; + + pwrite("\033(c\004\000", 5); /* Top & bottom margins */ + putchar(t); + putchar(t >> 8); + putchar(n); + putchar(n >> 8); + + if (header->HWResolution[1] == 720) + { + pwrite("\033(i\001\000\001", 6); /* Microweave */ + pwrite("\033(e\002\000\000\001", 7); /* Small dots */ + } + + pwrite("\033(V\002\000\000\000", 7); /* Set absolute position 0 */ + + DotBytes = 0; + DotColumns = 0; + Shingling = 0; + break; + } + + /* + * Set other stuff... + */ + + if (header->cupsColorSpace == CUPS_CSPACE_CMY) + NumPlanes = 3; + else if (header->cupsColorSpace == CUPS_CSPACE_KCMY) + NumPlanes = 4; + else if (header->cupsColorSpace == CUPS_CSPACE_KCMYcm) + NumPlanes = 6; + else + NumPlanes = 1; + + Feed = 0; /* No blank lines yet */ + + /* + * Allocate memory for a line/row of graphics... + */ + + Planes[0] = malloc(header->cupsBytesPerLine); + for (plane = 1; plane < NumPlanes; plane ++) + Planes[plane] = Planes[0] + plane * header->cupsBytesPerLine / NumPlanes; + + if (header->cupsCompression || DotBytes) + CompBuffer = calloc(2, header->cupsWidth); + + if (DotBytes) + { + LineBuffers[0] = calloc(DotBytes, header->cupsWidth * (Shingling + 1)); + LineBuffers[1] = LineBuffers[0] + DotBytes * header->cupsWidth; + DotBit = 128; + LineCount = 0; + EvenOffset = 0; + OddOffset = 0; + } +} + + +/* + * 'EndPage()' - Finish a page of graphics. + */ + +void +EndPage(const cups_page_header_t *header) /* I - Page header */ +{ + if (DotBytes) + { + /* + * Flush remaining graphics as needed... + */ + + if (!Shingling) + OutputRows(header, 0); + else if (OddOffset > EvenOffset) + { + OutputRows(header, 1); + OutputRows(header, 0); + } + else + { + OutputRows(header, 0); + OutputRows(header, 1); + } + } + + /* + * Eject the current page... + */ + + putchar(12); /* Form feed */ + + /* + * Free memory... + */ + + free(Planes[0]); + + if (header->cupsCompression || DotBytes) + free(CompBuffer); + + if (DotBytes) + free(LineBuffers[0]); +} + + +/* + * 'Shutdown()' - Shutdown the printer. + */ + +void +Shutdown(void) +{ + /* + * Send a reset sequence. + */ + + printf("\033@"); +} + + +/* + * 'CompressData()' - Compress a line of graphics. + */ + +void +CompressData(const unsigned char *line, /* I - Data to compress */ + int length,/* I - Number of bytes */ + int plane, /* I - Color plane */ + int type, /* I - Type of compression */ + int xstep, /* I - X resolution */ + int ystep) /* I - Y resolution */ +{ + const unsigned char *line_ptr, /* Current byte pointer */ + *line_end, /* End-of-line byte pointer */ + *start; /* Start of compression sequence */ + unsigned char *comp_ptr, /* Pointer into compression buffer */ + temp; /* Current byte */ + int count; /* Count of bytes for output */ + static int ctable[6] = { 0, 2, 1, 4, 2, 1 }; + /* KCMYcm color values */ + + + /* + * Setup pointers... + */ + + line_ptr = line; + line_end = line + length; + + /* + * Do depletion for 720 DPI printing... + */ + + if (ystep == 5) + { + for (comp_ptr = (unsigned char *)line; comp_ptr < line_end;) + { + /* + * Grab the current byte... + */ + + temp = *comp_ptr; + + /* + * Check adjacent bits... + */ + + if ((temp & 0xc0) == 0xc0) + temp &= 0xbf; + if ((temp & 0x60) == 0x60) + temp &= 0xdf; + if ((temp & 0x30) == 0x30) + temp &= 0xef; + if ((temp & 0x18) == 0x18) + temp &= 0xf7; + if ((temp & 0x0c) == 0x0c) + temp &= 0xfb; + if ((temp & 0x06) == 0x06) + temp &= 0xfd; + if ((temp & 0x03) == 0x03) + temp &= 0xfe; + + *comp_ptr++ = temp; + + /* + * Check the last bit in the current byte and the first bit in the + * next byte... + */ + + if ((temp & 0x01) && comp_ptr < line_end && *comp_ptr & 0x80) + *comp_ptr &= 0x7f; + } + } + + switch (type) + { + case 0 : + /* + * Do no compression... + */ + break; + + case 1 : + /* + * Do TIFF pack-bits encoding... + */ + + comp_ptr = CompBuffer; + + while (line_ptr < line_end) + { + if ((line_ptr + 1) >= line_end) + { + /* + * Single byte on the end... + */ + + *comp_ptr++ = 0x00; + *comp_ptr++ = *line_ptr++; + } + else if (line_ptr[0] == line_ptr[1]) + { + /* + * Repeated sequence... + */ + + line_ptr ++; + count = 2; + + while (line_ptr < (line_end - 1) && + line_ptr[0] == line_ptr[1] && + count < 127) + { + line_ptr ++; + count ++; + } + + *comp_ptr++ = 257 - count; + *comp_ptr++ = *line_ptr++; + } + else + { + /* + * Non-repeated sequence... + */ + + start = line_ptr; + line_ptr ++; + count = 1; + + while (line_ptr < (line_end - 1) && + line_ptr[0] != line_ptr[1] && + count < 127) + { + line_ptr ++; + count ++; + } + + *comp_ptr++ = count - 1; + + memcpy(comp_ptr, start, count); + comp_ptr += count; + } + } + + line_ptr = CompBuffer; + line_end = comp_ptr; + break; + } + + /* + * Set the color if necessary... + */ + + if (NumPlanes > 1) + { + if (plane > 3) + printf("\033(r%c%c%c%c", 2, 0, 1, ctable[plane]); + /* Set extended color */ + else if (NumPlanes == 3) + printf("\033r%c", ctable[plane + 1]); + /* Set color */ + else + printf("\033r%c", ctable[plane]); /* Set color */ + } + + /* + * Send a raster plane... + */ + + putchar(0x0d); /* Move print head to left margin */ + + length *= 8; + printf("\033."); /* Raster graphics */ + putchar(type); + putchar(ystep); + putchar(xstep); + putchar(1); + putchar(length); + putchar(length >> 8); + + pwrite(line_ptr, line_end - line_ptr); +} + + +/* + * 'OutputLine()' - Output a line of graphics. + */ + +void +OutputLine(const cups_page_header_t *header) /* I - Page header */ +{ + if (header->cupsRowCount) + { + int width; + unsigned char *tempptr, + *evenptr, + *oddptr; + register int x; + unsigned char bit; + const unsigned char *pixel; + unsigned char *temp; + + + /* + * Collect bitmap data in the line buffers and write after each buffer. + */ + + for (x = header->cupsWidth, bit = 128, pixel = Planes[0], + temp = CompBuffer; + x > 0; + x --, temp ++) + { + if (*pixel & bit) + *temp |= DotBit; + + if (bit > 1) + bit >>= 1; + else + { + bit = 128; + pixel ++; + } + } + + if (DotBit > 1) + DotBit >>= 1; + else + { + /* + * Copy the holding buffer to the output buffer, shingling as necessary... + */ + + if (Shingling && LineCount != 0) + { + /* + * Shingle the output... + */ + + if (LineCount & 1) + { + evenptr = LineBuffers[1] + OddOffset; + oddptr = LineBuffers[0] + EvenOffset + DotBytes; + } + else + { + evenptr = LineBuffers[0] + EvenOffset; + oddptr = LineBuffers[1] + OddOffset + DotBytes; + } + + for (width = header->cupsWidth, tempptr = CompBuffer; + width > 0; + width -= 2, tempptr += 2, oddptr += DotBytes * 2, + evenptr += DotBytes * 2) + { + evenptr[0] = tempptr[0]; + oddptr[0] = tempptr[1]; + } + } + else + { + /* + * Don't shingle the output... + */ + + for (width = header->cupsWidth, tempptr = CompBuffer, + evenptr = LineBuffers[0] + EvenOffset; + width >= 0; + width --, tempptr ++, evenptr += DotBytes) + *evenptr = tempptr[0]; + } + + if (Shingling && LineCount != 0) + { + EvenOffset ++; + OddOffset ++; + + if (EvenOffset == DotBytes) + { + EvenOffset = 0; + OutputRows(header, 0); + } + + if (OddOffset == DotBytes) + { + OddOffset = 0; + OutputRows(header, 1); + } + } + else + { + EvenOffset ++; + + if (EvenOffset == DotBytes) + { + EvenOffset = 0; + OutputRows(header, 0); + } + } + + DotBit = 128; + LineCount ++; + + memset(CompBuffer, 0, header->cupsWidth); + } + } + else + { + int plane; /* Current plane */ + int bytes; /* Bytes per plane */ + int xstep, ystep; /* X & Y resolutions */ + + + /* + * Write a single line of bitmap data as needed... + */ + + xstep = 3600 / header->HWResolution[0]; + ystep = 3600 / header->HWResolution[1]; + bytes = header->cupsBytesPerLine / NumPlanes; + + for (plane = 0; plane < NumPlanes; plane ++) + { + /* + * Skip blank data... + */ + + if (!Planes[plane][0] && + memcmp(Planes[plane], Planes[plane] + 1, bytes - 1) == 0) + continue; + + /* + * Output whitespace as needed... + */ + + if (Feed > 0) + { + pwrite("\033(v\002\000", 5); /* Relative vertical position */ + putchar(Feed); + putchar(Feed >> 8); + + Feed = 0; + } + + CompressData(Planes[plane], bytes, plane, header->cupsCompression, xstep, + ystep); + } + + Feed ++; + } +} + + +/* + * 'OutputRows()' - Output 8, 24, or 48 rows. + */ + +void +OutputRows(const cups_page_header_t *header, /* I - Page image header */ + int row) /* I - Row number (0 or 1) */ +{ + unsigned i, n; /* Looping vars */ + int dot_count, /* Number of bytes to print */ + dot_min; /* Minimum number of bytes */ + unsigned char *dot_ptr; /* Pointer to print data */ + + + dot_min = DotBytes * DotColumns; + + if (LineBuffers[row][0] != 0 || + memcmp(LineBuffers[row], LineBuffers[row] + 1, + header->cupsWidth * DotBytes - 1)) + { + /* + * Skip leading space... + */ + + i = 0; + dot_count = header->cupsWidth * DotBytes; + dot_ptr = LineBuffers[row]; + + while (dot_count >= dot_min && dot_ptr[0] == 0 && + memcmp(dot_ptr, dot_ptr + 1, dot_min - 1) == 0) + { + i ++; + dot_ptr += dot_min; + dot_count -= dot_min; + } + + /* + * Skip trailing space... + */ + + while (dot_count >= dot_min && dot_ptr[dot_count - dot_min] == 0 && + memcmp(dot_ptr + dot_count - dot_min, + dot_ptr + dot_count - dot_min + 1, dot_min - 1) == 0) + dot_count -= dot_min; + + /* + * Position print head for printing... + */ + + putchar(0x1b); + putchar('$'); + putchar(i & 255); + putchar(i >> 8); + + /* + * Start bitmap graphics for this line... + */ + + printf("\033*"); /* Select bit image */ + switch (header->HWResolution[0]) + { + case 60 : /* 60x60/72 DPI gfx */ + putchar(0); + break; + case 120 : /* 120x60/72 DPI gfx */ + putchar(1); + break; + case 180 : /* 180 DPI gfx */ + putchar(39); + break; + case 240 : /* 240x72 DPI gfx */ + putchar(3); + break; + case 360 : /* 360x180/360 DPI gfx */ + if (header->HWResolution[1] == 180) + { + if (Shingling && LineCount != 0) + putchar(40); /* 360x180 fast */ + else + putchar(41); /* 360x180 slow */ + } + else + { + if (Shingling && LineCount != 0) + putchar(72); /* 360x360 fast */ + else + putchar(73); /* 360x360 slow */ + } + break; + } + + n = (unsigned)dot_count / DotBytes; + putchar(n & 255); + putchar(n / 256); + + /* + * Write the graphics data... + */ + + pwrite(dot_ptr, dot_count); + } + + /* + * Feed the paper... + */ + + putchar('\n'); + + if (Shingling && row == 1) + { + if (header->HWResolution[1] == 360) + printf("\n\n\n\n"); + else + printf("\n"); + } + + /* + * Clear the buffer... + */ + + memset(LineBuffers[row], 0, header->cupsWidth * DotBytes); +} + + +/* + * 'main()' - Main entry and processing of driver. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int fd; /* File descriptor */ + cups_raster_t *ras; /* Raster stream for printing */ + cups_page_header_t header; /* Page header from file */ + ppd_file_t *ppd; /* PPD file */ + int page; /* Current page */ + int y; /* Current line */ + + + /* + * Check for valid arguments... + */ + + if (argc < 6 || argc > 7) + { + /* + * We don't have the correct number of arguments; write an error message + * and return. + */ + + fputs("ERROR: rastertoepson job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * Open the page stream... + */ + + if (argc == 7) + { + if ((fd = open(argv[6], O_RDONLY)) == -1) + { + perror("ERROR: Unable to open raster file - "); + sleep(1); + return (1); + } + } + else + fd = 0; + + ras = cupsRasterOpen(fd, CUPS_RASTER_READ); + + /* + * Initialize the print device... + */ + + ppd = ppdOpenFile(getenv("PPD")); + + Setup(); + + /* + * Process pages as needed... + */ + + page = 0; + + while (cupsRasterReadHeader(ras, &header)) + { + /* + * Write a status message with the page number and number of copies. + */ + + page ++; + + fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies); + + /* + * Start the page... + */ + + StartPage(ppd, &header); + + /* + * Loop for each line on the page... + */ + + for (y = 0; y < header.cupsHeight; y ++) + { + /* + * Let the user know how far we have progressed... + */ + + if ((y & 127) == 0) + fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", page, + 100 * y / header.cupsHeight); + + /* + * Read a line of graphics... + */ + + if (cupsRasterReadPixels(ras, Planes[0], header.cupsBytesPerLine) < 1) + break; + + /* + * Write it to the printer... + */ + + OutputLine(&header); + } + + /* + * Eject the page... + */ + + EndPage(&header); + } + + /* + * Shutdown the printer... + */ + + Shutdown(); + + ppdClose(ppd); + + /* + * Close the raster stream... + */ + + cupsRasterClose(ras); + if (fd != 0) + close(fd); + + /* + * If no pages were printed, send an error message... + */ + + if (page == 0) + fputs("ERROR: No pages found!\n", stderr); + else + fputs("INFO: Ready to print.\n", stderr); + + return (page == 0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/rastertohp.c b/filter/rastertohp.c new file mode 100644 index 0000000000..b8c6f02066 --- /dev/null +++ b/filter/rastertohp.c @@ -0,0 +1,566 @@ +/* + * "$Id$" + * + * Hewlett-Packard Page Control Language filter for the Common UNIX + * Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * Setup() - Prepare the printer for printing. + * StartPage() - Start a page of graphics. + * EndPage() - Finish a page of graphics. + * Shutdown() - Shutdown the printer. + * CompressData() - Compress a line of graphics. + * OutputLine() - Output a line of graphics. + * main() - Main entry and processing of driver. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include "raster.h" +#include +#include +#include + + +/* + * Globals... + */ + +unsigned char *Planes[4], /* Output buffers */ + *CompBuffer; /* Compression buffer */ +int NumPlanes, /* Number of color planes */ + Feed; /* Number of lines to skip */ + + +/* + * Prototypes... + */ + +void Setup(void); +void StartPage(cups_page_header_t *header); +void EndPage(cups_page_header_t *header); +void Shutdown(void); + +void CompressData(unsigned char *line, int length, int plane, int type); +void OutputLine(cups_page_header_t *header); + + +/* + * 'Setup()' - Prepare the printer for printing. + */ + +void +Setup(void) +{ + /* + * Send a PCL reset sequence. + */ + + putchar(0x1b); + putchar('E'); +} + + +/* + * 'StartPage()' - Start a page of graphics. + */ + +void +StartPage(cups_page_header_t *header) /* I - Page header */ +{ + int plane; /* Looping var */ + + + /* + * Set the media type, position, and size... + */ + + printf("\033&l6D\033&k12H"); /* Set 6 LPI, 10 CPI */ + + switch (header->PageSize[1]) + { + case 540 : /* Monarch Envelope */ + printf("\033&l80A"); /* Set page size */ + break; + + case 624 : /* DL Envelope */ + printf("\033&l90A"); /* Set page size */ + break; + + case 649 : /* C5 Envelope */ + printf("\033&l91A"); /* Set page size */ + break; + + case 684 : /* COM-10 Envelope */ + printf("\033&l81A"); /* Set page size */ + break; + + case 709 : /* B5 Envelope */ + printf("\033&l100A"); /* Set page size */ + break; + + case 756 : /* Executive */ + printf("\033&l1A"); /* Set page size */ + break; + + case 792 : /* Letter */ + printf("\033&l2A"); /* Set page size */ + break; + + case 842 : /* A4 */ + printf("\033&l26A"); /* Set page size */ + break; + + case 1008 : /* Legal */ + printf("\033&l3A"); /* Set page size */ + break; + + case 1191 : /* A3 */ + printf("\033&l27A"); /* Set page size */ + break; + + case 1224 : /* Tabloid */ + printf("\033&l6A"); /* Set page size */ + break; + } + + printf("\033&l%dP", header->PageSize[1] / 12);/* Set page length */ + printf("\033&l0E"); /* Set top margin to 0 */ + + printf("\033&l%dX", header->NumCopies); /* Set number copies */ + + if (header->MediaPosition) + printf("\033&l%dH", header->MediaPosition); /* Set media position */ + + if (header->cupsMediaType) + printf("\033&l%dM", /* Set media type */ + header->cupsMediaType); + + if (header->Duplex) + printf("\033&l%dS", /* Set duplex mode */ + header->Duplex + header->Tumble); + + printf("\033&l0L"); /* Turn off perforation skip */ + + /* + * Set graphics mode... + */ + + printf("\033*t%dR", header->HWResolution[0]); /* Set resolution */ + printf("\033*r%dS", header->cupsWidth); /* Set width */ + printf("\033*r%dT", header->cupsHeight); /* Set height */ + + if (header->cupsColorSpace == CUPS_CSPACE_KCMY) + { + NumPlanes = 4; + printf("\033*r-4U"); /* Set KCMY graphics */ + } + else if (header->cupsColorSpace == CUPS_CSPACE_CMY) + { + NumPlanes = 3; + printf("\033*r-3U"); /* Set CMY graphics */ + } + else + NumPlanes = 1; /* Black&white graphics */ + + printf("\033&a0H\033&a330V"); /* Set top-of-page */ + printf("\033*r1A"); /* Start graphics */ + + if (header->cupsCompression) + printf("\033*b%dM", /* Set compression */ + header->cupsCompression); + + Feed = 0; /* No blank lines yet */ + + /* + * Allocate memory for a line of graphics... + */ + + Planes[0] = malloc(header->cupsBytesPerLine); + for (plane = 1; plane < NumPlanes; plane ++) + Planes[plane] = Planes[0] + plane * header->cupsBytesPerLine / NumPlanes; + + if (header->cupsCompression) + CompBuffer = malloc(header->cupsBytesPerLine * 2); +} + + +/* + * 'EndPage()' - Finish a page of graphics. + */ + +void +EndPage(cups_page_header_t *header) /* I - Page header */ +{ + /* + * Eject the current page... + */ + + if (NumPlanes > 1) + { + printf("\033*rC"); /* End color GFX */ + printf("\033&l0H"); /* Eject current page */ + } + else + { + printf("\033*r0B"); /* End GFX */ + printf("\014"); /* Eject currnet page */ + } + + /* + * Free memory... + */ + + free(Planes[0]); + + if (header->cupsCompression) + free(CompBuffer); +} + + +/* + * 'Shutdown()' - Shutdown the printer. + */ + +void +Shutdown(void) +{ + /* + * Send a PCL reset sequence. + */ + + putchar(0x1b); + putchar('E'); +} + + +/* + * 'CompressData()' - Compress a line of graphics. + */ + +void +CompressData(unsigned char *line, /* I - Data to compress */ + int length, /* I - Number of bytes */ + int plane, /* I - Color plane */ + int type) /* I - Type of compression */ +{ + unsigned char *line_ptr, /* Current byte pointer */ + *line_end, /* End-of-line byte pointer */ + *comp_ptr, /* Pointer into compression buffer */ + *start; /* Start of compression sequence */ + int count; /* Count of bytes for output */ + + + switch (type) + { + default : + /* + * Do no compression... + */ + + line_ptr = line; + line_end = line + length; + break; + + case 1 : + /* + * Do run-length encoding... + */ + + line_end = line + length; + for (line_ptr = line, comp_ptr = CompBuffer; + line_ptr < line_end; + comp_ptr += 2, line_ptr += count) + { + for (count = 1; + (line_ptr + count) < line_end && + line_ptr[0] == line_ptr[count] && + count < 256; + count ++); + + comp_ptr[0] = count - 1; + comp_ptr[1] = line_ptr[0]; + } + + line_ptr = CompBuffer; + line_end = comp_ptr; + break; + + case 2 : + /* + * Do TIFF pack-bits encoding... + */ + + line_ptr = line; + line_end = line + length; + comp_ptr = CompBuffer; + + while (line_ptr < line_end) + { + if ((line_ptr + 1) >= line_end) + { + /* + * Single byte on the end... + */ + + *comp_ptr++ = 0x00; + *comp_ptr++ = *line_ptr++; + } + else if (line_ptr[0] == line_ptr[1]) + { + /* + * Repeated sequence... + */ + + line_ptr ++; + count = 2; + + while (line_ptr < (line_end - 1) && + line_ptr[0] == line_ptr[1] && + count < 127) + { + line_ptr ++; + count ++; + } + + *comp_ptr++ = 257 - count; + *comp_ptr++ = *line_ptr++; + } + else + { + /* + * Non-repeated sequence... + */ + + start = line_ptr; + line_ptr ++; + count = 1; + + while (line_ptr < (line_end - 1) && + line_ptr[0] != line_ptr[1] && + count < 127) + { + line_ptr ++; + count ++; + } + + *comp_ptr++ = count - 1; + + memcpy(comp_ptr, start, count); + comp_ptr += count; + } + } + + line_ptr = CompBuffer; + line_end = comp_ptr; + break; + } + + /* + * Set the length of the data and write a raster plane... + */ + + printf("\033*b%d%c", line_end - line_ptr, plane); + fwrite(line_ptr, line_end - line_ptr, 1, stdout); +} + + +/* + * 'OutputLine()' - Output a line of graphics. + */ + +void +OutputLine(cups_page_header_t *header) /* I - Page header */ +{ + int plane; /* Current plane */ + + + /* + * Output whitespace as needed... + */ + + if (Feed > 0) + { + printf("\033*b%dY", Feed); + Feed = 0; + } + + /* + * Write bitmap data as needed... + */ + + for (plane = 0; plane < NumPlanes; plane ++) + CompressData(Planes[plane], header->cupsBytesPerLine / NumPlanes, + plane < (NumPlanes - 1) ? 'V' : 'W', + header->cupsCompression); +} + + +/* + * 'main()' - Main entry and processing of driver. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + int fd; /* File descriptor */ + cups_raster_t *ras; /* Raster stream for printing */ + cups_page_header_t header; /* Page header from file */ + int page; /* Current page */ + int y; /* Current line */ + + + /* + * Check for valid arguments... + */ + + if (argc < 6 || argc > 7) + { + /* + * We don't have the correct number of arguments; write an error message + * and return. + */ + + fputs("ERROR: rastertopcl job-id user title copies options [file]\n", stderr); + return (1); + } + + /* + * Open the page stream... + */ + + if (argc == 7) + { + if ((fd = open(argv[6], O_RDONLY)) == -1) + { + perror("ERROR: Unable to open raster file - "); + sleep(1); + return (1); + } + } + else + fd = 0; + + ras = cupsRasterOpen(fd, CUPS_RASTER_READ); + + /* + * Initialize the print device... + */ + + Setup(); + + /* + * Process pages as needed... + */ + + page = 0; + + while (cupsRasterReadHeader(ras, &header)) + { + /* + * Write a status message with the page number and number of copies. + */ + + page ++; + + fprintf(stderr, "PAGE: %d %d\n", page, header.NumCopies); + + /* + * Start the page... + */ + + StartPage(&header); + + /* + * Loop for each line on the page... + */ + + for (y = 0; y < header.cupsHeight; y ++) + { + /* + * Let the user know how far we have progressed... + */ + + if ((y & 127) == 0) + fprintf(stderr, "INFO: Printing page %d, %d%% complete...\n", page, + 100 * y / header.cupsHeight); + + /* + * Read a line of graphics... + */ + + if (cupsRasterReadPixels(ras, Planes[0], header.cupsBytesPerLine) < 1) + break; + + /* + * See if the line is blank; if not, write it to the printer... + */ + + if (Planes[0][0] || + memcmp(Planes[0], Planes[0] + 1, header.cupsBytesPerLine - 1)) + OutputLine(&header); + else + Feed ++; + } + + /* + * Eject the page... + */ + + EndPage(&header); + } + + /* + * Shutdown the printer... + */ + + Shutdown(); + + /* + * Close the raster stream... + */ + + cupsRasterClose(ras); + if (fd != 0) + close(fd); + + /* + * If no pages were printed, send an error message... + */ + + if (page == 0) + fputs("ERROR: No pages found!\n", stderr); + else + fputs("INFO: Ready to print.\n", stderr); + + return (page == 0); +} + + +/* + * End of "$Id$". + */ diff --git a/filter/textcommon.c b/filter/textcommon.c new file mode 100644 index 0000000000..c1366c7868 --- /dev/null +++ b/filter/textcommon.c @@ -0,0 +1,748 @@ +/* + * "$Id$" + * + * Common text filter routines for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * TextMain() - Standard main entry for text filters. + * compare_keywords() - Compare two C/C++ keywords. + * getutf8() - Get a UTF-8 encoded wide character... + */ + +/* + * Include necessary headers... + */ + +#include "textcommon.h" + + +/* + * Globals... + */ + +int WrapLines = 1, /* Wrap text in lines */ + SizeLines = 60, /* Number of lines on a page */ + SizeColumns = 80, /* Number of columns on a line */ + PageColumns = 1, /* Number of columns on a page */ + ColumnGutter = 0, /* Number of characters between text columns */ + ColumnWidth = 80, /* Width of each column */ + PrettyPrint = 0, /* Do pretty code formatting */ + Copies = 1; /* Number of copies */ +lchar_t **Page = NULL; /* Page characters */ +int NumPages = 0; /* Number of pages in document */ +int CharsPerInch = 10; /* Number of character columns per inch */ +int LinesPerInch = 6; /* Number of lines per inch */ +int UTF8 = 0; /* Use UTF-8 encoding? */ +char *Keywords[] = /* List of known keywords... */ + { + "and", + "and_eq", + "asm", + "auto", + "bitand", + "bitor", + "bool", + "break", + "case", + "catch", + "char", + "class", + "compl", + "const", + "continue", + "default", + "delete", + "do", + "double", + "else", + "enum", + "explicit", + "extern", + "false", + "float", + "for", + "friend", + "goto", + "if", + "inline", + "int", + "long", + "mutable", + "namespace", + "new", + "not", + "not_eq", + "operator", + "or", + "or_eq", + "private", + "protected", + "public", + "register", + "return", + "short", + "signed", + "sizeof", + "static", + "struct", + "switch", + "template", + "this", + "throw", + "true", + "try", + "typedef", + "typename", + "union", + "unsigned", + "virtual", + "void", + "volatile", + "while", + "xor", + "xor_eq" + }; + + +/* + * Local functions... + */ + +static int compare_keywords(const void *, const void *); +static int getutf8(FILE *fp); + + +/* + * 'TextMain()' - Standard main entry for text filters. + */ + +int /* O - Exit status */ +TextMain(char *name, /* I - Name of filter */ + int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + FILE *fp; /* Print file */ + ppd_file_t *ppd; /* PPD file */ + int i, /* Looping var */ + ch, /* Current char from file */ + lastch, /* Previous char from file */ + attr, /* Current attribute */ + line, /* Current line */ + column, /* Current column */ + page_column; /* Current page column */ + int num_options; /* Number of print options */ + cups_option_t *options; /* Print options */ + const char *val; /* Option value */ + char keyword[64], /* Keyword string */ + *keyptr; /* Pointer into string */ + int keycol; /* Column where keyword starts */ + int ccomment; /* Inside a C-style comment? */ + int cstring; /* Inside a C string */ + + + if (argc < 6 || argc > 7) + { + fprintf(stderr, "ERROR: %s job-id user title copies options [file]\n", + name); + return (1); + } + + /* + * If we have 7 arguments, print the file named on the command-line. + * Otherwise, send stdin instead... + */ + + if (argc == 6) + fp = stdin; + else + { + /* + * Try to open the print file... + */ + + if ((fp = fopen(argv[6], "rb")) == NULL) + { + perror("ERROR: unable to open print file - "); + return (1); + } + } + + /* + * Process command-line options and write the prolog... + */ + + options = NULL; + num_options = cupsParseOptions(argv[5], 0, &options); + + if ((val = cupsGetOption("prettyprint", num_options, options)) != NULL) + { + PrettyPrint = 1; + PageLeft = 72.0f; + PageRight = PageWidth - 36.0f; + PageBottom = PageBottom > 36.0f ? PageBottom : 36.0f; + PageTop = PageLength - 36.0f; + CharsPerInch = 12; + LinesPerInch = 8; + } + + ppd = SetCommonOptions(num_options, options, 1); + + WrapLines = cupsGetOption("nowrap", num_options, options) == NULL; + + if ((val = cupsGetOption("columns", num_options, options)) != NULL) + PageColumns = atoi(val); + + if ((val = cupsGetOption("cpi", num_options, options)) != NULL) + CharsPerInch = atoi(val); + + if ((val = cupsGetOption("lpi", num_options, options)) != NULL) + LinesPerInch = atoi(val); + + if ((val = cupsGetOption("prettyprint", num_options, options)) != NULL) + PageTop -= 216.0f / LinesPerInch; + + Copies = atoi(argv[4]); + + WriteProlog(argv[3], argv[2], ppd); + + /* + * Read text from the specified source and print it... + */ + + lastch = 0; + column = 0; + line = 0; + page_column = 0; + attr = 0; + keyptr = keyword; + keycol = 0; + ccomment = 0; + cstring = 0; + + while ((ch = getutf8(fp)) >= 0) + { + /* + * Control codes: + * + * BS Backspace (0x08) + * HT Horizontal tab; next 8th column (0x09) + * LF Line feed; forward full line (0x0a) + * VT Vertical tab; reverse full line (0x0b) + * FF Form feed (0x0c) + * CR Carriage return (0x0d) + * ESC 7 Reverse full line (0x1b 0x37) + * ESC 8 Reverse half line (0x1b 0x38) + * ESC 9 Forward half line (0x1b 0x39) + */ + + switch (ch) + { + case 0x08 : /* BS - backspace for boldface & underline */ + if (column > 0) + column --; + + keyptr = keyword; + keycol = column; + break; + + case 0x09 : /* HT - tab to next 8th column */ + if (PrettyPrint && keyptr > keyword) + { + *keyptr = '\0'; + keyptr = keyword; + + if (bsearch(&keyptr, Keywords, sizeof(Keywords) / sizeof(Keywords[0]), + sizeof(Keywords[0]), compare_keywords)) + { + /* + * Put keywords in boldface... + */ + + i = page_column * (ColumnWidth + ColumnGutter); + + while (keycol < column) + { + Page[line][keycol + i].attr |= ATTR_BOLD; + keycol ++; + } + } + } + + column = (column + 8) & ~7; + + if (column >= ColumnWidth && WrapLines) + { /* Wrap text to margins */ + line ++; + column = 0; + + if (line >= SizeLines) + { + page_column ++; + line = 0; + + if (page_column >= PageColumns) + { + WritePage(); + page_column = 0; + } + } + } + + keycol = column; + break; + + case 0x0a : /* LF - output current line */ + if (PrettyPrint && keyptr > keyword) + { + *keyptr = '\0'; + keyptr = keyword; + + if (bsearch(&keyptr, Keywords, sizeof(Keywords) / sizeof(Keywords[0]), + sizeof(Keywords[0]), compare_keywords)) + { + /* + * Put keywords in boldface... + */ + + i = page_column * (ColumnWidth + ColumnGutter); + + while (keycol < column) + { + Page[line][keycol + i].attr |= ATTR_BOLD; + keycol ++; + } + } + } + + line ++; + column = 0; + keycol = 0; + + if (!ccomment && !cstring) + attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE); + + if (line >= SizeLines) + { + page_column ++; + line = 0; + + if (page_column >= PageColumns) + { + WritePage(); + page_column = 0; + } + } + break; + + case 0x0b : /* VT - move up 1 line */ + if (line > 0) + line --; + + keyptr = keyword; + keycol = column; + + if (!ccomment && !cstring) + attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE); + break; + + case 0x0c : /* FF - eject current page... */ + if (PrettyPrint && keyptr > keyword) + { + *keyptr = '\0'; + keyptr = keyword; + + if (bsearch(&keyptr, Keywords, sizeof(Keywords) / sizeof(Keywords[0]), + sizeof(Keywords[0]), compare_keywords)) + { + /* + * Put keywords in boldface... + */ + + i = page_column * (ColumnWidth + ColumnGutter); + + while (keycol < column) + { + Page[line][keycol + i].attr |= ATTR_BOLD; + keycol ++; + } + } + } + + page_column ++; + column = 0; + keycol = 0; + line = 0; + + if (!ccomment && !cstring) + attr &= ~(ATTR_ITALIC | ATTR_BOLD | ATTR_RED | ATTR_GREEN | ATTR_BLUE); + + if (page_column >= PageColumns) + { + WritePage(); + page_column = 0; + } + break; + + case 0x0d : /* CR */ + column = 0; + break; + + case 0x1b : /* Escape sequence */ + ch = getutf8(fp); + if (ch == '7') + { + /* + * ESC 7 Reverse full line (0x1b 0x37) + */ + + if (line > 0) + line --; + } + else if (ch == '8') + { + /* + * ESC 8 Reverse half line (0x1b 0x38) + */ + + if ((attr & ATTR_RAISED) && line > 0) + { + attr &= ~ATTR_RAISED; + line --; + } + else if (attr & ATTR_LOWERED) + attr &= ~ATTR_LOWERED; + else + attr |= ATTR_RAISED; + } + else if (ch == '9') + { + /* + * ESC 9 Forward half line (0x1b 0x39) + */ + + if ((attr & ATTR_LOWERED) && line < (SizeLines - 1)) + { + attr &= ~ATTR_LOWERED; + line ++; + } + else if (attr & ATTR_RAISED) + attr &= ~ATTR_RAISED; + else + attr |= ATTR_LOWERED; + } + break; + + default : /* All others... */ + if (ch < ' ') + break; /* Ignore other control chars */ + + if (PrettyPrint) + { + /* + * Do highlighting of C/C++ keywords, preprocessor commands, + * and comments... + */ + + if ((ch == ' ' || ch == '\t') && (attr & ATTR_BOLD)) + { + /* + * Stop bolding preprocessor command... + */ + + attr &= ~ATTR_BOLD; + } + else if (!(isalnum(ch) || ch == '_') && keyptr > keyword) + { + /* + * Look for a keyword... + */ + + *keyptr = '\0'; + keyptr = keyword; + + if (!(attr & ATTR_ITALIC) && + bsearch(&keyptr, Keywords, sizeof(Keywords) / sizeof(Keywords[0]), + sizeof(Keywords[0]), compare_keywords)) + { + /* + * Put keywords in boldface... + */ + + i = page_column * (ColumnWidth + ColumnGutter); + + while (keycol < column) + { + Page[line][keycol + i].attr |= ATTR_BOLD; + keycol ++; + } + } + } + else if ((isalnum(ch) || ch == '_') && !ccomment && !cstring) + { + /* + * Add characters to the current keyword (if they'll fit). + */ + + if (keyptr == keyword) + keycol = column; + + if (keyptr < (keyword + sizeof(keyword) - 1)) + *keyptr++ = ch; + } + else if (ch == '\"' && lastch != '\\' && !ccomment && !cstring) + { + /* + * Start a C string constant... + */ + + cstring = -1; + attr |= ATTR_BLUE; + } + else if (ch == '*' && lastch == '/' && !cstring) + { + /* + * Start a C-style comment... + */ + + ccomment = 1; + attr |= ATTR_ITALIC | ATTR_GREEN; + } + else if (ch == '/' && lastch == '/' && !cstring) + { + /* + * Start a C++-style comment... + */ + + attr |= ATTR_ITALIC | ATTR_GREEN; + } + else if (ch == '#' && column == 0 && !ccomment && !cstring) + { + /* + * Start a preprocessor command... + */ + + attr |= ATTR_BOLD | ATTR_RED; + } + } + + if (column >= ColumnWidth && WrapLines) + { /* Wrap text to margins */ + column = 0; + line ++; + + if (line >= SizeLines) + { + page_column ++; + line = 0; + + if (page_column >= PageColumns) + { + WritePage(); + page_column = 0; + } + } + } + + /* + * Add text to the current column & line... + */ + + if (column < ColumnWidth) + { + i = column + page_column * (ColumnWidth + ColumnGutter); + + if (PrettyPrint) + Page[line][i].attr = attr; + else if (ch == Page[line][i].ch) + Page[line][i].attr |= ATTR_BOLD; + else if (Page[line][i].ch == '_') + Page[line][i].attr |= ATTR_UNDERLINE; + else + Page[line][i].attr = attr; + + Page[line][i].ch = ch; + } + + if (PrettyPrint) + { + if ((ch == '{' || ch == '}') && !ccomment && !cstring && + column < ColumnWidth) + { + /* + * Highlight curley braces... + */ + + Page[line][column].attr |= ATTR_BOLD; + } + else if ((ch == '/' || ch == '*') && lastch == '/' && + column < ColumnWidth) + { + /* + * Highlight first comment character... + */ + + Page[line][column - 1].attr = attr; + } + else if (ch == '\"' && lastch != '\\' && !ccomment && cstring > 0) + { + /* + * End a C string constant... + */ + + cstring = 0; + attr &= ~ATTR_BLUE; + } + else if (ch == '/' && lastch == '*' && ccomment) + { + /* + * End a C-style comment... + */ + + ccomment = 0; + attr &= ~(ATTR_ITALIC | ATTR_GREEN); + } + + if (cstring < 0) + cstring = 1; + } + + column ++; + break; + } + + /* + * Save this character for the next cycle. + */ + + lastch = ch; + } + + /* + * Write any remaining page data... + */ + + if (line > 0 || page_column > 0 || column > 0) + WritePage(); + + /* + * Write the epilog and return... + */ + + WriteEpilogue(); + + if (ppd != NULL) + ppdClose(ppd); + + return (0); +} + + +/* + * 'compare_keywords()' - Compare two C/C++ keywords. + */ + +static int /* O - Result of strcmp */ +compare_keywords(const void *k1, /* I - First keyword */ + const void *k2) /* I - Second keyword */ +{ + return (strcmp(*((const char **)k1), *((const char **)k2))); +} + + +/* + * 'getutf8()' - Get a UTF-8 encoded wide character... + */ + +static int /* O - Character or -1 on error */ +getutf8(FILE *fp) /* I - File to read from */ +{ + int ch; /* Current character value */ + int next; /* Next character from file */ + + + /* + * Read the first character and process things accordingly... + * + * UTF-8 maps 16-bit characters to: + * + * 0 to 127 = 0xxxxxxx + * 128 to 2047 = 110xxxxx 10yyyyyy (xxxxxyyyyyy) + * 2048 to 65535 = 1110xxxx 10yyyyyy 10zzzzzz (xxxxyyyyyyzzzzzz) + * + * We also accept: + * + * 128 to 191 = 10xxxxxx + * + * since this range of values is otherwise undefined unless you are + * in the middle of a multi-byte character... + * + * This code currently does not support anything beyond 16-bit + * characters, in part because PostScript doesn't support more than + * 16-bit characters... + */ + + if ((ch = getc(fp)) == EOF) + return (EOF); + + if (ch < 0xc0 || !UTF8) /* One byte character? */ + return (ch); + else if ((ch & 0xe0) == 0xc0) + { + /* + * Two byte character... + */ + + if ((next = getc(fp)) == EOF) + return (EOF); + else + return (((ch & 0x1f) << 6) | (next & 0x3f)); + } + else if ((ch & 0xf0) == 0xe0) + { + /* + * Three byte character... + */ + + if ((next = getc(fp)) == EOF) + return (EOF); + + ch = ((ch & 0x0f) << 6) | (next & 0x3f); + + if ((next = getc(fp)) == EOF) + return (EOF); + else + return ((ch << 6) | (next & 0x3f)); + } + else + { + /* + * More than three bytes... We don't support that... + */ + + return (EOF); + } +} + + +/* + * End of "$Id$". + */ diff --git a/filter/textcommon.h b/filter/textcommon.h new file mode 100644 index 0000000000..354ce7ae5a --- /dev/null +++ b/filter/textcommon.h @@ -0,0 +1,93 @@ +/* + * "$Id$" + * + * Common text filter definitions for the Common UNIX Printing System (CUPS). + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +/* + * Include necessary headers... + */ + +#include "common.h" + + +/* + * Constants... + */ + +#define ATTR_NORMAL 0x00 +#define ATTR_BOLD 0x01 +#define ATTR_ITALIC 0x02 +#define ATTR_BOLDITALIC 0x03 +#define ATTR_FONT 0x03 + +#define ATTR_UNDERLINE 0x04 +#define ATTR_RAISED 0x08 +#define ATTR_LOWERED 0x10 +#define ATTR_RED 0x20 +#define ATTR_GREEN 0x40 +#define ATTR_BLUE 0x80 + + +/* + * Structures... + */ + +typedef struct /**** Character/attribute structure... ****/ +{ + unsigned short ch, /* Character */ + attr; /* Any attributes */ +} lchar_t; + + +/* + * Globals... + */ + +extern int WrapLines, /* Wrap text in lines */ + SizeLines, /* Number of lines on a page */ + SizeColumns, /* Number of columns on a line */ + PageColumns, /* Number of columns on a page */ + ColumnGutter, /* Number of characters between text columns */ + ColumnWidth, /* Width of each column */ + PrettyPrint, /* Do pretty code formatting */ + Copies; /* Number of copies to produce */ +extern lchar_t **Page; /* Page characters */ +extern int NumPages; /* Number of pages in document */ +extern int CharsPerInch, /* Number of character columns per inch */ + LinesPerInch, /* Number of lines per inch */ + UTF8; /* Use UTF-8 encoding? */ +extern char *Keywords[]; /* List of known keywords... */ + + +/* + * Required functions... + */ + +extern int TextMain(char *name, int argc, char *argv[]); +extern void WriteEpilogue(void); +extern void WritePage(void); +extern void WriteProlog(char *title, char *user, ppd_file_t *ppd); + + +/* + * End of "$Id$". + */ diff --git a/filter/texttops.c b/filter/texttops.c new file mode 100644 index 0000000000..776d508c59 --- /dev/null +++ b/filter/texttops.c @@ -0,0 +1,1274 @@ +/* + * "$Id$" + * + * Text to PostScript filter for the Common UNIX Printing System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry for text to PostScript filter. + * WriteEpilogue() - Write the PostScript file epilogue. + * WritePage() - Write a page of text. + * WriteProlog() - Write the PostScript file prolog with options. + * write_line() - Write a row of text. + * write_string() - Write a string of text. + */ + +/* + * Include necessary headers... + */ + +#include "textcommon.h" + + +/* + * Globals... + */ + +char *Glyphs[65536]; /* PostScript glyphs for Unicode */ +int NumFonts; /* Number of fonts to use */ +char *Fonts[256][4]; /* Fonts to use */ +unsigned short Chars[65536]; /* 0xffcc (ff = font, cc = char) */ +unsigned short Codes[65536]; /* Unicode glyph mapping to fonts */ +int Widths[256]; /* Widths of each font */ +int Directions[256];/* Text directions for each font */ + + +/* + * Local functions... + */ + +static void write_line(int row, lchar_t *line); +static void write_string(int col, int row, int len, lchar_t *s); +static void write_text(char *s); + + +/* + * 'main()' - Main entry for text to PostScript filter. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + return (TextMain("texttops", argc, argv)); +} + + +/* + * 'WriteEpilogue()' - Write the PostScript file epilogue. + */ + +void +WriteEpilogue(void) +{ + puts("%%BeginTrailer"); + printf("%%%%Pages: %d\n", NumPages); + puts("%%EOF"); + + free(Page[0]); + free(Page); +} + + +/* + * 'WritePage()' - Write a page of text. + */ + +void +WritePage(void) +{ + int line; /* Current line */ + + + NumPages ++; + printf("%%%%Page: %d %d\n", NumPages, NumPages); + + puts("gsave"); + + if (PrettyPrint) + printf("%d H\n", NumPages); + + for (line = 0; line < SizeLines; line ++) + write_line(line, Page[line]); + + puts("grestore"); + puts("showpage"); + + memset(Page[0], 0, sizeof(lchar_t) * SizeColumns * SizeLines); +} + + +/* + * 'WriteProlog()' - Write the PostScript file prolog with options. + */ + +void +WriteProlog(char *title, /* I - Title of job */ + char *user, /* I - Username */ + ppd_file_t *ppd) /* I - PPD file info */ +{ + int i, j, k; /* Looping vars */ + char *charset; /* Character set string */ + char filename[1024]; /* Glyph filenames */ + FILE *fp; /* Glyph files */ + const char *datadir; /* CUPS_DATADIR environment variable */ + char line[1024], /* Line from file */ + *lineptr, /* Pointer into line */ + *valptr; /* Pointer to value in line */ + int ch, unicode; /* Character values */ + int start, end; /* Start and end values for range */ + char glyph[64]; /* Glyph name */ + time_t curtime; /* Current time */ + struct tm *curtm; /* Current date */ + char curdate[255]; /* Current date (text format) */ + int num_fonts; /* Number of unique fonts */ + char *fonts[1024]; /* Unique fonts */ + static char *names[] = /* Font names */ + { + "cupsNormal", + "cupsBold", + "cupsItalic" + }; + + + /* + * Get the data directory... + */ + + if ((datadir = getenv("CUPS_DATADIR")) == NULL) + datadir = CUPS_DATADIR; + + /* + * Allocate memory for the page... + */ + + SizeColumns = (PageRight - PageLeft) / 72.0 * CharsPerInch; + SizeLines = (PageTop - PageBottom) / 72.0 * LinesPerInch; + + Page = calloc(sizeof(lchar_t *), SizeLines); + Page[0] = calloc(sizeof(lchar_t), SizeColumns * SizeLines); + for (i = 1; i < SizeLines; i ++) + Page[i] = Page[0] + i * SizeColumns; + + if (PageColumns > 1) + { + ColumnGutter = CharsPerInch / 2; + ColumnWidth = (SizeColumns - ColumnGutter * (PageColumns - 1)) / + PageColumns; + } + else + ColumnWidth = SizeColumns; + + /* + * Output the DSC header... + */ + + curtime = time(NULL); + curtm = localtime(&curtime); + strftime(curdate, sizeof(curdate), "%c", curtm); + + puts("%!PS-Adobe-3.0"); + printf("%%%%BoundingBox: %.0f %.0f %.0f %.0f\n", PageLeft, PageBottom, + PageRight, PageTop); + if (Orientation & 1) + puts("%%Orientation: Landscape"); + puts("%%Creator: texttops/" CUPS_SVERSION); + printf("%%%%CreationDate: %s\n", curdate); + printf("%%%%Title: %s\n", title); + printf("%%%%For: %s\n", user); + puts("%%Pages: (atend)"); + + /* + * Initialize globals... + */ + + NumFonts = 0; + memset(Fonts, 0, sizeof(Fonts)); + memset(Glyphs, 0, sizeof(Glyphs)); + memset(Chars, 0, sizeof(Chars)); + memset(Codes, 0, sizeof(Codes)); + + /* + * Load the PostScript glyph names and the corresponding character + * set definition... + */ + + snprintf(filename, sizeof(filename), "%s/data/psglyphs", datadir); + + if ((fp = fopen(filename, "r")) != NULL) + { + while (fscanf(fp, "%x%63s", &unicode, glyph) == 2) + Glyphs[unicode] = strdup(glyph); + + fclose(fp); + } + else + { + fprintf(stderr, "ERROR: Unable to open \"%s\" - %s\n", filename, + strerror(errno)); + exit(1); + } + + /* + * Get the output character set... + */ + + charset = getenv("CHARSET"); + if (charset != NULL && strcmp(charset, "us-ascii") != 0) + { + snprintf(filename, sizeof(filename), "%s/charsets/%s", datadir, charset); + + if ((fp = fopen(filename, "r")) == NULL) + { + /* + * Can't open charset file! + */ + + fprintf(stderr, "ERROR: Unable to open %s: %s\n", filename, + strerror(errno)); + exit(1); + } + + /* + * Opened charset file; now see if this is really a charset file... + */ + + if (fgets(line, sizeof(line), fp) == NULL) + { + /* + * Bad/empty charset file! + */ + + fclose(fp); + fprintf(stderr, "ERROR: Bad/empty charset file %s\n", filename); + exit(1); + } + + if (strncmp(line, "charset", 7) != 0) + { + /* + * Bad format/not a charset file! + */ + + fclose(fp); + fprintf(stderr, "ERROR: Bad charset file %s\n", filename); + exit(1); + } + + /* + * See if this is an 8-bit or UTF-8 character set file... + */ + + line[strlen(line) - 1] = '\0'; /* Drop \n */ + for (lineptr = line + 7; isspace(*lineptr); lineptr ++); /* Skip whitespace */ + + if (strcmp(lineptr, "8bit") == 0) + { + /* + * 8-bit text... + */ + + UTF8 = 0; + NumFonts = 0; + + /* + * Read the font description(s)... + */ + + while (fgets(line, sizeof(line), fp) != NULL) + { + /* + * Skip comment and blank lines... + */ + + if (line[0] == '#' || line[0] == '\n') + continue; + + /* + * Read the font descriptions that should look like: + * + * first last direction width normal [bold italic bold-italic] + */ + + lineptr = line; + + start = strtol(lineptr, &lineptr, 16); + end = strtol(lineptr, &lineptr, 16); + + while (isspace(*lineptr)) + lineptr ++; + + if (!*lineptr) + break; /* Must be a font mapping */ + + valptr = lineptr; + + while (!isspace(*lineptr) && *lineptr) + lineptr ++; + + if (!*lineptr) + { + /* + * Can't have a font without all required values... + */ + + fprintf(stderr, "ERROR: bad font description line: %s\n", valptr); + fclose(fp); + exit(1); + } + + *lineptr++ = '\0'; + + if (strcmp(valptr, "ltor") == 0) + Directions[NumFonts] = 1; + else if (strcmp(valptr, "rtol") == 0) + Directions[NumFonts] = -1; + else + { + fprintf(stderr, "ERROR: Bad text direction %s\n", valptr); + fclose(fp); + exit(1); + } + + /* + * Got the direction, now get the width... + */ + + while (isspace(*lineptr)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr) && *lineptr) + lineptr ++; + + if (!*lineptr) + { + /* + * Can't have a font without all required values... + */ + + fprintf(stderr, "ERROR: bad font description line: %s\n", valptr); + fclose(fp); + exit(1); + } + + *lineptr++ = '\0'; + + if (strcmp(valptr, "single") == 0) + Widths[NumFonts] = 1; + else if (strcmp(valptr, "double") == 0) + Widths[NumFonts] = 2; + else + { + fprintf(stderr, "ERROR: Bad text width %s\n", valptr); + fclose(fp); + exit(1); + } + + /* + * Get the fonts... + */ + + for (i = 0; *lineptr && i < 4; i ++) + { + while (isspace(*lineptr)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr) && *lineptr) + lineptr ++; + + if (*lineptr) + *lineptr++ = '\0'; + + if (lineptr > valptr) + Fonts[NumFonts][i] = strdup(valptr); + } + + /* + * Fill in remaining fonts as needed... + */ + + for (j = i; j < 4; j ++) + Fonts[NumFonts][j] = strdup(Fonts[NumFonts][0]); + + /* + * Define the character mappings... + */ + + for (i = start, j = NumFonts * 256; i <= end; i ++, j ++) + Chars[i] = j; + + NumFonts ++; + } + + /* + * Read encoding lines... + */ + + do + { + /* + * Skip comment and blank lines... + */ + + if (line[0] == '#' || line[0] == '\n') + continue; + + /* + * Grab the character and unicode glyph number. + */ + + if (sscanf(line, "%x%x", &ch, &unicode) == 2 && ch < 256) + Codes[Chars[ch]] = unicode; + } + while (fgets(line, sizeof(line), fp) != NULL); + + fclose(fp); + } + else if (strcmp(lineptr, "utf8") == 0) + { + /* + * UTF-8 (Unicode) text... + */ + + UTF8 = 1; + + /* + * Read the font descriptions... + */ + + NumFonts = 0; + + while (fgets(line, sizeof(line), fp) != NULL) + { + /* + * Skip comment and blank lines... + */ + + if (line[0] == '#' || line[0] == '\n') + continue; + + /* + * Read the font descriptions that should look like: + * + * start end direction width normal [bold italic bold-italic] + */ + + lineptr = line; + + start = strtol(lineptr, &lineptr, 16); + end = strtol(lineptr, &lineptr, 16); + + while (isspace(*lineptr)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr) && *lineptr) + lineptr ++; + + if (!*lineptr) + { + /* + * Can't have a font without all required values... + */ + + fprintf(stderr, "ERROR: bad font description line: %s\n", valptr); + fclose(fp); + exit(1); + } + + *lineptr++ = '\0'; + + if (strcmp(valptr, "ltor") == 0) + Directions[NumFonts] = 1; + else if (strcmp(valptr, "rtol") == 0) + Directions[NumFonts] = -1; + else + { + fprintf(stderr, "ERROR: Bad text direction %s\n", valptr); + fclose(fp); + exit(1); + } + + /* + * Got the direction, now get the width... + */ + + while (isspace(*lineptr)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr) && *lineptr) + lineptr ++; + + if (!*lineptr) + { + /* + * Can't have a font without all required values... + */ + + fprintf(stderr, "ERROR: bad font description line: %s\n", valptr); + fclose(fp); + exit(1); + } + + *lineptr++ = '\0'; + + if (strcmp(valptr, "single") == 0) + Widths[NumFonts] = 1; + else if (strcmp(valptr, "double") == 0) + Widths[NumFonts] = 2; + else + { + fprintf(stderr, "ERROR: Bad text width %s\n", valptr); + fclose(fp); + exit(1); + } + + /* + * Get the fonts... + */ + + for (i = 0; *lineptr && i < 4; i ++) + { + while (isspace(*lineptr)) + lineptr ++; + + valptr = lineptr; + + while (!isspace(*lineptr) && *lineptr) + lineptr ++; + + if (*lineptr) + *lineptr++ = '\0'; + + if (lineptr > valptr) + Fonts[NumFonts][i] = strdup(valptr); + } + + /* + * Fill in remaining fonts as needed... + */ + + for (j = i; j < 4; j ++) + Fonts[NumFonts][j] = strdup(Fonts[NumFonts][0]); + + /* + * Define the character mappings... + */ + + for (i = start, j = NumFonts * 256; i <= end; i ++, j ++) + { + Chars[i] = j; + Codes[j] = i; + } + + /* + * Move to the next font, stopping if needed... + */ + + NumFonts ++; + if (NumFonts >= 256) + break; + } + + fclose(fp); + } + else + { + fprintf(stderr, "ERROR: Bad charset type %s\n", lineptr); + fclose(fp); + exit(1); + } + } + else + { + /* + * Standard ASCII output just uses Courier, Courier-Bold, and + * possibly Courier-Oblique. + */ + + NumFonts = 1; + + Fonts[0][ATTR_NORMAL] = strdup("Courier"); + Fonts[0][ATTR_BOLD] = strdup("Courier-Bold"); + Fonts[0][ATTR_ITALIC] = strdup("Courier-Oblique"); + Fonts[0][ATTR_BOLDITALIC] = strdup("Courier-BoldOblique"); + + Widths[0] = 1; + Directions[0] = 1; + + /* + * Define US-ASCII characters... + */ + + for (i = 32; i < 127; i ++) + { + Chars[i] = i; + Codes[i] = i; + } + } + + /* + * Generate a list of unique fonts to use... + */ + + for (i = 0, num_fonts = 0; i < NumFonts; i ++) + for (j = 1 + PrettyPrint; j >= 0; j --) + { + for (k = 0; k < num_fonts; k ++) + if (strcmp(Fonts[i][j], fonts[k]) == 0) + break; + + if (k >= num_fonts) + { + /* + * Add new font... + */ + + fonts[num_fonts] = Fonts[i][j]; + num_fonts ++; + } + } + + /* + * List the fonts that will be used... + */ + + for (i = 0; i < num_fonts; i ++) + if (i == 0) + printf("%%%%DocumentNeededResources: font %s\n", fonts[i]); + else + printf("%%%%+ font %s\n", fonts[i]); + + puts("%%DocumentSuppliedResources: procset texttops 1.1 0"); + + for (i = 0; i < num_fonts; i ++) + { + if (ppd != NULL) + { + fprintf(stderr, "DEBUG: ppd->num_fonts = %d\n", ppd->num_fonts); + + for (j = 0; j < ppd->num_fonts; j ++) + { + fprintf(stderr, "DEBUG: ppd->fonts[%d] = %s\n", j, ppd->fonts[j]); + + if (strcmp(fonts[i], ppd->fonts[j]) == 0) + break; + } + } + + if (ppd == NULL || j >= ppd->num_fonts) + { + /* + * Need to embed this font... + */ + + printf("%%%%+ font %s\n", fonts[i]); + } + } + + puts("%%EndComments"); + + puts("%%BeginProlog"); + + /* + * Download any missing fonts... + */ + + for (i = 0; i < num_fonts; i ++) + { + if (ppd != NULL) + for (j = 0; j < ppd->num_fonts; j ++) + if (strcmp(fonts[i], ppd->fonts[j]) == 0) + break; + + if (ppd == NULL || j >= ppd->num_fonts) + { + /* + * Need to embed this font... + */ + + printf("%%%%BeginResource: font %s\n", fonts[i]); + + snprintf(filename, sizeof(filename), "%s/fonts/%s", datadir, fonts[i]); + if ((fp = fopen(filename, "rb")) != NULL) + { + while (fgets(line, sizeof(line), fp) != NULL) + fputs(line, stdout); + + fclose(fp); + } + + puts("%%EndResource"); + } + } + + /* + * Write the encoding array(s)... + */ + + puts("% character encoding(s)"); + + for (i = 0; i < NumFonts; i ++) + { + printf("/cupsEncoding%02x [\n", i); + + for (ch = 0; ch < 256; ch ++) + { + if (Glyphs[Codes[i * 256 + ch]]) + printf("/%s", Glyphs[Codes[i * 256 + ch]]); + else + printf("/.notdef"); + + if ((ch & 7) == 7) + putchar('\n'); + } + + puts("] def"); + } + + /* + * Create the fonts... + */ + + if (NumFonts == 1) + { + /* + * Just reencode the named fonts... + */ + + puts("% Reencode fonts"); + + for (i = 1 + PrettyPrint; i >= 0; i --) + { + printf("/%s findfont\n", Fonts[0][i]); + puts("dup length 1 add dict begin\n" + " { 1 index /FID ne { def } { pop pop } ifelse } forall\n" + " /Encoding cupsEncoding00 def\n" + " currentdict\n" + "end"); + printf("/%s exch definefont pop\n", names[i]); + } + } + else + { + /* + * Construct composite fonts... Start by reencoding the base fonts... + */ + + puts("% Reencode base fonts"); + + for (i = 1 + PrettyPrint; i >= 0; i --) + for (j = 0; j < NumFonts; j ++) + { + printf("/%s findfont\n", Fonts[j][i]); + printf("dup length 1 add dict begin\n" + " { 1 index /FID ne { def } { pop pop } ifelse } forall\n" + " /Encoding cupsEncoding%02x def\n" + " currentdict\n" + "end\n", j); + printf("/%s%02x exch definefont /%s%02x exch def\n", names[i], j, + names[i], j); + } + + /* + * Then merge them into composite fonts... + */ + + puts("% Create composite fonts..."); + + for (i = 1 + PrettyPrint; i >= 0; i --) + { + puts("8 dict begin"); + puts("/FontType 0 def/FontMatrix[1.0 0 0 1.0 0 0]def/FMapType 2 def/Encoding["); + for (j = 0; j < NumFonts; j ++) + if (j == (NumFonts - 1)) + printf("%d", j); + else if ((j & 15) == 15) + printf("%d\n", j); + else + printf("%d ", j); + puts("]def/FDepVector["); + for (j = 0; j < NumFonts; j ++) + if (j == (NumFonts - 1)) + printf("%s%02x", names[i], j); + else if ((j & 3) == 3) + printf("%s%02x\n", names[i], j); + else + printf("%s%02x ", names[i], j); + puts("]def currentdict end"); + printf("/%s exch definefont pop\n", names[i]); + } + } + + /* + * Output the texttops procset... + */ + + puts("%%BeginResource: procset texttops 1.1 0"); + + puts("% Define fonts"); + + printf("/FN /cupsNormal findfont [%.1f 0 0 %.1f 0 0] makefont def\n", + 120.0 / CharsPerInch, 68.0 / LinesPerInch); + printf("/FB /cupsBold findfont [%.1f 0 0 %.1f 0 0] makefont def\n", + 120.0 / CharsPerInch, 68.0 / LinesPerInch); + if (PrettyPrint) + printf("/FI /cupsItalic findfont [%.1f 0 0 %.1f 0 0] makefont def\n", + 120.0 / CharsPerInch, 68.0 / LinesPerInch); + + puts("% Common procedures"); + + puts("/N { FN setfont moveto } bind def"); + puts("/B { FB setfont moveto } bind def"); + printf("/U { gsave 0.5 setlinewidth 0 %.2f rmoveto " + "0 rlineto stroke grestore } bind def\n", -6.8 / LinesPerInch); + + if (PrettyPrint) + { + if (ColorDevice) + { + puts("/S { 0.0 setgray show } bind def"); + puts("/r { 0.5 0.0 0.0 setrgbcolor show } bind def"); + puts("/g { 0.0 0.5 0.0 setrgbcolor show } bind def"); + puts("/b { 0.0 0.0 0.5 setrgbcolor show } bind def"); + } + else + { + puts("/S { 0.0 setgray show } bind def"); + puts("/r { 0.2 setgray show } bind def"); + puts("/g { 0.2 setgray show } bind def"); + puts("/b { 0.2 setgray show } bind def"); + } + + puts("/I { FI setfont moveto } bind def"); + + puts("/n {"); + puts("\t20 string cvs % convert page number to string"); + puts("\tdup length % get length"); + puts("\tdup 2 mul string /P exch def % P = string twice as long"); + puts("\t0 1 2 index 1 sub { % loop through each character in the page number"); + puts("\t\tdup 3 index exch get % get character N from the page number"); + puts("\t\texch 2 mul dup % compute offset in P"); + puts("\t\tP exch 0 put % font 0"); + puts("\t\t1 add P exch 2 index put % character"); + puts("\t\tpop % discard character"); + puts("\t} for % do for loop"); + puts("\tpop pop % discard string and length"); + puts("\tP % put string on stack"); + puts("} bind def"); + + printf("/T"); + write_text(title); + puts("def"); + + printf("/D"); + write_text(curdate); + puts("def"); + + puts("/H {"); + puts("gsave"); + puts("\t0.9 setgray"); + + if (Duplex) + { + puts("\tdup 2 mod 0 eq {"); + printf("\t\t%.1f %.1f translate } {\n", + PageWidth - PageRight, PageTop + 72.0f / LinesPerInch); + printf("\t\t%.1f %.1f translate } ifelse\n", + PageLeft, PageTop + 72.0f / LinesPerInch); + } + else + printf("\t%.1f %.1f translate\n", + PageLeft, PageTop + 72.0f / LinesPerInch); + + printf("\t0 0 %.1f %.1f rectfill\n", PageRight - PageLeft, + 144.0f / LinesPerInch); + + puts("\tFB setfont"); + puts("\t0 setgray"); + + if (Duplex) + { + puts("\tdup 2 mod 0 eq {"); + printf("\t\tT stringwidth pop neg %.1f add %.1f } {\n", + PageRight - PageLeft - 36.0f / LinesPerInch, + (0.5f + 0.157f) * 72.0f / LinesPerInch); + printf("\t\t%.1f %.1f } ifelse\n", 36.0f / LinesPerInch, + (0.5f + 0.157f) * 72.0f / LinesPerInch); + } + else + printf("\t%.1f %.1f\n", 36.0f / LinesPerInch, + (0.5f + 0.157f) * 72.0f / LinesPerInch); + + puts("\tmoveto T show"); + + printf("\tD dup stringwidth pop neg 2 div %.1f add %.1f\n", + (PageRight - PageLeft) * 0.5, + (0.5f + 0.157f) * 72.0f / LinesPerInch); + puts("\tmoveto show"); + + if (Duplex) + { + puts("\tdup n exch 2 mod 0 eq {"); + printf("\t\t%.1f %.1f } {\n", 36.0f / LinesPerInch, + (0.5f + 0.157f) * 72.0f / LinesPerInch); + printf("\t\tdup stringwidth pop neg %.1f add %.1f } ifelse\n", + PageRight - PageLeft - 36.0f / LinesPerInch, + (0.5f + 0.157f) * 72.0f / LinesPerInch); + } + else + printf("\tn dup stringwidth pop neg %.1f add %.1f\n", + PageRight - PageLeft - 36.0f / LinesPerInch, + (0.5f + 0.157f) * 72.0f / LinesPerInch); + + puts("\tmoveto show"); + puts("\tgrestore"); + puts("} bind def"); + } + else + puts("/S { show } bind def"); + + puts("%%EndResource"); + + puts("%%EndProlog"); +} + + +/* + * 'write_line()' - Write a row of text. + */ + +static void +write_line(int row, /* I - Row number (0 to N) */ + lchar_t *line) /* I - Line to print */ +{ + int i; /* Looping var */ + int col; /* Current column */ + int attr; /* Current attribute */ + int font, /* Font to use */ + lastfont, /* Last font */ + mono; /* Monospaced? */ + lchar_t *start; /* First character in sequence */ + + + for (col = 0, start = line; col < SizeColumns;) + { + while (col < SizeColumns && (line->ch == ' ' || line->ch == 0)) + { + col ++; + line ++; + } + + if (col >= SizeColumns) + break; + + if (NumFonts == 1) + { + /* + * All characters in a single font - assume monospaced... + */ + + attr = line->attr; + start = line; + + while (col < SizeColumns && line->ch != 0 && attr == line->attr) + { + col ++; + line ++; + } + + write_string(col - (line - start), row, line - start, start); + } + else + { + /* + * Multiple fonts; break up based on the font... + */ + + attr = line->attr; + start = line; + lastfont = Chars[line->ch] / 256; + mono = strncmp(Fonts[lastfont][0], "Courier", 7) == 0; + col ++; + line ++; + + if (mono) + { + while (col < SizeColumns && line->ch != 0 && attr == line->attr) + { + font = Chars[line->ch] / 256; + if (strncmp(Fonts[font][0], "Courier", 7) != 0 || + font != lastfont) + break; + + col ++; + line ++; + } + } + + if (Directions[lastfont] > 0) + write_string(col - (line - start), row, line - start, start); + else + { + /* + * Do right-to-left text... + */ + + while (col < SizeColumns && line->ch != 0 && attr == line->attr) + { + if (Directions[Chars[line->ch] / 256] > 0 && + !ispunct(line->ch) && !isspace(line->ch)) + break; + + col ++; + line ++; + } + + for (i = 1; start < line; i ++, start ++) + if (!isspace(start->ch)) + write_string(col - i, row, 1, start); + } + } + } +} + + +/* + * 'write_string()' - Write a string of text. + */ + +static void +write_string(int col, /* I - Start column */ + int row, /* I - Row */ + int len, /* I - Number of characters */ + lchar_t *s) /* I - String to print */ +{ + int ch; /* Current character */ + float x, y; /* Position of text */ + unsigned attr; /* Character attributes */ + + + /* + * Position the text and set the font... + */ + + if (Duplex && (NumPages & 1) == 0) + { + x = PageWidth - PageRight; + y = PageTop; + } + else + { + x = PageLeft; + y = PageTop; + } + + x += (float)col * 72.0f / (float)CharsPerInch; + y -= (float)(row + 0.843) * 72.0f / (float)LinesPerInch; + + attr = s->attr; + + if (attr & ATTR_RAISED) + y += 36.0 / (float)LinesPerInch; + else if (attr & ATTR_LOWERED) + y -= 36.0 / (float)LinesPerInch; + + if (x == (int)x) + printf("%.0f ", x); + else + printf("%.1f ", x); + + if (y == (int)y) + printf("%.0f ", y); + else + printf("%.1f ", y); + + if (attr & ATTR_BOLD) + putchar('B'); + else if (attr & ATTR_ITALIC) + putchar('I'); + else + putchar('N'); + + if (attr & ATTR_UNDERLINE) + printf(" %.1f U", (float)len * 72.0 / (float)CharsPerInch); + + if (NumFonts > 1) + { + /* + * Write a hex string... + */ + + putchar('<'); + + while (len > 0) + { + printf("%04x", Chars[s->ch]); + + len --; + s ++; + } + + putchar('>'); + } + else + { + /* + * Write a quoted string... + */ + + putchar('('); + + while (len > 0) + { + ch = Chars[s->ch]; + + if (ch < 32 || ch > 126) + { + /* + * Quote 8-bit and control characters... + */ + + printf("\\%03o", ch); + } + else + { + /* + * Quote the parenthesis and backslash as needed... + */ + + if (ch == '(' || ch == ')' || ch == '\\') + putchar('\\'); + + putchar(ch); + } + + len --; + s ++; + } + + putchar(')'); + } + + if (PrettyPrint) + { + if (attr & ATTR_RED) + puts("r"); + else if (attr & ATTR_GREEN) + puts("g"); + else if (attr & ATTR_BLUE) + puts("b"); + else + puts("S"); + } + else + puts("S"); +} + + +/* + * 'write_text()' - Write a text string, quoting/encoding as needed. + */ + +static void +write_text(char *s) /* I - String to write */ +{ + int ch; /* Actual character value (UTF8) */ + unsigned char *utf8; /* UTF8 text */ + + + if (NumFonts > 1) + { + /* + * 8/8 encoding... + */ + + putchar('<'); + + utf8 = (unsigned char *)s; + + while (*utf8) + { + if (*utf8 < 0xc0 || !UTF8) + ch = *utf8 ++; + else if ((*utf8 & 0xe0) == 0xc0) + { + /* + * Two byte character... + */ + + ch = ((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f); + utf8 += 2; + } + else + { + /* + * Three byte character... + */ + + ch = ((((utf8[0] & 0x1f) << 6) | (utf8[1] & 0x3f)) << 6) | + (utf8[2] & 0x3f); + utf8 += 3; + } + + printf("%04x", Chars[ch]); + } + + putchar('>'); + } + else + { + /* + * Standard 8-bit encoding... + */ + + putchar('('); + + while (*s) + { + if (*s < 32 || *s > 126) + printf("\\%03o", *s); + else + { + if (*s == '(' || *s == ')' || *s == '\\') + putchar('\\'); + + putchar(*s); + } + + s ++; + } + + putchar(')'); + } +} + + +/* + * End of "$Id$". + */ diff --git a/fonts/AvantGarde-Book b/fonts/AvantGarde-Book new file mode 100644 index 0000000000000000000000000000000000000000..4d3a8b2ba78b38221ed148c50e3e47142f19cc8f GIT binary patch literal 34871 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 KVo^3%12X`fJ3UkY literal 0 Hc-jL100001 diff --git a/fonts/AvantGarde-BookOblique b/fonts/AvantGarde-BookOblique new file mode 100644 index 0000000000000000000000000000000000000000..c25c6ee4ccf2ca97f1e4f8aa66b83744f732ccea GIT binary patch literal 35156 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

RlC^~pcrIePU+H^E0qNt2K?ySSn%ft^;X1z^FO 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 z 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 CCFhd> literal 0 Hc-jL100001 diff --git a/fonts/AvantGarde-Demi b/fonts/AvantGarde-Demi new file mode 100644 index 0000000000000000000000000000000000000000..67046dbe6847b7748b30d8190d10ac897dab4576 GIT binary patch literal 36354 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

>i_dwcSv19HcLt%Sgkg+*t<)A&d98zh<*U(# z7e!e+IkG-Z>(yjBk}U5L3$0<_tKAa9ID}&b@O2-WYe`~9AjFESrU|y+7JFykTf-ShbdQqf{UOYh(NWf5DDIfKeq`E%%9uH%=M&ZjSUpd7a1Ja&}g^rY{F zHhF<5dv#gmEtD*zOppDc)XL7ur}1^xh~&GvhhYj%t%v;nzWd;x+N8liE;R0I6b
}mW3{{^l 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

F@{W|JT<+U#2+4pAp?HR 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 literal 0 Hc-jL100001 diff --git a/fonts/Bookman-Demi b/fonts/Bookman-Demi new file mode 100644 index 0000000000000000000000000000000000000000..4e26c1cf52eb6aa6a4a56e074c122c771cad8f7c GIT binary patch literal 44768 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 Q=&y@|ozY(#=m3!a0Z44<7ytkO literal 0 Hc-jL100001 diff --git a/fonts/Bookman-Light b/fonts/Bookman-Light new file mode 100644 index 0000000000000000000000000000000000000000..7cbac2c456cfd3cf13857b72bdff7059378fb1c0 GIT binary patch literal 44934 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�~L2PWj2p~&x53U&)itadc*JdTr~r@tMS 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 M+ZsAq!vui-7k3Ig9smFU literal 0 Hc-jL100001 diff --git a/fonts/Bookman-LightItalic b/fonts/Bookman-LightItalic new file mode 100644 index 0000000000000000000000000000000000000000..3ef45dcbecda613d2e6a85337c075ae6af195a7c GIT binary patch literal 44162 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%0Dfb&7z1mnMTLQJ}sBQXktc+hReT0+&BG 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 KXB*gnU;hDXc4-{| literal 0 Hc-jL100001 diff --git a/fonts/Charter-Bold b/fonts/Charter-Bold new file mode 100644 index 0000000000000000000000000000000000000000..0d82077ec4c7f0cc4b5a44b9b923c958e88d2521 GIT binary patch literal 33799 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 E2VzZ0uK)l5 literal 0 Hc-jL100001 diff --git a/fonts/Charter-BoldItalic b/fonts/Charter-BoldItalic new file mode 100644 index 0000000000000000000000000000000000000000..c7a5f8798b1d3159c8e5a61521cd972e658d64d9 GIT binary patch literal 35229 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

l2Si0l~Ai0)j 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 literal 0 Hc-jL100001 diff --git a/fonts/Charter-Italic b/fonts/Charter-Italic new file mode 100644 index 0000000000000000000000000000000000000000..6abe1cdfdbf4d0c03bd56d942ce42eb4a9ffb6ad GIT binary patch literal 35118 zc-ow|b97{Vv@IH|V>=bwM#r{o+qTt7$F^oj%~br-#Pc*ch0%*pI0@i#@>6a zHRqZOzft86d;ksvL`o>HL@QuyXJ{g7XX{MMNXGy}N-E@NV&H6HXDe*rY{CT)b+iD; z+PMM%OaMksE(T^UR+jGz&TmJ6poO!O^S84NK-t6I1i%RR2LvGRXlLeVVDoJkva|Pa zv@kPw{x<+%-~=$R1-RJSyBJzqIGLLm1KjK!tpJ7||1Tg3TO&FefRKTWp`(SdnF$R* zMu6@cNx<3~@Gp`Rz|q9X#L?BnnC@Q!TT=^T6I*8s1M6>WV}QM*oxP)liL-&D2f*3x zzu|rdsL(0V0mS4~MHFRaL}Zl#iXuwNiV{M~BEkSg2{CbHrEec)a|}~||C^to^>>}W^ZN(&|2+B+l}`U;0I)Ot*C;F}{4ctb%eU9R zoZm=H|H;M9z{vcM1Y?W;hyqX;e6upLet!vk_r&^Nat_LWi2kP+JLNahfAOOO{L@`$ zM*|~gJ4bpO16!BxE;xVJ&hej8{kMVnCk;kcfT)F|lQTf++hF4S--Zalz{JSHME75Y z_8Z6GyV7PBPR=Hd-`)HsGd8g?_#Vk`z5i`=7#Y9Y_uU)AZ+BZ5`hNyp!q(Id!1*7K zzdQY(CIEo`yQlvljfsxopOvEgCNVI!v$ggB7@L^>;~{J3{M|hO#sAL*0sLS00q|ee zf$o2@in>@^%Np2x^Zp+=A#(%AZ}k8PXM^v)|6gJZY%Huj{y(Drr@NZTziKFC?Hp|k ztpBI|KWGGO&A#Ug!1!I8@7MpbSvZMWxSJTuTR0n;156F9zi0bDEh@IgCXUt?wkGm+ zP8R=e6D=bH=l`&NFRqc5t%;KpfQ|8AqsjL|{Fe;=?c2X%=>JoKpfc@$@bu z=YJ0~hW``rpNHH3zLzoh-c5Ia7Q=V?jNgvm@BekB^WXSHY>n)UEo{xchw^(n4IGXC z_k;h9CMam<4)CI7Vqyc(GBLA#SB0Ggz{$bj^WUIUY%LsIOeBN>jI6B83~Vg_q2I{G z(ebyT`?opi>)n>yesAt;f;#W-u&~s829Acy2_Lsy|^j<+YoOcV;Tk z;Z`GvyV3*M-VyUWox!NbDP)&63Q@fhVh5;!I|?|=yxtuczD_!lHtXnt#ZX{RSxpXn zXmPv8vb7B-E2Wzok))dJOQL4qq@O7NE|~QszWEXGr*h8F`mh$LFbgwg<*f71+t(#oZ{;5^~`+jWJH($}jm ztBD$$e&#%OX>wTvo?~HNZ*^YoNYg$$qsS|Zm>q+ zF~Wptf3rGU+tA*^^!=)__Rb+jrfuR^4bpfir3ag1(;_`#7rP|CZEAu( z0)6~&tMi`x6x0l3vM@yjPr4B(c*LH^AfWb8pRvVI6-lLvFCcqc-EPvoDwr)@&s3*Z z5fUbO<&?N(d3yYY>Xhy$pDk08=?GibXtDa8JLcD|8{{3MnfpoBGLGAVT?n^&2=87N zaXW^_bHW+014g+2M#!`&JI1*AtEvVM2J@1N?YnAtgiiBk^~DN?+z67>LG3R|9WRx0 z?-MqO7dy$}=0cab4ld=|z-q@VhOC2%ttlT|WFg+j5-~IcH*&&vBwIp89wNUkesrqt zMTQ^e*}^^11}?JN{=&QJiE}pRaalnDF9&5z_cur}FT^Qy-956{S7y`}&wKJpU9*KU zrd@CldyZ~#uN#?|+u}>Mz|Z?0!BHt?{@ay)!u5S|cdo#2o|nPpgkPGyAh`#wJ`T$B zrN7xO9UPDbwaQBZU2!8|qM!5RoNfb i9Wz7L$6`e2dLXK2d&XsS;-P|v+`StP= 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 RoYcgklKkAnqHL}PW&qGCxKjWC literal 0 Hc-jL100001 diff --git a/fonts/Charter-Roman b/fonts/Charter-Roman new file mode 100644 index 0000000000000000000000000000000000000000..b25133d510afe403b3e87a6ef47fc8176b4012a6 GIT binary patch literal 34869 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 z z9$Fl^NGsYr!HagM`XfV6rPWxH_d?#8Cxr!`gyqSAT3-?FHaWuQ&~~C}FQAMc8gJK$ z{U>2MKj_Fv^xeukFseGZDh;KYZ@UFXU9;*_*<(qF^0=AiL}7IZniuLvEsCuRRBCKx zf6*K~0uT2aYmIPw%F?;)UUyOybvFisf8pXVyh=(RHq*u_by>QfE4f>|y3Th^12rbb zuj|Bs2b-H{e)!)+k{GQnXr{>EeN@XsOdo&FVtN%fYg!gYl2k(rUBwRjQxG7^r;zSz zNWPm7jegv<1fpN)d6w89C1pa!?+!cGqw;A_!VEAcKm762x#$(^CQzEu&TGNhD0$da z&&FJ2O*tlZWiw-f<9MzWoI%R9j!)v}s$N?v%r_3)I?o*9R!L);8u*>3EO3#EmX5eh z^94)dW)~Wyncwz!R8JaVxDY=j8kkPWUWFpBxZXYq zgIeWUj2^H$?{+=i%5wDFev~$3+dhz_Ui-p3FT-cp-Z^|>b><&RLpJawB>$ely}ivs zW%APUQO4hRKfioWNXHZj2GnlX-$$gi!zi3Q!5%#S)BD#^9#_)Sr*&gVad4SJ8dNXh zha(8p2!%oCsv=m=rO43Vl1Mb+z~{j@?fSMlXo}sIodg~~)YIBIi4PNr!@PkkOB!tH z0aYx6&7ZA$`mGa-1SmL4$p5(pt&}}QERqGKr}2v~?w%UVjXx27_Sha_7N0972ua(l?`sg}W{Akn|4s+8o7Wid6e!KRCC=gLqGh3;l)LDu~e zqAgpQz4w%LDGCaophS<++G{7DlinDd!$TQc%;;KzsB!OvM;n~cy$Ij)fF zS5)9hA<8kw1nMS~F0y2Kp_SkjH$oazm7CbiW}v{k>zIdD$YNOdaYz!Gl7g%vxZFP2 zsx9#1cUD^1+5yD)WqJwRk3G}8(012HLoz1D8mZS727 z3tK4t-vUaAjmKh|+l05dno1C|wBEIU_gFc!VO!#nNCX=?vby$;YZYC`l3^Vl5)8Mlr{C*#I0gi_koyRP&YE6oJ%K5*%nhAdv`W6p=( zg!k*9eqJC2N?p+dF`~5}=VV+47qnx33-WJpVU^3%+_DBFsWi5hO+lscgK`Pgr!f~aqOW#;!y1UwDEIH_>3b+qV!;0<|Pf+OqyyO zWDsqssY}(Vj!@$kPQ?xPEh%fS-+=JU?>gO6Km3l)qiqH>!X)yG9XpNCNcz>Jgo9bZ zQ`?KI{frn)xjVAs$y6{t^mQgSazU|}&2I#AA6^WqHuaM%V6Xr?qsJ4zs2z-MD0snQ zfvB|EJD)s_A<(9Zc(T3OKOCPCp#Pm11V{I=Wn<3V@FkIIRRaq+6Y^usf9*RWyE7*x zt^%4>nh*JYKmIO7?tTH!JNwGrAAP47a<41hQ~fZ1erzea0)-q$T{Y9(c(twHrh-CK zg*NG7Tm&5pzvoI%qyy9q-lXwD7uU^(e4)<~N~vTJU^Dh-F2ISOY?g)nvw>oK(recg z*E)Tx$cE*%cI7?&AI)n~A!4xDC}e@3UX1jEmGk_Z;%aj;1sqre--u~d?IUg?55!}2 zsR9MIL2Rbgw%O_0UVsDx2eKB7UQLn%6 zA~-NJFY?N(m%e<$f5unzQi;%mDfb37G-RrOuK}Nxv1@CJHCJ70mM4XTC<)R0Lv>a? zb{6SS^aDzo#}~&a#)}-Ym#hJE?v`oxr=?)lnJ4voV(A!it_>4T5;C5lPxauz`50^I zHh6d(B*w+hS_o*{FQ?=}jAG4$6&?HXt8;lbV-qeYjh!T1@#WP_A4!ES_O^1ae6Ks* z&{*lXg$Lp`tdn3m>5C$iBSwTZ*hTVeA{C?;jnMtqQx7=7=JjLUW24m0YreXCZu*03 zQBK%sIr=wfrGTm`5mO5Z4tdzAjGYSTBD3PMfs18K*nkru)G@~A3xd$_<(IK_1w3k2 z{oB$&+hjvL5$}7rDrkxcs9&npc*dD4JTeAy{t&%3R=M#v&w&PtvHZ!!Xnk#1#Y@iL zB6yi>4Ax>Z*@dW>7K3hNPPTY;laAKX#jO6^YoiJO+*CfT*yK^GG_ZgsX)ih5Ur31w zQVnNY{OXcT0>98bw}@xs&zp{LfiE_763%pW5;Ycc!VSWvG`!Npjmi1qf;j<%QhxdM zouo<-EKt_EuyQ~e$1`oLaQgbSX6T{boz3VFjL@wq(8AE5KSCDUu7URt<^95ah7-kA z-FZ4TijaF|6W?yhHSP%_E~3PAYS%jAi0)9_TZ}gwl@0SQvs<_lqg~;ia*2EN?+MoW zVK$|{Spsn7W-n+@x<&*;Q(eYH23DquZ-g)%pP1uDmOCOfLdVOdv6>5+dCM*1m8adB zlb^7tkMGpLnou`)IpKSv2%SjEo}5$!U*qfnE>Z8J*o`4fbXd@JOfqp0P}0A@CBkFucMb&5tSsC6eJPgvz~xJN zA_hc!u5YPQb%X`iLtem1z>BnfH3No135E$S%}*hM4&R=w+_o?$ z1cM&Iji%{o>T%1<+Cds1qtXd67<2cqhZKL_j@BEr#!{GAY;XIWq?*qW8K(Zr6LZRU zDKOrmWaYY`5IGG3s!)QAhx*&%kBm!|dAdL|O>uA3Hq?&YTx|bL2Knwd%qcQHR1cNi=I9K7n>B)A-q@`MGr|*Z zKRU1AWw9D`X(ht~qnF-pXd|6|FtDEW1i{bIpVHHI;70)H{M#o+0pvqjuq|Ott~FCZ zP)dv18IRySH+(%6RPvc7oOBE~YnGuE1n&6xH`Cm~9BR{phZWf#A#F3X+RuxLS{!W3 z2AK-6IH4r8^jg|(jNOSZgERe0hQWvZK9Br{dvSTjmk6|?W+-97eFB}k3FXIQlaaeU z$Lr}E-^MeP@%_OhR0Fd@`{GW=lT!|zAjfxmkFDivKqkEAfF1&SUTl?i&L2Tv@x7(q zG!k3Vw)|=zOSWJ-u`SJ7DAJA!i4Yr6wr)X_J>~#MMgQcMl>d z0o1(YVtF{B9tfL=LVu#_5KU(~j62B$#M@&rRj23nd@$%vJIN$o$#H^t9bBWc<>8^D zewZeLEL+T?sm;m|HA72ivB6GZ($6=AC*9@T3y*oC>#Nc=QN~sRiI1OMir3FQI0Vt5 zuJRCm4qKf{2^N6qbA{=HYscbS!8fD#xfeG4R<+i`R?n;JZB0HjrQnzwMG1(t zQJtMkV;usFLf%CC!>X3=I_O*5)`XpEj!;IPXz>;Q7C=wp3I`LTaCD(@G`>@Kcac3p zW5|Gqhuv!;$eLC0sTdSy4*jzCbOu4U9BnCH!a8GGP0R3uY0s@chZ$gU98OysUTxwZclkh5Z{WHC!X-ccOwMGgmjqzC337F-qv=-!1dj z2c^SNIXG&Ob}@dZQABRbN1JOAi~gPtZX-5KP1{GMGe{eYGM|*8s0G2&DkehdH)f@) zWkNF&*G}o$6M#Q0N z?cgv=rLibaD&afzzbguzneaZ=isbT(#z-{njRf{xu;l`8W=wWHq|%Q}!zSLa1USkBzW*MVLf;3L;5SkAnqt-IqyL{3|k zmvI@>RvTR8o#gVfbhpzj-OBb9P`M4%M2X94!XP-|#p_dZrlEfAmA$e^)bdMVJnv%^4y*9- z+h#5@+@VTD%e4OV;Bs97`GCZs5X5EjkyE<-Auk?36=^s>l`mbMne`njT5Aq4= zt|;dl)C%8rP)H7+vsobEJff8W~ z;SH)gf?BpnvsEdCeQqx62mP>f+)N?z;pDBGR>w9lihT;K%5xdXOt1pG`C`P}1Wjf; z*-U1t+kyn%%kUD;o{%=UG?esI)6t{zI3cF_F&F^(?Og%o=A!O=ChCUGlLwpaRmQ}1 z^I|vWz29n8*G=V`7VDj5oW*quDxbY-T&wAlXRq5qQ*~>^V#+MEwikHq(O>*p)*QR^ z-iSR(I9cba*wtkfwyCODOLF? zAz&2F$SJ+0Lhr6HnT5q`dRzFLL^mQ-F8sOOlkL-_IPYhSUHkL>5`qf%Kanatc~(g0 z1c#2B=yqk}YN;gai#{UWljMWpMM&)HA@SQS-hS3aWSmI^p#d}qzu-}DyEI5I>ULE2 z=ooy_jUnKQ?nrIcC{3mp{mvQ98^+RL|NXs+JT$TIT`Rla#=T{kX=vw6M`>)xZ{b_d zuBff?EFYW}anBMVJlvye7Eu`m0h}A|$)iSBixK(ibIB-@!Y8ssdGgez&M!Roc;dl2 zh;}J8KYra?HoxS@ox(67-8k91dM_0}4jP6g?R@6Ywy!qhoh**0st-EhHdzE2XelDh zm*Fs-AXe4+^?ViNM3gzB6JVZiC6`LrY9Iw#1xwsf{>rhcmKbr?oVGa8U7a8$?TpxS145*Z z9G9QI^@RMm7=dm|M+~XREOAe4270+9!v?Bo9=u3@prqR{oNY%Nyly83QJb<>ftbTW$QbSw5%LnB zyl$%2n3YfPyi@o@HN_nM8H#Sds6dr6h4$C;e)}&@J~FJV+eM@dg5UBuN{Yv;pVR0% zb3EzdJ;M*OCh$TU)8(Qg>z}W}qx*0`kp-;{#NrnGb*g8Zb#TI>iRW1qWCC56RO1I` zGVxl{v>4%WK>>D9KZwiHD+KDWi+X*Hs3oJme|}ScWzE@~zhGpEMvYE+^*_s{cZz81 z-k9&)=F{|xpVc~TTMqA}Jd&ezFzs4JE_Tc)wh0u86c>m}qCe2QF*348VbFsktCZDc zf0>|<`xRvE7Cp{At4%cfgBaY1t?eMZmPTgw`M_xJsoQ4&mD1q`eq^fN_Lw$>R3LQ5|t-AohW8xuW;i03WXI{^vvTF;S-Yh8b&=>dfIKjZ_FHF3>;dv;4jsrbhwn& zAz5GU;e}Hsw_CeUWFuuKfXJdL&O3|Ni@6Zqz7#uKHjVai2??QacY7MthUT%wL@(n6 z%MSa<4aQ{Lzrt^Q~zoW}DXyD+mZ+Ic8VC>E4I9`j3vUdRA)!UAT?E4)f66{M~H6yC6rw zLQfb-s)Zw{CVdb zcb`Obofh#JM*C%-|b)=ZyGey67y#-!9 z_cF_a#<_q!bHxAzhdzd#zd<2~zDxLPPEwuYP|lF(UlIUB%Tdu4ioU+fAHKP(=JMx+O z%+5Sevp*|ooWavxXUpr($(Bi!tow6o8?Uag3tW|8^fvPx8lwQA3qqq#_O?*vHKFm5 ztjV4`LWh+ja#e2q*lGZ?x#+ENooKP1YuBjUWO6huNVjXZaT9=4aBqXcVgh|hz$30O z+A^@hY_qC_N)ec}e_3{*Le8jy*Y1Q$5fM;HZ==2%vHR@O0buF`#k}awU|(0=!Rix! zE6i>Mhwj3*w6r>0H6s?FZ)n)8H4AjZZu365hG7onk;8Ju)#YH0L7U|H8Fb4>5f z2j=TaYT0>w!ktQ-)J?dVk7?Ge%l&{DCK?Crie#taOzV)ze*m|v%jy&md5irGdMbaCWt6DF?A*bd7N=)#YvVpq_S5MTiSiG0)OZhxv!=E6RCIrhrLwMPCTWx$Iq?%y zk7$!n_u3hEaLkX$%h+Zqe^*YU#dwm`6IzkaN-TL-4fW zNhn0Mz5LeoBdtdoeYf$E0r1WkgZXPi!a3^jayFx5lp7SHKuj1)i?1@iATkred=kF? za#U5^DA@^wYx^ZnOcK%O&TLAWY6MNTg8=7_hEbn0+lf3OqPHTXJ$MnH#{$Nwo4_${ z#KOJ-(sWKmgG+dgc9+x1ZcfX$u(5`eN90Qw2+rIVz2~TeZNt zmeX9q8@(|6d1H$cbkpXy8=!Q8UYA62J1hlly_A;Ci7tzX|M+Ss17bx|+ zM0-N>c+9^~pl2M~Fd+8zz`SSLbae0TGzyW)rr8{Xi|+jo*bTjBm*fOYZUqUL>-$_~ zXl~n^*;8f?75ksZu8X{9m07U*8*(0^_OTfQT`I9CtG6KX%h|vLo6vZSM>r28)z8tZ z-XA|iiG(D3+2rBB7H>_P`}X$-cLr5F9h|RiLfqHp5fJy^00_(8%V52VI_XTk%a8eR zx2L^EC7BO|E7+vvZua!GCZeLOx2cQv(p{I!yD9<&hxZ??6VkS;LNjeKpDHNoIWiGCCwsFa z)v-gf45)2g-guy9lFq)!mHXER@W2l)S}of)>wv@O8_ow(bfQL%&q}2mzo28u*DO-) zF<*p~f8;zSQpz#VjI+V*_we6-Tw?1ViwP{UppN*>q995$z3@=^A>oxmlq3&A1&;NTg-LtRX3;1xq4y`wHD$Q9JlNA$IglY&i&tB90|6lP+jl1sFNw|!yR1*A zUoxCWSuBS@KX>m>JT5_7tq9s`jc)|h9^ak^u+wnPNrP*~<~yA=_2)yn?1sz871g?6 zv$Pjls8c5QV&8wWtlVayDnSR`=s0JPgh3Fk<7|V2mPMxxN&6S?r`>(h-_!3qy#C1k zh)iv&Dv}jow~e*b(rJ89GmE{2Ho~~oov$a0baxLhqRO3zzB;W)G+thGRU|M+xq!z` zzWw>5=;1YQL6@BeUjrl+XR~<{Nl*W%&M6!zu(E>D9z8{j%rc%gcr*8@&aCmvwQuk^ zfrb`smGMEzS(sbLay`3Au0&RuTBN^NrH*`!k#dxF*7=+QFG-G>-7TGJF^86jPLdH# zPjz#jH{Q7iKi5rA`s){!vyRNDio=Fgs-tHUcJ+N0x1f-hpQ`3wP2Mo1w$K-9*jfn- z`Cm^ zb#S~AF}R%zG6W~D=us2w#uHPJ8xOvJzdiVSiDF8wPB{^A>)zwNCAzY+?&QY5KR}K) zkf7K~?|>ZzYHs`0BC-tLD&TEMNa@sd5Zo?@^uA zs$IZ@28-r9@N1QAV-acgB0u%J+3W!X&WUX(Ug*+(7sR*d`fD=E{NmY{re=3`&{((> zof}bE%W7ear(N$u{Kh;ni#qDaB?Ie7FcU{(LdSRRtdY6Q;zzz8Yn^o^pZ~2}66q<* zb#tFP!v~Ddwhf))3y+={^moa~EK`UI4QQ@|Op7}cmG6P1f|+sf@4T)BP2eIZY1toq zmOH=~gu{(YNaJl22V7-Xzu1*Gxg~R2LVv-h17fE7mJ@2Jv|A>|7eO7kiY7GU`O!PQ zVQ!XGsjZ*L8oC_Q-LlNt6J}Riq6{u@=hP*Quip*yo%+CdvCIT1Ba(A>uerLJ372=3Hi*&m&5m1jNI{aI|LCg(HU>d1D0D5{Rn6otqR%` zlHNZNSDwE@){&?%G!ECs7dT(42Om19;1uf%c$Z_kF8u6J+sJstOa^b3r7!swzDE1Y zydV|Tcz%B5F4J9_`ppuSP=lA%!5kL?c5lXlLd6 z_p+F0QCvdk}FL-QiPD(_4B$z@-WO|dIM z29`)q&N<{=+qDE((V!+IuHKK?KTc>P?z8=)cu z*lPBKSu3X3^&AkkYw#7Rf+WRXcyOf%=g^ioUFWuWA+9>Epnlw6&UDrtYd!%&n#Fd& z;^(*}65EpGp)XRq5SBEeB+7Is?s5?GSGci4-GHYV{hDP6rkeiFiErHt9phWZ2&LqY zYhvgLrtjMLfZK;zV+xF}Mi0UI?l6P1nWNrOrIpRxw(m-X#o31*>0QOO1Orj5Bj0VJ z7rEFsY>M~sKYb6yWvoP-kNemGy}}6PaA;`@>RUe_Y-AtC3Q9;u-fQxbQcuBfwhCRk z?ka66f7_*^Yfh$pUi&2zHN+W%L`0_jGn2WSxxxl1D}V$~HUuDxxGBgJBu zfp`~`bs{azHH^zCdQE@E_V!1I|Gga_kB4>4mG=$fI`E}cw-}8(jkGM6I)1I7?pkez zJEDUkhCj(_3%ot&J;tgBg~Q!tC{X=piN8{h^B&`p*QObOsr1KBvhmNb>l;!Kp4~0>Uu|_Je%;ggqPxiHn0JW1s*^$8`=YV<=V!jzBC4<* z{`1Sh;i~#`IclNK;?yY`VeOsL@ph{V`F)^xWoV3vYVQ z{`(}4p6#w#*-N|>(mGO{;PIY@b&XXD49NQQso#>NNHa6ey*h4<`UtQ{V0pgTWMFt0 zgjco~GXlgN&-p)x`FC;GO{V=Xf zgH=u~qX#1hW`b7WiFkfSf;2Bw=-^a%&Uo# zlYc?M(nk{K4XtPa99C;kA$L)WL{U(2ytx&rY&f)rW;Q4IyGkXx3OibjJnKE6>g@xmHKZUo%>7?UQBL{=y}?KOw#e%zebr6C^AIo ziTBG8B-eAE*i>|W!edg%_DyOh?zn+w%%M#O7v#+wHx8R*OB}$2Z&mpuFErZY`RzYY zvWj06RPmZ%7lg8WQ@8^3p8D#Oyswi_DJKr38YB?1TYiOL+26~%C6cljM|zLgFO$A# zc6Ss|DDLN76l^|t-WfbU_@Om!PR#9h4yS_OtG0g|x05GEZ5e?_OfkkY(yr~o?;_Zi zw*eK6Ywp84MaZDvsr2z{jX~WEeh3jcb?Ma#xpJ?(*a1%y4Hi!9AIVL-JlN=dgm-zN zf6w~k)O;gZZehEsLIDptJXsZAB-_6!6m&&z;RC0tYh^^duAy-|AYYj-OlT|?OsT!| zOJO?tRs5PIoN*>qIY730T<#P#@O4Vxk+o!Q#sSsgmM_(k79p8w>Upg~w8XIk zy*a!QHl}_v-akQrsp%B`$e63NbI-mx#3Qy~w{@vA`EZ_sAKO+&?whNe-HZ{yuI)Cx zN(N$Xy+l;ej@U;+UjslcsgF>$DT#<{zEni7^Qe#@$lNZ|FNKheE8{)Kb_ z^@p<6@1FiWPV{wS7MWf|$Kb=#{JWaKo5yUpyIh^t1HZJ4?9Vb~i zcDS=*ESpwlZXiVC6MF;Kd*pAmn?LNV=}fap7HuGq^hysiHkf5#JtKXas4J4DfDT}au*aI&OAig59hLoVVWlS@lMl%gpgSCq6W-1c5z!N_M)m? zX%hf-fuo&BNr+$Nf8WdFoh{xlrJtO2O?)>X)2E$R)dlRoS~Z!|@m&k`$q{I^Sjy%O zO~!;g9HFa98?${kkaU^vu$|V<|{vC14${?m-+g?Vta5G_};Wz-7WOt z6O5q3)=0!Y3>zp<8JiZuPm@?E3uwU&xHE@BY$Qj9p9fKgEOm+peO>DvEPM604Bb;e z456~<(T1BuZ8$hs;#sA!o z5_`m;>*}a?GGPEReJ42VTxc&tx^6W=2{Ur6=RpZqt2i75CkbnYV$eooaS)reIZ+5p&?N!RIwAvmuvjW zh1DEA6j12Y*L}ar9bJZW=ub-F-2+|Fp&mj$`Ub$+MUqf=F@u! z-t~NUT8GeQsWDhhxI{62S$}rjm5c9RdcGt*80mGI#$=>b*b)lcvQifL4k&A_<#)() zeRLv(#vLQPwPSuAQ0Fs`y;;0(VA08n;i>M>)CS~aw@wgVpmt8$9aYj*!`pRAF$eQx zfrOF0DhENrZjz5(d^s-pd}6o0Quu;)7@Hx-f(-W!#39$ey2tt_RHi3~cz$r4&U;H( z(aGS}1OMdM2MQ*Tml>YL?9H9~4XaQ;kvd~^_TnZ&3xf_-+D>S*9dl-Ne~twm8+8xZ zOp0IuKEm0FIf%V%YY8XB#UbG4?-vv~l+&Q{sN~5b(av2(FX9pN&>0kN#*`T7=6cnEI(H zpY`LQS0^a9DJt&zYb(beEuF{TPs2Yl3Gp{Tx)3EhSq)#^c?!=HqJy0RpbNp9y);bd zZDYpxsm2VU&kWoALu-ml@sVR)BT#NNmnzjU66SpTPCJ|d)lTO(7H-f^6GFVzY=~W$ zBOA-mLU)A2#G<-vYY=*a<}%PaJA=O^qt+J}vjp}yrkkTBJoH~3bDm4QBufX49zqrg zxWwvy2S?eb3Cbu{0mO`5P6X?naY)r1CQI_g;wYdo!C;)YS@|g_c1--BIoUc|M=zAK zv&hdakQohbEfmT0m3Pi#;TQ}@?w?yZy2+y-bOqP2(?GX=KegNX867^ zo&NMYc0l!`v^_^l=T@dMRys7*LTFb*mkQR+!TS5tFftt*S%xtiR70S?TGzX4CTs|( zxjR$%&c}G?#q&bMwWQAc%F#1F{Dq0OnOq%io5XXTn1rz{z)$Y3=qkBxWP%odT8aezkj}H+btl#m@zAdLwywzfhw((u zR;GXDbfB2yMvz%dt?{y96kP_2@@5;Y7lzX2DE>o|d}Q-${w?OEps}m(s}Bvh`ww1z z^5C=_Y#jRwd@I8gzYjmC3(xaJ>pap5sp{^lfOPcyxZJnu*_v0|H|Xq{=0|AE!Xz|u z3e2AMCfH)jaa<^FlS?xBiKWIxQv6;TAc`a`m#<>2wss4K-5HLOalxp+H~1Rk6633e ztNot7dYNIq z2y+|_kbjYt?|YJ2VL`=2zSvjh8!MPA(XvXqJUMAplhy_8!vA;5cY z+i8wT^MhlDj|gNXU*|-DqY+-S&Z#fbM3;VM*|LPsb|@Y=oW3uCZGH8e2Y-?~4N<7e zl{=@~r4}?q{HI~F%-XQjK9gBTYU2KwX_OvNiuZJdl!}B~kl5lrQpKBefRTr87_E04 z4SZPj$%B2PqmeKxo7mrr@GFVYNNe-NcS7w<7)p!c!e>_j4#D&0|_@4{#*5 z%s+*=+Q5HcL)1RYAHe6ip0tS}T-~(G0O^rtuo9VB^TT9{ug_B5oxzS1P~-qf@cAmw zY2>$tTb}-~bK|Sfkblr8xbB{zN|CD2!9uw~Kp(eKToN)~WsB{l>GaRdr=VPC{&p+z za;uQqCpa0OW;=Hb6kwEnK#jLmM$NkR(QS19oSDcJ))I>9R*4D^m*g?Q2;EYbCyB!D zpTQM!%4cwA;9~5+qE15sV-NtxfFX|E51q+?KypB;a>bM9kbq61}fI?8(PG2 zH^b-i=|_yDw_HeZ#2D>qJx;|Q0j!G17l#yluoE_L&I$Wfbwo`aR2AtD`s!-6Mbo{0 zVr;z8%qx=Ww_-7|UZ)Kl*325#ox1-<&5SN&ba?P-fM7r7wV$zUMc_LKpiYtmLS?Jn z#G6?Ne0ytxh(xX0NDL#}PHz>4=dBx^Ull>I8W7c{v5lS*cIS~(AbS&|7w07y(>+8m z7fprKY>AH_Z#XE`E%iQ_tfs~o1-cih;fW!!b<9Q~EfwQr2XkX|@Ax|+v6B6GIt59J zBlo>Szvo8dR2HzMyuI>_Q<3TI##NpYDNr?X;V(ih*L)8!bf_i%$IRx)SA?iMjo%!sQQDT=h~9--Q2Nx?UtfD!j~<1C1~twx1W^3$~XSSbkS`N ziovp{HZ`@zH69wJm+w>hTBNw-HY{syWj*oMpx1`yhgc=S%?!*A0q1E?FVX@}GWsv8 zR9>?o<2i9$1DSy?8XHfC`lH#>Ii%FunBHUz~WH*&=m!)xTLV_lYU%^`uR0?r^eC7YW;=uqIzK&^HV$L)Zy`JtTNP@Ip?s)DxKSfMI z_e#8y6A*%_TwXF zLF%Ue(QsN3T%0p!WBO9m1wx|2pFgKK&ak`2Da1NO!c4Hj*Q&7`RSgRrl>Cfjq2=^% zIj{)T1RO)E#4Lh+9lSC|7fhDCSu1=AK7Vjwup1TQ*^w92bdGOIfk;E7U!H1%%|>4% zquF;cLRnC%f}RM?o0@txGqBW9+n9vMNP z{c2lTz~wuHT(+`&GlLzE@1ii*+L@JzX9?m*Gzeukk1rVp{0g!~7`APwF6& zg@Ghnn8$R{;rcnCKZrsb-;I{L$ybEFhJdA_fdI~n`Yd>A&m z+22Caj{&_5NuS2M1SLN8Ie#i}hGTbySL8qc4~sv;chqIXV*iD_0Zp&}1+ZB!rJ1jobujlOOcqYKid4=dU}%G7@zZ#iKLOFOYyq`-l@ObYW&!u40oPI zYGf;7xmui5=Po_B$X>3zs1Ot(eD$!@7l)J;3Hp|u@X+O4Ii^{L_E;w;g( z?0R!r`{!GJQ7!sEnf?$2gCny(GZ}Nsv3SQVECT8X+g{5bGs-#lqn0&(KU1v?k8Dch zp-R!v+)Ypp^3-PbW=3=4#^{w??b;CUM?O}|g*>cUsF}y8Ye(NFTfZ(-J~wwZpB7;| zu8s3-X7AO7C+s1UvJT(e`FpO}7S=ZI-ogl3TH6^@Ir@Df7?n1Uh9c(th!^>4#i@8T zN~0-O|0?8IE-a)qIWkSy)?zXfYR53BJ=3B@XIB3l$p{|fh$NT*iHQD91!Xt%6UTfF zqvw6Vi0})Co*jEZe_7I=ji}eS3!6D*%FUbuMHOz37GU~KbqAQ>;P@rIAfAdH!()#` ze{N$d3QfQ&023V zI!D<4;WVzM=dWdE`b^ZC!dt*)}*_8=%%xyfa91`<6{{*gHRw6UJ_ZS0=jRU=!u`tU;`qXxPGu+e$ zG_Y;Up4b~8G6inW&o@)l&A-QL#J&noh@1yV5XwQO!eDM7Df8?eVJiID z+1upA|qZ+fL`K6zN70hy;Cmvn305-S~&6UsDf@p-UYaO1KbaZ+Oo$xuQe0s<< z2D#EY_m)8=P*P3wix{kmB;&`NMoJ|=<1(YcgPHrR^x~k#Zxt+`iIsX{i#3pN$8+m^ zdkAz;D1uu0uv-ZriKUp%>olSC3(R5QQgFT}o>1+P1M?H0>bM~AQ?)i}GY*e#??nWl zT?iM0Rr19aECB|jW*5y1LQlX>J*{r0YxDD}yv97$1f+R-c9^7w>h&T7MSl$xmewsN zpjQ{NJF67)dVqqzn~=D?g0Y|3gap~FBdl|Z@a80dh7(hbH1Gi$=XI^KVdF5{msb#*fLISv+-T{J^_WxjZ9w?E#DuA5#@9OpFa8sDET5jF^md>i!YJ`_XqMN zPGp;Vcy)f11#OV_UGPjt=R4Q+%vW;3B|je&6=&~MHHWR)2l56Odtnka#x%)yVdR5A zcjj5P4&eFIdiYgf7|#Vxsz3^Y4TrZcGZTKY`a6t2j}C7k!hy?_3=gUL09cYk(!=WF1?I>`1Jd~xD2IxafeyT!b=gtN zNfxxE$kcJWbDbubOnwRtt#+E6WK5n=PQRtya33nM)M*4Vry*JfyTGW zeaUWlh1aB^6FbwGqo2+D%ZRM70D#Tm>f3-B@loTk`sZjAN6DCa`%Uy^G)0i~eIVq1#3)=_ z_$c~2qT{1JzO;n&6aE?xrmES0kPat7V*;kH@p&c+AZeM~asyH#vAoglF!s^{;#HZo zHr%lc=di+q@>D#xX;&t69U4b|3=Of->dC<1BlzC#Ua-*C8r^={P>C|CLppp2rwo*uFW|zm1k)-d~yvyL)J@Zs+nSf?&6lm^g*H~?SWab zX5p%tZ6vIwUe18Fbm@I>emN@Ezgar8^NKqlY@p0BDA-4YSaZD*v?(w{qA60^x0p38 za?bwv|KJrFEU5Mjkkb^Xt0RgNVFQBs`0O2wAIkdI!WIpDiF?aF`(Dd%mr16o4dQQuWM+TY;S^Q7e{ukVJi$`Em5b!i*_- z(0s7w?2SMv++?cb+wYFLR}wZMCIHR~&ZFu?PC*P)>E-d+)gl$D1?G_YG=t04MIS>E z%@5K)In?0>=ACF2Wvl_F2qYvqkj_4ZuzT9L4ao9ih)xC^Qw>g zU%PeDEW^6T+1;zU#zexDNFt)1_QZSsXO%!g6=})*-8%t9+K3!5oMI4#|7OZPBXM zPYv`eC1871xP?STTBve?k}@|X2vKiw&&ynLwC~?255D4om?F))>P)YOCpv=D@KE7G z;o!KoDC18k^gUPi2N+3@Mv&XH;?MrkJArkCS5z2ip-l{Px!R9II@qWG9UkL@NX{B< zmG&jb$a05_M%a8H>CHVXLL$^#wM{<1>oDa!`ezrlDv%|TT<_6;d0%+nJFD6&>gKY+ znO9N6H2U7lrI;60zP;CAG>0A(MHd=z_5yp-RtFvH>a8NG_4pf%gW-Lh%IVsIo(B1}4yxetho#GP*NOoMPfi*)9oBP>CnDt+Ku{tlGd+KV6NAdeEbegN-`Wz~xU zMsN0))<%D3pg%MyPGdr{5ugGkrU#`~s~t>?LZJcwXI+&Y4_b9EBzew0*QEGFh|`~9 zF6BB@!yqkAU>AcY2-F@^I1{MWaCSl;$8NG*Yh!ct6ZU%n*89PzZ8#qL(L{yE6_`pB z7@c?b3itzDjrGyeJMvRfMPYdnq`g=Mi9z57=hJ3T{NQN>i?F=-G1FjgK64H23x}xF zC@joh_4x4Iam3*F0^D1Qj<*;k;G1bG+U9vb3)bA(FJ8lO6`u`Zx8Zb`cV>|aT_6*$ zKqgLAH67^pw+DL#i5R=x>|RaB{ZzO+3iMwQryAv!Mw3%Py*L|kvBpb+M=Z%!A0E}M zYhC$3h)-p7&@fJ0oy;hQT8im@^ZqmjjxIL(Myg!BJ=lMe?u%AAloJ4<15Z%;)L;Tm zM#6Coy#FQR(R!Q=c9-KAu|%hT3OTX+=@87RsMupH4)Vf<)vJvGO$#l~je7=(uLMca zq9}FCdZyUGJ5)}GE2spmb#M;^2;Xu-q`!mt}!UN2W_^ zGZZ_Sl+-JBegF+UXZ4xUusInzLw)Oy}4q1*W6lN#|ko#hwQqJ{@-)p}3|DHJk8u=ms4Wifz~g zfjU`iR1}}D8`9!k#7@LmuU;k@q!`6Jey^OzU&0fIt&4w-UYJNcu6~AvIFQ#xh{$kw z#ez5Nm)rh|tAvOXgaXUjT!(8z!hr9yS2Q7bA$WO^o&NS(A(x!5_%LT#*tB)S-`5yW zbisw>A}#B9AIcmqdu8L-ym*eQ(x*jH#k|tcc9jrzbI7xdQ_DhL1LP***@(n)Zg0Do zj-rd&%28H1G83uG946|ndzCce(olmp^1r2YP)bjFc}9MhQ6At@SYn8>;FZJ~AkKFK zO;YNe2jAQC@RZllUk^RKuRq=K)Jh*w)Nt$%XCwG4!02?nT#X)I1u*trYiD2jv&|Xt z(kOl3$QV0rPmn7=U*cP+KcxXSjE4Z%}NS+Xoc%cR0sv zFzm`wG?SDnrqPcJX8H~$|-w40NLm4gqkI8W2Q&`F=X8? zKBHx?C8fdZCb2sc46cE`79*g@+jZ>Lhz22>eY33ex3=g5YhyE$dNdAN=386v2>&)8<|48=&O zMv{wAZvfl|7p!v8@J6v^v6+jGbcRy=^?BERF^xQma8|ju4O7ILT?-9Oy$|7c)tz zZZ8WJYn*+;vDu^5d1_`(zYAeiw_=Q2KUBmzI_%Mrv@IVHj7lai93uLNusfjaK86(dv~c0a_Q#fd+7rLE~F#SZp5vRbLO?`gCe0c2Cj%&k!GD#PV8ovSg9~ z{9JbcJ%uF!6*~K)(xtf#M1?LC=C*=r0#RW$I`t)@LjpeS zFoYx0d)6dicdlg9h9yKl(LQ*QUx?y_0uTvSi=HY8+4oSnF156ZVA0vGB73BKw*E=6 z#T)-xd3^|f=Ey~aWz92KyW6!-)+Rg}y2h8RI1h9e-{Mnd0`RAAtaQRjE>cgoL;GP& z#Git{S^nihrrtEeKD`rD7-$Z`OLx6;u%&q~4Ny^-6F7w9M$^-%+80Nq<3TlJtaS}- zEn_-dkgF4G@bttU835thRaJ0#ZP&(cPrMJ_?*Qj@M3B{q%uK>p{6lvJ%n(ihkTfVA zs2+6t&5SMHHCd(WS*CH4ys7O;|HPYMTAi$+l>Kfg^JE0;j}c6S8r zb;Grcdy}O#zeD52?W@-0WLK(Ul2~0j6pAtMRi1@aWE8(H zo(p2a3bIP&I4W%=!b)9KvS%z-iNpVNHHvK^A5BEzg~m&sl`6v44sD!)ZC)AHV%F~+ z7_)$rTP)0@5N7>&komOJ!<~If5o{LNl{Yu-{Phv(Nf7b8!=*6^#-bhIoKpUzcxJk z-s3ojouXtZF5iCNcXp`JEA*8=ALAKz3Jhyvb=ywSvT-#NAY$uFde5@GsIuKFsee*U zkpsj&f&32n;EM6AyzuVeSnONuuu2@Q>B2o;P~Z2c`z(P!Pm&+v0;yzz2kBh71&wyb z<4Y6jJXXQ%KRfIBiDUd$YUl_MzTXB;GPhct%TYpRmkB>Laj!NQVV~d!(8VkH+G$#^ z94f5a&I9O=Ac_SF0>|p9M)VrX_5S<==aA5dXW~`nhqh#)Fv;@wQ-A8KnnNG=i_-TG zPCYrS=pJaOICthIBL#FWeHPp|mBs)+tMC=dRyh`{dtm#2Zv5`PPoH`P@gTWlj-7Xa z9OD_$nW6Drudhk9KEiV9A2un_6AdxzNK`jp7ZPZOZKdok$Npg}x%e=QE)DZY9NSNq z_|+!s1l(8Is6+#hDQ8h@eQT(cSUz;c$)ZLh&ZJH8cP=W*yIc+*-o=8kLke?Pf7S78 zct(Q2&?uC3GDKnSn?$MRJh7c2T(R*DFY0mDB~sQC`gL#9N!Z zcCrR`rS_>BSWq5l`E0PhW#0B;%^k6xr~@DF`_Di%J8)S?YOkX^qH6g&V3lg>ZFrya z*bdVG4<>3YhjZ?%fA7o1%!a(_ik< zqVpxf0|z2k+h{;d)w!;=JwzTstvFv74c$tmSt)AILT1O~yUJUWZeS>@8@ftF$D2n0 zvY(>uW!NW6k5s{Z>GbhY?FhwpOd7>DM0bDYbv0e9UR1F$)=RspfgP-QCEx<~E4`_B z#_Z|0#T+76Hv+o|y&;AM@~6qjtE(F(E0R1&H!!s3BUT4DifeZYS%hBuWK$BH>&R}n zFfK*>+upp0$hET(StSHTAQ@Uh+yM&LakC%@I)j>VNkczbL@Ffiz=DPa6&C4wuL*2U zhwhGvHd~!c$H*LU-~h2xqJDJXQD5^8KoU|BO~=%+z#pz&^ClqIO`S|(wme;RJ2E4w z$0mK%7SYWZ_x@j|50BfbsCSKdsCu}N87HiV4Ok05nEu1j8H$m1ZXM)P z8G!XicW`(;tm)pxnId6JAJ~bA0DNlS5X|o3IPbzVW03ra(XIGleoj{Zry!D%JR2r8 zgb15X9w9;#^=kA-XNpC02_8P&J7hS(1v$_I0Bf;&x|sFnxy#J0|7ZiV9%|V^nFM0~ z8qp_QdI>IPekHiRXq^aS$L)E_wHuLtY!n}zLnCs=n`o$x)X_M zhxvT2rMK(h#XxD^r%Pd1@tgdo$@_(bFQS%>X{|j% zsW{i>`RVdw2}C+=mwaSlH35U235O2?(t_C#Cv%J!(PTJF^q$|oSXlvZQb;;DUp;Ii z$m}uho(IKt9fj6#E94^^mHst*_HuDWO^c;L1SuW$93YZ{Jy_S&P|1?++$&k9AjcV3 zkVM+yN4H?QoP+jmCv?MOQpzMPOUB=@eHDpr-(3e{p}9#L#Pp)<;-JJ%xbvjq2EK>L zSM$TV0q4Q9Dc4mxFI$Wk?rt-lTr$U6kxtn&#sOz-&UNvhc9%C+Q2cSAAM1RG&y%o+ z2#Md8EtHzT#&XJ9WBZ$KpK}`rTmrheDSpy1fSJ9+((5LI9Qg__IErav!668n^Gyij z&QS@OFEF|I=(Qj!&^-gt-~bYZ%tlAq8M7!x>?8Zg$q;M0dPzKiv!#o%J=NEwJGNpf z){KN5e-SqLm9f;6mWX=Ct;Cc>fI1dR3Lmb*nc5s0xn%owF-y7E)T#vkvsYF@_j}zB zes~VI&B1zzA&eO35a9SJYThCH-!-}h=nAI3$e$Z30|#tvuRjmEgj!pO6avz~Gh1kT zKrld-h?YNXtW-q_O=iOY-tK$nP?xMUZ>6eP`~2sB6a!rx}XTvY<wDAT!18~J!i>!53!th1VDf9aw;dN(2diL^FZ=& zoza)8_9mX;w5|O1j2wGDQZaZBO{+aa1)++GisRG%KvR%XNW{)^p#f8HDTm_A`vK4H z_-YyLU(g0-|C90bct*^>A#FlKk{GMJmE=~ybdjgQ^?17_n z#Rd%z2X=R=LZE9+yhnRR4~=FQiT@1#xGAgb*1&I}t+#I{{!@Xw0GrTTt2AmYWi2Fl zu&BpsrpcJea&Cvq+GhE@V*Er7x)jGWa1^p`g!2VfxN=MCfxmXsLSy*kTIyDW9=l)| zQow=%ZC3@SFb<31Cu@_z9&7)EZydGrcQnLjzot%;SeLhn)tFr4+M15I3zs%s@?Ktt zUeRTQR%-e=DcEVF`kdFQ^m}-dm=gQpk0~Lulh=s%Tk!D4DqGS~B+QtEP7Y4q%q7`3 z-&Sx5Wq5zY(UGG)xWZ5SFZEDLPGJb;`(I`f+g7{R()2U_;kfYEfb36pK(znBA2lws zn770cZ}dNtp%~y+*4QAwJ3*(wo~<0j|BzBb7iq<7MVUB$u#a^OYH2sHY|2AYqx6;* z7V8o@?^!K!_osjom7(rFmx8>N>S!|YvTu*wVc%Yj=cdq^gkf^@^3ZE@VHi@@f{Q_4MQ$tb-?3rF{2P}AuvuJ%|2G^f=9MAM2 zP4nhFbm%?5E3VB)EU_v2w_s*ET4X5@aWRLqCu8WNX2ll@fub{Rn1S^cZ`t6c|7--a zw`?_H;PKx_2V9}Pnt9cXvy%DQ_O)C|1xhun;j_*@jXZ(68Ck(+f-`kuZrW_4`PNJ$ z-g=)dBfT;ezdmJy4A`S&{8K#asJ44XVRF|Bi5^Qo<67MI9zGv;aet$dOMAY6L%D%p zmv^M_2YD@RZ<#{SBt^oo+y}H#45Kw8S*kH&G7U6v&=h+WXt=2q;NK98E?Rcdy?t27 z!q-4PbzkU~s&yg-J50Dny`ZG&wQHBD(23*cL2hdu&=ew@ko_^5MgA5V4lt7D1imB^ zTT%1p793>%`_k>6w2RS0LdwD80}Nw7y=#Zkg(>+Wwc%n=@g;8aS} zA?7Cim@MDc?h-v45W*;rTNJ;~Fj(%-Hf(VDVsdvD~6u5#WY4JwCl*InyPS%~_(@ zwg9Z2=fEJ+D@x9GVzWttOp7_c3B1pjgS5EvT;&0#P?NI@ZQhOoXrMg18E;@>L+o*12&I+=An_aLJ z02|%NklTM@;E)7af*O2qW7}mDZi?_)Xwq+FA^L{ou3}|8Wp}KRhx67!3)|Po5S*PP zLw2v!w}Z+6M?NQ)vxUf5To!VZE)_@87(Ilo_vZM|LJb3?=ZevBtc_CiL&s@}?@^$4 zOcQYtL+b$SR7xv!A##g(P%ex5DmhHh%oVS3J6zzqc;^<07y_b!yN~9@@)TQU=1u=) z2{Au411Kb5KhJ)saqCist8^;@In&DyG+Jjmutp36nMr%dEn?C&Nln;4hvaHER)RhwLrq7nPc@?6=rKlsU$x?j`QqPr5=nmcq+6|K z-+L+Kl@fq4&6ZX}Bga~ZxsG!)_W0f$j&&ycUyKnD|E^2S{xan<@gk3U2~TIUQH}th zafyFU+h~jVmr*0j;ob<9>I#S_dTFKCX-q`1TI98o&pH=sw&`g-fZ4IQo6}s_h__^t z4u)QSn$YMbZx;kk)>2W8hyU&!!(>7)S7I9esTK;1d0j-N&I}@AI;gK&2+JcG^EKx- zP7rWyY&CuT@PgCpMwdcgI!dB@o|EhQO@2``SOKaD@GFQ*7-e3Xd^`9}Js8 zNu>W7P;TJXwQyxuxG~_IXnU*9cumT%7sRG4^PTd)izVnADfri`s155F6Z zM=_Rn=rCkueZnI2xSw9l25%1eEE$v0Vn@z#uII?KWOpJH|EIX@$+Y|n!v}*c>tJ4J zUvB5sO3-9NP7-a_s*!{lWsaa$~ZP4qJ*KO7bT!vxvaK!NNLmoZW@++9u5 zqoc8GhiCdT;_@fVx94BJn4KL_;xZ&Ay5m~uOsI2K#m^yq-hr*~VpE3b5Kqb>cp-Rs zke&XoJWEL;{|)!ILj8_Y{|3%C&U&}ndTZD|bu$#SrQ28|03CYePHArs&QJzPADy4O zPeETY#>=ds;OyXzZ#6a>q|4K4w*cqXT%LYtD94~)^GEC|LqAOv?$_W3X;wJ+!|Q`X zZCyv*Wmp5kU!kn7bp~*8%$A91WO7i;2rBFT8J%`NQ%F#)d+f#$oQT6}<=#!e7BR<5 zBfr4DAY$C0^b9t+hR|Ft2&%AOy#=?*-7|`_Bm> zHknACXR7NtS&MOts@P^QJ5~YeR>61#EG4zeSYE*@Gi&!tv*uNmo^OSoV-oBba_Ys8 z=}Bh$ENJ0iw2&Ha=K!$ zGDS6(+p-6y>P#OS%#d+qSbYKY81SUC6>8KzIDUqqd4vHu{`fT;-D?(Dc@Gi z2er>7cIk0gN|z_NPOfg*(^K_A2~0Z?{F(<*$%gX_5Yt*(-JUT5(2M}xq>q#&N1_2; zmdA?$9`|F_)J@{6jFr1M4s;WWlWqgyxW%@*w-L#e{@=L}wl@@C>KA9pC_TrCB@{0{ zhYk%BnN+ynW@IDfCLFR1ufmCr&a!e0?vkovckvQ}a*${5J^tXTol3hh83M#tM0R1i zcv4|>5>I@cRc8IGUEfc(z={mFfQ(tYLf%Qpf34K_Sv8=}*A%$(wf2OH=cWag4Yabn zw0D?VsU?q+gt{Ngg*NNCL&frWu!WVSJGuF~}VyVT2d z6kpnhIcutJSa=mo+6!%q$C<7N(kg}Yv+CUi0ROQUxV&<)iTzqaG1!G=J87kcY42k0qKZL z?o|e9Hy49ez4?Ef8(5v;VU+wk6)PgV2IPb;&)#T9+vb(uCAx48*IW)R!pxTz-{Pd_ zTvd(^UQ!-#*DzjFdA+dptT6DAr+j3$yV+081W1NmhHp(I9vLC;Qjx?Iu5*G$2icZf zp@qW$TP1^pV!1cT9@)dDN!2Xd%^=Te9f~kAT$iBuGaB&38Y5-!<8*@qM(>@8U+E-M z5SWKvGP`l*tGv|dDC{I>f@@% z$joFm<#9S;t;W@kik_aAiIa=-o!&L`tz9o+od>qNT{S0tC(sQQyfmvs?vLxjnKks+ zk8y)X8#4SddSe{8c9+{5`RX;g3726bThRLm$?WaGDpv9VGJwAJ#eAKt&m8_PWO;2t zh3&*?ryZ7vo@7SE3~&WGn~7iX<-GK2!Y~j4c^|)iiC@2DhY2_CW^!LFR&gz))PT6A zI4m)K@1Q1v5oSm?z^+KxdfY^~nPfb|2gN=V$7Tmy>OnFT2CK-CYSQ;(@@R-* zHmfF45?!K`NVdC87a<@%VE9l;HO`o~cpU8D0A;qKMwtQvZXo~h59 zgjH%?ePZ6m9)C}eEVt2G-7S3exn)yvI85xPHm-++jh9p&#zp)M=ib!g$hu34nQ?A* zdM`pk0*hh#D#GXx{mLP&2cnLptEDo{VO287Hh#`EuU_3e=#8db_m4IUfJbLs4-Z`o5M^oE6hi`4A*BJnG$IeHd z{lpvdM2q-YqTjTF?$8PRIK@b-{8T7}8SFc9Nw#kl^);ME9Nleqxo(~BKCZ^qCefb> zWk&`c=fule3~{_&-w6yhI*sN?)J(T=W>Q(@1#|zDTT&?=f+Zrr-6dMntwKj-iow12 z9xRKtFGIrfnM4t|n1q5Kzm`0&q*$6k4~}6me+0|1*7+&4GT2J;3Q77bGn>g2IAm;6m8qyE$ zRjHcnhnZhgfS)2^dnlhUI>%_28O{*-)kSZ5NCXjDzD(O({w&88lp2+|v4^!kbi%kU zs@$n-*tr75ju+9pUXF*m3ZqoZ?SpkX@7^67^-eNIsuYFymi{~G&0V&cEG9?f(<`A% z{a*0PU$OUp4qX%10aU&oE8yyEY^NGfB;8DalEh_^Fd59a*-7HvT-bUUW*%$2$SCNRu*A?OdZ!F~^#8+xy`&ESeio=0e%Q8>odQkVHN zH?_vuk$x?h#$IzM5_Y`O;vw*AqTzrb$clB~EQe80SOB5e=-s5m7sQXR*RqB9cNvM$=ue5Q${m(p z`!~l=W8jaTTFVGpX2@HFt&Bc}HBA@bRFuE3lHE>`@231y{*t%C%h^2Un>Eiwy2_(E zS>Axv07juC0}0|`@%uGiN%^r`R?1K^dMskVxkT@MM2lkkb%0i7r48FKoZrXGb7&VT zbwc{L>zz1Y8HjX~4MLAMQP^A}ipFfApFewFE4ecRvfULjzbEE~Id&_YwI%r$&_|A^ z?QZFFUUq>g9v8CHEUrOW%>H*hn#`9b4ssgsls+rWxXiy72Y>hf(}~>h1_n=!iR2-o z=-3I5a=xA@Y(9ccpkPmlSBZvf+a~G(+SIgfuQ&wste5{PVr#(gS<)0buv)E@MTxAn z;ZzeWlakmYz;ddGnUoD&m^f+=*0j*IHd0TS;Og1nj1%zlzHI`5=9GtNZ$+MAKs8&9<7RZ;kmC}=8_$53heamGpU|N>e zNiE#0D-*wvPKe15*Ivheb7Z@9t{@9xHWelWN|eXoGrNY=MVIY4v8_9M&W;deoUOl} z2ebPG9Py~F#J5a2FlvR6)r~eb?T0CxN6ZqaM-mLF_i=(?Z-%!dc_|1sa#d%2R!LtX zsuFdw|F0bH+7dd6gvJNdIL&+jw`oaxn)V@-iCk=XfsiMW@KewvJN};FD%@ zf=6AY+h=9}R$yr%Tfm*rsO1=J!oeOjceQS@I_h9G(%d@T9TR%tUyqupwF_j&x53}l zfm_@EtjAk~B}fFgz7$EbFGa39cTBbqI-8?K4hW<}FY;1$hU3iyr|>mL8??ROPEOe{ zo^XrcLsOk8fd?|`dEN9M30hPnGjezM2%y05_D<=dS1tq<$MVcCg{u#(0sp;&l&fUVxCo{rnlKnW_*VM zQ_4gNaxXbR8mgQ+i{QEZi%2@?ny&SCmwh{UlZhoIUx)L#9LXoxCR1GRTUg`e`=jSDf9* z--8p1+U&5m32Rac#MylBb^;;*`DH>72N%SAz{Q?O+*kMlj72?-MF{`RTR;Dg38qb< zjR>Xr9=4Y8X?2b@b0QXVZxSJrr)9MSI&p`@a}L{H5y5BM#xJ*w#?*Mnok3(=AQGTw zsK}MqM#q2A2L3d{$cO?D+>lg#`t}20Co)U=(E(RTIt}`g)prmpi7uMc&Sq@kIQa7| zhRdPtA3eQWMya?xecq~9+L9Ga*7gjcF z?I+>GSk@2->?>w%G>uU6w%c;NXmk#Yt774Ds*^G&>I*AolFES9Bu*y)-aJ|(^JfL` zti@*T#gxGP>oJ=JvaOwML%TOp15?W=3K+oNl1SdP%` zI0OU-h4^PKp?Yg3Aof$)j%9~rQp&9B)cDhx=vW@=iJV#G^$0TDx(pW-90;Zf^l(S> zI-(1KRWaAxka8*}BCtDtg3nC+haW}vx9~u}Ao8Hw5DWS9QX@Lc5Kz%Vx?AX}SMjp1 zPd;TE8nXyL41c=JlSpIIgkDf_`r+f4p7JORR;Vv|?%-Oa>)&f(!dV#C1lRX%3=Ms} z8;Cz)Pc=l~B}tqXmV3r+)t|>6{{5S+KEg>wyl>&Ph)Jj!yi`nJ)ZY*w8!P0uWt~h! zyTZIN0R^~c#^@t@@g^u!Y<)t9=gT|%VExEMZ!rvNtwnzuLJFoH+H{g_$!XV8(6`TT zHm%r-#%I4t5~4R4OTrB}{G#Oy`Du@r6Z;iHb(*<*{3_ zLkGgDyxt2ri_OT(GoIu6NV_k^v8Fb&2!yjj#L;EC2`TER)Dif4xU*|er5mC!UTA0! zdRt4#RZvnjN*$@D{idR`d$LF)esmZiY&eQ4Y8di(h`lXW6|!Vwv%M)KqZybUXnYmj zN95{p>&SoCTyjM_a)`*qcmQIv7%K~_xz20W?d4-9(>J;tJbwn6GAS*0>Y%k1)9c|o zTel7u#%5S!tOHN$gG^P}%^U}V1cw{<(Wio>Be@m!aHX8vFzm@qDgaMUvy@|^fm_QO zmVtX+5L%5Kp{Nm;qo_RAOR-$ZzcI~y7fl|gjFokIV0vvlIgb)6C47ra$08$O3 zs&(MS5mtST2`A^U!pg$l7a){@?XHoHU0Qa^YQJCeQt=u+>?Yev#^Z<6LkMpBm5^x>`PzR=-$MF5K$XR|A?w*r)hdYw^ewiU;|XEKltBZ?}JJP;HZyk zn@~{W-7+M#5qW<2E3nLRqjxEaaZLk&>?EdSW9ZQ!%4WU9zw`ldi;0N}OatPhO0Ahm z+h&xm=hizid4VM5Ox!i9PWb(|NYciEh2$bF{P3_nJQ5XHLy1-?Bv9wPVBick^SW9k zSiw`Xr?cg@c$q=?$UkMU=D&JkXe6-dFbK(zn{8}z5c5dKC4{DahAo6NgaHMzffKd0 z9)?KbgQ{ZY4B{08X9GLlB&@M^2I1|T75UU;Io$xyTOjB-O`^K)#Em@r2V?&?gP;Yu zr047l^J?*RU;79wY4GUufO;v1*Q1Q(4jX^}J!ur*;<1|4xTM2aFZ86NgRx$*U*+>* zG`R+`k82|ytn_-l8&a!R3dv*?8JE~jhg7V!o#nhIb8zo2AUtLrG9f!AAn6h1@GMI$ zneT`v9$a@U&1`Z=ecxK%dBz_>OiUoWRlbghdRKkh4S^|1?mpo}Xwt>z!ZKYY!=ZT& zu-%~8h+(IH&_j_RW$UJ-njTkulu(wqXsI*71DU_@U#ElD-bO-A`FnMsL8VW})69SDskr$iJ$ z3-9$@8=}DMXblC$K`wPV5LRw{jk3}(J+&4cUo#hR1=hNJ^pC8|I!>&qBh{fJ@|7RM zefdg;8gMXFWL9)()kh-xf}V?qy+nI66N`9abks{JjB9wdVy!U>#mw!wU>c&ikY8?mSw%k%U2Nz@ z3yRx1H!DE5Wea|Ru$T`CQVHnVv6KN!DV=4JM6d5G-(M2IUoip4IYifPp5pzIkZUEj zC|9(SvN~qW{}~7jRh3_%XSb?;6Te@ma}j2hQG-FJ3ZxiB?*qhv!lQ3w79Db26%K}; zC%QC*pT>eqy&*(5!MY zx7^C2{fi(sofbuTnrR$l)O`GvF-0Bfw{dF6yKh;mn8SKlAB=xtDFN#qu;^+*HvxWW0;@{tlN?hYC5JdYZTuhj3cp83Cqi zO^LIW5$XfsMD=dVFRX{9Gk%Y~!pwbBwl3XM)6IAI*rUEdcnQbic>vM;OZVjhCiNz(mbLT{YQu~E-;2VWikiSa0pmwe9l>UiYEK%itRJ;@R zb+zfo|^4&ZzgO>8*0WF zz#_6g-yr3HpIom2n1^erD_46GkAc_<|HQVcn~bMNw}UQG4?s-5wmCVq*r$IzeW&t2 zvUb%_30b3*qNr5b8a5k_K+&M|AI5!AG!1BcE9=dryQCOtOv92e9w_6&!afJCs`N>4 z;MSlOg!QMV z^Sj!GXt%QJ%b^VVS19$SV4A|Ekhe&K77VfREgjQt3slZHj9iZ}H28(0nR!{C=GC5) zbD#N(F06TYU-?!-B-XT4{K5!BAkvJG0|Gacb-5AW*_9gyUQZMzhNF5zdhb3Jfk5AJ zH9ilMB}V^}x%;=oO|esOVChOi5oG8T-ZIhi)CklxRwlT<cLH3(gP}CSLuL2HmT+z^lGg z@revTMMzy8PoM*bOAt~Ne9~!ED`qrclN(<5f=ukU*SKG1WT(IEM2db{9j|DS`1r8J z_{b#H1_vyj_Jh2Iz8-&0Bo5>YvEn^Wk8g@G^kng+(K(4lWCZ^@P|e{X4-G+^nv65jPBhFrM>Z0v!x__Ex{tEbjR7r>t*gM@S?@ z^@oRWYw5?UghVK+yJmUhxR@uejQLdnld$*dc%?j|ON@zU39cd&Fohs2TUkk5ms#?tR!)3c+s0^xo9eJ`(dSJUfERqe8k7cm*?L%xjIhc86AT*hB zjeiTIquye(iXmu`ODCL^Rh67k^4v)UfiW#6^N|zeEc}6ZeAAxTgc*i)DU6wL&T9vx zIj$GeM)9G<#X)}n)1rm-n+U!m0f2H~j*TG$-EOrgB{d{$c))7D;*N=dXd@YKZK?Lr zRW7>HqJ}f9^YUwk-en(JH8het^+#Cqlt%rGmJ7iM|BxWaiqOB5@=uIJNnyViLf+pr zgPKl;mQg88jGBXkDH>Zw1Qw>l56H4@baYKS2ARBlefh5$=E9c)F4i2`z62dY;iyt_ z*?|{ojXeT`M$)tWZ1cbCb((e*pFD%3acA7 zU4tb$bAq|*TdvqJJ9@PtT1?ZdyV8n3!cW-d>sbIk2s~A~u&n5Zm!=o(nzNcH0Aobg zwr$(KYumPM+qP}nwr$(Cz4=q*3DV`uJiuwDm{W`(#70f8?GdsAl>zq79^|JEXh&5< zO|m(*lI=L#6T{{)xS^h&-_gyVJSg}K#kvi=v)gso0)%!@xx@+7wS-HyHYS%xd&54j ze~{Sagv2a{Upd-quI;XETgnH**0)Z`#7lr7ww7;2U{#;S**;#YiG`AixQ%EL5$*I_ z?k6azASAGCRXvK=$RTbQ8&Ya*J<4GziG%5)uc}aAzvXZPM}OB2)XjpnXl(795Qz!a zq*?!4uOJfHmR}!8W9LmB{izE*^2Q#%E`zO7vcj&7eXKfD3}!pY`5i+HgYdfwwN^UL(v{j#kBL(Azux6yz6KIF~`Upa+lxFjbt1DYI-X2h5%M0{T&dOq)6gdZkC z(d=Sv1NU;#nt47|2bV&iC{D~A#H41!1;mo&b?L_z?(t5ausSy?rJwZ}cnq*`Tk6M@(&v)8=X{Rl%lr9RWoKdpjZ7rA~ms@U9a0gromf zRF}OJxJvs}w*|dRCkH7Y&9FWo-@VDjdymJeWjgtZ#>R91USn}}jKEP_e zcdpXP>r_-Rn>C}n9R#6fBR+TW)4|i?6V)Ji$%tuSeqlL$F_xDX0EqGd`#j0yksP#O zv#XV0ZEW{Q6MkoMyD%?ND;Qq_q-}#%dD*7f6fyO`el1)>RE%6r@mOVk=N6Q{!&(75 zXMh_fL)fR?qeaP!odD4_J99`%!9F!mQ+;8?8i-3uRp{cNf1G2>_=tYBbPn(ONpZ^- z6TJ0jZYHmdj$~-jy3svzx#_ab9#xHY?W3F%uW~BkvOPVc70^Xd9E#p6)pyicuFMrcgVI>CqRNSA7f%k9UErirJV z0fGM*pya!{7zQ(AUg`su?v~c)jFGI0^n*XW@AzbNGeyeaGje%%qW}ivt#t1Ja4481 z?-pJevLEB`)W5)$JT~)2A&0Q>=X;pRp> zq`{(r4pTd-*b!MvG<&sO-d}D#!l<+h(b$ zSg`O~mk7W23x4mK2MS0kkoXM!w|sx^h2(a!@zr4d;oFC3qglCr@39m6_S@WdQlud? z6o@(q77M1rI?S{$r?AYDO5;PL;n+!pnJ!@a@^^^=T*r>S{%4HFB4_z_mGa(fLWE(ef5Cys z6pVJ^Z;+m*7gm0BltCzI6xg34Hf2HE6ov@Xwrzg3r)2!mc1kBm0(5NrfBNQSk<}8Z zE*L4f5>;{yi1t4UswBAN0;>(agY}pMaVSsIGhQ;CxU8~w_$zWOA0k~A22z3YT zw4{86`$>0NtBHFd&e(ibLLA-cp)_jRI;q(w1A_ec4!GnBZw8WX@N4hB*R=rqN%Emjm+aZQ;~WcT%3I*LoK7~X{POvL6g_trh1@1b_oPC4Ih34F^fSt+9! zwZJR(kT;NaA0BeU-2ECofvyQKdANa{27;(tAT~LJ6knD?`M~~w`8g*_?I)~6BsOMC zR#WwQ2~NAdD6->MAHPCJPEB-POh+>ZBes_TmaU72QQVhsQL$1Vx->cw_QrH3iE-cz zABn*>H6mPL?S;{c-!~{Md>gXH1C49!$Cq(+;V3=En>?gYZs&4CzhQhNL4)lFT5!MOFfUB%b%Q@{Ges` zy|{46g$+m{&ScGvl_?nux}?RN_Yh6IU&(rb1a*3w+BQN!9 zcbfO;HJJzT0;DubuAGsUJ``N)A95yl)%3#YI>?htP_k!3?wXD)Js3sXQ?q+P<-zOz zcv%E`rZJ4QM|NjFD&h#b_>2Q_JrR(8VmEKFJY_A9UXx_-(@PW`}S*y@L+8I!ko z(0~b8(`tP?t#kwice5i6^=qYbpZTgpzAE^|ko{eGgT#@`kE+fO?R#ekWfo#;FH=t} z=@~(3Q@|ji9>b1{+nh_6-C63Do>8$Le}cF4A8dp{^HcM^JxOBXB?7k)V^a5o(*m@z z+-2yc2y4FqvY~w*;atdPh=PW6gFeOG%Ksurv;*hNJe`sec4*O(TlDCUuG$bay;{DrSzvzXFCEb!`gH5*cEE~GXJNo*thdI4SEwf3=) zFjJhnXLLv|x+?M$G;|>Q0SC0fyrFN@0XLacy;hy&xQLiGlbg;$*NzwE2_VtE;(N5B!E-c2&7 zzbq1QHlaZXj`?;$@CoL*B*eEP0Z%aj620*$S^N)KmO&la6B0xA_)i#VZV=>8GQ*|A z^1T-w82=X~2&4{27LeBQ)1y+zC?Y-L&tUu^f+I z&}VjpvZ$Bn&5e%i8orzCYPhJy;LhcO#?3YO(u-s1U&i{|tZdi89oy^}lD-Dv{EJ>?b%}&QVIh|CAaxI(ySlp9DO7t&{B+(CUow%m|`X0IS~<;BRRRzs)VI%ppjIJ zj;S@#_>&D^p>}ij`jlE}wU_v6TD+P+p3Vif{El8tMn;C0Q7E@lS8B3GOy8jzXv2=E zc><(L$thBpg>Ve(Hryh9b3gh5%=XHn6o<9I;k+F$4}$LI?oVmSpDh9!axZ76?hB#^ zZ)!>9^)lW;pHxVJ@PXLP^^ncabs&s#x8{Kta@5~*5ws3M6S&b#vIJ|N4{v{MQ0ha^ zy?G0!!eZHOb>%MTKPVncRtS88fzIbPbB>QFRG;jbyie04pbLsn7N}SNCKL(tA_Baz zrE#BF6_E^T2qMMm=hQ3S+7ZY_A0`_W!_iPG;J{S<+Em|3j4P>M5KP>yqJ6&Btt!at zejL+csZVfc=6vxsfsIIzw@Y0gMv&vxhGv?lI6ZN~D>J6i-M7Pfvx!@p=4v3G;vveV zfPyjwylLj-qhfPDZ|E96!c4A~`IoY7?jz)#WfoE$ zqzoum$}yx8EhoA$6KuUw{BCR3qsO+xp;l_gaUL^HXXN$BQ>UcE^)cT~4L;1TjY2(( z+w`D)s-u!Il*)FKkJgl!~cw(|a|lqA*rA!_N%U(RntJj0AFfAgMoRVgHZQX13{n{|Jg zvg;=~A7t%kRg^-Z8J6aACEU_XL#0?Vk{Ve)PdsWGhcmy?P^U;aTzZ8MH?ZJOa;W6l zTW=k8kVy$5C{bRY`%ILSONJwESS)i@n~$e!WfU`|_s{i(B83=WPl$ zs^w}SrKQ{jD;jCG(H0pTM%V}~M<^0pqBm=Mf|-6Uln8iCBYqHFC0(}ZU@Zq zlw3}g^Nw}tfS~P0UP;b}Dw<%O=8Mu!if9iKp-?lth=5!>xpV9>Nj1YoRNA}-y^#d! zpq^K8ts`Y;x=>?65Akk}rmZOAp&hEVlXW$$GebnH0Fm?}TfWdIrr$IpnI)^%>@{g0 z(6rMAd{^BID*1nopG&Fb88RIG?lixd{JlXjOegKgtHmg*0TXWSfdVQ}f^G9d$gW{6 zoB$~l&RrNZu+gHdSF_-Si{-;_X>N3s_I0sKj976ph=?A!)C;W+x37g}(GCON5`upU zCXT^C1jr$A)hO1MVJ*P+UnmY};{rACF8k@V0&2fv9ng%QhPK;ecd$qvN zo)IJpjiv4mBN5=_UT#?s^qg!7?T*f|@O-G+YXZ4f*oRvOdvcG#&>Yamo9Y%PE7>&k zj+E+{m%zZbGU#Qdqn!^1S}x(59qFxepxP>Bg->yfFSCd4j67?VVQHbpHl}E+8j5;Z zjMxB6XbEhZ^qe2Wv6N?SAODQH7=eNea%Q|}6(PKTQ@oP!Jjm`^hP`e=<#g81PSm+p ztypdqnD^G&qf=ELQkPc-=k3IzBeX>e{qWv_UXYC4KKcFpmlvm05VNA!9m(mT&SOW0 zP%A}q*{3`|EY`!#6$CAhPH(h^#gX-<)hXy3Im}3nD(nabmtw4Jg|Obh?oN{B%(NFQ za;HUwMI!2(s{}?kys*xNIkTtgj%VB)H=M;Ui-D&0@_b(8D_dm54qts-9*2w><7#ps zj(t!$#_GUU0q=)!Dk#+@-XTvf(F>5nxpgtA%dYq`VXRb8bItnuLw>z4W^Tpvy7NtG z=^sj0^dj-jePF7&MZ4tUT4KIv?nPf1oTwhA2(Eg{p|(17{(J|c)L8X?mZ>Yfnykou ztz91)HaTI~!;k5AmXgpz3~gHIlEK!)YNl@ot8LHNx}QWOqZGg~e&7W&dBL`MCw4)+ zHckOUO}vm4jlKKWNnO2A_&$32%UU8gbCR8PUFxN~cU*L7@W|>{-^+;eWkEWJlbcKu zYD>n)$~ofNc}eWj`Q$U<63{oH7ZKct`W{7Ej@=8}nDOLzdUo#@0SF)v!v-gIpfs>J zpr2k-Y`kJjwvh{0LN|jQxK6a3)s-qCo1R+!9VPYulaAY2r(EaH7Pv5L)daABPobE? zX!=TS(HOT3ghx+2iRu=q-3Geq%MXT$bxg;bE=`Z}x=KPiHv*GVH;8SRd$f|-QY^6? z9x^_H`z9d7wL>5yDq)ZQOM%AbXb&MFzN%Fy1r>KuIG)WAmw7XEOYpkIWG*1GD*&>x zaaQYLOZ4{``KF$xsGUePTL6qH;fc2+YQs^SxcxVLM#71zhF-cXf-p&4iXsZwSL!lC z$|Wpx5F|g^R?!VE8#&>0+={76B~-wDzJ$k8$GB-f7d4atS>@l)3p;i$sD;1R84=4$ zRSAV7%`t}9G*qo$=BS$z4e1;oR|E@20R0sV9UpNq*$MwI3xJput!9ptuC$E@J=ReD z%2EWDvN!tm)s}FDArIQ6Iq$TpO0wQpeCN&m`0F4|97%N5|H9PUXW^KD)ThmG@7LY+ z_5BER)qGA^wIjd%dUPNE!wE%Bg}mStOo!eq?VD@5Jyut7=a5iTZq1!|_AOt7ia)yl zirrDGiSsu9EfGO2yzws`C3rPC2DMY+?&xw9U>K;i`oIQ7FZI@iNz$Us`+Zx8%u{u0 zuRt~aA8{flR~*t4?-O5EW?99C=AIw1d65i_Sm$(7V^IYZlKwXrvmi#_^~?>fpFrSr zWxB`fKG@@zJ;A|3f{t7R%_CR}xT5Q#?<@d?$>%E=-WJM&Rx``KLt1fx;H61638a5` zubXdO*9kl&&;Y$%`A>`YaR`ZE-+?7*QEevn6G`Yah`18H(mSEY)g1ix+7;VnlxKHO zO6jTREl1$LQ6>&UN@1sTy4$BO-WCK5E?@MccP~I1aozT-Fns{89^A`o2n6fRmUyOF zj7qqGyI#m~&zw)-Q&+jJT8J|O!ph7`(PDr8OYu`npipO@VIw9Si18%3vPa2VzigO{f>in%}7B0Gi|sVi`hGF0EiTpm+|{S&8dZ zOS$R~k+XpT0K>#)|gkF#1$fxA{i-bqvaj(N!$Eq@(D#1^4<;QeF)|{KvJI z)e!>vkQWIZBNDU!aw$G}46r=PL=uaiV|5fJr5ch^4}tM)__Pc?I)h@e18?}5EQ@K) z%JWoI=9VdQbTW`}4tuwFgfk)tB{z2>B8KC2iNv(F+L6z0pFPCg%St#F_TL%TbX}D@ z0w#}x+9%+3+m+*7&Bao0V&?z_R?_DwcOxq_J_sX2sSqYxNdIDf!C*0+8# zc-5JK9)Vb^yg@c(z(gBvr6|fC*~bJD(|xZ~UhCiRvmKsQh60z0k{+bme^Ap#8pq z|M(MbGjrtb=%StVm{?;X?#TliPoT-P%|)~wD5%q66n=+4eM4#t;?oT&wKw2l%I^Au z{^i=U;aik*DUnX@Bh$o#+kOeyZIX#RiG3XA`EnCL`foEK_jcR;Xp3Y;*UaB40rS7J z__UIb<=dJQh?PsT$$(2T!&hJx5pd&;zgJjKj6k#XxuCT-?X`aY%FBJR3sUJ&*8$Ed zrVT|w50qW=vf2;q_D5cOBy`e5fGCaz5+u3e#OmW|Z-2 zDW6AJY^>b@QAYE>0(2ERS0K(|D$&fNh~4Yp2}++Ti-a0%#7J*rIXjYE!0Bi6)d_b| zPVL}jrfG@klHQ35`w97Hl@TQ>!@T33PP<@Ln4pk@LXeUeCIrLDVP#v2P;Yu4=H$M{ z0Dzwn`uvnnPw|5?1PoswRY`h{7}H0Dn0=#xOz5$$hfw>Syn9zZiW%~@Rw}X35@X4W zt<%mhPgo_SwG`t9R=+4cVc1mx>gF}#m}8AQFS1Q=&?Env(e9owL$(xK=Kf(?3EC3w zETsik7rl3YhF52SbR;RU1XZ^lA!+KwrkFs7#K_E}gK&h$H`?LZdk>(;DeDXu%{*eI zF)W=fX6XZ%GQvsp%3~ngb#~WNcw{-hJ!p&7^)eht4I{IX$Txk52?UQEPykb61Zx3j zJ?mU~{S7Zmw2a|C5)SCVziJ+=Q_T&7E&nhsixQ<$oTzY^dsc-HRoD ziGMsPSo}iRa{4RM+3CaT0-#Cqs<8c=3XJxuvF$XiO=7QBL|~6*5!+}|FCCVc#3?67 z8YV*LNb1nnj?POlA}zSf8Pfr^f2LZH^XY+XR10G2wy(d9 zG}DO&I23Vlt)!w@Cku7snf8tlSN^2s5Km_fn^o9Hj`8bcU6h2^VuAGJQ7VDfE_xx&6`C zDcgAkS7?^<3#`D?$;}(R@C6^R(Ft-vzmDc$y~>F}o;`#(81Hn)HyL{IT*yvvC(GlM<0cXM~Yrd z)(=Pv9Nmf9X3gN~OxqB)G)g)9e2$;3_t}Z<=hbs`YnFPTiUNb64@l<55)v|}IX3gi z0AyL%pu(#5JamEUoX}&-R$+tpbSAZuxMJdc@PIQ%6g|*)J&Z$r43m&wJQ#{nW3M=m z7v9$)AX@L2sgO^`vS+^c*e_4(+jxHW$o9kY;NSDMUeK`k1@Z2(*}Bq6Ow!N4x;O5K zsZ{fk$anCI8Q|={fHV072ntI2323wWs?PIb&_XdzPdf%r^`LnUg$YkI&qhN~N6`d} z&ohdB^t)@)8V@<%TWR@Q-wPaWwfw|$eh*tQt|~vrc3f2-dfJi<@KQ@tLZ1Rwa)ZIwyf$;|O`xV$N%@Y4M)QjeJ0TieW`clOnU(2TPT+MtzqhRigMz8% z18$Z1mGrXY5?UA-v29*SPfp?|7Y{?bsn}X(4Uh~v!42p!tge~QRf*B`FK&EgJpk9v ztYMql(%qOnJl%5MsG>l~6A0XI2i-q$92tW2L8ADc(a<@F_{OG~D$hNg6z(jLuX8%e z@1umV;A#0R_5|jFTvFfInDf2NHW>iI_rao;)U*QWVz$={47oH6N4znu1oTTdD8Vm` zpyp^Zr0pJe40D$2(6q7bJx={wRe;j4B&&hg>s2(@TDE z83_IufC=EaO$@xFqao%xSBE!dcZ;G}J@zC(#pHhTMgbpaT4D4&ZsnrE$R&k4K&ALI z$08i;c6>HGZ?uSCTjeE*c{F(o=+@e&QRd6JeaP|u6Kl68kh0x6CL>E|F+4ZfXDBidE z9;tPepP2i7dwaR{)k1Io{OcS=)?u`OL40LF^}pMhZt-L9Y5A4UC_IXOjDN4bYh0kZ zO^vHdBdO|eV`pXvf!ZGA>pGs@iIlS(*3nI-n#DDqYO7(TQIn~?X0#~7xgpdm6)q-;VOJ%>x$V5EVmgm9AeyA~OTAE><#i*K1M;t z07A!WkI7~=6F(ElzZ5$IztHDu$Zs24?&in99z2(rRm8UWi z#-R)hwb%vEtSzWOsE+B|o^M$7toi1CsHQz+F7{({x|UKj3}GoS3wcA{B;o*ETZy6l zl6Eu5gehu{{+Jv)=ayRNe-bI+a534_@EnEi-hqRIcCiMh0pOdG8MRqAh3z1t&*&og zBB&e`gvqLUt!h86Z(RS-`kLTE#qLih%__oJdGx}?_t{z`G8$m5-8202zD*HbBWV48 zQ2q_nr$sKF2G~vO?*1yYLO!rbTHvhvd&#D<#HI`0YLloPnli>H8Lma6Hvuot6uxgK zIOxIdYPk-DvgvDLp)T~MY&`NIeYPC??=Jl=YDg-*D`Ept{YhgrHcR1mSp!g5Td?cq zLZ301nTGx8uRgxmMY?e6qRuL7LgDGP#!S<08T(yq8CcY%i&KVV4HG#PNt%PT<9ZkG zE+x`5UBG5rlbGr9Vh$=q20KGV`%lMPG)CR{7WeunL2;oLmmiot+Myl^P*d z#zZBbk7VM(oE=GMq1(lt-=GZaGym=izguB3ptlpO!n*GAM_B=a;7GJ)J7|kbmewq9 zGm2ds9idZy6Z`(NaojP$Hem{HMi$d>C1E4P9gCr*c2(;q&3s8}%E z{AJs;-N)G1?8&#WO^|>03Z<1eZq$}|f)DRl`sR}WeLdnj2K-zvz*kz2V48f|Ppt+9 z36dXc|1BtIRC>5cXY^NQG71zD9dBiPOD3F1_+MvJBXs`T731NjUBeysaHpc|f78ZJ zk&e4w83>r0)~as08H#eKcD_&lgu({^ru3X3$d&uqO^$;imY)u`tv0at0uMut57AZ8 z;ne*?i{wX~u&71)fF1YbI1$cU0(eEllCLA6$JJaarE!>gWm~5qAJT4q13q)(DPn0E z>$Xgp+}v)_%|4BBuv)VZ3ekb4GNYm-N#jrR@(GS)sR`o3&DoJ!$MZsrG(3VWv+s$b zyJoJzOfCr+XS)vgNEE85BIeGeg2zTMWKYwF4x9nCDBKi~Y*iRvefEY5NJ$S>(G(?+ zah^JU^x2OTM67X@%4CMqvb&xTr{Tof4?RId8{XL14FiAyf&}4UX4-FCmsit ziGwg=+QWZ}1_}VYp{;MmHUQ(F(n!QEJXGk5vD)H^tqzEw!8}raldX+Dz%{Hz+NR>I za8VHT0ABzOINnni`&$69y-1Fyk`~meK!3NFE>)ho;GUN@Z-#kGfZU;Oas&Y(&eL>7 z%ra_9Bc&g$*0)2LsrEX=)}?THfE!ek3@GAyP7d- z#ZdDhrD+!Q$6?QV5+$~i5h&-v+D0Rn`z&t!P!dM8b$~|9gNMR3eV2is@YdJ=kX${Z zkqX4MaYrbWY`jX|B0ZitY6;-^fGsdI$^DyI61R&L!R;AlK90J?Q4wgFVqMvi_p;#h z>iU91ni0n*Tmb0MA?RZetPs=A&e?#CmTe1?pRid>z(u|JY-%4w^{drk8Q}=R#3_aKUR6)`F;3oUjv+seEryz6Ko+d!Ng*T z4I)BQfNy!n<8KO@o1w}~ci z+0bnSej{<%eK4`k7qmz@&w<9YhXSLWyzA$1IG|5FjlB#n+>RZB>RU4!8mO(W>^njx zTq4~~z4)sdLJXpm(qavh#7HT6c!u$IY!?h0U{e!v3a`VLCzFOi07%jh*7LBlBD>!H z8?d{tfrRe|ta#$mQby*PK8)j6v5b^vR}IQBwYKGk6=%8eRVW;3#vlPoMrF;hJYWjL zhKpTj8kw4$!D>%`s7l5~m-jCgVQ`X!u>@XDihEAK1d%H41A7IpesDmz_Tqv(B%JIJ zn8+fmF>zq+{r7~q#WM?3K6r8zH9>Qzq@4T~WCOqA;?V4oRZ0rf(muz;3Rbrn z%C+Rxq%>=bbe}k~nsuaq@-K)w{ZyQiG4rn8ufrMG7PcbLfO5-ogecJszPb*m$MUN@ zlu)rx%urCbtC7~r4q`EbqJ$fD$a3}M!^^C{@$%8yznmqwqD(kBA5ygh2ZY!0s%-k z5e=`|?Q8R|4$o;(%B9n>R~v;jT0}=FB*aBF&m66g>=n)iebhP`U%?t5v=pPCXrQb- zOuByQt@_JuEyoqG#%9w1ml4>HowEli6pcLAo^&$E3}Rem_vENqVss>4DrNF{@Cs5P z#dtXKE#PZf;(mA6y0JG5V+6Hd6+$_0%^gP$nhtY<>J9gocKfL%iqfzG8jIQKX)Aj8x?gc=aDc>1fQ2%(8&|g0828N_Bw^< z>my8ut;p!8a0PV3$}SGL?GlF+yNdoTXMLtIEOp_BO$rfs6EW-3xSGWzp4eQkeWlSw z`-HfOK7=V)SDHZ`*bc&QYOQT~n}FbLF_pgsz|+0XCJ7a(5>O?i&wn%GXZwI1=&tfo zVFV|{#yirFLNmk1Irrsfi?>1K1slO3nCnm6+H;pvXp-iH!x8nfW|OuVg&EPn&oJO? z=zY-u$Z?KX#n_%Nh%N-pyIJ@K#jn;(RrwbpSvC3Nl$Q^G@U>LVmaV_jO)`q0a}`l@ zL|FcamK7M!MMWHU8i;aFBSYa#y;PZkc1+h$@Iasl)lxfsgqbKdN&y3K49!&MllXU} zlHlp9w3GcioHXXz*qd8Aq}6DgVa=%W#k{8|ME#gi%1Qw?O(u_UENECF_Qr60i?X|r z=+OhAX(6@$T%MX((kZ8i3f>r{Z{&Dl8qFg@{3G?D2^QVtJHrM03JEQospahh%jYE- zuFc2^-y$iene>JOhVPeJK+`uBK&7j#O32nKdesuC)Rg8u=FyrXzPDP6+G?oZ#laM1 z5kwOM67(w3ehWTUaC8_^jzWXH3;2TOUlO1L>@+$i6uvtua`+n5HHR`hFdn;29OGt+ z21g@dYOSi9IoVjLdLU_F2}h-vVuyvKZh-7lHtsV*n-0KKyv2-IdmjeJ2i;3S2X1vf zZCLuiUQjj(!}&agEH2ueW0R2?+zaOXyyY*G9s4Cn+~R&VDk3nVyT{;Np}Db2@Sh~k zvb&OTQcd^&TodolJV%NMfBcxUD}N@K%uwW#&00anEkK4A+O7Hz?7hT>iU;~KaEesF zhUkn`iJt{sr=8R{l?8;N^rj@uv{s=PkY=`|gVZ$iJnsYRAW4vT&A9NK31xi+(tnO? zAI^1=vMk*TE?m-LA4On{h)Kh3icJVR*u@2SfiQIU4UD7r{tzY=B^L53*FrJf`37Lx zT$H=ysf^*YNO*GN|Iji+v`iLrNSl{nk59Oeb0Y~rv$s5qEUx)M{hZsjr8H&!EgOwm z9iQg|+1%IxA`ENQ5k91~N&s2js_KaidP;VqDtQ0{cT=;}w2hvK5qrqqRSs`Eh?EW0 zqK$SLY1+$vH+FQHpt&lOXr3&aHnR~^iER{;cynpWUX-0aW(9qBtU=J%j!eEbN4VAl z)Ffi&ys8P##2nXw3W(zGfj`S8pvT5N3i1Mii-ByOvBSPWz@m#_!VD&}K7`d>vL8Ve zj_hp=gWIAGtV5eePToe2J-@!R6kax^#gvVCs5@j^*kmee9WG0S%XY|yaSG1f|4BH@ ze?c|kaMG1Z_x4v&Fa=#oIpwlFexvA>`2Gp;vVH9l`ZUSK{s6rdXt^(6ILM6j1EW!mgjLqB^!%>z8Q~Lo&UNKXAbWis=O82&7B&i}to+{4I87 z$+Bwj&LUiOQYEs9*XAT5sgQfw1}FykIJ;9b|7ot~`$SvgX&}?`>f+b(nC35?QWN3b-(@OgE;n2G)GBN@V=G)7n@O(w z*PW>IO}lpm@(dCn?@8f{bJNFq^;IEEIjely$~N>boX|e{cc@tYK%0|WN9%1mI67O+ ze<#%jut}!nV+h$VAJWMDu{J#DlxFMOfa%TLZ{fl~%!6FcDzSjdMlxDJPeTC`d1m+3 zHDpRI?HArF`XYYvV!c7J;hTtA|5Mrj@SkB{Y0d*~+FewRTpWlK;LDcpk(3-~YUv?a zdk0fN%5?0^*A>eg^&p6ACKguXX)nft>e4`cyVDzR~S(uO>Bel2L;KyAdJzA!2!1&XybKSD4OS4;T&O`dYLoqSRYyTfrQBZ${_4_PR zUbS8o{!VD$Y%29|k7b=|y5wYRF;JqEPD;oQ+%`t;lBF?!MBX#DJGHfn%5Y$;QxwD} zx}_?b4$rj6F7kGwVZp#V1#^_RA-ai#H&BY`=pXB#NcK%xDxFRpLN!hRz3a?=7-jR| zcl|A7nD2pyfN8x1KKHC&1AvT~li-!D22~JKRrCec90LT2yH}6e4Yta&LBE+JP?h^z z&YN}x>Roy8$}H?ZODQYW^PnCISwc3Ty=GAzMnrR3S!!P9ye>Ep6&1$-_ed+1%aU+B z!y24!lliO46>2?FvnQ;s8w|>T|^AcI_AH zD-b&vkuYPv{!O<4D2u*oX(&mDz4`tsT2)pcSTYIq$jIe$Qn65l6sVw;`^TQ>A-q6& zXMP#9ekJ9FFoy4Cn&}l3_QJ;sD9c<*8HSRV6F!U+-sM(!ICujMxl3d_y7}=s-M7gL z(Izg8jl=oz_8PwXgZLPRznLoa!dQ(jq=m;=cixp)7TE;Qjh@cfxwiT}gDF2D50XCz zeO2x=NNLwRw$Ju$X9BOWh}(X|BiVO6cCqN;iIoDx$o|rhMFqCE!<2SuFnGCEuH)&* zhYrh4DGY8BB;BG`Wa%8Hi}ZBLqW;?O0{S(UG?)J*&b?}SMdsW*h@-Iw`9vq zp7m=nk0l4iV!mOU6+P<0 zf%x|UZrE_XRwu9ikLs5DYVJ?jXcpU-`HE8XzK+A6yl(TOWWbfQAk1Gy4}?&c^E2~j zI>7w)0p=~7sI&bNr5hYH*BkLD(4ZnlKVm*lA=b9$TLK+iCJ8kHNrn6-M}efc!xEXu zYsml!=3osFrj@#yp>io%2si9=crx+okFPPe5^N=Sm?F8d^74WyPF&db`#gl6Z%kGK zK}Lt*m*14%O=2nIfHpU*hmvvP&2 zfZZ6j<*fC$K+l4m^pB-rP);(R-RG1m%wURiWRH&C@%l#mg~S3fD&bf+ottkF`w`ub z1zG8C>D5XVzOYY_xTe!M#CJRz`m`+e1~E(xCrZT8hjdp>8ggGc?dRc~d*^GM9Brm&ym)5-ZTb-~w1yFUj*pSS4g_3rok~*43o80x8!2uMcmoPD( zsVF|$#!(onBamt)F9I!AOXUKI;^4MMa*ki)O^027S@F{?io3S1UnL5UbO3YX3l{wg zepR|(C{W|R06*tMH(sxROi^-|fx$QG?I)vkg{0d`RN7=PO2N{CBW&qOfi1qR?1stQ zc#NM|(yD6xQx7Gw243pJ?nAeiM*6Z`=U?EL$h;V{f{Y#{S*YUYfY{D^BG2!G>xg|o zPHexr3eIg<>EF>uy(+mc;!gR7=cT!P{lxBXVjwYdgM|ys-ah z%1t_-wBvZCF8q!6f7RM2Rwk>kD$?pszYLY2#)FvHR;vAGOtvu&_Gv*AJZ^!8c)sm) zdcYuYA(H6@VOi6Z{%CTy4y*^c(x$CUm#Fuf@nEOYxeBIQl_b&5U(Xu_sZ!egN0AlE zY;l!N`YI|%JzAmsvS@#Kjt^3Z7*v8cTm@EN8VNf}(Jiir)jwp{sHC@IoYwEj50 zXopK<_xDPptRzkn(?NDxwo!kD)W2IL4h=g=4XW$*3{~>AF;b@0G+&Rb5)w-e_NC zDqxjz-7Q#mMTyD!wsC-{#7444-$5%%;43uxN+y@2DxM81AX+20f10nmsh%t#>>GTh z_k>z-_Zn9pdaa7yJhKUnEb6LSI4~`{1l5n#Z2*greq3`jCX6ZQWIleF{znoTX723Q zAH7|tHtI!^PGaNt`ouLwA5>xA+Uj`=P2b;UO)a(4m6dL-2}?{YV6&n825iXQ5M3RK zbNMT4SFp%wCGH8_(ZqmL(UxLpchf}4%_cW>m=&vU#~R8M%tRa5Md0G(>u)F`o^U9# z|8VUl^pN4j&9*3${F-&#Nf?>TCTiuej&@o`;{7G_ol#h zsB}}?r`GC>EE>GnR0)2fL`Cg}T=ai_R~8L-j8hd;WBsaNk=uB^!P9vC|~SgC@m`vi#KzMCO>O3v^0ux)^ch!rVtlz4mX^XZ zX~1S&&k2GPlCt-OsrD|+zN5~z>{Hh^HHHuuALceaKT|}kMnBJR+e)hpI+Jpz>9arq zsKgS`D{phEJVnpkmsYlO#39Lz|6#P~WJ6tcV$CIP(NolmoL5_iTA~16I!Vtp-yuk> zR^#L4FgK1Y#q_`LzKCRO;>)2Yx7m!`QS@-D7Zar=wWzZAxE%_{KLv!p)!^<1a9$h$&A-0WV*={f%U8#G zxRCJg1$?j9e_5_~jC6hCZn~xb=VZ8Q+Yzx_*EnbN>0s5GnJppAgv@pNe^f)*wrPt| zi%cc36vU`0i;aWWq+H}>%M4}if3VAyN(v%>Q9uH`dBO1JK!)BX$G9DhFjZ$yUzSM2+!k3+)} zwOAAJp;a=FM;guhQ~WVD?13jdwme&KM$OAFXbCWp6fKi;L!0h`0VGOU^=Z8GIoJ-?Wm^vk%J@yJ+ zJ8*wemd*2Aly;q&$SYG@owu(8LRGBF>kKnJMoD%ly)iG#ZONsir?{-|{GBbz(k@Tg z`UlYg#Fe*Aq17S3Y z3tgCZmw=UrCu_KB$nd(f0hAn3z&Ea}R+RjcAozXuITlAttJnPQoab6L47PhKX-nI8 zuS;bmcgoltRR`E`d@C}oQsntA0OwW7{A}5_+!svRgoD&<*{TY1%>j#ebD;HCt+>TbZ(C5%)&E(3nf_C0a37HAx==)Z~NfuV2S*OlqNrD9jeB1lK9{zRI1 zq3b_nk!~$y=9VPY9HpN+mc-V|Me;{t%7HsFHkGCZj#6}Mz^%{i3?Vc^CN{o*s^S|L zt)14)AY?o3xsYoG{zNmx29%!2bz=k+q3|qqCijfuj|aKk$D6z*b`` literal 0 Hc-jL100001 diff --git a/fonts/Courier-BoldOblique b/fonts/Courier-BoldOblique new file mode 100644 index 0000000000000000000000000000000000000000..8b7c24ff3a4fb9c650b7cd17761344e3b84a141f GIT binary patch literal 51527 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


Rpv?jshwuVO!aP>iL9a5$2Z^&C-|v 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⪻I#o( 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%0D=G)|)}E-({ldlI8h#(JA-PvXxaSTii7+}Aio zLBoPkA+dslo#g|UHw<7q*f7#Ht0?qDT^!iYSryTKnO!*rft9X3O@CEmQ|BdQLjCzx zW4Ed^P-oPlt$-FiZ&)m2U3gx+6@Fu5-+GM!Ch@hCU1XKA60u6~5Z2Ikj+$rcTpwjk zzC%42P7Vt}!9IySTpNB6yx@!rvxRB8{7$gk=bHi`iO7=aW^m)1ALyOM4Jn4wwr;?J zzL&DnUhU&!MtEcpD#D7O_okmsfq`Srk@pH-6cParo5C79;qHwMr`7v6k%dg(vM(z| zyi>ip1NFWFt@nkV;Fc{6(gXI;pqfvTJW^?@Hn|Zk4(}TPOi0QSWB}Y06)QnUPv&7y zpX}UyOlmoBMPyunbDWg390>pHBUGeP0}peo;xT~|F#aDjEt+B9SQxsS1@wS;%?{RV_Od(|w| zav&EPGt5|Ed3e3~NjXrO((+k0Ts6BNZe2LWCoAx+(tk4jIf}ul%EYybYio{u?WpGZ z$~u4k0GbSf?Wa6h8QAGGSq+DjvwQRJC_#41?0C6o=>!Y6p8mylWE&1Jtxw8OFNe*$ z9qY$@}?r1`I{w@jVN`e6aqkeSwygIUss+OV`gX_amdL^s%zul^v^@BV|O6-3Ug$!k*ZASm1* zQr(-bsid~|UBemf~uA&pc!q~lxX&4e8PbFcC>

>Vu7UgfvUY=JlKjzm8DF=1F&1nQ+5UE~g*3K{{#I?{YT!%WH^nw<<=f za8RsMHRL{llOYoPE~aCJ+`L)mNA>{u%`e*4Gmq zO^L~VL@4t~V>Id<69_?9UA*+$it0wq#PJ@YPtkol`UHB0NeBA@kmE0xfXmxaeG5ul zpK>iVq7~4inpV0%wel|iF@JsGrm-x;S4I5V*F=|OO4t><;VYoQ(c49Ws7CkRDG3P$ zSZLQMU%c$UEGpTSG(!W(1R9)D{@I?B^XbLnMDxL@QYvbnJ&NBh1esL(h0Oyfk{?s# z#sWhzgIo66-f zGUD>kk6dH6&wd?7nJ_}?fo^oZ;c3~pY3AZf`;nw#MLMZt+lf3~Gn9nVU*s%f2z1!)PdkOnP2A@gv87 z4p&hQ7t_wK6#9qOfz0>`y^liEadlmAb-@G%Cj#Bqh~;hu*S$&^U=h!=O~8z4{1DxlOOw3ghS<7GMepky)T`I=i*|Sjka!!e3^L|SW_IwLM_^cNW z5(n-e{HkrR>ndG1q+vJ>Q)G>7UOLDtdSi%djc~a5V=ZMS390PYYD=>-&qFF z&?yCf*gM5n{)?>|Ke|!;-oil>!2r8=x064~8l0Obhm4x5~mD4j5_Iv)i zP0S2Pl8Jf8gpzk+{-Zo?3AsG|>Q4uU)}&t$RZEqDdeGXcGAcsM3)LI6K!vkr6YcSf ztr+g_P=%8IR?#fYD*19Vc=Me9tkgCR@mkb5a!}*A*$Y5O@oAT>i1@fO!C?JYoSchS zKr5wCNhAZi-%eK1-pQJ}!)!K$-)cIOr?AVjXf)rA9!)j}RG(T2!bz9Btng2Nplu1W z_xY~_v#(^$tl~F0X0JedSHt(s``hT+j8+8oaV_WyWy)K*Qaz_KUG6X>S4e$9%MVBe z^ZmnkYnj*-%mSe^*KJra01)n#UOEHh8*9;J3SnctQaO?iN_IvI1)_DruZXFScD5L^+rEvku-RDR z6cIfVrhxiXwe0ha`YiV!QsFXHix1Wa6Zfr7QESMjtmbBHGb;s07ytB%b`X#=u}ArI zS#Ad0`R#*{3m+0pN9|wRRYCq3V5THUZBXM&lE|JIS6PvZ72^Qyd6ToFmeYrAiUdw@ z%~DhoT}(I9|Ci6C#A{YD=r}bEIn<)kkIcfdHUZ=+vE;q%XPAnnsT-X5H`}yNA z?R`W2V`loHZRyw}KrH55Z7I^DZWFrEgd%3tpzoJ!$@+l(b_^zCI%J^IduZ_khpFn?qW^3pUOB>d;(b{F#WW4ok0&tZ zPY(M#E%Pp+g{Oy##K@eSMhp#*3zTv=MHq4@1}2IZl6z|IcYJyPJdbv&>`vdVYg7wV zR=KW%D!7!Pis)o=vi0^K;p*mOeNMOvIqF5ykHE>`;RfTx-)IzeKB^+BcmPuTiY{x` z5|}gd@0c@Fc4kd47?}j9^A)2%%ZLZ>6qGe#yq9gL^aF=0+|qrcr#=>$xFJrmp^SAs z4&|c;S(M3DAT+ShuppP!Y9+t%za(wHp)6r-l&YY$BPH$N;kW#78QF;bHvikKxkc7S zCYzE|C;OOAs7R=34o-zh6Ekz_5XbE!EcK7nq;qxUjlMK28yl~9XpjsZKC@o`SMN^H zi-w!K3TTwcu>Wa4Ttw^1n|S;s=B$@ylR}9_naj_o!8+wcbI3fRI>@o#f-!4ejyg~@8P29=uI^`w_uVu@*?|38L*Ive{5u~Xf!3-L1z`rJ z;$~k|j}PX!ehf!L_LP^zWM-GLJKxhlj`)S7afV0OPFV`utSDN!3MiS!wir-7HO`CZ zuFSJgm91v0xo7}lp|FjBS~z3A#S+lfOh@3Dtr4=}wIK^7^Am6HA|?k$`BVgxyIOMX z?>Zr)Kne!f>tsKh(5|FL3e_lt(4-QaSz0zB%0&9AV-y~#d+VBqkd=;WjQF*8Ng-CD z)|snj9X=tZY>RsEm(BDjcv5g7xkGqem_?DU=Uaw{il)UY3pJ(NJFNIYUSICW8{6My zH9_lSi{Wy6>vmDbkC6^2?`?nx`y-zVF)u%D)fFx?loU=0_%v$o+^eMC?8@cg=bY3C zvw+zV)bWzVv1E}&{dLUF{z+y+btdQV{#10Mrplg&_}UL!-^k#``_>3xv$CO`ES-|6xhvqWkPU{6 zOvK65(8bc;PSnuFlpCOKY61{7H3l#<1DLqDxM0WtBK8iRPL}2tE&xhZC3Pwq8ruJq z{9^(z^863YUr%RCb2|X}-xoJi8+!*^Q#+Tx5dYVX%BH3O7YkE>nWc>>Ktx_aQ%X(( zKq(=o3Xm|hGj%ew0Vuc{*;pC_WG#(N?VL@i0A}`10Godw0LJ!qCYJw{=1l(=OUM~u z2yk{VHMacgX6j*V>hO<>7T{p&WNYc{{P!JT=?pM;GPHB~+XEMSfTf+WjjPE&3H+6t z+5amc2PgZ#7PfzNf58;&on4%boh%((0Dq$@h>HI^PZtYAmw#eATmDr8?9KjKn%En= z{!`Mwbbn#~YF!L1?VJHFrXDW;#4<7km{>YH*cf{Ljr|wQ!O8MpX}CID+L`}n2DAVt zQ*%Qn6B|=!=f5z2vH$7Lf7S{3->NrsaIo?Gm$&`Dto~OHmM+ewHfHoNOw4~{8oT_B zZEk4?!|>0bNZFa$1DF{9EjMv>_z#_%snfq2METFmQ2kB9(8S)(#uH#-Y6im~XYcYi zB!Ke&j%E7)K9c_%DE@CD_`ikT|2J~~D@Xs^CH{ZC&;J!#+||ZL&d~Pn0Q`Hw0RC>Xfu`&G@or;B}v9;Ylt!Mi;oT;73 ze@*@`N&iZn;lD1^f2kGzlJ277>F_tB|5?Kidz1fl_{UjT*xm!+O~=H+3ZP@=Wcz#9 z7?}WEY%IS2hd}=VV*1bX4?`CxOAmnd-)jFl{ZsS*eE##K`(I$h?2PSA{uvWx7ehOf zzmxU91pl*iOGj5zDbc?LGc$5AGXG0z?CRw7m*#)1fWIC1kMqAK-_+E@)EGVhgzYB~ z&{+)hib3H3?Jf4}rey~4ptd&KrBwl2;;604M5kU7&GYis&s#H@2+J&&Ca3M(Sld^! zr=dHrv)d7_rj7FOOX?x)ZyK6y1MS!Ya=9%tAv$@Y5$R##?hhYTkk`TcBTX6}K;i;# z=G*1`VopRwM;Y_J00jN70tIHpY%GgFJJF_H7x!c!K2JufY&!yK?Jsyu-EluO=!luX z)s+{e@2pKPTwKj)OH}+TAZ;NH@O;}y6n;BnHX0okH`-XKMK;-VZnr#HQk$ZUsg+CY@ai2lc-6<{lt`e=2_{LvG0a**7x!f0y&dG2i*tmzP!qPr z?r#q~1|>Y``LRbRaMSL?Knf*(Z^z_;cK^Y8iiKO?xCoRNjn|8_g9K?_<`M#A*Z9;6 zeH$jpbvB8xpx|ozV#kJRp&P5yGue-=UHTHf*J&ofKj8^CK(5?2nQ~p+ajT)Ajz&DI?=I9zGQ?0G&ttSfi8 z`CrN%o_SWKBk^`(a3?Al!W|c}8gH4+7UkQpA{loM{>(BiwP>|aZL2zM8$JuS>r8tN ziP=dKm8NZc2TO^u{_$uvG!{eP#O_${(k8q4S}Bx-Yn(z_FaXY?g009rvoZPWjM?MG z+=b&=anq&%_gVbO1Hgjy@DPP4#408JvAMx>j1tf<$ZDw@IKuZUSXI4{*;ilrB3Y~% z`eo{C;o1`CJ3cbqwie?#(tNL3@K6$dQ--$U%g5_&-X<;FHrRadD*A449!}gXrpeyW2%%8~59TiLg~#xH2935TwV=t60QlM~ z&Ut%!jOCbL&iX>P)?rHMxN%t?`GH7A%39_jxWn@98y?GgKzVt)DDsAU(|ApY1$bP8 zQyhq4AwGSCRW=J*9kpWGOnFip-|=*}gGWpuTxPyKy#p4xj^{}*hVn@HHncw1U-5lz{D-bgoDb{Em1Ia`@0&Ib@D`zKtsBPT~ zc`lzuWbon?t5fQP1iDIVtK!BV_7CMO@;NBol#x=r2M6OiL@4Vj+>i2TJai@SZRhfU z0cY(}d|W9L{K2w@Z=}GJI zs!FeQ3RNLZx#`3gde0E3Er}9?tF7}CY@}z-8c8`7X=*Q9j6HtZAcw?GV!q)I(PohB zE)yC;>WJwURE{^DSaPby=?uLuBs#+_*>>aLLc4S*7l8D*xSCGR?14;~6iF1j9tzx> zt2&SBc={Zkc0$}<(`av8^2{Bwq^St1!XHir8`;7c!}vi@l4UUUv21hwrHMdPHZWpR z$-}tb@2UdPnpk0)D0JyWz@=e<%pKp^Yb$u4B%j(InS`E;1&w){wM5ZAG8HuG+2Uds zVz+|;Xh5+*_=GLYN83mfd_Tv^FIhgdHEJ9L!Uhg`5vPM&$Cp)7_`NV)R?nQqK4oZj zM|4jg`OXtAOkE0cGs}|=pZa|JEdd2wKc_(P)|iw(DKkv@?LLunFYu6A7@!Gn0jHNf zXGS@|HI#y;=esIjJXrdI?nN*fS8`QeJ`kWUzQtU`79R0*VfF^=E>f zIjq#m&&=b}n<_(s-B!%Z*%%ko@0qYwtE@_%xX|%&i;L)-fQmWYc@11t#ZUbr!NtdNpL4;D0sC8na^ zPPmH-1$TxMJ~)hM(-E;5O1mn0_W{W9rJT<~PvfxK_jH(vw*F4%5QR+ zB;UjL$^jnNMT}jxUHc|#`vK?;M#gB(E=|WFNY8k1kw`DHPpGi|re{OH(v}-f#Wv1e zcdy7}Gl*(<-0`pSzVn$l_m!IME152*-Y?3XDdLV;f_5&c>^?d>S|3hJWA=?O$bcT? zMm)+tA;%o^_Sd?{=5f7SS2ep!0~sLW37H8#n9~k0YxHUs6^L*jo_Sprv=j!C_YRg1T%pf(rviC_FN@ zC%HV7uaW@?XNiwg_BQctNDnFPNOlwix939YW~fJUU9vuib0EoGBEGDSJPj(&?aBr> z&!&Q5v$E)ao#nbq&MF;wYr%MBL#V2#=q7$qc5B?E&`G}1j}+&)7K7dNocq+yD-Ga* zT#_^33n#*33Q?5N=OUk$c$uEYnuBt8Z{3IIjOQ>__R!k61XJw8pGs&8UlRQcD{X7a z%_6>Eb9Q9K?gFD|U#qRO6tY*0f*(-i6*ebke}U%QFZES8te8k_vn?@EM2C2M72AbK zvYyPDVt&OY>@8qBo55;e`R)$}?c~u_9+~z0-H^t6Mf9y3kv$@GqKjIuS!zsPDMe+T zbBnyBa_D_E@U#7CcVdlJXaH~a)5xG+e>D$J@NP|=jBQDq(0yEkAG|WIxG<91`_cy+ za_do=r~G2bt(nN;L1jJ-7^Oy_H4_2`UL6#|m~`s2X+boY6MFJu5&x)WR7~F&@%OrM zht=TLYi-&5S|N-pTnB&N^h~Pr#HF=Hv*S49v+be|VR+9Ng$`;K7wmxGIs{%f36%DU z{{Dxc0_Cf*;|`qaxNudm>jtk-Ao-bDEld2t`xKYKwccJ)mUXDM>p5}72^z#~>SgcI zWH|-Iuu+;)T&R`($C~d&c@Fd`TqK?#B+w2U8PU*3F9)M7#NeP)5;}uI^5?+@i@FZE zT9(>&^hP+IK&wXN&iHZ$kBL)N#LuG7$7~&6Ayb5|@W*$pXXkJq_#~cg2L8}x7OFhA zTA)O=?Up+jeHCS``n^x*+NL$Ox?J`GO};PPHJB=&i`dJGyTW&4Sm7ATQW$<`=D4GF z?l7N6p{}}xCWn%6li=Yv28vb);t~8y8ICDJ($SCU@a12%lZv8CLLiA@<_1c!6p5g= z#`gw>KbTZ)r7|CKqX!s|`sc4q&Fhh&cX?}57)s)oIR;Qilbbdq`>fk31q<@>mdUBT zNza>Wb5g3FJeD8N?WM!0E_`_8#ycT6RJqwo=|^SE!%3(`h!Aq;8Y3CEuk~;uyB9f- zZ;x8n;U!Ckgw$fa!p>AD(R!XI?UFxp7UeT{YAu^CUdc6;_lf%}{a2MGS~Cn)qn@*P zkmN6`^G_3dtbnNqHIU141@JWmn4$Cr%0zr0Z>TYf?E(p`CvInj5~!nJ#E}Az{d8yL zL}7d4z+h6k(F$EC5e+0v$s6n^D5h+~r}*+K5)5V@Wj3+4@=FvnO0S`JIuM?ep-#Xz zxZh4tyn*9AuR_WuI_ejKW(J&K$xmVYKp?v%zXHrL;DR*Wm1?%blR=XMX37g;S2Zvd zR`W_w%INPW!i<2H-eoT2_j!`6LbUZCE(EWE_atfin|K}k$mSr5Lv}rFR5^mcnG?@0 zp@wc)HaLSY*z_99+MAjus*;D&b1U2=1Lz*7+u^L(CpuxbY1pMM*ws;c&hd|2#o2O8PyAlbaRGS#(?%2!`q#X;3u9 zMq&apfDM;;?cseRFcM%w+?F1tvIr?`@YDKNQnW#cOhiOg(7vsj8_09|hT1Vo{`4ff z%c*QSH4JG0j`d(8R)D$lgQG~i<6NDp*6Xy~Ftft7`C97<#m2uEJilFrFLKLdog;D& zhU3u|g(oYw;QO)B^qDct0i z%rJkWsAaSP_-#62@SE+p%3-g*87|#XgThgxvd1o0l~n>0sRb_Lhez`tyz{1G9`B}_ zz}3+4A20q~#=;$ZsPj*$60$vt`rCghu(^1TE$t6y>0O+ElOi(40*F3id`R-kx$vs_ zWU5^BbckdeiW5tcc~UFmLfAW6*1ev$HXbjRz zvK^yjwy4ga2Lc;5I;_SeeOcHe)#IoWh!aNZ2lbO@$6bAGx^*!8GrUx4(BU3kslMuN$#Y!x*e+BrNk@u4^f~p_rVS!`HR84ew>#$IL^sXk& zt(TUe9;~a@LH_}3-N?0oBfC-zIp#%ct~Jv}t+qx-{<)!_*Weec=bJo?(S3eEw`k7b z%@0JreRvsPn+kwo1l8k={IWuk>BK7X@pbO1`0&dIa9db&cD3Mw9&e-kQcoDt7^0A| zK@5wKWi|9>Z#(a$bKp4$lHaywyM_9~BLKFfTAm7qA_i8RUa?_n0PwH%=Ax}TCyPh~ z>lNu?tkV;2E`!dvJ(FStE}Z9$@eqZ;8b6<%HKQMM8HDX8M$>XRAm#TRbqZRIzJ6J_ z=rF<-yknPu5(1mo9ktkJHKL0@NFc_H=dp9{AG-FXIw{d?7s6#Q31#nEED&rlZ+#_> z*$CJw1OH%RZSdq66fE*`?i*l}6PHeD>|&-2ms{cxThNS~;eq`AnCd=vWgS+zgAE8z2R z3`Yu3y=^g76Hxd4^7J0O!}kOnG9Vz7&KWJmLAQR57=`eS>M)9vA3Ks9EGs&Ih56U05 zQ^_|`3q7@eu=g=ZmH^kbHXo*!YXh0~I25?Q;|t|nbOokxI3!*P&JSV|4br9Wwi7J6 z3l1{hb1YP;T=WRqC#WL^UI&0o{fSxi9=e&g`fP9-o6FW(1}eAXx%D~HI&co(C?$yy z`|kc?TC4^8JDXd4^rGR66I zF~ z!R`zQ!X%A|(fYYS&m}w{uCE##peqRej1rs?hYc027uF2$ZQ|ySETmfp?@Cb9&G%40 z#U3XE!9v3x20Ih=fk6EiPi|}{%)5!s?96FtjU1rh#r03ph;sXAq1&0RznP}e@Qd8p z$sq@%GU9{yBP@&^5mz8@;pi&0km{S1PnR4R!FLoVpeao}@FF;Pwri9fa= zcID%cskmdcm3MNm!b&$cc|>vP#@ueycaBRspbdKncpAq-Gp*G#Vbro9ew%h$eU<~+ z7c%Qm?iLrKWr?NuEJyionRc{Z?9xxpJVxSJV27=(0K2=;#TDqO!^4>eq5AcfTuWY( zb4gKaWA_p6y)dp}v*h0uZSfA60}?0_s&?wXCKW#}ZSO<=fT^+_N?T3x&Ahi&I5DT} z0*MQ>^k5Lbynpq#`&e)PL0f*u;q~&xT0NP*Xw3lxBSsaL8wBsVc(KI=85dy8F4GPh z*ANq_94B_z;=lzg_z{q+Z2aMC;+7tK$isXhfFaH59uJ}LZpXfr+~tp>Lx}|m#oU}4 zG>H9a88d@(cH>DuH>@(f9aj+*>hqAX;KDvs0yg1UfYA@n8HiK69MzDLBF+jp{laBa&@Y%%7HvAla)bB znxuy#&k&KO;^gB}8506%Ihyn(lxWtt*C0l#P&56KgtA;|5)js;PJqy$qv$)=e9BnU zms%9I3-b$~@i0AR7-!f=D+?`OeV{wTuG2RTY-lYbe$d-!KlZ=9tjSfK3;}y>4K8%~ z6X?yFk#>|Y2dRquep;UoAQeY%JUB8_%ObwKA8$F+&X-i!SN%Y+p5;kHiJKwDY0m7r zM*QZZY&>#QBVVaCSYtTO=_s6!;!|ll&69Sjvm58oQ1z~Rg3K=qmq|_%4_=RG{{VS3Oqy)1NtN{SC8V6;!o8jr zbOY?~=@Lsk77&w3@pJ2D%B_WUMdA4Q*IcdVTX(awY`<_}vDI-D>_?k6E9<;zk*TA~R zg>IVdl#qJ%);t$;{?QT=&gfdF(RWzimSFB6FpU0_vKst)5mDesWfm?Y|BS69z~SRD zGU4bC$rX&1#a*94#Yqg_)tE2xF{aF0f6T?OgR&Tp^1j?h7WtUtnkMxZzDfAI8E?8E zRc-=)AOdjns6B=ST`q{$J(8l(gazZ0|H72W99S6dMWpwGtOsQYO3AQ~$l&ui?n4y}iy6jtOSI<7DGxlIx zouITgTjl;MEP;|z6cJojq7lEvhZajU|48D2cl;Scq-+U=mF3|OsfcV&_5~^-9GR?_ z1nwX@Fv2@CXj`*vuz*@mwbDh&JqucF$bJ~$h(YB2sK7Kn7ReS|5KFU7X)PvxF;kTx z=EWN+GpmLD941)ml(CwoU)8Rw+%wqR;xcmqMjg;MYV3a3eEcR@x5RwQ0kP66tru|> z6c2b1TuTh`aj-)c)_hH(=kaGDr%OH%%wx`k3;XltkZRhZEb`)UM^{=`&NWy@^VuY) z8X15EEl_ycVOGfCAudtJo3DYAl&9$f_Xlu1t7ICmB~v=&ZDC$zNGt7Kn5#FPfzqj> z9}~isqQf@8NuVk60ME}AOm)4XkCS@_c=@i{S~zjUrn-4-Fj3B-P3pp2Tl@W9IH?wDe0 zkFfG|Y18PZLcY;T@COMRNWBl0m~QG)S}3J?%Q@B%(3Ff$U~6!3$(EVOlPmsmLRp%Y z|0Rf%!x7B=+0@6TA3lR#SK+8>7Q<&oS_IZt~gc2+xY_nSvNo(HL5ghh{vw z!xPZkLsR0w(PASl=_WRg1w(i6-NMEb2fDmtddJ=a``*bZ-gf^+UQ5$sB8%rS(;Ibm zj6B12=Rzv_eYm?5>05j}HUlOdcn4^PgoLz#b9n4kcj*`n_8g8^wcNfHSx_#`m%21c zf1k@z6*{gR3x4|5`4D4*SYoO)?}W}|LcYa}NTd%9Xbjv<0b{=T+1gKGI^iH7r;OU|2 z(p;YqP<^X0ekrnKW?j1LG{y7zwW9HnCcF0DY(OBp+WYEVLS%!h4-2ZfuzoO=eTbyM zfyh#iu2H9*JJn#o82(X&_9OO3qALs20nmU4nzGbHa7j1^M0j)*x`YK!i@N|>8$t43 zop1(X_LzDd6x;H=!;+Zo5i7aaIzM{fYiWN}-ISko@{|Z{G>`=8=ybO|&a|*<2k$+Z{9-Lg%&9jg+Y<1L-F< zVb~|7s54mt&rn*VFz6`Zg+3ZB;xH z3WO@D^oP(}xk>_`q&kFqpS2Yr^8ne5ov7?4v+%-bQ`RA>ZCxDbj#2yPgl!;}p!b&JB2f zzm_2FhhoU`Ki^`TwkH}oB%h*U><+@mz;Zc+MxC3WkP{7D*_jG1 z6&TP4*`yj{WLuY0@{(uM^Nhod{Al#z$0fYNL(b3`C&-CPmu;De!7-U$!%4+5MrJX) z6#E#v&UB_hlDz|K-kfLta|%M>CDno`)QfKH7gIKk*A;fk`%EOnsT;7=fU_8LR`}Sw zS<^7lHt8Pp4v|rk<&0*Gagv%A>D9~UOE;Apz8Yd%YLWZKd^dIwynI}-f?Wow z{MDA*RW>sYdR94UwX>lZSsyAyD3u949fx98cqgxPH}%K!=X{myYzj2D%KGS!0MueI z^?rym)u0O!iSo52R&yZ}HEx;^&QFf&S9WTYX_GqNJ!TN*Odt}Cl)ehntpTOrRRn}{ zX}#NyBz0hV<%4cyQPrx?w4h+9V1k_p&w){=Usa@75a!AH4vIGztqm@HqT~{+0s*7>4Aj}R$qA9bV6cfN#=4o^Ww9blEuSwLBM(b;Foh791OB0tlpE60x7^CL+ipO62-LFwct#y#~1hll*I%z)GW5Ov^q3 zEEngV;PuaFxDojdqF}2}ti>$?d`O~@G45E)w&QUq|Kk@A?BV$=b)SJ3S$R<@q_#h zPfq#|fBqo)Skg8~11^u*6T1T0)UN-R=a{2Oy`WEqFz%+y{61I(3wLl1}?^27u z>ZabTzEcB?T*8i-8de#?tyL={5HnRvwIVr*5I2;#w0JIqPH#|{C_ZjP6=+=Rj(*V=uIFa6 z(py8zP^nVUnTgyX_a?Z_dcl(bi>lURJG2O4X@g#hX926xt37x*ta|ur)S_eWsg2 z`SN3shKO!0Nr?uV;y09zj)&j&7_a!4I4Z##n~(;%d1)AU;T&T1*?h?b4fX9xLm{=d z_V4(GIw03wP?A3WZQsjqvmt|n`be?mM-0elC-vw1!$)ZzqR-)KaFBq=JUpQ+ahB0> zbmQJvIjH(Bqus&qDL$iwdTEg#*978M*8-n8UOuW0EPZ_%r5lwm^Zj1Op9rK8zk*bRD<5r!Q<5=>pnE3+UtWIzlPyU zw>mqoNwc8o80WwwXC~KEa@x};@n~?ciaDCt_cpDfo$ns8VQ@gQ;Obe;JRyzGjqWjZ zj|!$u`prly{cIy*h)FT~o#D4~qk0Utjgo6rheKoqEuHga|Na1Qpsh%rbr1~qfup;^ zq^?IMyzCy?o=9QHsvHvYQvtvMp%hBUf;IP?R6Q6cp`2tiTg9?d?U(p!3(T$g(hkkf z?QITIGMIIn-;#>a5Iuu|Nh^*#d*CuPX@-wt!T|RI5{bAOE>x4N*eobP(6cz>u-{`Q z=YeWa+E@*uC{<(T7X?tv1AW~MEiS^{Htu(q2XX2M)be%cMAXt4Il>;F2FSmGxKe8Z zD(}hi)vHG|7Kslaf=jictGe|f+5B<16A*8W_ai$iE~>s=ZMh_X3g0^%+Foc57QlhB zr4?l9+t!YsFYGgMnQq+>WH)ao*JKma_uhXL+7IfO80V{`<)PrK#uamchPx3cZM4XnM4_gW3j;V97UlnC#_S@!pQCAFcw?M4N%Q=Xit7UkoVe`9eO{{#2K zeumWijL`eevdX1Eh_N>&$~B5;S8456u$y0`ZcZbUN9okaBa6B?L4`csI`t3l%gFrS zCbhr#31c9B+%j+^=S2+jOI<=S_7Ut7Jf3H;C9?uAll^JfYoMEE#1+HS{Mhf(_?>&r zPR60SncPA2#81R*`#~+Hs9vv#UYhI&zgT~7?qR;Dr-9a#C^w2=pvKc**=kXMVa!Oj zf@m#X;f#N^aS|@Vc-_!xrkU@`$I6tL`<1AG@XI>`O!h-GCPdRfcO}&@hZJDQqwYWO8#a`AS#A{f`ebjs2dC32@?#5msUscT!WJH%y(Fq%W za=b{D`qmR7(LreQXkPpDxh;p)*p@m4V;o3)&;trQE;Qq8Fue`M;y$nSR!IUAf-Pn1 z1w)sNZSU(E6?lgVt0h`Piy#w!6q47>399i&o)CMQv@gi5sv=|nm{~`wqrMmnCR%td z%V74I`>E9U{Pk{E+jxGZhkOLarMLgRPV}SMWtL?}p)Ac*e%~6c1|>n&F+=Flvc^hJ zU6SJu&z)!t7$5@ZJEum12YlWmi9RCj{Tl<>cdtExMFCd?60}TT<;0uSgD6@oHh$iK zFluN8#aP)BAE@~J(XqV4uSV2}UkD{#20wh4MvyAWd|OR?-@`|t_Hc=fJN5k=&tO+$ z^8mt3XQZ!erCc|!GvIdPw*3VpibXqePVGhZlR_O{`V(a9atD}s`OQ?bNrq^SI)j}@ zhA?iWt+ld3TTJS*g-4Zxsv}*h7Z}bCn|4b~Fe=xb2kgk({nexozewa_-AgB`TA~I` zh&4GqKQ`z7WIs!IVIkftsuj6HMlL++as;H!_MIb5HU%@BbE*TA!3qrDHI2B_TfzQ@ z4U|;stmzMOf;%izU&FsOaayTNGTV{rBROGl&`w>rc1JHj7E|)lTlj8e**-(YX|{x^ z8DQI&(iHDL77HoX-C^>x6M<5S*Q9UJ;<4$Gk&3vv60J3>raW28Aw9w)iA+8JVIsx> zBR~Lig6r(aI4DR~k>`nvEO;0wP=l%UQ%_51B@1HOCU7EL853a3ZXsH$@Jc@--(%8B zyLSm2$x3GLQM#Dq)Fo+-!}d*2*i6`quarVYt}=PeDgx%GMLZ}RjPd-XM*{Yc5|`MC z`qSiHwH#5ZWD!%ilNw}oSRQDcgFYv@O4pa<@)gFWRf2_K@8IKCsH~P?a%g7=t>?ft zd>3J`HD>FF&jxx`V4(hm##hV8Rtp>GEX|QP{9W?+G}oH%bEMck?)nd&sexVEmF4(( zXQEAT6@zdUKOv}Ayr1W`Q>u?kC`26HxOPX30-B!Lk-Kpnyc>z5&%Liy9jPb*xgnu? za)EAXMMnJyW3SJ(yz86$U$$YY*?oUQ!K3xuQAH^Nod9UwEMsC8C~tLXsRv zBN0@R%oFtegTx3O@gSwM!1H}NIZwRdPyT+@dS_42(+kzgX!dyOI}i)n-W&|7I%H=? zM2_@c?~WNsE5}}Un1`2X0UF(x=;9CdW|A6iZ5<9VBFd-Oc{IU%P@;lsI#ACU&Hc*UL9C(Zvx7l56hg|_Wu>qovf7+5|x#O=q zhILYP^jyj_1qAKHzV!~@5!z7$Q5~!w5K;TnG(Ax~zUYdYdvw0lM~h7LE*ydxnC2#D zol4cOz#!0NUC@4n#}8RODX&7B$d_GO9yA5Etc;8G%}|7<;{U#!IiB&ivWgJ0nHm<3 zka^RujPuU1?Y7j*UBhb2#Jfh_TZId2X0$0GKF{REkbxtHDm(V97~ z9oi3??@&UxO!FH%0jmE)J45GCMr~l!oc+|e@00N*eod&6|N7(O(S68nLQ$0aQkY^O z6{I&1ECAU?_{w17#ehXosEzBM?Im=>&?c@2%zdDwovgj)^j-7)Mmx6fKdyaZucxxj z*C3;8gm_V`P517Rqql{LwM%QZ~8LU?l~{Id%1^+~dl7&y~qr_YNG3q&h&znc47X z{FvIO(=$CRK?ubw9(zFWT?Uo)dQrMItUK)|h{nUq+*e0ZlVffKDJEfY|G>*v zE9`Jf6Ap3$d8^EX8V zV5nb*T^4v~E6~N&XP(L#EvoHQw5@C-tF=(}x11*}1i!E%1lh_gSF35*cg+T?xG4m9 z^|fZZ`dQn%=5C15zX63DXz5&MI(hZHn<@f>e7;FXCwE- z!0Mf!cRV|$LPkV5um1_(L)>&e(Tn>Sh+?@Z7>j}d_v&Hx_^Gkd$VV3e`ntkTN_=rhSTpWtp6M%@JtSC@6= z+`>ucyEQ6udFi(wR^JOWQ(?_VZ_I@)2NCH6o0nrd;ZjQ6(52hf!6Yu+<~&Rz4&LBP zlqW0+UDEsE`-{RF3Vuh3vMAr)Fn>qu%y%WngpDC(G(5G*mglq%!e;FJM1I8k<)kl4 zwHS8Xb2)R;IzDrm{aU%h*8^!<>J&Y;7mAnz!@{Ur;t3w>RovEm=k$xLi$*GIp?{B= z?w$-}j9)y^iN;;58UyD(=T6WIYxpe@XX2nQ;uLq2EeW#>V*zWEO*qS|k~TPwi3(yO z58O^0#lgze$@L1UQSx-X?aen)OMb=Hi~I?TpiMPrwye^GGV0H}{aK!y9Yva_(Dt}` zh78P!4C@x)*Vgm!3-%#n(+~~G91B6Be$riWq%?Aj=uFGrms_#AxclLmHsQ|%8W_$S zKOt4_Qt^*6ZD@iRxZ0|~!fwgleQ=4mx{BDQAV-qxfvA6wRUlHqdEG`(nmHJW z(at{RjWL4<+YNnrmtKyrk>MD+#Gdso9|>g|8Eck4DmGYQaVU{Q>1w2(D}Pa8PK@{z#c4jo;n0A(P8CDK>)PJm#_tTwxlPdcZSjdGz>Pi z+^~I9_`I`0yv1iGW6u;fl&~gF>FGTlO#{b%KpO9v2M;T;otmf>%2?^EMzE=-VeS|d z#JDw>FiQn20k&Cl?AN9yKTU{~&OyEH965u%-Q;vaRtJ3hd18eR6--*7RXsW3MQA+W zkyhLB1dG`6!Id(Bei-~blO2C3S^Hx>i});P8nO7)%pw@a=gh2W4e*vW(d6dyT-B1z z89+LM>c!18T-*BEW~v!?zb(bK$8H$W6VMG{{@87XYlXjEU1GwB>>F8fb&mpywl2Y_ zL}_^&$fRKd4vXmk+S|yKxz3C1`}L3rY41k4y?cC;8@kgGC@G$U*1Pl*nsp1&phq*_#Od7}HWXNx6%-YjQh7O0KpyRVG~sOxNKau&~HtJ_wC| zO8qQc`^`dP;E=gK(QtHVgW-4G?6>|br?!C( zW?G%>%0-&&@X*%sb`VLes{)?=G9Wjkf0SYQr2FgCTW#z53@0g4$iC#HasdM~)8NDH zU=QR7d&=f3L{!`}UQ^eLGfp`lgj1E`(1f@kb!tU*c zCh}xWUL;`}gJa!uTuXg-jar@l93d|q#NIw1r}UrFaQ;EaxHmH73zA)@DrR- zjb$p-Z<=~v28vs{jv#KXS2D^hy=>rac~&rN_jM_;s-Mu`OcsmEV4}(M)=1?!L~x!|`wU*?MVQQwz*l&=7gl}X z_Q#Ze|Cx(Cl18sggsQ1+IU7;QCoA%+bY_0aW3M1im`KEz6Np}2SAPsT`gh=?NU$NE zg++$~o%;IGn6;}Ez;ss^9pT~|40mhjWk~u)DnS%~y*H!IDQvoK!~V{q-yBFlK7T5f zMSxx^vT7w!9?BTQF(rHkK3ux*Vw2hBdyAp)0_E4CSG+^CAHbGDPM{s26QoVs?KuED z0NNhRvlKxS#x?<&32HA)#ESVqk5E*9Kc=p2nK4HMyXC`p59(^^#c3mFt-^?qO9DTq zZ5Rd^iVoD`!jdm4(L6>(U&!p~*R2IVn8dP$`ONxFILdD{tKDD_jyfC> z7G1ohURFqojD9d~wpxoX-VyK{MnNGz4X%`^aHr9EXcuRT7fCL|eVC>olBqYfxq-BX zDE$E!pj>;;z_om~mGOgMJgo?1N?6*=${9vNM%X@3!PX)(cFh)N8HiclZL)EX(<&T@ zdi;~q74CP{tP8~7(serb0AdGuG>qzV9z=?^`e>NOr}g}Iw)(w0sB<_vyf_OiOVCP^1y&rER8>T-ZFkRjP{D{a&G4Dlw#EWQ0-4z z7>$r?^~Le=V9HoMCi$qcYeuSpwHyUo0x=fH-mGb5mP1J`l&qSZKWK&0SV_#w(J@W> zY;TWd^=JN+`}Yh+%VD*6$w8q;st3?Rb_*|b?%;T43R?;>pX2hlq z^oA5agT0374=MWfnv}A>tsV{|Fj3I0GOo#?yE_jk;5aEDu@+d$c-i;#Zl=vs8zNq& z_(c%X=!(U?c1gJL2Yf|x@6?e>z>sypiaXc?L`}B=;yCH}5WC3AIu4 zi&g4gEp*E@_)Dg*urSJfA=r9gdFW%>{*t2(vKY3y9pBt%O>EGjH^M_UZ+$}-!2(X+ z9D11!WJ^6(4_l|U?y6kgu;vOJX_eIH8?p+OteAA!4Ffmxb9zfnT*P`xx1;~(re1qZ z1$T4t14LBf4vzF}e#dZ7P-A2Qs5k@(iLr9rLo8(C51d>Fz+H0s_ZG*p4_7QqsJVG? zIdD=N)|l_6XzvTQ*{K-O7ab0A+Ku_M-u@pWcTd^Xb?d8d-^G!!A!$hqB%Tx|>&D9$RK?VmjA}faND5jaR9~dtcO!eGt%c)jKhB zzz9}hrt`sH@T_Kxp=3P+Fk+)1lP-(B%N5Tmw7we+(QAyu$c8IL7b*I;cX}&$gOS z?a!dl8x<_SAz-Yo+$ZF&NXz4vK}D6CSU#BJegxYBKC*g$U^yvYs5-ZfdkH|5E~{iZ zgStGD;pIIVrqEqc?OAvdxz7z6papP$r9C!WWtK32qFWp2*EJkAdjM^;t6*c`jF`@< zCNS5+vhXpD*g$vO&bvJs8m?9}-AWAt0I@CsqJ%iS5nGBF+Vgy~4A8(xdybJ7hwd6$^JE*d}Lp3#PvI^y#O z?dn=Ga?M(5a>@eqik00l%;-VBQa$pkWkGsP4(vXn7uiSa)}e+*!FjC*2SyfCP8gl! z_3YVtIT%?pKl7)kiX=0$&W`2cYQ+Z6?wq>|DWnkX9`$D%BHPpeD9%!&I1(yW!g(E2 z7TP}BDASD1_d!)(Ol@U)>sd=c!h-v_3rG$hpqBf?V$8O~wlaA{H}rzK4t|cT*oGY3 zvPLl^!ZApm0!PjazXLS39o-&1SfhKcRf_*p*u+{aI)IaAW5;b!x0Ob z>I4hg^cPv!SQ0gpaA0=UFHAu1Fjs9HBJU5S6`=O2dVrBaE}1)5c$J#99(5^HRE&E^ zed=Qce|`(^IG&Un%O(5yDfE!Zlc@eI0ZUn3neS@{=jil_1kAJ+=y5n2(*`zu_m-q- zApX+Ffv{7mQ_CsDC0vO=cS*!XuWr%&yTGiF8NR3Ob&PuU#SdenSgtOJQytf?mBE;c zhZm?LIX+3!4+Rb}9B_^t?<59yR~%)(LpILOf!K*VTi1kP-C$=t>h^cQ4MR{Z7Z(99J`*Y zF3PT$>6nQXCTCigVvsJsBvi!`s4%(iIDVLCMTLOK#E#@;8qw zK%XHYQjJ2tCm4YHMu}}Y$00-C1484hJ(S4i5CCjiimvlo8p4BgFgj)mi9ln6EY;cf zIqSVJEfn&rU4!mB5`NP3q7RW2ggo8xlPV^*nWF{I4DLvfKMhsS=L4u807(QVxKGSe z$;s5=cC`(;gF(m|W{>I{?Tlsx@84iDRkf%pYTu~9UG4*<1qDWUC`Q90_b1gxv(+0o zq6irfuAPp-tO~Z1K|30^qnaQv`Pox5$gu|AK-VW8pEo~q90bdJ1|}L*PODr5z)}a0 zW>pMr$gki$i2gyv$k@4$7=O-DtB-OE$w2#C4fxo|6z1j`ijVS}9{$SzF_Q4{BM-}$ z1`C4ZeZhd&+Ex%^m=e5w&$-5hLU#Xjv31s*QCT4R&!7Sr%FCZynkL)>Lb6f};^4Pb zJ1snLin-4*!iHc~b9!cSWBc`pnNQtywT2Ss%>rjdG!q~^Xh345oHtT2?!DVFfbAp?=K4P)&F{1rrbMKBA^8>MSgr z?4VWJR1I6ET@#uEph0Bhw(-@9E$!Q&Gx2%(oWLE+J90y_ zTsrnZtMs*3w9SWtYmT#v73yv@I`@wMCPQ2X;{BCH)Aomp%Kfsvl zin>&uKW}O|eTN~w_G;iP;Zeylx7sy|*63X5f zThoirE@aM1zfv5&tT)2ENuJT8)*Ojkz|a{7Fh!K8!u+nDC$Ces24Pc`kV9 z9h~4yTs95RD4w8!F6?=$uB<=jKfFB$CqWb%?3%u^z2WwSq7IIQimNUl#KWS7-}MF` zG>nup@)J{CLk_v!cm>;;E_?5&d!8wfsBd??Joa>`IF{xqJo*5TC&b;L>{iqAw;VXS z61WbsD-nXDQ^T0|LWfs;`>{e9irtEuT-$x4u-MQl!8Qk zdH~eF5GcZ$-tt!i-FxQOTj^YJD#|~_hmtg{VfcnNoWJneD?*|8s`NfnOiF2gdT_>3 zvOL2JR5|3Y8V(aFc07utzGu(MDp-;>R1HpU{I#$zLr42cDLjrfPs(*^?aXvY$X$xF z4Nca?d;h~WVo$o#m=$5EvA)8=-7g^~AZ(YjQ4DmsUE0g679hOl)`9ALn-Z`~ z#fm3F@ZSZ&JR1C2VKXFq*h1X4Q?nxDsR!g(1ye=!DnX=E<|M|-?f8zW+L%T6)C9;F zeHDu=v^2z4FX|7A9fP{a6XlB%pHH{}>OR48EhFfX1COcu3>v8+UY_-zGc-<+85~D1Jni%>V{*7d}X2 zyux)6fr*uAtZMmuCD+qb^a0-V%ik;1;891d-gZpn=4JACxb0i8ZT6AEQ3l#N!u56Z zsd@hd@m*V8r$Ax;#jt?I4&4a=ZUzeB#%U=2B^1G$kP9w=GbjlF(k(GsN91iAq5>|G z!2ZlDShA0WP%~|zOP;}JKdS`0dQvTVBH$f`?T;K*2#0)MW~W?sk+&+;LcM0wHaQGC zrHFg9&ui$WiWk{2b}MilCoF9=-@2UIU=gL${Gv?>3HFQaW+{xPZ!i+q{(}QvJoS!E zECTL;UXLU@(*mIGGU;z}5Y8lL6XWg*nuioiqBDTj(!;_Xnm~jShpt}FKEoU^k*+}} zv>>wgdc#!#xv(wevYFrl%hP+2Nz<-k{*)-xg>emy?P-m~PRBA|3*sEyymB87a~O^7v$j(5<-6$-2Q$GryOIu^9V|LWe9uBwi!@ zXI^NX3>_br*+93e5|qp|r0C-$zC^@v`CZNHmAPI%lz!lpVB2u8 zWx@h2wfQhLbn^2olwxfW_O>f~h4YcHn)4k*@60&L{mFWOyG&X%dfwsxGc#wX!U#CM*v7~fPlKs_7-Hd;P zNb9kLzDv&^U2RyNxo*9?12=oSz?m{mZh?{Uwg3F&Y4n!C-sRAv{iG0=Nb*%HL9s@PC45as|#NwOzxx@cyUt) z?V6IoL4fU#9NH~O*UdOIq5w-aPTE^?-u=wn9Ti?!y9Tu()j9S8QGDpNnx)Ev(Nc|$ z^|UkdK;sL@hwi4Zh*aOh(K54En4Dph7$+zz<3HX^{_=J9E^-8&5UV%4FDUL8?f*ki zkkpSoZ(m!w%3Wm1Pg65KZw+me8l>ePLD&q1`Ag7JBRN!nP-Zt>uq|GK4)gg`e@&XC z-I_-iiH=#(#)V#$g6u_ zo2(k>9;Rfpnb3^&_3%(_nAiJ{r=E}n4Cmn>VrJEJ+21lP0!<&_0j>98^C449NH@hE zHVjF*%!bncIr|IUjH@aIEBOh2%&KZ5y@P20}s z?Ybd1?>ldrTyGf&FiZzz$7Bsow0Z9CAZCaPA1O_|ILKd_7t%6{TZ_oMr0l1VtM3Yx zGc>TYtiY|mOfheUA-oMxXM0CPG|)^k^pHOG=-5we>eC+S8HzCh!%xwGvp-~1Y5YfP zG9{x^Os!bxoHtN_k1h72wrCt5;%&0aI)GP=2PLHn+9<-@HBWqU0_$sd2-#vbMfEXH zWQwoQte27bVJHyWOvj_lH26}crj~)qo7Ozr&7RN&u7z`}rHT?UV>{&FS|l^QX^#8y zrdvTC?-aJ)q8*^}m=X(@6gMi)fxqlc#@f$;FVaISjfCSCC-GkSCkZQC7LIrZukq*cVF#xcQOa&R ztb8g1&-JN}xl_m){U|dD=>}w1q*hwJLMsBt3RDi(GP}f0&OK+lB6ZlR5wnoxfasjv zF-}BbJ2#S>O*#;KxCFU7hZTro)Q60n53#Tr@Cra~~RZ4`q+V^qOPg9W!E#q?05xYv%45{mEE|L zofY=U4F*=*JqR4>&3Laa>Xa#!4na1U1W$L#?-R#=8H?Nks3_hA!<&ENKQBBcnIsC3 zWE!hb_1{h#jIn()@2;Dhl>+pjA5-|Zw(7BNq_(laQ&@To(L9h1OWs@peqZ|MXcL^tDl&Lvtc7Hz z0EU`ihBDbM*@VO@SEY%H;Fm|!ckBu5)fhS=l+6mt8NNEFfSJP2k4i#fU_W~Uu)>et#Jb zT73g8*41c7>-GKIWCe~KpZc{b6P8mnUKi_!J2&0%VF(#;`^w9F0jfjWlV%7mnq-0# z^gHTg9t4_eYWLJ@heds0oniUCI^lt?;}HiG=HnnqGf)DAL&oYHv2A7N!24CxDuYk3 zrmA+?YKq%m41UYa28y~n5AJmjFezhh_!o~$a^43W>p6F&6N-3OsQOQVc(5qS8^i8A zetlv84c36qQq@3pguSs()>6LYrXC|66G}IJ z7BIKK=k9woZ9neF7yiT|KA5jhBf}utRjb#0F#A%aBc`M{YjTu_cPo*;l#68M?#t9If%5); zs&R6tVVw?MIH{LtzT&yRK)`NGS8s3_{#5`OmHHe-RVTZtP~~be_S8DCgqC*uLJ0!_ z)!lmt((2h&d$p^hSZ4oOajL^}CRGud55%d>X3BeZDC94P6o+G7ek$fwbG0vdz3l_wnQ(n>j*i-_%w&J8ZTOS4pX zb-GWWlW`nd9|m+4*pU8N)uXK^N9r>Ev>ajfj!4)`Z2#i8BH1M7dl2z?dPat_f?xjb zx7)Z~ene!5bJkZ+7RgGEh_eFFZW1f_XQ~TDjgIt!L8r^Z5jT5z-&N)#nk?t3=Z6eF z?8d|F_0KDusVDp;cnvo6X2kk{ zhokh3-s75O(z{F#r+{s&nE{!D_j=1GTwn2eF(iz~Sj0jb6OAl9mtaoQ0j)o&;<%$R z_B!%bPdd!i&HPO}#fj#}yng&W2+5cFp7&ck8aBz9Z}mnc&{JbRqvgVYs8-+Spo9`< zF9tBCA{B;gtap!iKGwn@dm2KOcSGl+YxfY;qvZxZQ`scxxmJQ`{4gmK5T*57$8rre z@}en8?Qg04+&d=)qj!$`dN$+|C7xglP_31k!F^U>jcxnZxmtBif7RQ_#`eeC$7&q% zn!39GFI6QJ!?Z@6*;krInLQgm%GEz*$bC@N&ofDtZi6}I+XH~0*}?Z8S``{c3kR-; zfpadTh+Q!$7^h8yT+xrK?Di!-{^IPxqbpQJ?RWbxn2%>h`|BmUzR_dqMCHu{qsP%y zO!OEHzeEUXK3`L#tZ~)?z*p%Z9VN#t^K@u)PNQHOd`85-0`PL{+%r z*ZCV)_+Ceg&*ElAiM<_GN2mbWk)Ch|rkdX#1ar#52j_77=69(+ZdR#o0Gse^rLN5ZL&58Dnkux2wc5xivQrWgG zL;~@l;18UmKz9@{?^LBy?I3Mw%0joEQuyl5%{m0SapDFKd=_}R{;m>H~d4v@{E0#+%-aO+VSfU{gyCc&@6K)IjoKx3Ef|L)#0_p9s}B$p7v*yG`vpx0Jo zuUr>5$n#!>*t&n;0;WxB1t0iiU6ImTu{EKHLgMSR_DuF;$m17wD!!Sx zkn6)59)=w4@3fQ}%Va_}zc)J(Jxe!T+EzX((>DW3{Q@%ZwETckFeD7NA6E8OzOpyo z&7HNX$3p?}F;*u~wLr{EdZqzIMazXaa#aqXLdt>l4EiM+ioAD;fd$6z5DbI~U$4?0 zQAl?$S+ya5n%_KM+@Xuwk@hdFFD@S`@6uX$7+Awy4xbpChkXUurZ;2G41hVx2(-sP zC#GmbFI^36R)3va6;h#GMGjGj_YO0?-tf`@AP5o1fj+Oft^I=a&xQCr!oK#)0hgiY z-K4zwE|OuRC7&!5@@{4e7fUhZu8%@>J#{LN-2lz&IzEVqBzHKb_kW5m)GVQ!{%7=v z*ptUH@)@igF6~6+wBycRVL!``c$QwA)5SO@M-jb`!<}2Lw%>jM8J?avH{3C3NOnLX zxLh_t8>>BXd{s$^gK#fiYbkj+Q!NVs$eeExdnDdN?mnPhwUBHKeQ7gJ02-p_S>sBl zyQ|)T`qz9gF}1m3vO30{^*z_Z!va5q92Ww6w(aJPw67h}!Z_i`Usw7Sr-{BkB9Y6@U_s) z4G>3?(xyq~E%_6%!W`C+oY@09MG=Rf+kQNk87$^q23l2(=Wb2Bn0=DWNh-II@T+Aq z$MHq^FlNGM6`@;A2JLlk7xr^gG%#Z72`JEwED`rWbI1$2w=gHBES=J<}9#HMn+W5*6rT>vs5uzE1y4pRey zIxpXbsxY|0_u*BD^Q^)30$7wCJW4fx(x9v?lj^I#pK`3*-IQL~anb}mb1{@2uTJ^n$UFuLtO z*M+!N{-&|DtA+Jel(>se*D=ndHAOj#o~|8rj5RKY^)j(^`*oqN9$cl>`7=z!a7{5| z^DE5%u=NfE%c-J~5;`YuG=r;m8)>;(F=-awdxWS^nBHDJbF+VF&09a`yQ zH?5YvWNnQ4)Qt^} zLuppS$htpsv~pi{celMH=ZkJLOt?EhR>7GU)kO_pa(<_Up8je{ZhUtaIt*Zz3~8N9 zdzs}WN`u<~!??l-6q|qm&oI43>wWjgG5tEyHD2%B-Fv%Y092z@b~;1u`WN7R#s-~M z2f*c^Qdx%8O6k6Avw6*g5fpPuQ3+3*MY?LHdV5-zx4(EIY-%+)8&E};Ir9X!Gj;*Q zS`cWkX$3l}Y(1Dl0vDw+V`T@;#}^&D@J|>rP%tH^O%Tss=5E1uM0iG3uO5} z^J$WdK)7P9MDLnHC-d<*KbQ&9KqE1k+@bb{hcBcGUSO7SH&}zr!=a>1>{h3Yv zgkl=|2c@0C9LXD%wbS>XE>ODMh9-AP9otN!=qcqaAWTconcaoBwe9NCP!bfmdAc=u zzOYe6a-R9uhM&Z<*s&=f)e@hgibGT>Zr8Eo&mQxxlzLhGAKSGzH8h`vX3!sk=bicw zkeEMgzv4u(slbEK-qJ!I%pKtD!^JnSdNil;r70chzPsu|;`V|7i*Se%o<=;y?6te< zjawb)av+pOka7$8YStqS#|T5AzZDKQH73th3EK1Od_8(J3iZ?}+!+0{PK*-dOG8aB z=3_j5QP4Q}7L=x7XwGI!%wC?vkF^J*5qj~$p<$a1*dRo+ z#OO?Kb>s&L+!RVsia{JLpV7osN??gAxd0QZv0;hijPcXSMaZ?vOKfiEKr`03ouJ|@ z@@uI`sKQ{930u^l4`$)a&>}&SZ{n`a6lICq!xyEed2~gZcz8y7>0dmmMmwwoGxj=H ziv(h!C>Wsx#d=S&!pcsG_OyG4EBbf^rC_eB7lrc3SbNo|v#l>dwP^$Pjo@av%Aq zKb|k1Vlm=um~3xK&39&|cY5a$1+9~kKCmObLINbCp>F;LWHTzCT?Blu-3WpK zazZvV8x+xsD2wH?L8zoXX+HH9UPaFaIGQgx|2j?ym+Vn<}ZvjV+4mmBYN9+H3=h!$*yyB1eEQ0^#I6pb9QY^W;K0$c;U>& zvE2h1s%FQz4lZ0AB#0n}9@RJ3kd-=|3$rN{uo)up&UJOfXR~;4%VuII!Y!P~{nB>IBXM5s@Q3Q^L zImA;=t2jG#lzdtC#u}{<5HBj72e>Q`+hsws(r z+P_nA;d|&+WqYAo83#t?hOkU}9$?>zZP?s*w#^;Fy`myptBq8(KBTZ56MG>Gioh@W zOo_J5A>F**lX4ZGO=B6u8rsy{yjdu&Xh1s0((C=+e81n2Cv)kaiCW=QE&00T zn(BD#;i^OY-kxIF2`f3d2W_ z1a1>wvj4CBwhaLdoq)-47tOI0(e3++I9oS~=g+r6P?fgYBx(NbQ@_Pj5~A-10B_+Q|M1?v z6=nv4K>i+Pye_9W=eIBV2-#zOL6po(UGFlEkY%-eGuvo~{3sS810oF6X&a7=+$M&c zN$)foakL%SQQ)WNC04ut%&WwfA7H%V6`srSF2v)bQ9`@2oNR4avc^Q(uqGBN{@LQZ zlPqJLn%sQ9v)vURDma%$2X>@n9MsBCHT*@OZS+@5kRSC(JqU8kx4X_w8Abx4eK>nS zvkPjxa>tz~>o%LNshRR1Kv7B~v;6*sIg;bjUL{Vwu)kz&Mw!7q zye_mzj@00bcPzghu6a?Y88|C(FS9%RG!u;wu}}y8DX&37biBfZUD~RyXlQ^H!9jq- zM3`t@TOQ*UV7Fo!60t3a{8saw&$H`Z-H%KkWS|Jtxz9-42fcFU22?@&>DNu>9 zunhH^wv4B)?BZ)27G83D-VVYQU$^tYw$?_+Q6h$JoOx4~bi%}*Uj(FJ7owRBh(>6^ zZdXBu?nLzbGoGUG5Qy{bF{IQ}AiWUT&sfJEjib~@QFpxsZX;b%HE3~EmTikdhmWBs zk=l`~hjto#2M(uEK;Svei{u@%L^;t1T#Y(;koo$>R=`^Z2d6C*EQCv{4KDXG`qP2Z zKc4u!=@PVu9S%yDlbqvA+zulZWomoh?q$*Ly>sQ z%2_jmx}-`W1C{HjUTrACH-hoTQK;y&*MPST%TB7^Ce}UU7r_d_i<2YnOok8U_E;hr zCA4u>X$K&lft0WKnN4E|bh!8dX;SHXC;X~Tbx|h66~c~r0#+R&3* zFK%wecZ#*pO^!((24E9lxN`a{!6NPUY#0eQZtF|U7lqMjg%kx!^-~3&)&c*n1tU@E z{yIf!ETJxa(WmkQDm6$SfR<a`?|km%F=mps-;DaTb6P zhg*3eh_`P3Zfo*$Y)p@IRyKsCs5Cjj9te~)oXz{FT9?FHq1lN>OQIa$QY(vc`oyJX z+Aac>*|!`J7WF%IV|N{nIkU5}Mh=^bGPBCN=~_#yd2=iUpyj`V(k z&4WNT5cOs})cRDA~HDk~mAO2$*4Pz(qUq>c2Bt?t-1`34V;2I+e z#(xwf1?_P=H9gOW1%bcNKWFDV!EzqEy?dI0WtdFKxpw0LUvdBu40c3~EC}0Y3d2iy zt&Vwdu3MTKRB~J>7;7OaS+hsE^nn~Xr_Na?Syxh>q~gK z0~D{7h~MZ9qBo%x1f2wqRY{C3_x>?5Egp>%eGHQ!LyE-6>*vk?X;aaP(ZW|V)B{l# zp5h{3%_3T{`~=tT%sS@o&_u=~ew~PV85!J^myW7B9<0ko2WC&vDAkWh&q>ohzskqG zFvP7CZDceu_nNI#sYNE3}|&%TnOR}0zdPm!6y(- zs}~02Cx6e+=myU6KaNZfR+I=nAhTtAdfTx z)S$%bIIt9hszTWf5LNJPEa&tvnBE%M$!3-QP%)L--wc=ZVTrw2{AoJ^Iuyg;h^0Ya zG8qlou11@P)0Gtt!q8X}fWIA^ZCW;IlN(alg`jZivOht9Ppx0w>@wEZ#hgqZe+Yx% zkY;SK7TSQrtNLO|0zN@Sf0!&&0hJ%jkAdYdfTF4KDZJ5+fU*|Cb0^>UTE*8ywXk7& z*AM7|x$DV!XU)B?9soq?62%&iL#|7^+LJ^Xj#Yz>F z7UZ!{GmAy^I_&zQ0P)|E9OZwBHQx4WWSiW@q&dx)l|N^}n~wM?$#kc7sskt+ zkW$5vyC6)KzDOmJNyzqhRqLYh3YW^)5TG+}#;ah8T+>RQ@ATi>P2VmAZhU(+hC4fx z7GaPZ@@$6>I%r6p?e85l9of3vYhfi}gEJ2y3yTl!N;yDxuguMY&%!gt50_~obLzkL8OgKvm7D0AL(}lq*{mI;`wvOpX7C25!%46T z-FAdF_l}#v(jp$z7e5ENDEV$h6GXi1AA7pAfzVuO2#OA&+vv8UeF!fbhlgRtiXW@8 zY9VtJ$1WC5i8K@28>3=mV{33Zz7y9-W=i~KbUQ(l5FieKyFWf)!f{vZpl(`#4+%mw z&jJ^z3{CY&H0X7Y-yB%{dny7b)B_%imo1?h1ze2{!26WSOryNLh6t zUdq<#DC+1sRUK|n#E}p?Y%NR_Igc`u!s8AJ8w@?Z%I)r>CgP+$zsO+#{+Uk_%Vp3+ zl&qkquwh&_ol<>=(+o}+qLLz;V&V36bi6d4m%I+~16F^S`=uQ2Q2NVBjnG_oCj}z$ zL{^ur#x~Tw!}U)QVOObH9uO*XwPLd(`NL{fP`Jl^BpGCmgi*7pGbD_Vr_R?=#p_`$ z??s>3_``;=W}zcW-#HP2|2(*T6I3*Yd}Rqgw`Yk3>ebYE9cxZ5uL*JiamuNf?n|Te z`(d#e!ZH<0KT7M+uXZXi9%$0@Q!a(KyE^FrvjF|RUU%$46x@-E(ITH)*i@9lro53@ zubIXln9GpI5+j6URe8vdh>mXcIbH{ILA4npY-=o0;kD$q`&_1Jic(@XUWWOe4ljmi zk>C?EHUoghwBuNd?tL4Rvf=&vtu{l+W5*n6d#jBou`nXOtgOcv^^jf^p2*3Bfs1Cz zieRjjq}U_!t+cC+2B#0m&iJ17-Z^)Mwd0HMXnfXzXxy};-)L^smrG*WmQ4O&4W zBd@Il;wP{0NI?t|?rTER?s=tUljHGORthvREuj0r8oleG6;w&CN0I#rEv9p~JP2|9 z<%cKlq^o(wXIE;IAGJZ9q=+`{z(ibzTV z=b)K;T)rAYVu4(7=?0(ug-F6r&a_jw9?KBJ%q6U0-IrS-mCyKQ0LDZJm>ZNWBJv!p z5IKM|J#+ZDDB0Xvc?u;4lMVkOv>lD`PR?#5n?y-{7Di71X{X%;v=%3Cm~fCs!)DOq z1skzDqWX)QtA0%vtyM(R`MPvvHTEVbaI*7X%qxMM>>92C?XF>2n1ZkZT_tuTv+i0j zy$;oR0)gI$@Fm;>KIcMG$`vxQRB#;8(`DjQ958ApX9nmp3vclIT(dMS=>C;+SfgIJ zO}A2mxLY1X%&d9Clk<;rTo>Ost!K-{7)HO`(v)uqUxsziJyRBt|MJ0oWBCaZMzUr} zy4Dglcc-lC^tid9iCXDt#rRmQOruTLdMQ5mSvi&jOTqRgd!J6A+)t_^bMLI(x!bN9 z7$6&-;RMlxN(RL+;p{8G*I?Rkt1tN0P|iH$-y+XI&ULreodOy+$D6jVx%uj^VjNrX zAejV!HS>$ zO(}x|rV*nQHU=OJu1v+L149v9X-E+k11Yyiapfzssn(}iV;WWGR548)05yf^zCOSX zI|-C_XfHKsF$!WIwtKTn9!1yF-aK4md#e|b!#&Hk1NwxQi*<8Z3I zCZ^yyP-$n_(gFDcpFIcb+^sDfMW48WPP*{yJ;SW0N>d&>tbB?gfDl+Za1Xxr;K!(n zugCG1>%YL9UUQKj5fTD*^a$FIUg%gAu>tP4+lC% z6NP$>#XkhK;-o2iKq(!%2d9a~i#+3EVi~NXk?<_dD%ht)g_|nm;Qe| zud#Q$7^z>JsQo&fZlZ3?Hu1-c(Ec*AVtD<&T=y+Y@UM98Osq};Bk_IQcX(rJIsG2S9Hj!5p6&)$go$W|D zD|_syn;=|;<&Gh^RT0BPLUmtz3w{vqW?YEP8 z6P-t#hN$Sg@yRIBOb^V0%9FQy zuqdX?XD2iG-WM{M4#KVQH&^9ds1r$I+OMDk%;ff)oOr$20F0{wxqlLx&G^;N2!4EI zU9XfGJWwlK+m`tU*RAQ_YY=TMlbg(ucK%PQfyo4P$Pd_&n&?l83OU=~@V;Rfkf|$0 z*`t029dR^y(mpg;zy8pIKO`)9sLc&0QaXY*<6(_0f&V1lN=)`T=~e zrTF9FVI&~6oJl{e<)GS038hZo4X^?|VAmu9X{M?8-E*CL9JTcY{`e_TJN!!_x~<1f5b$rGXJ3+93A zKP0vdJ*Sq&T|c(zdc=uQ^&Cj{XgVXAE3N~TRc`XWt|7t*E0$L0V@!yF~M^PUz z!Avq-Y7W&TBOLI`516nbsckW%j^yZ^(U>{&kEub11(glzVs|27aIIy7A)jbHaDklQ z6tdM}a+y2w9jQ4rPrL3jMG)RR%Ad7Qa#7vGQxb0=iIxMW9t*4QwsWV%NQ~nE2g!YA zk2dU2XN)JYO8o{z_)NJzC4EF|N6dY_+|6eBv`zUxQ)Yz7L>Qbd;UF)iB1@-<_&tvO zVo)p`B`#LFJ1Z{4<2a{UZ+aoF+VP7g-R)iRoIT3ZOA(#!MAV~Fo$={^94O8wjS78S zd|rOB<+=M8S~+!qbSiKH=v;#b7}UilJv{80-URzByWo)7?uFjxDtmYXd#@l#DBj8= zAyJ>m5d~&i3=NGf8$FeA(DQiUnsa~6q0ym7EQdd^31@3O`ak`r>!vFjqu%jnp^H2Rvmwu*2z@BX zg6B79M#;~gcbe~!8-euyG#*7$s8gMv4qb?E5M!3ei#!QimKV2#FMI9kY)d}{!nXD} zsTF|dtTV+>y$51(?FdBsQnk|p2>{qhqvDNazF+1=Y6znp2bagt-;FKj`z`brL%>jE zlf-1QL{_b*BAnwCVb3u#vtm=?rB{EvMTFQ2LggKE#H_w@d06^ioGbSa0TQrY<$A)_hSF zt!$gK!&dVKF6g!WqX+o<{xRLZL1Z4hhx!ba$86osssFMgn>)NpVFIX)AOgxomjehU z$2#c1&p_C;bq^qzq(?B^eZbR)~;HbM!S z4OF*D_xthEL20ganwlvSp66h^8?TkcmWf=PuU)t*!_8>=R#_3zPeNQ*le0LL^*ow{ z;KMxK#YRP%qkj{poJ34F!V>~Ur?!zpbG;-7b&FB4-@k53xiPmFLES!~!nYt4 zMZ|>fIOrxi?p|Ur2l#dT{2w^e6x7zZzVpBZO2&XsIQ%fcO`mkS;-h(WO=o>3i3}1r zBkAOnxbRA?bqTr9joyvRnj!xK zf^$Y~a6U{pxj4WjZm|$o2_5zmtVF+$yR5O-8S2uL1;FDhK$ntp<_L` zwTSgi%b%qbQFBx_vZ@>hRq2dZSynvfJLgkkUDj0uMdD9PEN8$d z$cu?Mv!)BLekqKF#>Oav#Lq}=)wb$z1>z3L4n&+V#Flzj-&cxQF7D&Hqn~3X|3eZxtt_Kb54P-xU&AYMSu_ zF^f07mdQBZk><0e72QIz@1vdd52fFh!R^(|dYFsMOdT2rcR@@w52|X&5N5Hk_%$Nt zi0W<3Lpl`fA^cwC-SM58@6#k!Pv`9kALzO`NF2K&zNu7 zB!Tx5S)?Q>3Lv9)Gy?b|0wvF7aq$--7}a&VFgVUzNX_e9!588hq~oMdtY^CpWyz4r zQe|J9{lk5n%Hv$_ z7XN7Q=&yeRDOPXv3w2LSPyNZ1z(Q13cDMH%&=N}2?Ib7b4h0TKPs5cug~T&a;cW%J z4I=Dq89nni{q7el9r45P4=xCfxcmhB;FgS=*TJAe&eiEvJdHmUAF zB4h=E$#P}#ocOKn=nAuiH<2w7K3^+>jc9I)T6(#FGBQ_6LZC2z!G?=pJr-;etu?zT z1raupYPBXaUD7KGfPfsptHTj(_sJl$r*m%()f3-ENQ`38@-47ZoH>2C*fNQ1(M$-j zblUKK>vOV@bF@-^QdxN-Jcv+Ut#0p9a9jI>WIDkCGkWF!#q?rS7ruyXs0n)>J?xTY znqgh{#mXh)%IqZmMMP!TK4{Kf{b_Gr7p_sO)d7tklKh@nOl!!3h#v-alzjPa*LCT; zPJnhFeC%^2^oY=OB54R}Rixss%01j*Gp;%qJpKx}kGe`5X4qrN@Z>i z2HV*YO4zMQ)Q>M&kx*yw4V)$`CP%8=kK&)fkFX#?#L>g>#F64H9|kpYpT}3F26Il=`;MMt=r6WqLR{h(^In%a!lXoow5aAbnoK88_Vzsc$pr zw!tcge8>KAzkZCa1s^D zv_wxBIJtdgv86YA+&EZN8!=0PyOBECe>`tXP@;?6S7eVoDbxY1h9h7z^DmbuF#DCb z7(?1UaO=p0W0#DW%3EVP38>8Wln^oUGM@&B++JT1g@>x}`29jJqAR|PK+eFvksgApj z+nnj^CB#Tr6%SD>e(!9RU-U*MzpTRyhN{kXccp_bL0p zkxX24J0Bx6^>B%m;t@aQkgw6HYd{lhg3fcA{eLW*X70B^G_DF;B}%G|5JIbg#<_7P z)e9QW`4Uvc7N3E4qrA4NSj|CKX_&?O$|JPdBLm%$q34Vb*Nh=qQPG}MBRVw_?Ka3= zp-B=|@8lYahliX{YJ|F~M5bGJ_=0Z)ESjN64jASoyfp&I}E+r!tAl!s^yZN-3WDb zUIisJnYO3pvMHvLqQs&TCOOjCrq^(7+sFlU4b`C6s{o)eD&`TMw}5s5$1VZ_cIw=p zWJ$bBkPbj;$6meZSdy-AYd|gLsIN z3Yz%b9ZA9;hI@sRgeUU$ulr(1GY@PT%r5w2Y*y^!FuG->FAZ6X;dD`sE4AF35zY9x zV3f}~nfiJRs1r!9bbu;uo%XWdg@j?(f@5}R9+9*|d*Q4qIy4ao1=)zg}Zs^&u<9#g@Kv_1g6Hyd*6qP1Ot(gH(3@6Js#X`dz!r6Gp_S7(zke{RR0 yhRg-SzasADGq|g><4&$b?_@zmAprsSf0@+(f&U4BaLeB(A}TDzCxR%REc|boP)6PW literal 0 Hc-jL100001 diff --git a/fonts/Helvetica-Bold b/fonts/Helvetica-Bold new file mode 100644 index 0000000000000000000000000000000000000000..aec380a3310caa55a85897adb78fdaba1e405a4c GIT binary patch literal 35941 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 NgEomqW1iPNZ}mq$GwBU`4a#mnz4 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 UR{+70w}UXaC{z$8LXrgd3vEJVKmY&$ literal 0 Hc-jL100001 diff --git a/fonts/Helvetica-BoldOblique b/fonts/Helvetica-BoldOblique new file mode 100644 index 0000000000000000000000000000000000000000..479904083a9b7ee14e0dc02a5662d402f4087f2c GIT binary patch literal 39013 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 Tc5V(fK7O9=Ha@O^aLoSz#uw_p literal 0 Hc-jL100001 diff --git a/fonts/Helvetica-Narrow b/fonts/Helvetica-Narrow new file mode 100644 index 0000000000000000000000000000000000000000..f2387225df28049a29cfbd2c4bf0aa58e99b173b GIT binary patch literal 36615 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 L-zC_WEf(}2=zpZ+ literal 0 Hc-jL100001 diff --git a/fonts/Helvetica-Narrow-Bold b/fonts/Helvetica-Narrow-Bold new file mode 100644 index 0000000000000000000000000000000000000000..7ee6a2c812cc2761694e134ca3f59ad74df6497e GIT binary patch literal 37240 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 M=K~G&Vu+#o58wiKI{*Lx literal 0 Hc-jL100001 diff --git a/fonts/Helvetica-Narrow-BoldOblique b/fonts/Helvetica-Narrow-BoldOblique new file mode 100644 index 0000000000000000000000000000000000000000..d2e96f3b7e746a1785124dedbaba777f416a7261 GIT binary patch literal 38310 zc-pMEV|1lmwxL1dMDAj74p2oM;$m={W&1=GF$zj*9v=QZ$0LRz^a$HbxRo z`c{CyN)~7m5+Mg;eJ68U8)1DXV@`mou@OMn*bupg;D9Cp2-(`XJD8iAIRVI( z6;vsxsHp!_@{b9?!2Lfoe?1+|O>F?Ae}A|bTiM!K8{0Vjh4{aAR5UgQIGGs(Ow6r} z0Yb8J>JlnPn*URp zBkf--0Y`v7z|qdw(EP8Pv74c>-9IX7fSs{}wYj6?-`@apM}Vn=zKzr09yr+o%xw&< zoQ?iT;IG`o_FoCvIoSTSu>Pz23npjl=;UbVU~cCG_#0JDSoGg{I+^J^{S({K{I42d zYx399$kx#LpOXHi`wR0|>!fdP;|Opvc60hCmVq(A$lTG+O5go&?7v`k4(9(#!`ac? z#`HfkpawV?o9a6lSs6Pz{)PFA{ZDuPvrfSOR=vKRot68)ylwww^}lj3cXBkgGNFZL zVEh}?(CKe%Q*#?=x_<^n!p6iFz(D_RxskKof9PC{9sboI@_%NA;%^fAMz%Iq?f@fW z6KFaaTc^Jv0p$O8EYtq?k^J94@qY`!|1I?XzmfZ2Ir`r&@&D_6{;$xY&Q?}3`qqC3 z;NOb|@ORTV0;B-{>>9v7%jTbijR60w9CO3}kF&nDxt06>!TrA)sv7@0<$qBBtM1>> z0yd_9xuM~p<@mSM+)>or&DcoJ+{w@kV4`pJw`>2BEC0>N!OGmm_%FNvYAk?;fu8=q z=#+lbV zprEZAz>|i7nF&C{$iWWaU|<4puyc6-AL9KBhv7fZ()vyg=57E@dRlsV2EgC%|M>jp zN&CORh}am~8vQdlicb1AMt_Ixe+m9)2h8oAjU|Nt*3C%I!NB@2siCuj!(ZnAwH5w0 z;y=#+x(vp~ZpMaiejpIhKtN~FP%C-`{nWRZubbu>gaewIESDDfEQur5O5+_mNmS3v zTS2!blHulAPK^%RzhkUlNuCDpz|L-mIT|<0!Y(NXF~6y(w)He)4oGFTOay3T35I_S z5q5oeDTBNY+#jh^aRCw+xHI1_=NEIr%iBvC_xT`b(FND12vadSGL#N13DGUIA$esDbBMML&R}*#M(07)!u3BIk4*uCQ{tM( zay1%a7r2DxXP5nAc#SSWh+Sq>E|xp;O6)5BQ%9s7pXtPu!aUUbLuM`(u3**-$Q+V^iKIS>50pr<-7O)f5A7uDZW5XW7OHnq#`*L#nPWWdJW8t&=+ zoIufJT(|$BMnJ>tt;Jr1YzCyyOV%Q60{ZJvt?Wn#z8^au@K(=owPNjjOM63qR}P;5 z4pW=$tks@VXlTz}uwh*n!iC;;B?SK3A|fQ{yVM4E0gJJppY}%6a(g~jRNb3-GNN{@ zclQ?B0F2)srJd8 z1WEbZLxyz9YG%&*Q?Og2)#1AtflFQUBied$Mfq_y$h6jY9kY`JSBB=k;Xops6sy?{F7W?0qY;c)X1^N~p=WnRN zjTPk;={Usgo*ZVV)027riTHrl6v+|dVQc->PG@plx7Ter(Zk-b{mgT;hEGCF1&6nk zY;7Pyothj+Qo5Wz6BM;vp_*ze2D%5oW{moG`H~1XRDgvavu%TqENSv$_GpN9`O_Y7 zTrUWKbM>ojPTiXToir%dqRk8-&AjY8NaJ68^|*w+OF0Bdkqmcna?tOY>d=MbIc=c+ zoPHHmqeUj+-z3Fz<2i-s8W^^T;`fVh(b~$dBBXTqF$8J;6OD+%->uklxE8VKaX^;& zbm2Fx}e8{lt{s54AF z076T}$?WQM9JdQZwDj=Wd^l_~cVeQ&PpJEgwND$e2EHXmo{RxvN+L&bz`%E5-}f*5 zurhR}o<5L+V}edMCXl)Nu$kzvpJ^E+wEng{8oxf#G&hvY=p1%hjygIk)Dj{vIr~Gn z1So`~1hque(MdCGn$M?`0WiZG>I}bjUrOmq>=OteadDjQv;Mwt4DUKzC9B0E=Km<1 zg+4*#7l}%s3Y9q6Y@(53(55+<$5?dR#9MiwVoHaQ0~0?Hc2+lHjS>!_P3X<@gO|O6 zlf`Q2YZrnv4hW0vL}lr#74-+3rAZATM5~qZmYp9w2KO|GllVy%T^QjeRcn?gd>fl9 z>M^Uwe(l;+K8BUE>O)MF5(7)O!xxk+vl-0h^s)mK&6dl4r{_vk%mYq~uWP59rvNn0 zYkGXY4|Wn*Kwf*^7I5~W;{o(EQ!*bGfQQa{XI_HTLkj87)$ey;j)y7+P!l^-SeI!b z!e6n^e|UtMW2^csRjQwvz>N>{&>x33K;nhl7jx9}*{=~Ybmj~tH(0@&i9^=p@?QjE zmW#j~Ajg+z`8X9#&EWW%gDj;YHE+APAadp3$<+{wMQ`7UZQ$tg~>>P2wiYi(rOuc-_l5*kjJhhl>tyswaKSkt z8X`ZSR|1;`GSV*s61c!53(zd+u0eRj0*s=u{Sq*Dw3kdeRm`BFPR;*`H1fXv8FOyQpWx zhi0v->+O3!z4!_F=|v+K&^^605MoYZWEovNIPJkZEZvN$;2E#Kf;Qov!6LOA8%9DG zv)D>y%Sn1cx;=-Wutrn14ANk?+}mTT47=?2%t&8381SzJF0u?L?sLX_I8R;=eEqU47C|ks_fqrE?2aQgYVH_~R6j4X zt{C03LX`#72kJg?jmO_XNsN83YCi!_&junb%*ykLNL-sA8SRxxRzHTeQJS|;(w@?j z(9kmtndQaDP04=3JejtCw}DRy5u_qS)`rC!stLn?R6x8B1@vE6!c=tkY(r}m>*0hg1~xm(6-8%8bVgNZIY zgQqi}qfS215r36!IU$!6^Y!~^NV$B z!#7X)(}!1xnQ<1YZ{BOTFz?u#)SoU}uCvreG-^DeoC^qnY%hQ~X_Ev)opmN>WPthe z-CM#7-{Tc(6Ir4j0Qvy_0>vHF*hqieb^An^UP!#!pP>8O6uCa8@O5?;`?Q@|^@|uf z?Jf7Q5^OCz#6OBnu;($22@ESmA7UGI23y)ytejHLLcxrqDV5y@+?Bb3j8l%G9gp8& zv3&JDi@SEv0c%nQz09b$tXY+EV6?3qkcRWM_ZHgnpsG1*P-y1SQtb6g+++S;fc~p@VR>A2_L*@8lg`w|`KBd53B#qkt z#}Cdx1SzUF_@yM7Zas*AcVciHGIoTYy)^+$@OsX6zJgdqQ_+ZU{*W{mG2$-$DZ!DG z*4ke=fwDh-k|SBwfli#aZ1iHIe#HhL3__wPDu;E>6G8(OX({_iIWj`#H<$ydWp6Fq zbhj0>1elT8Y}2Doy?X99hOaG}lKFz&=<6^Od|*g(tQYm3$zFRzj|mJXq_m_bP$-(o zfKUc1F=JRaidRvihwZ;hMhpp-*N|B*9ia^h$*QW5Ku)>uNE~DHuSO9T$Jyilf84DD*^Mt8Pn(bR7w;p@_RWK8mq8Z`=h#DU7SMFR)lD%eKCr;C5^A=A&+%>U%nIm2t*}F_nioH#{u%HInjdIU!yc129ZJ0Nnx?VG zB8VL@zCDLo*>IS_b--D1zfC`f8AO?f*nd#NcJVe=0EdmsNl^C5`o6V#{PLwLuNpv9 zm5h>@`;|`#=h7jWOXctpyUMs2G>DQ3jMNi`i4%Hsf^SO|w#d|iwsuG=700c(zJ(aRSHW3wG~A%U^- z^^emt+3M6L1o(bzo{j!J$d}IZ8dS_959FZQj^ls=^ z_n$8bIM*08KCNOFya~QwI})uoePOzADX6?Kl|S=dm+fQS5@$E)C~TEFVLv`O4(f{E ztqLvr#I=pakSWpm5j56r+guPKStbGdLIF@!EH2%g(bk+9`%U4<$5805;aSPPpaS~k7x<;Ais~LAJvp8%4fUy zl|+Om=a7jM0;6GgtHl`v?qZKH>n8l(vS%^!e)1&DIkDd1mfmU@W>MS| z=RI7a;I^Ccj5a|dYHg^*V!@?iZEAafeP5z%6P!KU&q$@UNQE}d2>jA~wom40y`H(a zzONH_OS1|gAU0Rw7R}L*h2s>(j57q(7Bg>@aU&EzCDLA%6|#tO;Hw`ylF_Nw{aK}s zd7rev6G*Aet=CtssNT{+fgt!WxEYezXARyH;kHsVdRbr0{Kq7j56LM^QT=kS<%ens zIzBS*a66d(nY|EM3+Il!O_<`qE*1on;OjVh9CYhEHiAB;GQ#RD!|^?qSc^9WiY?-K z&SpJS!w=3LS?8SL$)Lyt%#+d^kcJaYLT;0;bip87$>E_k(o73K<9By3&<zu_t9JBD~jkHWRFOAn(PVBJw*Y<&(XX0Ijelk)XGRCJ~qhgj23cs4!ncY4tgy7-2r;z)n zUpa3P)XYAKH2&~S0-^D6Y$`OCF4Kkg$dtE3=hkKe^O46*Rs0kz^%qwzIg5n|Bi|-- zZxyEEE7`Pc91=vnNtn6Nm_GiF%ObAGM|*R6PHt?H5vr)}@45#jf)|HpUI4n1!zJ|u z>QcBJkk?Q4S?dU|y_-GZ92qwZjNTKqYZ1nZE&fH4gmq~iPQ@%XP{{?f0B02H*b9ac06v&TdZD@ zx|mIMZ@RVe6Zz$>TZ6c?7TAr&alV4Poer%i*MH~)S1ONm8G9Go&bl46o+o%R62eo` zsWqv>>8dN*$ub~KvpdQvS?+||GOoPH(+C!? z537>k%(+Xot2vfJ^|Z@lM@z`zB}b5HfFBrL`<3zpn&ge|m!~Hw*%K#$hs{eViy4@w z6lj5mndfOfS;5MCQSV(YqO!!eokqZVoH31BivJ{0@VoN`luv3D7Ne_rG1kWkt)oa~ zpz=C&K@uFI8{d#w2oC4x9K zh2M>`rQ%t2Gm(s+kR zUw-_>y==QL)c6NdZo2AWdS*Acoy9tuBt7{Ih~~h9cfy%2*Y0#)6B1PH%Z`F*tb3Vb z(!`C$rb^T+D3>~Pc8^|Z-*uA2Q#5om}`Da3(n1CMK61i zmRZtlqL) z7wPz#eZAMC$3kesllP~48g?7yRy{2Og}-g{@E-}PD${UstB;LcNJMUTC-kOQ={(QQ z#Q_+YH8hpcFf zC@R_wMu~lm?lIzI}2=1GxV_}PJ%H4SDN~4P2CKbGcEm)sPg(v z2fLZ@q9KW-G19NQ?MSR$n8F`?;^}(+)*R0>s0LfR!{x(}=*yvgM`TQsgxKlIWScUKbGZ$PNfXZdR`Do5j?x zX#%t`7s5la4gWN(edQ~8m>7M#5cmsX)R@tVXdp*=S{@B1Ewm%MX2ZwqM+lq}vqF`* zFx|Vpnx|ka&H&o{BJdAr+QMEdXTAOFnu{9;pJz?2+X{gp;n1(#nfp;iu*Z~wd7Pmn zTE#Gi0&x zaWfYGiQt@!8r9y_EPw}ZwU{HMamdBy(_Y_dH5tMGyvFO&&p z{k5G_2DMK=Uh0?S@?Do(Y>*OdRXIOwJ6+{F%!dWWF-KvkrU?S@RoLDB@GjZ7s7P$S zT_H+I)6oXjrOAtHa3t$=$wLvde@M6mTQW{#C|(FZUyNKadCbj`9c(yp$c8U>p@3f7 zPwnJ;L{1S>KvA`DJnCUG>()-Ft~UEOwhvg!&9}Q(AQ@_M$Z2|4f2Q;5EO@Z6k<|)` z?MSt>AwocsOEru*WXE82VHi4Bo(&Xu3eGSic4WW`$*7gJ;nX*78?u$B_0I3~#@L92 zd$+gU3f8Cr%MH;ZJDI}Y<9F_B+NV``XR$Hz7Q;wo%z^L#VZ8QIqHP9<5IUuTxmM`i zScz0jaRUR8#`>Pw$d&9tXW$g2H|9^GFziBvfw@~n3}Iszx)`VeT=zO}uW zTkhqu{$Bkb@$BgW?7I)UC1W}f@~SR+sR$-_5Gbn>lij?l;6NkA8Ej0Hh3#Q84Uorb z>jE2lGO&o@mbg$cEwvgFU=ZCJZ}sc0N zepRj+nNln(2Z@7iX;gR3yjlc?ZT;EXbA%@luVUrl_gb531JcGhI3J6>y!h3X>28T3 zZXfB3|)IB~G4c_efI;w`1I)?kgIz#N~NfhEy`v@+f{m zj77z2@(%VNmyRzma1?hf9U5RzosNR2vfQ6;^W{ zjK{sxrJF|D3|7F@R2AzpDUa|a-NW}v<5YKA#3-6EJ&De!R29tzWUPT%@*GTaV? z5?F7jkQhm4YLtu({2xKbKdo(t0ZRMM4y}FTk6ZQf?X`}2+<2#P#hzDbZ% zs}0fXgP6dl0%WBD_GuLiBpXkV*Fw>C`9>&(f%c_as zt*E_1$0BX_Vhv{ZV`^-JI}(O`{mRou@p?w|-ka;KQMgPA02h+O_anl<$FN)4Zqss} zavT6JQCv3x(e=6)yvZ-5h?}q|0{1 zS_vao_oH;_oroxIg(ypDyGVDJxkaLr<8A*v?>dLvk>#6cH}+@t@5v+O(!yizWr7P( z#y7Cq_d)be6_L8DPKD>T#IY?S`BTrQ!l{qlLx@cLajBG?-H8T+ohxzHfrvVI!+{8r z6@2K^c3t2Q=Q(1NxRjx%{Ikk!F8Z;?S_P9Xg(h`PCQgX%JZv@G-dc>f6mCawN`p9B z{1l6)^W0gOpIZ5wD(bb$xOc=TXKvKO3A)*^1WtZdXKTSQ^YL%8u}9q&ychHfy<`a! z!uc@E074t@sY>Wc%p#h%FUPi&QU4d+w&sM~{Di*p{$(iDGxDE?%wrq|_8Y}T&6uw_ zgO`EVg-!2z()KIm%rIk-F@xZYB- zo0Y2~gTw?9E&B;DNHKvg@p;C+g4+fTs#aENTR>!24ib)OOW6T79pZtW##Sx}wsjTqi}jKB%?oYdhZitF{Qzee^t9@{NXwMN6^e~fnKtFrTX zI?wQAdw%sj%!9%_X4wSm>bY*?`MA{$8Kpw`ya-2uP^lB%BrbzcYfl?xQH_%{Zr(`H> zZOqIE$_8U56@$@Gx(1WwB}LrzoKVqc5x*>~K;V}(VENNiM|o4ZJuz(o_6qk#8w!K? zoELblB4JrPOK?V%tLuWezB9L5X$sEBaGd!1v?exAMb2Nq__+Tw|AD_gBk~a9;Q=lB zyFNvjNy>;DO6=pNs~zFG{LNJtACra)*FGCD&Sm#zRS8>&w9BB9%{+Pw>5v@bonaBY zxSt?o!zd;ICwX$&zZOP@R^m*`DRUKNFW$6UFv9~}^guT9i3vih(UxA3T1kKGt7mQc zWYLww87L$k4(*dV{~M}(Mw{(-D%bL76UCc&N}o@z!U%@f{!?~J{4rpD;-|ZnWuY7f zR9imk^7#0LaZUb{Y%dq$(hYN6lbt)7i^XQnP5os$8a%H;TYcwFFY}%y_yqAzuLO?YIJ$){Z4Opbe1x-GY@??y&TU9djhZ}DUqhVd> z`_eb>LZdvQ?u!?4Bo2LFooI|@R3MGEkmk4Sm5HG*8%Mq|x8Pr{As0ufPus%vfl%kv zs_Q+(t;QW{jNmZy_!Hg$>Sf@WrM@)chIur%Z=N%_k}zvwwmJABQ4DD`R2X(WyL?kg zi}dO>d&PTr0EXi*50}Zul8?ekT+WzUq=!BKwJJRTFzMkRca*`JxGPGKC`8(V+&%Iq zTa)#0DWyfP0&u!)DtK zNcyREU)Y#z(yKjHYXAT~+%2Z27~5nrVZS?G6b40u6w~$G1|l%C{Iq^E?OV=(X5TrF zJrdDZ5_Pc4#3l0%zTQg$-U1zP?@!$Vbz#y>`P2eF?gc~fX_aIKt}q2C@8{_T}2!W7{~HOf&1w2z6R zut>}=gEleO4g*Vj8{*qWAQTgk6E6Lt1l}II`uw14U&b2bmpu?h%EzKlUSVx>^w~CB z)G}09?w|J691*!piiJyLYB%6lVAQjvAv5MK?#2CP8%}w%*cA!1)Om*8%8@XrY6J=R z{@Fd(DDhIZ; zScyA+6(6Q*Mht4vwC+d>PWnM4r0~#^Xv!Q(-J`k&h85Y-LsOn7R8>2Qo3O7)3eeVC z-ne$TP4G!!1^IhOo8!9kC2_1!HP&7xkV1*d5iHA+RlK4*_-__)7lc73j1L%0kHU^G*Sx2#U0@B7X|DA?LJzFGR5wu3+pHG-OGgA|nhSxDqbDW0Zex^adQc=YG0$2hPy~R?bxEggHJ$ z&F9fQc$|-(tOBgcW>w!Ac~f3ah&xv&W%(=gX8o4Ye#@kCX=R@@bYC3r{lPph1OE0$ z>Ukx%+nt8ka45?uFC}Do^V^Aa|3k6(R#22|=_&U0%}Mk1P0RtEG3JnUKtQyJUt%!D z#wR=?`NG>d!c9`<$j}~^t94GlMP=(at-TN#k6 zdBigY5KR(I^o1g@)Yi#>?V)uS+Mv&Z?7xv27BccXYaRVR^|bs1+l z%~~u(sCBGd?5so3I&?@Z`PP+8p*Rk7vFsbkm;`g}dS~;ud0_ZF&96OiqW=4WMq;Hk z$HQa|+VR9TUMJ#N5_p;jX@uhq7#5P*7;P4GPs6L|EC@0l{|Nqm4k}ciaVA<$f81Z( zti8ER>O9Z;68hPsmh2Q#4vEYa7jg~j(zp<6ucu|C8yF>y+=SwqnpEdKG6N}Qd?wg z*m~hSBvMC!Ym8F$8j3%3U!M;P(Zr_JakU!yeqY&2T0@B&yGeW!-tl|tVUA}?^>Qk) zuJ)p1|J^P)j4dSzv2>})^%zcE3yXIg3N(quJ?ZQ5?-0O=Z4=Mf#!ypQt%phQZ9iESqvJ z7l6hF9A<<%hAg6@oF_Cob@phgoWkNJ0li;9F3U!b(BGAto0ma$9l*%f*Ch_!ZVvQoA##_; z-cDXmuzZ{Yedq5YQt#3MQEp*{u#9;b&_UG8_5#U#>rXAJTrb|L;FozzW*=qMAn#H+ z?HEe}_&$xxGl(yx1|8f}64|>zPIwgXt>@2n1zTRE@EL4M$$9!(`&~eB2d?6PkP3u2#C1SR!9WQm7#+;7eISj5 z$3r_Y?8bR&4j8f+wAu^=rHBpVt;J{PTjxGCFQ}PX1qSO^N^aKFvb+k&&z|2?Ye9V> zQWh#T0vopn7B4=pN0p>QL2Yx0T7Htb?e6T%llH}#I(U9Hl7ilvy?{MI0V=VuK3wXm zW}t~3ajx6)g|`+ds;wSsSEg&AlR3QNsH88yrAbqrMV5RoVEZ?*)n20uHMW)a^u| zcR+eB1?>ha_OBD0xS4*EWPdPP39cRWJd<0Gzy;)9sGbTQh~o`A+csEY28M_FdG)KL zRVaZbdiNSt33p~W>H_vpgsqim9Qr01B=8w>6rJ0iu)%=*VV+A6vgZxqdeNS@Dh>e5 zC#c%$^5C-;bl5S*PL;~q$L6A;t%vF9E(UK^L=gb!qD-W2=k9XZdoh$54zG-OIL3JV z#$jp%es+3gvKn)d;?PRN=)>E6D=%MYF*Z;R`#gPmJagO+<7(UgSfQ5LOVE=i;m7Jn z)nWdFmwh-vF6#pAqgfpd@yY_sS4|C1-s7-QC|+HzCugx(DG%9ADw_K)LNUp4IM+f# zc6}*-=*=sDoaWCn{F;o~*@5a zdsjnGL~wF9MM!;3?AS~&0$umtX-vd%#GJb%Qp&#^XXJa1Q>zgs*Z;`0fXdP~MwI`N zv*af-ZX|%YyhFsWorG$d9OJFsKo3t#H8#KSZLw8GBV7*VMsbIE2i4f5;NFl4h`n)j z(f=WREJx!hyo9S;%4ioJ#RfGbhpCdjiZB4C-vFEuu%Q8mtl0jPe7=THpNXn5{8lE^ zy_+=5GS?@kc)^S^Cbg3So2uF#Oc$2m$q3dr&$sx21!BtWnWe_eoR7K@ycrgb_Uz&* zol-sX$ic=Dx`R2N)f(DAoCiAK8WvT>&g(J=U9PI|?IzTusVS)HT5f~3T;;#nCNp!# z%57p&QzIg%85KA>Nyb20RmsRWHj;!T%D>lnm~KI@-GQ~f8I5aUK|NdALSSp(A}X7# zZnM&gECgA}2;ySP;?^9=M>mXBD{J2=SI(nJgrrxJ7{h059?}f&V*48!2W#)1;PsEI zJjDhh+}E$yPfh_E!aU8JmoYR1=h%oYiMI{U_ZUS z(t1~z)q5g=68(qyU0JiR#Ue2#muY@;nFkP-WI_t8=0h;%!Rbf$}b;?m!I- z%PppbsdC?z?UryaOw3d#2kbOXN?BOzZYdYzBKccP1-@Wbm4S@97yiCeSzE8}EDf7P z=^buaysnCT@D}+N|Jv~dd6jT!cSuje zM~ihKEW?OrTflq8m=E%KVg-G~&x-4LMSpq5)vG~i?TEF_f^6oc><(bAia676vw$>@ zRZS1J$(UAr$R`@#eb7tKadEE27vf@2J;nxq#inzc`k&k>c3~@?H8F5E&#i_cLa_D&D{Xexd$;KGPNeY@5Q-rJRZU{&;f+ol`4$ z%DujD09li!mhs=XqGlGrznyIi)U|?%bT(5@a1^|@DW!)f;V;y9UEaP2=8Zwm-e00CdIj$Ww#LqA ztGY7FNHer7@s%N~<>@S$N^zisd8<_Pd1)c zNy(#O6Q5bDv9iFB>Q{#G^AyK#62ZYs#t-~fXm3nQlR~@@v*6w;8N+nC?`$_5R(%mH zv!4M|q?0lu&Nb1>7FLV)fNvUI`;YvXYJwwdbSM}>eMv%IjKFODowwKS6e4f=uw=DD z;J{4p^1$J} z(nc(#Cj`IQ7Ld|ii=b0ce?f&Eiuo9neO1aYpE=XcJ2sJbH=dHG=pP~^APWrW;>$Y(R1(B2m2hH)kzV4)p!v^EVS*wg8ir(#XaDa#XgY9 z%g*=YKgNxsTo!9snkK@}pFb9r-^?xmJRi)&KmWR$=j3Qaudt(s!NQxI$^SB9ER=OX z28$r>#1l+86p|oHte@|3XdbiBTIrT`PWSz_a4ouP0M6LgwDVY(eWc~W>$UUj(^-FH zt$Z%J_PB<_;Hyba>Jxz2X&f%NVf|IDr=sjnLlWXd$c~txGs7sVvY*^@tdZH+XZ+Ty zw{AqB3;wb{Q89Jr0&VR~nCrtdBmt!&b(7r2VW+xKrIs2uLG}QeNcTca$#!69MaH`yS&J5Fb*DhC6Ny+%x_qfe_$E3tNG!^X+0g5fkG>B7HQIO5+dDK z+JI?H5=;s!4e|)vyAv>so93+WR_2z=NVEQhG_@eZhc2<(SbrwwJ3d3H4H|zV0kmY) zmhvV1kW!DHVYHKSnvxi)CM>t6IJntX5ka!3d@|qlLSYYnZo^yn3;xKNvdbB9x1)eT z+}3Vpms*0Fv3Wjqjd|n-$4fwy{fb++VJLto+>bJ)MF@0GN?yyY3+u`{!Ik%_Bh}Rp z(r*e!9&{Ku#vypjo^EK*g5l}URTp^(Oe}}kuj#cix`+MF8~G00bM;8%RyYPTitG!4 zN*wYE?`0e{J<<@YCGf&r3J#&`*PLJwuLE_}eC~%%(y?L3KN=3zN<5zUS`P|Wb`W>T zcD{A+YxP5qxL{72>`cwa#Z^wS)B@_p44R!TI+xPbnxjxFCm0^A=}YMzm2I36AG}3O zFRg@>!uYx6_A~+T(C$${^U* zJ7+bi5qrLodn5ZEiR`^^g4g+_>{ zVbp|Y1H+P#hNSH<#=t#c5l7CUy1rQWGAR^rDz^b-4^~#{ASutAoNTgpJ@}OY_~}*d zp)+l?3xkG;A$yBC;C`CDcbFsPK*khg3u&@sKRaF(3a?$4A3U_vhQPq>62$GDq}}!M zTiDc~Y9^?UsWGm^MkrN40?O~jrW&+VQSIQgx5M7=mfK{JDQD{9C;JQWg+*wyz$d#; z(uxBRw{>N3#{7CS$1AiU1|f!iY*)cKz0-2GPWxVb0at`a)lf5mvV*puQV;nU^sdiA zr{j0i;2dkDt(-S5qOTgEA@ET?Pw}&ytRTsghscP5r(r7Xj*B;(4h_NG|lfyLsFe$qkQzv$#W-^jQp2G;}a&wvLC21t7L6xsV% zg|tK|>IWZ-=Ui2+TBGJk?`KrqRQ?WTfKG~}KjjW2*2E%!Pdi8`u6sbfsOQBxXg7vK z(C$LQgAXoKuRGTv)+xoHUbBI-BQIVSh!U9>7CGK?)7Tbnk(3e6wZm^(SNgFr8VNM) z{bRk76ftA@72jfduJql9Nzy0=X}~!1Jnx6q@KNCSdX`oy*_gr`s)QC}A2{5qr0y-* z0PIYUX{7XT-TTPW12JRAlC8k+`HGr&OD4B{C1ne|t7^ESjveSk9DdTDhHtJYckY2M z?A%DSnwCpY+haqXofOraiWTeC^_p?-l)Q{l=FNPi#UcHvgX<-{px=I!@JefLm0rE@ zI=&$W5I1mg+43RHEAFGSKjHyh&Rgz)$JRWnpzWwyv{X_c5`+p}u8CvUrd@Z-W7ayw zvz&XehogBsA$2RrmyrfzFZaUL31%&Z1vqb4CcM|*lXj{)119Fw-U7R(hIf7F3*CG? zs_6V&LbDbZ!pAN~sQA??Q62r6u~&74@4&Dv=-Q^LYTh6D}5hgw%|~ zdoyp~CYqb2`9B`au^qgrk_?vjkaWV8X@5qQqz;Gu0|@xA#R)~pT3iU%x=)S@Jkjtv z&jYGOF2LIPpzP}se!>W{3!li!Bds5Vyr1>eZgB2&(4QaSQT04a$wxVaF^&jszv1{z zm+yn7imfTIE>=*)a@FElQSLJ*nV-s=+f0lagtCbc*8TYoV)yQ?7EeEY-k|kO4CyD3 zMx?Jz`ecq#L)|u1OG|ALLrC#bXjIsK(brgCb{Os^16@O4J z{G%OU)?^6^5KHJ^akE;lym3?n=OVs&m%y_>H3>qWtjI__vumG#u1N#`Gb&^*vAs}Y zuma;$Scnp-m8Zk}yAl`E|7k3;FIZmYIJ|P|fL~?xK+xV~HuO%r_8A4u=Y~hL(WwXi zp#tfD02e^$zd;18V}sq|DMS+!l#E9fS8z;eZdI_0XDSihEO$(3PY&#l>AgUU|4vX^ zXxk43*ld3M984q`nUiYcu%4^&rNF{Uo-ICbw?&V@o+(uH6G$*Du4X;n%>`)dx<#>i zrdw%OvJZD&0)q>Yemt(=%?Ql{Q@FXk9T};M%f;qm3$%N*IyVZZ5lCl-Nz1r79T5b zNwoq0i`Rcj?`Jc{=g2r|+AkV?bWF1fQT}1xl-8-c@33^Is`R9@%ESpKL&@4xp}*6# z$o#pw-DbCqYRUAb+2ve-AZ~B{#u`OLc?Gj<02Dl5Z>>H`KSj4BXppt8?Cqrw1mS8^ zTKZa#-%Jg*+*M}^mtK!zPh>fUbs-gmfL4gYGSUVoCurs^!E7&STiFiOk6bFIW$K3V zP5Zb0LC1Jwf#DD!6@fHNG)gO&fNbk)?Ma(g*4u@W^KYuHT1Y=Oi~;yJ7|?I#H@Z*) z!KV3X(#Zj2MHEWH)f^#l&?B%6#z5b6o+0cGmR@_=f>p4?4n}SQ$&{n5jNmdu+#_ zNPKyNYxAx^$Uc{IZ-_0IXF71agn?I4xJVG7=bDKnRJ$x>0erM-BLdftK3b~WV!|sz zs5bAH-jWjVzZv4Qg3!XjXRWvi=!gWb_|XMT^=tL zz~zKjrfCu>%_24xQFMJFVm5x938Ojv#&`!yGu`Rm;9+5`5d?Hnv)&C7yBK&GkBZr( zvDb|SU=ee`@tXgqm>Mv(scIjW9AN0_oWUa`>*w|x;<{r0xWTyHLQ)imxk1`0IIce3g zf%?Piywco9bvuy!EMT$-a=d7TFrWh;$U~jP0ElyAvr|uoLK0#^4{n7MQMR_Oyg|(T z3iDD^@AEQS5E>{Hp_f3`_(jJazw=8|1FPAjNrCj6rSeOCi4w!xfMbRR0&8)NR7Rj{ zTqm5yHPpju0LXNN9vXCzguq}ggH!c_#zV(k`u|7bvlM;3lYSR zOh*`mbzQBVrp40D2&r>aNC0_g_(V2@a)p{(>(lg}O#if`&_Y!bDo+F}dj8BH>Wv@J4X1@L)q! ztmXC?jAgY0=1w$^)dAN%eXl4P0JoE4t&CtxNPzFe8-_NP{#fldPH4jiGJC zFDp0d|C%2Ld{?uma$HcSbT>}=0sc{>iTFpOG;i0t@+3|W7+-C+%DO=FQX>QRvm8Up z06TK__N!)PU4&0pM9C(@0&DzCBNLJ1$CClRhLT&N>Uj^;*@>Ld$h)?_nN{wm*3M2E z_$1ko41#lTc3|tuSP&4!Sth+TtBF@HW$YRscCo(t{pTGlMd=B17lsCvIKlY{es9M4 zayQhV7bKG#M1ll6juUC4HpRb!VBq|)A6n^Uq`1q>d-K{7n)__HILpra-Gt=~!)#k$ zDWNZ}*>REV>F2FAEFa1lsfP+uElU$-a$gS!w^IHgH2;wZf4FxnQW;bE)gz?D45>bd zz^Hwy2nT;d;cKSLV*yPfR!}Xxr$at%-R(6whpFAEBab`{Ya6DIb`tV!PVYa%0X-5{5^4}&1!Wfb~hyE-q zuqP`n`~JY)*(|&D6JNE1-;lMQ(_^Tg1lK5lb|<7+{Qva(45k9OgsA6l5+qH3@!)>B zXW;aq21psfylJB_^Jb1=;i#WSV06T2H`7umFyKO`S}r-l_WT9eF?Mlf2PLY-A4n0fsG3FN_zcmDeC!CaFX4yY88vmMW6d)y=2K=N>y2r4u5}l8GedqT(c8-|` zhxT}MpxBCkR%nB*r}Y#LS(%43Ps%KowJEaWf;;x`cs^ADqtj#6vO@jr8&R_PYR(@O zEic`b!6EKJpY`~K)&#U4s`+)C2;3vbZoZxdPO$H8H)EV1BRAL1D%I)KeTU8w-jLNB z_Z;!^Wt9jG+SZr+^$6**%iOgHJVGhiXMY`NGI2R_%P6Q=NrK}Sz^bpt^qx~;08v?# zd_I5_FHze2puns-Dlc~`D$(=LOG#IPag2_g()jvG6%B0cUNvA@SJ6MA3=2z`1}u1a zsVS>VNa)(au9a$MCV2AdsyJ!wZ&)KQKy{!Qq?|JjV+Y}Ne}q1BWpc{`l(ZRxuhhef z3(@Em3d!FBIEJd7tB70ekz9ix+)Ug(xZ^xJBgxVg;jv^TeYU#DzK}V8x)L86ZnC&Q zR#d!8StH;SOt2VNx}4MMr@&lk{yQE-URM)Z2lTOP`)^mxrK!udoQgxCfk^*&zW(BGceiQ?{{O- zm2l$@M?-$Fs@>{_GoY@QSi>6JY3*koO)f!~$ZT1nKN(`n$@?Ot5pId5+*p$|7!}kD z`e{(QNrn-`1A)tCKr#sxr{LcHMQ@nqbc=Ki00<$MmHGwQEPJa?d@{iUH?k)XlZ!JE zP2Sx&*52?5HC8>uiD{6e3vwc2CS=hZ-{Ez+^#}4t0o9YXxA<1UP&_ubOu@ZvtbwGu zEIvqWD@-^eB!BJp)lxb>zMJ?Fy3xL4TlQ~M!?+O@!XJ7&MI?#~0cSTaDm`Zf0B{aq z*H7!Zs^n*oG4nswr@T{VO3F{-;G?Hdh`gw+2#4wd{cnDPj06J51D-LUG@VtrE3)u& zTa13nT>a^_S6^STG-3N`k~ibg-wlevxT{JY?|pU3Pm*&{mBc8C!~0#06LBx8XScBy z1t2VvN!e?<#+maeCNknbma4HI$#+N>aK0seD5OaP)O z9_%~hlE{!-p#)IQq@$I<}dFA(lJKL>|;0fKuZ!A113LNa_y&x%%lQ^Z1ii5y!!Mp=X z57XS|%@WN*oMj9-`Wy49kui@Gm4ht^4p6r|^AzcdKejIdWb_>d0Szp{E-!QsPAK0f z2}0g0{3VG&+If`G!GzzA|1uq>9Eq^wcQ)&LV2vu!7!gZ=L8#!EJ!a#wFr@r3Qw9;kGS6Lxbks8bkI+1-%GjA*ygot42pBga}wg!WtC=H zf!3;?9`zmODb!k;QP)7TsiCXb^Y}LKBb?hv2Z%kFg`dM})5g^|;IigJ^EEjgTOo|! z->|I`AKfKPP3zWD3JK`LFK=>4xECCmN<+_%JG~!s!1$1q3x@pz@`61xk8=S&IxicI4y@WEl9J z{qo^UP^E4V3hxpVCg+;3IG3i4wWN}xJ}C;y&aF0!`Q1ad6-Nlaf#HF}u>ae#Ja8tA zwk#18ENmeL9BM~|*%AAmcW$~QBk~Rrlqn>B;{F63F&afr{>F};J@Kr71imgwz2eMC z@P4Wrm*Dl3s}Z0^_f-n_NhOqVlvqR4e}c2gwF+mkA$q47l{OuuQEJA9FpjC`2e1;L zULms=XYYFCEsul4G2T8-k@3+HtyY$8#mK4w0ecd@voaR@=TpFZrl9ZH__)yApimVjDw35tVbOtDY?3y%ODJ>xdDn7d@0q`cuxeVKsd3b?}pUwp^ z`;*L{_d+H*V^NWuy5xADOKU}Ps?JDBkuMFY6*GlF%C@bb6BCy4tfR_@@wQcLA4oiX z_~^;BB@P8dgoN6wwe2*H7B3x(Fic&*VT(BWKxi?NsO3sO!3T?sf?4T=EDM$ywjh-q znusuxc>AR-=*0QUbjb|Y&LS;6@}63(PS{d-FgQvt_ipbzLH&FUW&El5^?K?$=EyT> z9z*l!OT0GLaNlzBj%+g@=&-LMtLiVaibHKobyC)>9`?`)?M+z)(O z_}Bv()Ihg*6h)b{&q4t+4#VFJ#)O@)g+fWDKX77G>W&*M=0MH^oEBgU9vMjpP`4-6 z$01+2>Uw`!pE?SH43on{?P?7egY?XT$W^h}vuV}p?S4p=x$pG{?MCaQ`LfKPk=Fxk zgUdHLd*hFio2IoDFKwc+bTLEn@c=5<1BFP`=l>W}^76Sv8yuhhNoamh-Rb$(JT&pXt`o;UKqP-7xiVreBMIgkrlN6sg1YKN?IiJ~$QKjIn%Oq*mmxOR#LXB~!W}v1O z9MW*=L){k_4UIiFLs3T^%drnrpl%g(Z@ODkPS2yTyPTgskBzYQu2xh3wiq~If5R*s z!|d4l1$RAkzL|g>&5$9Nu9e+(ozbTN>@plXgv{LSM;(O@(Kq*;BVkH(q2Do_N2;A? zQ{nrSJHDbF`LU%;x$qkTtLk-P_PpjzpmhI|hJ1sHRHEH|=e(#OZ~BRWnT z@=J$0hklURh}Rjx&|qinEOnn*a2^*&a{t|RWJh~?7d{3am7;be#eqnn&Iq4V;La&D zDPtk$>vQbHOq;y^x%qpdR*Ze>u&n&hvtQ1K-sj2fDl~VAczG%;Js-`Ln%c*Br$Inh z&_-o9Z^|%}t|EI05&W{ua~^(6^WZdAOv`CXfogsgh7~T;k{9(7{%*b}Q|hl3&$99$1zbcQ`bU{(Ep@bLh$4yj*b!Lm59f zsp=({#sF+Y0M0vIAeNT*0F(;jtWQj3%ZzF;SY@v>yf#PFhR~fjC>TpjxGPOSsZLT; zg8jB;Bs?#d{=mD7{w21vQNjW6)#*!LqcLoZhxSmT+3Tx>j{r=B-8W1pZO-4N_6SY2Q_-uk(@r z*Gc9pA*Sh_hJ0fV$F3#&l2hwJcU%0*`bC>PJqJwN1+<@t(R{pJF?RDn&l|!=MYhx(`_WVp6 z=rH?ZNzbfSW|qf@<_KQWP}nwT(luaBo>slR-E zNJP#g8%^A_$F-K*xUXdF+JS02WOnH8o90V1`w^Cz^+5g<06Te5n_gRqMn&GQautoQ zb@BZd)zfrsxmHTCu*g0cd<8s&;1!M#aF@zYfl$@ zNqoX2)I;3N{^dU{S9E~W+{VeYnoNerCP?UkwKAjHTUwh=f3?ZX zxv&nZqt97VE5WxCcEUJ$;!YuagBkLjsL7V{-U>1!zP5pv)1&gVhf&4G83cW<-{DZ% zvm&1|&<~ll1Wd_h#asP0^DKi{N`eCc9X?78TI^LsyLw-lNXK_;$Mdmms(+;I%bD#z zQ(T{p;|pDaN(OTWnXl@MsEudx-DoM{6aSMhi4H{q$&NI*yDmjz;4*L6^SxHw?WyWM z(5O;sf>azuvm_K>_np>zA$C7>@uL;S+Q^BO)&#TQU@71lY(%3jq|wgQFo<`IFB0*e zLx7}yXSfMGN<=X)b%qR@n9m|O!pQ?=r0Ck`1{Il#!jlMEXqGfz8xjrG^;i1zUg(-n{jt;`(@V5F3mc7^_8V=p-2}?g4cIG5$0NSa| zafv3fgGlw-!cd_C=Riyqb4dzYfO2c7qTm$sc)R@jtfbU?*jnfXAZkeJ6pM|gYlsA$ zLSCy$;HZbD+Ei`%wtjj;pVw)zUN9_*XkGKx_jy4e!P}t^b6kPC2=b_2fDDfx6Rz4a!Z>=ewGc8U|w@31m3)$&XeZ$wQ52#Q?KO z-%7Cgbm=@wPW%^{fSdy_C!QR&tHX40BfI`&0p`=jB)hrh3E%NX@tIw=gMw=D;;s?ryfuyUmuR`+L>Z;=RS|ahc{F1o$!s)XLVmNlFZG(??dLmHKYJz&x`AXAnca)wdlR*s* z!!gTjoZME6sg>YdV!A=a!0zpH17XI`6$iXHrtR0KR>ktm}m9AKHk zosmCry6D8;c-IKrY$MgPDP_Ob$BmRAL*fPz)HNH*;r6gHSu8Iv=Pu1qh=-KF8V3tC zJBKxYVq65ZycHR{nby3_9th12wQ2pz3u;JbEZS6o=~VV%+JG=#M>3lp?G5GiGeGWR zLO$6}e};n~s+>p?*#l2-zeeFndLv8sJbaj=i<_6QshUo7RYv^(LG3HCktWTGJ`-qS zH~rkW7c$HZi2|&ZkEbvs1=Unkr&AG+A9MBV`N8}wXgA+a!zsO(q!J0amT_)0 zAh!JW`0Vx72Qr_>Lw6CjI|%`(R+o~sa+UPdxND$%8!inTN$Nk6)JKy%*BMIr@Hs)-=0eM;hCY?ryq6{N*1X6drPtvSCsXtC z8^*(t&)|&UTbrQQ=>eCa;st0wm{i#>J>F6ZB)$N;Z%2}kwRzqREQrK;vnl=#wN-TPF5)Ea5nNe%%tw`xhb@R*_y zwTA>2{rIDt+y<%Pi=H=A18SZlS%`DNcFmr-8pa1poPiFs6EM~aGQ{znTJ1y}F+D-7 zp{6;Je&X>$n4~rCr5z7ty_7ii5R#~HT6&mFGG(Rh691k4wF`7A-hyP`n3+nU>UDAv zXIwqB?CyAUTmuU0p`*5GP}E~LVV{Pt#;exY&@};HeOIuRO}Z6{T9w`(B3L^cgUphg z&r%s1E#InJ!qHkOlFRt98$~!xiK7pA?`>KZe|vIKZ8_>bf@5IZEaS?DeK+W^_yK+uK$B62sU}aCY7C{Ej8QM>ayJ z6C_2!H@fI*UW@%ROiQ@5+*di*-%X4UQBU@nX?frX;e1gnR7#LDx)2Z!!C6ec35{FS zD_KJ;MqDz!b8U=}R0eI$otlE~DXRhm=t@4C&q^q$uC%beT;&}Q?&S~h{!mFIO;jA4 z*CMrpC^=OSO<6O4n;zl_w)_;|= z>#tq8IIhYO;dJaChhaVvA9nEf7u=f3D(+z@3x7ai{Td}9rg|o8vfH*o z>$TXZF630+$Ngh=FgGmFJa4zOq2sO2n{|34MXb5fbVUZffGzsiI%UR+Tl@0{h}M#^ zzoq6Ek7ee}7nPZa=N7dDv!N0j*3`5aT`whfjG3U{4OV$)nMmcGRx=>LuyZYTw988q zwabI>5l2a^y<~Py)>8Ex6hZvzz{Tmg^h;h8&6x-PXLeE>Obm>>a~f)#G5UWMW2tna zHvDd$mYKrcDadQ)=e6_WOUmo~NFU%UK~u=Ju)DDly~xk>P$IjHo^>PN!1JCaWh%W6 z+J)!BK|9|qYgP1_1!BB5HJLX2T&si5fIKib@87+7Wk%?$N6?(?&GHQ5`rO_i!f=;i z%}YG`?reVLX=&TMMHf|*1JM07^d<24@G?ZD)QAq{?Q&3Uf~KHq!_uMB(|r?<+T2`l z_HgdIM{fhLWDbGLCfJT}{dNT2qy>1uqRJ>Rr#oS&MWSfcZZl^r7sn+3uUvyvGili= zhg5|aISl_ZH^yY{cZQytQ|E|D_*gLk1X4+$g|`M^sUvy^cOxp5?JEVq8!{yv%L^V` zck)gS;mLUZ^lQ)b@PGba9)XF8W@fMY5S4xzmWlHPlo_bdoFbv1Ko!V9V%g=yDSTCI1X%zAuQT2h zX8_PTlVYQ44S&H-{eIOYznLxga?&eD?x`e*{R4JmTa%N12WGT7PAAephRfUk7{F2v z4DbDI-q!TpOj8*vq$ihOk)wa_|{qKWMF9{@6GJ5b3O= zc1gv10bPyA^~W=Hz;lpm9;R0RJRN}^_+XT@3#&NQ^kxi1i$k1hfZ%3JZVfUw@sJ4U zKM$mbwlU?fKqB3;s!D+$LNLl5fCH;1=iKE{_JEbVPh zDCP=Ml6jWlcR6YzCvE15W<9WK-Qtusag7+jNtT(P=&37XCP*0$4%+n8?#hFc(1^Bo z0tfb)Cz}Y-US{#&1Yt$1y*Kr7#l%{XF4I@(GDQ>3Vyv@+WMIx=bf>n5GwVKlDS za~Arf`ltd1=bDS=x$HE7Ru%G-NCL)2LK>kgLY+MZ+TDlHh^#O$b5+u<1o>EnlV>LY ztHGA#)S)>D=~J5Fhy^u&j6wVBpfKU%#)(i;k&DpU`p}h(oO(}^!n2j6NJi-h3P>^P z9oo|rTm&S!b|KPAywJNT@Lf{V#o)aH=wK#L zI8)9lnR+|VQ1?R`bw&_nk2W!~yZf~MY7w!pYv53_*-V8*I=rffLJ0l zlhTh&-dAPYt?U4gw8q5ka@$^oGk>7!wpw=k{NNJGv}$`uO4nS35{AX7li$%+ldgD7 zXxB=a6d56WU+$z(YSSgm`@j>KswYFW&+Xa3@~L4s_AD|4o+mOsXCC`ib>x{9^dpMO zSaVJfn~_yDr?V@U%uB_zta>uLsuYn6AB08_!eYG_Pv`{MTY*^OK6A*d$oAgug2+Oarc$Zz-I1$gxzD$EY8KA`$_ zU~k!g6NrE43V=iwbrN)a$Fw@b^N;Is=0kduK~W)|=f;S*^y^UiJ0%dv5a1rCEeq_g z(76oxV}}xSlFX88Fx2<$JmieE&>3gJ{0|Dp8;kMku)?8#ng_HJ?V1BPv09#fkt0dTMNqg!fs`}u-hU>hMP_FU=Le}H-H|K6$DY(NSI#@5CLfDNUFHgv% z=fG7c4CN7<2e_nR&9<0W!qD+)822_QxYIYAbJpl1_K%a~)oE0rXvA2+((-I$9K;+;R+$~lPO?)A_ZhFDrfMT?VzJ`7(*%=_5v>@(&@hwLFDk$k z&52GI$=k8ogiKX_WhS4$c$;m)30K1ImDX+1={ymg-cM>t`D}g#OE_Qs;6o-8pMvbG(r9?m!d8369%-4Nd(Dom%o18=~Yqp#; z^D^B`HZOU)g1MWF$)i5noV=rSBEw`s4>lCLqUF*bu8A&0=1{x^ zc?Ex%V5D#7cUJjx2AK8isPXZoGm~P-a34_@oAb$&yV@@{CIo4%dw6+BkN{*Y89}+@ z*vNJ!)Bf!}u${cXWk!M=4bV&qoZxw+7Y@o>(q|Z-1o60|(CL){zW;hejK9+XsZLd1 zbYS55Ai=OOJT`1{Uad-jhi8N3G7>K8NWVbDjS0_C|O>`dr?TMHz%CMD^e zcXypX7HwMIfwqtV9z^J-7-j!i)(=j9KGi%=JiBAdVPi8-klTn0n z{2ctX;S4T9cq?pNV+lJI^oRQ+jn&MTsX$KsZ5tkg3SV<38a}&szntw~qW&756<*zpX=2!4C+9mWg!Q&@rBQEWpT5zp0_`x z^@XwWE>^oA42-wj)$J?Y>RZkPUiB4v3NnR*27?*KJ$7} zKHpddm9$_$efX+Oe;Z#tT8i)g3Zp_o5>wS(5=5nr_)s!qz0lapm_z;TJ z?XpQ)X*)M}y~HbfxOIktz&{D*sTD=E$-wKj&03;NUTuXHmel2HcsteLlUtfs6)ZPe zHep&(ZX?w6LkqS2Z0YHli-;c`*S5|dDDhmx%xJfQ4iXXwKlTWLyEPFFw?zOs&9*TIc|RMyU=myrgAslMa{%zFh=#EN*UwFR{uzXNs~4`oAZG1jA$h~ zIPO*Pd~=L@z|_GmYUKOp-h_i2BfN|Io0os_86tPgp;_jD!Vj24~SMS$tUywlo z($qOtRzvg;ZA!^4wiN_^!6%trF#KM3&o~r53Q&-WFZOy8i*wwm59R3wJ$2t|6)NSGQ{Y=XSun9!z?@J zwTBfp;`VAQpO#)7L?xMXf!SrxMXWCJDQ4*s_!IO5J$BO;i`Nxb&!8)dh=vhnBwK|| zo<{>RxeS$dtoT^wWyS_xw)zU|?M|31N#y6&*1Kk4+`-(w7N7B&#cwks9bCsc7}76+ z(s6MpbKa?Vx4F3O5m$pYM>U|}O>*_a;mv!_WHfocd_O)C!NFl!Yn#GG{hF2@E#;@S z(WB{4%quWEeyV7@j8XcXk(RgSAS#!U0)ob2J#K>9%vbnb=*sm>d-OXHU~p2bYjTx< zTBoUByJ|6A9!2B-f88=|BY5!umwnQz)UK^;ZKFsGg?oN4?#!$Kpx<6oS}`eRUl4C8 z9okq@Cqz}dTt28nY&W)Ra&-!ihhO=|q+2FTRE7x=WN;|(3QKWq;O(dlMG8Z{kAFrj zED+OYPjdCgCz;0N2m*>@;iKj$`lF)d5<9V*%Gw>Fr7?qnq!CHGvPuG|L$pKCw0t>t zuK_Z*+--u&I}Av{Tffq)=gNlN=#5i<602n+)*!i$3G$q{J=OR7Vas0@jge;jet&Mn z#6ltLT&teJ3z_-ZtT2rHA|L^M0uvub-P99H;G~EwwU|7^H&KCc@*(f5rgK?!(}hH^ zLfuEdo?f7b%skVR%a}mXa_FLV>N{xQ_c@XdLl+sgTSh|CUX)?eQN3t%t=ccx5S1Q) zwr^I%vXiN%IBKV?VShMqunu6&a%v6=ofBFRc0?NdG0tL#A@GTl^cv`bU^pRC6>=4o zBoUPBr_h}Qx3{n%@B*N;btdYD@ zUu0eFN3;Mi;BSzmSid9CaA#r9Pn%jciOF)txCXyhGt;=+k!Jv_kW|(<`P4xIV?!I) zF{ZxRrP|8;&*p%rbF{!4nq6)g+^FRxrZ&00)-^kc?9ZXM5W$_Gmx59-rP(Y!V$FD*y$!4*W9;5&Uoj+d4azz*ed{s-RA5dL0eTrCHc zvAXIv7X~-l5ASkfdLYIZf$W#@>;zM(wIwpEk%!rB|2l-M@&UFJR?q`-FT?n_*KXX* zkd$oju6yc-K0A4~icmKJhVd?@V2D&jqmFiuGzdA$XENo&upYeT5zfLP zc!L}U^L?0dvMkY>Lqu_k9MIGJd-<-zyWq!t-@{f5Bd#$#IF&(K8t}V(6B`OJztr+1_~; zEf{yQrUMYsU7T?yx4&e7L-;3}LODXEhoCx<5kzfvcBIdD7*R-^N2oU?G%R6loroNI zPs-b3?9``aScb?K{Ky8WT)%uf!*@y7?ew#8kf5Sb26jJ61aX9f6W9If^T4BgSqc2s z=F`3ClC=CmF0L=*u^)}!UnWz=2=2oa_A1v7J7GnIHEUF1i;S)OnbglVh@WJ_P%JzX zHv|d6icf{#EUyj&-v{D-7=+KaKGDk45(>(9@T%Ckhzy{UgdIKKlqh2T#v76WRnte% z#ANOE-h?#o2y-AwY}7@53dcbLZ998QqRwV_P<>MOBq2j!4f$X&CH`xUVg^|&cC=DV zdaXtuKl1M|dlMk)F-}lkJRAh4@ql%XZL+Tqs0~KLxj7phkFVLP+6W)G zdl5C$TtEGzB$(GDHDkB3IG98XEIm4F4K;#|XY77W^+;}0j&ognf!ac+U zN20F*HX>}|0nrjL0}_f5dHmllRaO~tY-AK);c!`mqI_QDK}%6MoKfJw<5G?^KMh#u z*)5DGljNnhU<&_C_*M(Hkga`76z~>!12n&tsyX#%kcI;B{5xWqGs6x3cUFQmp_BFK zIpo2_uOb=NYu^L(nR~eg@7PYLisIUS{)|di77yQ7T!Lp-fMD#SC(?{_tr78iI8o%3 z^zbU&ebomF49=GZQ-?2%ySG2_Wwd)M8@^i!FKD!1P>}|xY#V!oXb>je1il8Vu=gG1 zOG@ahoWh4lqV~y;S%g8mMD1b$v;+qMnkZ=*$@p$-*lUS1=O1TjLC>h8@}1+W>I(%^ zm}fLH!B>A=#2f3m?cb$Z~?SMlf75uu3;o{}03 z_4z0m?um*aMY2f@IIiOPoD|Ft@0Y%eE!=(+tt4w?TI>M)bab^SOmgjY)F)2F7`H97 zSWoX_GdIQs+j(WWjSH^YEwn);S@-z}D>LHv{i~SH{vNzy&k0lev!Sfv(gUHcqR5_1 z#MvR_`C4BH98X|2Hbd@f2h!29iMR<_OLx^V7CNOK{zlwCAx3`7&7?m%i?F#$)ByQd zz=}6cvo}~-QhTe`bhsOG{ZznF(H>SgrMhDhpyMJLS_Mhay443MB(>BS1~up?wU!LN z@da!FGY|Bm?vF8RtXK4T60)O9HbzW@cK$d;e}Zv8KWwJK52C)RgwU{QMc=Dj#(FbL z!zc}|ugq*VI@M!Af;5D8gv% zR(J&A{c_L6#DTm&$&d5q2kykttGz3eWkS&wx7&FOrL50n7?VwM4Kpc8Iv1?3;_b!xzRy zDPs%gRMv>%JA>4$=EQ}%vt%U~YDPa!`2<~uL!c#0 zowct*k;B&<$CWx88Qrajlp6jF=QqM+O5v@Ikw5$#=5STaA0+x+Lfr;dyKkE`3-pFD zn`z|Ayu&+bzqjtzQElr{s*ZHHBvEY`kjPeJ(^sU@aat++mU;z+7_98&I_)(s3=@o00W59+uwcNW=5b<1iRsH+0HlV9CN%D` z6e^Q54j%31ESB<*=$qw95Es4Q3p;@x z#LDzau~xW{k8B1XT7bnozjT(!!H!-|T`9%a7s0Q zx5^a`qw5Y-CAi0z=R3{*^>Sh?0R6R}!4CFw-EMW~|n zn$r#AL;uGU_5@T@7phrQD3;`VX7C7QvHUFh3P#$Eq4$McY`rGDg7_};= z;sN#j(p~JRug!)u9{IHM`da>=W+^{n|9i~MXK&2%gHS=*dA{MqP}x9;r{oBy7@nON zGAI4+<@bJK8xszY`2|YB6^vPNk4ee5K^qHS0(pW_GwM}Y>Z|Hg&g$mn>vBS7 zDztRZE@n5N%~AKM59#5XqIXkbL`t;8i)#&Ue+MIeV}P>!U3<`2acmXGUHizsRF5_ zKW{saD+G*5cGDh_d>o)|qKIb*`sr25iAaHq(f`#!37#z?%mn_!S^y(Rl7F!JbJ-G! z@fw1j0WVNlKTm;6w%5F8M!MX04Du^(wJkL{w7&*Ctskpz;tRSkH(NepTlYLIjWebf`4Xc88IR(9 z0d$<`=zzlx=3x-?0D5acZfd575QmX^p|!&Md{>Kl7Iu;M^OAb*ON@{k4$6vHU0;{k zOW@X4SJ&_ofy!WkpbsBu9cJ)y^($Z(1N&mTLl3*#M`1ieSw3AaT3{&|V? z-Hr}`EknoMTrJ25JYJj3k4Ap*#vJ}@@zyxYy241~HZ z?wC=9lAtSfG<7YIEA;c<;XC(aKe$^^Qqrc$Arm=ostA|6RjLwmDO>#1|V$TeHJ`^6qdF0-Rv5BQT%zI z&+QJ&3qW&6T`0SSm&+PL1208G3G5(m-xb=Kz~`(C0HMu~TW= zwoH-rT%cT9lU5DH8a7crI`mpj{{GIeIkxyc?tvB81hwzoAUgT$h~d!5RSve^$>Avb ztqL8=g1rR8Uup%BrE%k|fIhEO5X&yd?&QICu9(%hZOwn{brP2i$Pe{P7M`6~>PJWUM+7~cEQe3eT@okdDL_{FnF-LG~DeS?^Td1+!RwrhQ?Kl|*5%&n|d4jBz zZ)>fW0Tl%6w8jJKg$hvNdjutuE?tf}=h{g4l9cV){-xnuT3FX!pH5VyBns#vOF$jC z3D0IEuQlhDqSGOh-1A!Ycw~&>ADjfG&BwU^8l@2zXdcc0C$e4P$$z@IP(41Bf`_yW z6Iq4*AU1&^{*0vF-$o1EbKS{!gV4$G1GMYQRX*_|r(V1Ae5n(eowF!iE^4TQp;@k< zk#p9JdZTyW=|1MXZsf}Cci2Bw4*tI=1JENQ;L8Z#U5t!GE=~bj@RcDvNMFL@s;UM1 zmeDdEA3Pl=`$*+X0>LnND6-Jvf{so5D$%Z^K5jG!FE&f-UM)xR2@$S^#@4x?V>S{m zUn{z6j%W&ppeH5zpWlb`)B~PHX@#@J%4oxziD2>uBnClgqB4_aJJMHDebL5n$Gi)n z;U~c{g>U!?bl`KBjWAkG3u3t%m`?OcAEh81KcY$~V1`RjLz2+L`S~l8$0_|v9q&6J zLN$%d2rjiC>(JJUy$ZSk9o8w{g|?GdB)3bki# zDptjch`nl6ZAuZdsI9gjQKSS_wRh}&8`apQ+|(YmH?@kY=XrBJ!FhLn=lTHG>+ApO zPim-qvrG^6t1h6ZznD+G z9FSp7GF>+NInNWuf`qtv;NxHxlnTzRlWUslfsA{?oOM5_V2`+pCCeLL)kI$4EhE*( zii8FOu&}QgK7=cTC8pUWxfB6|!>{S2if2}=>@N}e#P^A-7MCuC&k!XUXjC4S zU!FWE4&#!zvveM+B)gWOHxn)MxIZKuh(VwVaBZcJpsf zzXkJD>`@+}D+r{f71GOKWBD3(B}(a>$*4!U%%vi5&0N+6uboQOTXOnP`Zj2ZyVS@> z>QW8cO^{Qn>+3tgx`f@*43&68V?j(MaP9bt}_ z^T2AI%iLTTk7U6)Lys43BYX)zSGZ`=jMtD8#E> zlnws;0Kc)d0D&cgbDx1 zQ2OUHBer={%1wgB6CJh(opc_)Xk;+pSA?a44uzK(VtoUu2&_%{iK?=Gc63EbRh&IV z6xHEMz?vYrZ41k?mMUyxR11+=Kxx&fNQvi83UynZ@q~DiD6(sNLTDsZT%;#!q{*el z%@mP45a9W*BBi*@Dtl!m^Y5dGgu3tcPP+TyfO(JhtwcApm@3@z7tz0Nq>AfMUgoA1`Y z?kf{51pH~MovMRR6cx<=R3_HkPDx=fec(1BPW+;MwVAAPCA+oEahWwp7Zk>I0zH3{ zfSu2OsI=ip!7Rg;LLNT0mmo!c?}WUX_Xh=K!Ly-HFKaa8Fh^>?-v3wx%=q>tVTGM# zC%s-EYKm9AD+UsI&cbL?4-EdBV3}SWmpI6A=ki3>PAh3c_t=pQujCk_iU$Pa%F*G;hBbquC9A}yRedtAm$05$pPk-s}w|yV7d6N@j?M`v>R=E-9X8_l%+{7m%zwaEZh!aME}45oe`6f;;uxTK z8}7|AD>0*EoKB<=K^riWe}?ww)8v!D&+O4#t|Z>!@ag_>ZJesvP}Irrf3sfTB?5Edo;@rIW#+d0Uft06b*Z|K;5%0cid zEpe}xepYk4RSrC8FUpr;;~vWV;B4+}{)aeE+wvyt?IcLJ)YInNa(&8EUs5v>c)6)I z5W4nig^IEFalwbK?8eq;EKqDqO1(z}CX8sjTZkWvrKy8+eq<76BE`P8`@BAcMpJjb z&NuD)oYtSY3n%apqlg!N7_E%J?}f~WE}*g2prl55$gGkz!$*J`q?lKkS63+zFgegB{5QTzHGOs+_w zOQj=;U+UR)q?IrFGyQm@6sywHC~!(Y*)7s3cfNVD;cdaza?Th}^N*(8y~6P;6IZ=I z69oez@;fbCBE2T%49Wu69A(X{_@>3&_54|4$7tq8p`D+M)3!BVyrmXP>cgf{3V9`Q zL;g9_JIF1*MbOXMe&dEii3`?1>IR~?fSl%k zTpjPHJVuZsG?fl%f3x%9QTN+7)J@%`wS8EL1iQ)B2_+4at`JK0uEie$i7WHhJ|``M zGCEF)&1>5F>=K7ntjdsUo7il{nGZ(VW|QZaWUq=ivY-wVrsK|Tls2?)&RY(2GD{HF z8lz&6O2C-puz#>(`ZNEpFDAKGJW)xp4{&o%0p4`>^1-RKAffEGAFNq`J9;jw*_WQ9 zfR=g{_e3MFO3vq#(LTv3LcF2=JToWq(y_p^HPQ4w*nyMJfVVgslW6H7$rEO%Ve~ux zKW{@+zU4OUbX)m^9O&%d(1)-9q`*W0^FUI`LZNmJquy=Gs;1!ShRxuW_k#VBGK1%H z`}&EUJJt?(Slzk^Ln`XHVbn?pLSrz9AC~0$X<>iSFme7}p6#ewRjswFT<>8;%v}X1 zDvsk2wHn4`?3bLGWGrInnJF z>bS%Hl0VJ89wc!|85KWhu_04;k1(O$40EKYlqBY0RLCx@kR;=osfCYTapY~9KRl^xzS~z z%dInz;umGjpEjrpsAC=7+`zFYCwyG00}g8%HlsNck{nTw~BL85$$ZbSZUeF-J`KWLSBo} zU;g(GCM)_dnv)ilCSSAl(q!kEkexP500Vs!z8On z?Y&83@kn+$4VC$CfXmu}i6B!jPtk4EWpG=B?w$xANvt&my9>^ld7huX!~5at`82fH z_X6gvA7%N8S`5O~9uOvMxPiQ13x_7x)rQb8yB~X?K!t!G!KfZZpBB*C1pmHR6%{6) zA;tZ&u1-9s(8$2PuiiF|F`<%n2CNBD8u)A(*C~d}xX?T>^21=bg_Dx=15OG$?yT=D zDQ2xSjWhfNRw;n(GfJbQOQgt*$*W!Wg~aInmcl*8zlmAH(@%i}|4dQ4E^QV!-?Z8s zgFU=uNzG@iZ(gS6;qQVZf(JXl7mVh_8FARO8@4=%CF8!X!03p>gERKEJ9edd*jy&U{J08xbh0b)fY-~a#s literal 0 Hc-jL100001 diff --git a/fonts/Helvetica-Narrow-Oblique b/fonts/Helvetica-Narrow-Oblique new file mode 100644 index 0000000000000000000000000000000000000000..4ff13e5f64d9d13c631ff312f371f0b503e4927a GIT binary patch literal 37247 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%0DyAU8qn2cq%xKALkFr@e_d2ekWxXvRrArw& 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 literal 0 Hc-jL100001 diff --git a/fonts/Helvetica-Oblique b/fonts/Helvetica-Oblique new file mode 100644 index 0000000000000000000000000000000000000000..876cda876dea9c970f07f9be9041d581e0d13568 GIT binary patch literal 38314 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

#) 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

M~|z*qvw+ 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 literal 0 Hc-jL100001 diff --git a/fonts/NewCenturySchlbk-BoldItalic b/fonts/NewCenturySchlbk-BoldItalic new file mode 100644 index 0000000000000000000000000000000000000000..31e589003a492aac542c201f83d51bac4c7fcde1 GIT binary patch literal 47083 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�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 S+n5?Ux!BtpI$1*pfc^&`R7%(Y literal 0 Hc-jL100001 diff --git a/fonts/Palatino-Bold b/fonts/Palatino-Bold new file mode 100644 index 0000000000000000000000000000000000000000..7f5df43f3df8aab2e8bc09e03f7add8740fd5937 GIT binary patch literal 52406 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

hIvnv4(lkKAY{G!A+ff&Oz0J@M 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 literal 0 Hc-jL100001 diff --git a/fonts/Symbol b/fonts/Symbol new file mode 100644 index 0000000000000000000000000000000000000000..d0505e46cd55172d6307cb0dcdcd2e9030280e16 GIT binary patch literal 33709 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 L|JyhS69oES=1X#> literal 0 Hc-jL100001 diff --git a/fonts/Times-Bold b/fonts/Times-Bold new file mode 100644 index 0000000000000000000000000000000000000000..47f8fd57da463f4a8b03da9fdfdbbdc6dbec0566 GIT binary patch literal 44729 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 F{~z~bSDF9- literal 0 Hc-jL100001 diff --git a/fonts/Times-BoldItalic b/fonts/Times-BoldItalic new file mode 100644 index 0000000000000000000000000000000000000000..2d19d942eae6feb71fd75ae412ec9f2b7f73071a GIT binary patch literal 44656 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 literal 0 Hc-jL100001 diff --git a/fonts/Times-Italic b/fonts/Times-Italic new file mode 100644 index 0000000000000000000000000000000000000000..aa9ff5f8ac9238dbeabc25462d610ad0baad72dd GIT binary patch literal 45458 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 literal 0 Hc-jL100001 diff --git a/fonts/Times-Roman b/fonts/Times-Roman new file mode 100644 index 0000000000000000000000000000000000000000..cbae7ed157e14e2d693385b5d23411107f1b7534 GIT binary patch literal 46026 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⪻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%0DA~N3EAosCiT7zKl&}@z{%%VZeQTkI) z7I&K+eUYcTJK(wG%1)GJ6vm1@w3-MIi ziaS%|l$KX`f0zv&YxA(0>xa{8_)!Lz;Z0r#a^L>oj>c6q zJrQd4L{(*I^u(f=$+uM5`P8d9X~E&CWM9h6jubry@Y!sNar+O~R996fY;|a8<7S6w z*W;LQnnaV9WO_S%S<^KW)0&q#P(F%*<$IU#DZ90aPWG@}MA?ZCeW~FP!UISX>6gE? zyy*B5awf4qo;-7_gm|v)fKrLqWKpkmdsD+STS2OlI+#!&=1M$BkszpaW4b#8T9P+6w#H-gvi#y%mo1WA19S$2U~iM12LJ#7 literal 0 Hc-jL100001 diff --git a/fonts/Utopia-Bold b/fonts/Utopia-Bold new file mode 100644 index 0000000000000000000000000000000000000000..06b91085a442ec590833e3a4f65d40311b8be842 GIT binary patch literal 36580 zc-o}4QuzCN8dj5!K~fosG=@;jpkUa&Qr` zaB*?`3;wULM3&A(Mnp~kb4zCzfYU!wT%3$d0k%d?)JAi=_#Gh*HGf!PCjo+`@&3(uC?C{hVC1|E}WyO9v5=kc|zI z^1r;CiIf4(04KM9(Ep#s{ZE17t~NIEMz;S*{I9_OYR3PAWMpe;Si|LOe?C2Dq- zj;;VHQ6d(0HddDZ9YR>x-ou-YiH(hjj`^Q5n3!3)h`5;8egALXCaz9S06Uj|58XdS z{`c9;@}HXo06YLDFaaQDkw8FiGhttn#E!~}Ju00zbWy6Z`OzC^TvFxV-Y(l6@pEO^gUe#Qy- zU$#d%_}nMU<6-e(A3imR;K>IxkKxX;eEGs%DpOCELd8m7~h!9^%2 z->?A;C1w;yxLli31a#2X<-st4VvkoWp~yP8JLt!{Z=W_XlND5Au#eo)ho?+>NOhKi z&dbfX-Ym$WzcOUsx9A&*+T;z(z-3NE=+F>OjzWQ&po;2nb)MZbhJyVA0Q^KBXCxmw z@v4>OVuu#}NSlM}1&Y?&s?L|;N#pYbP*CbF+SE?X;et!phSDsNEGsyopc6>4j&s!H zUv&^apv~l2md?WQ)o_H>OGI~KbU7mWlAwO=bGDD9yc_-MiH1Vr(}4nhg-rJZ876H# zxKLi2+;`%x9X(86>~eZNTN5oTWxqLxdoC#pYx!t6gwU1nF8*hP9nNZawt>bTMMvoI^<3GiQf31nY!N`*n{0tTECqKv`>^7^q| zcN8c>lIJWT=>I`AL(pg$hICf+EJ`XLFy29)FJ2Nhr$WR_ zGJ4lL?Vv3@+r0GYa2PXd+UK(CpH<82L87nihtKZ0LkvVP$qTjm-NW{-szQZ;VmYvodaS}Z08@t8 zUY)0{T?aKz@9Ymn(@JdXGqAEA2{B%;E6O}CX2jvbDeBkqz6+p!mBqWtR6_;K<=JO~ zE@<)XA1eY0)UUK?1~aZI`|rR7CV#>$QZb@1!3gUk6ufo-cO;s|b&aRYwQcB?Eg7^; zNSufF@BlJTojZsp?5RQd8JmO(1v|n-5-)$Bn$P6unaPbRds+jH$xR>@po7y zE31S%$zc>i3l@6jpqh3WUR#B5_8!Hhsi?5IciA2f4I$>X#gdW~yWDPo97NW*)-p=c z1=tXk-!T$|Sprq^xMhbm4H2&r-{UY^YGEcF;rp0kF^)Dc3W5rfTk_d{k_sEyR*VV4 zt0hp8CdmuD@@AH%wzIcgA%0NX!y4^2ZDpsGi&3<=5h=w=ieYYo5}{AqtUr4g7!J)h zIIN~2!X_H_xXC_+Hcq%;5`N_j+9=Y?%xTh3DynW++jY_W^{gdD(UGM_t#oxj=Lz1M zmdpK{j%l9N8N<;}p1%I*WZALP5!@r!Pn8x6k4e?t@g^IY2~j5q|CsQn2KDz!MY5T| z1WYJ63pwvIz>WF*c#rAy)C556u{jp}-C<M)ti%L|;{h`>k8nkB67hVoT-dB#WwdH2Ukq3p=HP+^+_Lvd(Fx z4!^&a$$hBRV;g-gcMb`DV>i2vP(93uiVYozgvbIH<}2M*T;}lE_BKY>mn*f@|BL!Q zQ(bPw4ef}6FI4RXe3qKFK6S>7dMeOlTUXOv;?TdZ+RS%ZiX_gPL2$M-WFmdBBhI71 zrCuk+ekpzhTnnnE^=17c7 z6Xg+{C1%+)`+h=nfu|A=y19C>F}#{!M6o zMF|Ffe|r#1!3b9k&6pYvwgL31k1d0iE?6HKD2JqYfRh`c)3DA~J`GL1nGY2jhcnU; z()#uFM`*d>7tX0d@vuLNf#fv!$W9z>q;-2VOo)l6s5==0yjKs?a*qaR$9+J3mR4VF zzZu^Y?et*~0RksOu)nmz9)iXS6DO0}3gK5`h$l zEjqE0TN(yT(WdKLvWmXV$1F(>z}3ST-Y52a&IyrtdXRpB=468A<0@dfhTk5sZi z+LYk|d#1#oBSN-nN}cYGT`Nh*Fr;J|zA_jKP){P>Qv&kHCLa-W5rjVE%ilD-_|{32 ze3t;ESJ>48QM!~z{i_##Tk)VV!;9=|Zv_{}TO(>1f_PrL3tPuoMO41_W+rQRBo37DI(;mKNvwhMy z!neLK#JI9}o%jKpbR@XT8Q&@MR;hiM#chk#7-8kVJ-&sjoc4@vtvOB$cTDJn78HP}{ z$Pf8_V_ZibLKCWEx!6IL77lH&cL@)Ic4eFDkyRQ!l2$R4I@ zz*+wOoNwpuk62bIf@9h;)en^)HFyTYAyD+V$567xz|rRR2%tXiCD__nDY4PbR<=N` zL8$$?`j+PW%lp7;AC>EZc~FydKXnsKNUpeAmxHZWGEYxzzjK`@xN;K$FRf_`3c0Iy z)yvJK$7`tbJI*+iwlip;#{Lp^8t3*>EE~$Axow~(1rR3wc;Ni$ z9S>y2pa;PedVL^-*a~XQ#r!tA2D=ypQWji|t{`

d(A>0GW|SZx_`nCI2yl7&7Q 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 literal 0 Hc-jL100001 diff --git a/fonts/Utopia-BoldItalic b/fonts/Utopia-BoldItalic new file mode 100644 index 0000000000000000000000000000000000000000..c36689694d2810d66dce3b4c5d2b64b6ac816a16 GIT binary patch literal 37836 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 literal 0 Hc-jL100001 diff --git a/fonts/Utopia-Regular b/fonts/Utopia-Regular new file mode 100644 index 0000000000000000000000000000000000000000..1772a3a0b7d0ea0bc4546cba06f453f8c230f246 GIT binary patch literal 36350 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 literal 0 Hc-jL100001 diff --git a/fonts/ZapfDingbats b/fonts/ZapfDingbats new file mode 100644 index 0000000000000000000000000000000000000000..4a3c386d292d5609de78d1bb0c44b9c40c688f88 GIT binary patch literal 45955 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 X|A7Arz}Uvr(8. +The HTTP status messages use the status codes defined in . + +If you would like to contribute a new message file for your locale, or +have corrections to the current ones, please send them to: + + cups-support@cups.org diff --git a/locale/translate.c b/locale/translate.c new file mode 100644 index 0000000000..e56690be62 --- /dev/null +++ b/locale/translate.c @@ -0,0 +1,259 @@ +/* + * "$Id$" + * + * HTTP-based translation program for the Common UNIX Printing System (CUPS). + * + * This program uses AltaVista's "babelfish" page to translate the POSIX + * message file (C/cups_C) to several different languages. The translation + * isn't perfect, but it's a good start (better than working from scratch.) + * + * Copyright 1997-1999 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44145 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * Contents: + * + * main() - Main entry. + */ + +/* + * Include necessary headers... + */ + +#include +#include +#include +#include + +#include + + +/* + * 'main()' - Main entry. + */ + +int /* O - Exit status */ +main(int argc, /* I - Number of command-line arguments */ + char *argv[]) /* I - Command-line arguments */ +{ + http_t *http; /* HTTP connection */ + http_status_t status; /* Status of GET command */ + char line[1024], /* Line from file */ + *lineptr, /* Pointer into line */ + buffer[2048], /* Input/output buffer */ + *bufptr, /* Pointer into buffer */ + length[16]; /* Content length */ + int bytes; /* Number of bytes read */ + FILE *in, /* Input file */ + *out; /* Output file */ + + + if (argc != 3) + { + fputs("Usage: translate outfile language\n", stderr); + return (1); + } + + if ((in = fopen("C/cups_C", "r")) == NULL) + { + perror("translate: Unable to open input file"); + return (1); + } + + if ((out = fopen(argv[1], "w")) == NULL) + { + perror("translate: Unable to create output file"); + fclose(in); + return (1); + } + + /* + * Do character set... + */ + + fgets(line, sizeof(line), in); + fputs("iso-8859-1\n", out); /* Right now that's all that Babelfish does */ + + /* + * Then strings... + */ + + while (fgets(line, sizeof(line), in) != NULL) + { + /* + * Strip trailing newline if necessary... + */ + + lineptr = line + strlen(line) - 1; + if (*lineptr == '\n') + *lineptr = '\0'; + + /* + * Skip leading numbers and whitespace... + */ + + lineptr = line; + while (isdigit(*lineptr)) + putc(*lineptr++, out); + + while (isspace(*lineptr)) + putc(*lineptr++, out); + + if (*lineptr == '\0') + { + putc('\n', out); + continue; + } + + /* + * Encode the line into the buffer... + */ + + sprintf(buffer, "doit=done&lp=en_%s&urltext=[", argv[2]); + bufptr = buffer + strlen(buffer); + + while (*lineptr) + { + if (*lineptr == ' ') + *bufptr++ = '+'; + else if (*lineptr < ' ' || *lineptr == '%') + { + sprintf(bufptr, "%%%02X", *lineptr & 255); + bufptr += 3; + } + else + *bufptr++ = *lineptr; + + lineptr ++; + } + + *bufptr++ = '&'; + *bufptr = '\0'; + + sprintf(length, "%d", bufptr - buffer); + + /* + * Send the request... + */ + + if ((http = httpConnect("dns.easysw.com", 80)) == NULL) + { + perror("translate: Unable to contact proxy server"); + fclose(in); + fclose(out); + return (1); + } + + lineptr = line; + while (isdigit(*lineptr)) + lineptr ++; + while (isspace(*lineptr)) + lineptr ++; + + printf("%s = ", lineptr); + fflush(stdout); + + http->version = HTTP_1_0; + httpClearFields(http); + httpSetField(http, HTTP_FIELD_CONTENT_TYPE, + "application/x-www-form-urlencoded"); + httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length); + if (httpPost(http, "http://babelfish.altavista.digital.com/cgi-bin/translate?")) + httpPost(http, "http://babelfish.altavista.digital.com/cgi-bin/translate?"); + + httpWrite(http, buffer, bufptr - buffer); + + while ((status = httpUpdate(http)) == HTTP_CONTINUE); + + if (status == HTTP_OK) + { + int sawparen = 0; + int skipws = 1; + int sawbracket = 0; + + while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0) + { + buffer[bytes] = '\0'; + + for (bufptr = buffer; *bufptr; bufptr ++) + { + if (*bufptr == '>') + sawbracket = 0; + else if (*bufptr == '<') + { + sawbracket = 1; + if (sawparen) + break; + } + else if (*bufptr == '[' && !sawbracket) + sawparen = 1; + else if (sawparen) + { + if (skipws) + { + if (!isspace(*bufptr)) + { + skipws = 0; + *bufptr = toupper(*bufptr); + } + } + + if (!skipws) + { + if (*bufptr == '\n') + { + putc(' ', out); + putchar(' '); + } + else + { + putc(*bufptr, out); + putchar(*bufptr); + } + } + } + } + + if (sawparen && sawbracket) + break; + } + + httpFlush(http); + putc('\n', out); + putchar('\n'); + } + else + { + printf("HTTP error %d\n", status); + + fprintf(out, "%s\n", lineptr); + httpFlush(http); + } + + httpClose(http); + } + + fclose(in); + fclose(out); + + return (0); +} + + +/* + * End of "$Id$". + */ diff --git a/man/Makefile b/man/Makefile new file mode 100644 index 0000000000..8424c53223 --- /dev/null +++ b/man/Makefile @@ -0,0 +1,103 @@ +# +# "$Id$" +# +# Man page makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1993-1999 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +# +# Man pages... +# + +MAN1 = backend.man filter.man lp.man lpoptions.man lpq.man lprm.man \ + lpr.man lpstat.man +MAN5 = classes.conf.man cupsd.conf.man mime.convs.man mime.types.man \ + printers.conf.man +MAN8 = accept.man cups-lpd.man cups-polld.man cupsd.man enable.man \ + lpadmin.man lpinfo.man lpmove.man lpc.man + +CAT1 = $(MAN1:.man=.$(CAT1EXT)) +CAT5 = $(MAN5:.man=.$(CAT1EXT)) +CAT8 = $(MAN8:.man=.$(CAT1EXT)) + + +# +# Make everything... +# + +all: $(CAT1) $(CAT5) $(CAT8) + + +# +# Clean all config and object files... +# + +clean: + + +# +# Install files... +# + +install: + -$(MKDIR) $(MANDIR)/man1 + -$(CHMOD) ugo+rx $(MANDIR) + -$(CHMOD) ugo+rx $(MANDIR)/man1 + for file in $(MAN1); do \ + $(INSTALL_MAN) $$file $(MANDIR)/man1/`basename $$file man`1; \ + done + $(RM) $(MANDIR)/man1/cancel.1 + $(LN) lp.1 $(MANDIR)/man1/cancel.1 + -$(MKDIR) $(MANDIR)/man5 + -$(CHMOD) ugo+rx $(MANDIR)/man5 + for file in $(MAN5); do \ + $(INSTALL_MAN) $$file $(MANDIR)/man5/`basename $$file man`5; \ + done + -$(MKDIR) $(MANDIR)/man8 + -$(CHMOD) ugo+rx $(MANDIR)/man8 + for file in $(MAN8); do \ + $(INSTALL_MAN) $$file $(MANDIR)/man8/`basename $$file man`8; \ + done + $(RM) $(MANDIR)/man8/reject.8 + $(LN) accept.8 $(MANDIR)/man8/reject.8 + $(RM) $(MANDIR)/man8/disable.8 + $(LN) enable.8 $(MANDIR)/man8/disable.8 + -$(MKDIR) $(MANDIR)/cat1 + -$(CHMOD) ugo+rx $(MANDIR)/cat1 + $(INSTALL_MAN) $(CAT1) $(MANDIR)/cat1 + $(RM) $(MANDIR)/cat1/cancel.$(CAT1EXT) + $(LN) lp.$(CAT1EXT) $(MANDIR)/cat1/cancel.$(CAT1EXT) + -$(MKDIR) $(MANDIR)/cat5 + -$(CHMOD) ugo+rx $(MANDIR)/cat5 + $(INSTALL_MAN) $(CAT5) $(MANDIR)/cat5 + -$(MKDIR) $(MANDIR)/cat8 + -$(CHMOD) ugo+rx $(MANDIR)/cat8 + $(INSTALL_MAN) $(CAT8) $(MANDIR)/cat8 + $(RM) $(MANDIR)/cat8/reject.$(CAT1EXT) + $(LN) accept.$(CAT1EXT) $(MANDIR)/cat8/reject.$(CAT1EXT) + $(RM) $(MANDIR)/cat8/disable.$(CAT1EXT) + $(LN) enable.$(CAT1EXT) $(MANDIR)/cat8/disable.$(CAT1EXT) + + +# +# End of "$Id$". +# diff --git a/man/accept.man b/man/accept.man new file mode 100644 index 0000000000..ec1ec74e89 --- /dev/null +++ b/man/accept.man @@ -0,0 +1,58 @@ +.\" +.\" "$Id: accept.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" accept/reject man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH accept 8 "Common UNIX Printing System" "22 September 1999" "Easy Software Products" +.SH NAME +accept/reject \- accept/reject jobs sent to a destination +.SH SYNOPSIS +.B accept +destination(s) +.br +.B reject +[ -h +.I server +] [ -r [ +.I reason +] ] +destination(s) +.SH DESCRIPTION +\fIaccept\fR instructs the printing system to accept print jobs to the +specified destinations. +.LP +\fIreject\fR instructs the printing system to reject print jobs to the +specified destinations. The \fI-r\fR option sets the reason for rejecting +print jobs. If not specified the reason defaults to "Reason Unknown". +.SH COMPATIBILITY +The CUPS versions of \fIaccept\fR and \fIreject\fR may ask the user for an +access password depending on the printing system configuration. This differs +from the System V versions which require the root user to execute these +commands. +.SH SEE ALSO +cancel(1), disable(8), enable(8), lp(1), lpadmin(8), lpstat(1), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: accept.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/backend.man b/man/backend.man new file mode 100644 index 0000000000..561ba11411 --- /dev/null +++ b/man/backend.man @@ -0,0 +1,109 @@ +.\" +.\" "$Id: backend.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" backend man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH backend 1 "Common UNIX Printing System" "22 June 2000" "Easy Software Products" +.SH NAME +backend \- cups backend transmission interfaces +.SH SYNOPSIS +.B backend +job user title num-copies options [ +.I filename +] +.SH DESCRIPTION +The CUPS backend interface provides a standard method for sending document +files to different physical interfaces. +.LP +Backends must be capable of reading from a filename on the command-line +or from the standard input, copying the standard input to a temporary file +if required by the physical interface. +.LP +The command name (argv[0]) is set to the device URI of the destination printer. +.SH ENVIRONMENT VARIABLES +The following environment variables are defined by the CUPS server when +executing the backend: +.TP 5 +CHARSET +.br +The default text character set (typically us-ascii or iso-8859-1). +.TP 5 +CONTENT_TYPE +.br +The MIME type associated with the file (e.g. application/postscript). +.TP 5 +CUPS_DATADIR +.br +The directory where data files can be found. +.TP 5 +CUPS_SERVERROOT +.br +The root directory of the server. +.TP 5 +DEVICE_URI +.br +The device-uri associated with the printer; this is provided for shell +scripts which may not be able to get the passed argv[0] string. +.TP 5 +LANG +.br +The default language locale (typically C or en). +.TP 5 +PATH +.br +The standard execution path for external programs that may be run by +the backend. +.TP 5 +PPD +.br +The full pathname of the PostScript Printer Description (PPD) file for +this printer. +.TP 5 +PRINTER +.br +The name of the printer. +.TP 5 +RIP_CACHE +.br +The recommended amount of memory to use for Raster Image Processors (RIPs). +.TP 5 +SOFTWARE +.br +The name and version number of the server (typically CUPS/1.1). +.TP 5 +TZ +.br +The timezone of the server. +.TP 5 +USER +.br +The user executing the backend (typically lp). +.SH SEE ALSO +cupsd(8), filter(1) +CUPS Interface Design Description, +CUPS Software Administrators Manual, +CUPS Software Programmers Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: backend.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/classes.conf.man b/man/classes.conf.man new file mode 100644 index 0000000000..85f3ea58b5 --- /dev/null +++ b/man/classes.conf.man @@ -0,0 +1,72 @@ +.\" +.\" "$Id: classes.conf.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" classes.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH classes.conf 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products" +.SH NAME +classes.conf \- class configuration file for cups +.SH DESCRIPTION +The \fIclasses.conf\fR file defines the local printer classes that are +available. It is normally located in the \fI/etc/cups\fR directory and +is generated automatically by the \fIcupsd(8)\fR program when printer +classes are added or deleted. +.LP +Each line in the file can be a configuration directive, a blank line, +or a comment. Comment lines start with the # character. +.SH DIRECTIVES +.TP 5 + ... +.br +Defines a specific printer class. +.TP 5 +Accepting +.br +Specifies whether or not the printer class is accepting new jobs. +.TP 5 +Info +.br +Specifies human-readable text describing the printer class. +.TP 5 +Location +.br +Specifies human-readable text describing the location of the printer class. +.TP 5 +Printer +.br +Specifies a printer that is a member of the printer class. +.TP 5 +State +.br +Specifies the initial state of the printer class (Idle or Stopped) +.TP 5 +StateMessage +.br +Specifies the message associated with the state. +.SH SEE ALSO +cupsd(8), cupsd.conf(5), mime.convs(5), mime.types(5), printers.conf(5), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: classes.conf.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/cups-lpd.man b/man/cups-lpd.man new file mode 100644 index 0000000000..e02fe77c05 --- /dev/null +++ b/man/cups-lpd.man @@ -0,0 +1,58 @@ +.\" +.\" "$Id: cups-lpd.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" cups-lpd man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH cups-lpd 8 "Common UNIX Printing System" "10 May 2000" "Easy Software Products" +.SH NAME +cups-lpd \- receive print jobs and report printer status to lpd clients +.SH SYNOPSIS +.B cups-lpd +.SH DESCRIPTION +\fBcups-lpd\fR is the CUPS Line Printer Daemon ("LPD") mini-server that +supports legacy client systems that use the LPD protocol. +\fBcups-lpd\fR does not act as a standalone network daemon but instead +operates using the Internet "super-server" \fBinetd(8)\fR. Add the +following line to the \fBinetd.conf\fR file to enable the +\fBcups-lpd\fR daemon: +.br +.nf + +printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd +.fi +.SH COMPATIBILITY +\fBcups-lpd\fR does not enforce the restricted source port number specified +in RFC 1179, as using restricted ports does not prevent determined users +from submitting print jobs. While this behavior is different than standard +Berkeley LPD implementations, it should not affect normal client operations. +.LP +The output of the status requests follows RFC 2569, Mapping between +LPD and IPP Protocols. Since many LPD implementations stray from this +definition, remote status reporting to LPD clients may be unreliable. +.SH SEE ALSO +inetd(8), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: cups-lpd.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/cups-polld.man b/man/cups-polld.man new file mode 100644 index 0000000000..d89f6d4806 --- /dev/null +++ b/man/cups-polld.man @@ -0,0 +1,46 @@ +.\" +.\" "$Id: cups-polld.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" cups-polld man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH cups-polld 8 "Common UNIX Printing System" "10 May 2000" "Easy Software Products" +.SH NAME +cups-polld \- cups printer polling daemon +.SH SYNOPSIS +.B cups-polld +.I address ipp-port interval browse-port +.SH DESCRIPTION +\fBcups-polld\fR polls remote servers for a list of available printers +and printer classes every \fIinterval\fR seconds. Printer and class +information is then broadcast to the localhost interface (127.0.0.1) +for reception by \fBcupsd(8)\fR. +.PP +This program is started automatically by \fBcupsd\fR for each +BrowsePoll directive found in the \fBcupsd.conf\fR file. +.SH SEE ALSO +cupsd.conf(5), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: cups-polld.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/cupsd.conf.man b/man/cupsd.conf.man new file mode 100644 index 0000000000..d10a67fca0 --- /dev/null +++ b/man/cupsd.conf.man @@ -0,0 +1,246 @@ +.\" +.\" "$Id: cupsd.conf.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" cupsd.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH cupsd.conf 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products" +.SH NAME +cupsd.conf \- server configuration file for cups +.SH DESCRIPTION +The \fIcupsd.conf\fR file configures the CUPS scheduler, \fIcupsd(8)\fR. It +is normally located in the \fI/etc/cups\fR directory. +.LP +Each line in the file can be a configuration directive, a blank line, +or a comment. Comment lines start with the # character. The +configuration directives are intentionally similar to those used by the +popular Apache web server software and are described below. +.SH DIRECTIVES +The following directives are understood by \fIcupsd\fR. Consult the CUPS +Software Administrators Manual for a detailed description: +.TP 5 +AccessLog +.br +Defines the access log filename. +.TP 5 +Allow +.br +Allows access from the named hosts or addresses. +.TP 5 +AuthClass +.br +Specifies the authentication class (User, Group, System) +.TP 5 +AuthType +.br +Specifies the authentication type (None, Basic, Digest) +.TP 5 +BrowseAddress +.br +Specifies a broadcast address for outgoing printer information packets. +.TP 5 +BrowseAllow +.br +Allows incoming printer information packets from the named host or address. +.TP 5 +BrowseDeny +.br +Denies incoming printer information packets from the named host or address. +.TP 5 +BrowseInterval +.br +Specifies the maximum interval between printer information broadcasts. +.TP 5 +BrowseOrder +.br +Specifies the order of printer information access control (allow,deny or deny,allow) +.TP 5 +BrowsePoll +.br +Specifies a server to poll for printer information. +.TP 5 +BrowsePort +.br +Specifies the port to listen to for printer information packets. +.TP 5 +BrowseRelay +.br +Specifies that printer information packets should be relayed from one host or +network to another. +.TP 5 +BrowseShortNames +.br +Specifies whether remote printers will use short names ("printer") or not +("printer@server"). This option is ignored if more than one remote printer +exists with the same name. +.TP 5 +BrowseTimeout +.br +Specifies the maximum interval between printer information updates before +remote printers will be removed from the list of available printers. +.TP 5 +Browsing +.br +Specifies whether or not remote printer browsing should be enabled. +.TP 5 +DataDir +.br +Specified the directory where data files can be found. +.TP 5 +DefaultCharset +.br +Specifies the default character set to use for text. +.TP 5 +DefaultLanguage +.br +Specifies the default language to use for text and web content. +.TP 5 +Deny +.br +Denies access to the named host or address. +.TP 5 +DocumentRoot +.br +Specifies the root directory for the internal web server documents. +.TP 5 +ErrorLog +.br +Specifies the error log filename. +.TP 5 +Group +.br +Specifies the group name or ID that will be used when executing +external programs. +.TP 5 +HostNameLookups +.br +Specifies whether or not to do reverse lookups on client addresses. +.TP 5 +ImplicitClasses +.br +Specifies whether or not to create implicit classes from identical +remote printers. +.TP 5 +KeepAlive +.br +Specifies whether or not to support HTTP Keep-Alive. +.TP 5 +KeepAliveTimeout +.br +Specifies the connection timeout for HTTP Keep-Alive. +.TP 5 + ... +.br +Specifies access control for the named location. +.TP 5 +LogLevel +.br +Specifies the logging level (none, warn, error, info, or debug) +.TP 5 +MaxClients +.br +Specifies the maximum number of simultaneous clients to support. +.TP 5 +MaxLogSize +.br +Specifies the maximum size of the log files before they are +rotated (0 to disable rotation) +.TP 5 +MaxRequestSize +.br +Specifies the maximum request/file size in bytes (0 for no limit) +.TP 5 +Order +.br +Specifies the order of HTTP access control (allow,deny or deny,allow) +.TP 5 +PageLog +.br +Specifies the page log filename. +.TP 5 +Port +.br +Specifies a port number to listen to for HTTP requests. +.TP 5 +PreserveJobFiles +.br +Specifies whether or not to preserve job files after they are printed. +.TP 5 +PreserveJobHistory +.br +Specifies whether or not to preserve the job history after they are +printed. +.TP 5 +Printcap +.br +Specifies the filename for a printcap file that is updated automatically +with a list of available printers (needed for legacy applications) +.TP 5 +RIPCache +.br +Specifies the maximum amount of memory to use when converting images +and PostScript files to bitmaps for a printer. +.TP 5 +RequestRoot +.br +Specifies the directory to store print jobs and other HTTP request +data. +.TP 5 +ServerAdmin +.br +Specifies the email address of the server administrator. +.TP 5 +ServerBin +.br +Specifies the directory where backends, CGIs, daemons, and filters may +be found. +.TP 5 +ServerName +.br +Specifies the fully-qualified hostname of the server. +.TP 5 +ServerRoot +.br +Specifies the directory where the server configuration files can be found. +.TP 5 +SystemGroup +.br +Specifies the group to use for System class authentication. +.TP 5 +TempDir +.br +Specifies the directory where temporary files are stored. +.TP 5 +Timeout +.br +Specifies the HTTP request timeout in seconds. +.TP 5 +User +.br +Specifies the user name or ID that is used when running external programs. +.SH SEE ALSO +classes.conf(5), cupsd(8), mime.convs(5), mime.types(5), printers.conf(5), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: cupsd.conf.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/cupsd.man b/man/cupsd.man new file mode 100644 index 0000000000..51ed3009a7 --- /dev/null +++ b/man/cupsd.man @@ -0,0 +1,51 @@ +.\" +.\" "$Id: cupsd.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" cupsd man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH cupsd 8 "Common UNIX Printing System" "22 June 2000" "Easy Software Products" +.SH NAME +cupsd \- common unix printing system daemon +.SH SYNOPSIS +.B cupsd +.I [ \-c config-file ] +.SH DESCRIPTION +\fIcupsd\fR is the scheduler for the Common UNIX Printing System. It +implements a printing system based upon the Internet Printing Protocol, +version 1.1. If no options are specified on the command-line then the +default configuration file (usually \fI/etc/cups/cupsd.conf\fR) will be +used. +.SH COMPATIBILITY +\fIcupsd\fR implements all of the required IPP/1.1 attributes and +operations. It also implements several CUPS-specific administation +operations. +.SH SEE ALSO +backend(1), classes.conf(5), cupsd.conf(5), filter(1), mime.convs(5), +mime.types(5), printers.conf(5), +CUPS Implementation of IPP, +CUPS Interface Design Description, +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: cupsd.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/enable.man b/man/enable.man new file mode 100644 index 0000000000..86ac155095 --- /dev/null +++ b/man/enable.man @@ -0,0 +1,65 @@ +.\" +.\" "$Id: enable.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" enable/disable man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH enable 8 "Common UNIX Printing System" "22 September 1999" "Easy Software Products" +.SH NAME +disable, enable \- stop/start printers and classes +.SH SYNOPSIS +.B disable +[ \-c ] [ -h +.I server +] [ \-r [ +.I reason +] ] destination(s) +.br +.B enable +destination(s) +.SH DESCRIPTION +\fIenable\fR starts the named printers or classes. +.LP +\fIdisable\fR stops the named printers or classes. The following options may +be used: +.TP 5 +\-c +.br +Cancels all jobs on the named destination. +.TP 5 +\-r [ \fIreason\fR ] +.br +Sets the message associated with the stopped state. If no reason is specified +then the message is set to "Reason Unknown". +.SH COMPATIBILITY +The CUPS versions of \fIdisable\fR and \fIenable\fR may ask the user for an +access password depending on the printing system configuration. This differs +from the System V versions which require the root user to execute these +commands. +.SH SEE ALSO +accept(8), cancel(1), lp(1), lpadmin(8), lpstat(1), reject(8), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. + +.\" +.\" End of "$Id: enable.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/filter.man b/man/filter.man new file mode 100644 index 0000000000..9942e1dc17 --- /dev/null +++ b/man/filter.man @@ -0,0 +1,116 @@ +.\" +.\" "$Id: filter.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" filter man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH filter 1 "Common UNIX Printing System" "22 June 2000" "Easy Software Products" +.SH NAME +filter \- cups file conversion filter interfaces +.SH SYNOPSIS +.B filter +job user title num-copies options [ +.I filename +] +.SH DESCRIPTION +The CUPS filter interface provides a standard method for adding support for +new document types to CUPS. Each filter is capable of converting from one +or more input formats to another format that can either be printed directly +or piped into another filter to get it to a printable format. +.LP +Filters must be capable of reading from a filename on the command-line +or from the standard input, copying the standard input to a temporary +file as required by the file format. All output must be sent to the +standard output. +.LP +The command name (argv[0]) is set to the name of the destination printer. +.SH ENVIRONMENT VARIABLES +The following environment variables are defined by the CUPS server when +executing each filter: +.TP 5 +CHARSET +.br +The default text character set (typically us-ascii or iso-8859-1). +.TP 5 +CONTENT_TYPE +.br +The MIME type associated with the file (e.g. application/postscript). +.TP 5 +CUPS_DATADIR +.br +The directory where data files can be found. +.TP 5 +CUPS_SERVERROOT +.br +The root directory of the server. +.TP 5 +DEVICE_URI +.br +The device-uri associated with the printer. +.TP 5 +LANG +.br +The default language locale (typically C or en). +.TP 5 +PATH +.br +The standard execution path for external programs that may be run by the filter. +.TP 5 +PPD +.br +The full pathname of the PostScript Printer Description (PPD) file for +this printer. +.TP 5 +PRINTER +.br +The name of the printer; this is provided for shell scripts which may not be +able to get the passed argv[0] string. +.TP 5 +RIP_CACHE +.br +The recommended amount of memory to use for Raster Image Processors (RIPs). +.TP 5 +SOFTWARE +.br +The name and version number of the server (typically CUPS/1.1). +.TP 5 +TZ +.br +The timezone of the server. +.TP 5 +USER +.br +The user executing the filter (typically lp). +.SH COMPATIBILITY +While the filter interface is compatible with System V interface +scripts, it will only work with the System V interface script as the +only filter. Typically the interface script will be provided via the +\fBlpadmin(8)\fR command using the \fI-i\fR option. +.SH SEE ALSO +backend(1), cupsd(8), +CUPS Interface Design Description, +CUPS Software Administrators Manual, +CUPS Software Programmers Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: filter.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lp.man b/man/lp.man new file mode 100644 index 0000000000..ec1e0eda15 --- /dev/null +++ b/man/lp.man @@ -0,0 +1,112 @@ +.\" +.\" "$Id: lp.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lp/cancel man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lp 1 "Common UNIX Printing System" "9 September 1999" "Easy Software Products" +.SH NAME +lp \- print files +.br +cancel \- cancel jobs +.SH SYNOPSIS +.B lp +[ \-c ] [ \-d +.I destination +] [ -h +.I server +] [ \-m ] [ \-n +.I num-copies +[ \-o +.I option +] [ \-p/q +.I priority +] [ \-s ] [ \-t +.I title +] [ +.I file(s) +] +.br +.B cancel +[ \-a ] [ -h +.I server +] [ +.I id +] [ +.I destination +] [ +.I destination-id +] +.SH DESCRIPTION +\fBlp\fR submits files for printing. +.LP +\fBcancel\fR cancels existing print jobs. The \fI-a\fR option will remove +all jobs from the specified destination. +.SH OPTIONS +The following options are recognized by \fBlp\fR: +.TP 5 +\-d \fIdestination\fR +.br +Prints files to the named printer. +.TP 5 +\-h \fIhostname\fR +.br +Specifies the print server hostname. The default is "localhost" or the value +of the CUPS_SERVER environment variable. +.TP 5 +\-m +.br +Send email when the job is completed (ignored in CUPS 1.0.) +.TP 5 +\-n \fIcopies\fR +.br +Sets the number of copies to print from 1 to 100. +.TP 5 +\-o \fIoption\fR +.br +Sets a job option. +.TP 5 +\-p/q \fIpriority\fR +.br +Sets the job priority from 1 (lowest) to 100 (highest). The default priority +is 50. +.TP 5 +\-s +.br +Do not report the resulting job IDs (silent mode.) +.TP 5 +\-t \fIname\fR +.br +Sets the job name. +.SH COMPATIBILITY +Unlike the System V printing system, CUPS allows printer names to contain +any printable character except SPACE and TAB. Also, printer and class names are +\fBnot\fR case-sensitive. +.LP +The "m" option is not functional in CUPS 1.0. +.SH SEE ALSO +lpstat(1), +CUPS Software Users Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lp.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lpadmin.man b/man/lpadmin.man new file mode 100644 index 0000000000..e40614961e --- /dev/null +++ b/man/lpadmin.man @@ -0,0 +1,125 @@ +.\" +.\" "$Id: lpadmin.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lpadmin man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lpadmin 8 "Common UNIX Printing System" "22 September 1999" "Easy Software Products" +.SH NAME +lpadmin \- configure cups printers and classes +.SH SYNOPSIS +.B lpadmin +[ -h +.I server +] \-d +.I destination +.br +.B lpadmin +[ -h +.I server +] \-p +.I printer +.I option(s) +.br +.B lpadmin +[ -h +.I server +] \-x +.I destination +.SH DESCRIPTION +\fIlpadmin\fR configures printer and class queues provided by CUPS. It can also +be used to set the system default printer or class. +.LP +The first form of the command sets the default printer or class to +\fIdestination\fR. Subsequent print jobs submitted via the \fIlp(1)\fR or +\fIlpr(1)\fR commands will use this destination unless the user specifies +otherwise. +.LP +The second form of the command configures the named printer. The additional +options are described below. +.LP +The third form of the command deletes the printer or class \fIdestination\fR. +Any jobs that are pending for the destination will be removed and any job that +is currently printed will be aborted. +.SH CONFIGURATION OPTIONS +The following options are recognized when configuring a printer queue: +.TP 5 +\-c \fIclass\fR +.br +Adds the named \fIprinter\fR to \fIclass\fR. If \fIclass\fR does not +exist it is created automatically. +.TP 5 +\-i \fIinterface\fR +.br +Sets a System V style interface script for the printer. This option cannot +be specified with the \fI\-P\fR option (PPD file) and is intended for +providing support for legacy printer drivers. +.TP 5 +\-m \fImodel\fR +.br +Sets a standard System V interface script or PPD file from the model +directory. +.TP 5 +\-r \fIclass\fR +.br +Removes the named \fIprinter\fR from \fIclass\fR. If the resulting class +becomes empty it is removed. +.TP 5 +\-v \fIdevice-uri\fR +.br +Sets the \fIdevice-uri\fR attribute of the printer queue. If \fIdevice-uri\fR +is a filename it is automatically converted to the form \fBfile:/file/name\fR. +.TP 5 +\-D \fIinfo\fR +.br +Provides a textual description of the printer. +.TP 5 +\-E +.br +Enables the printer and accepts jobs; this is the same as running the +\fIaccept(8)\fR and \fIenable(8)\fR programs on the printer. +.TP 5 +\-L \fIlocation\fR +.br +Provides a textual location of the printer. +.TP 5 +\-P \fIppd-file\fR +.br +Specifies a PostScript Printer Description file to use with the printer. If +specified, this option overrides the \fI-i\fR option (interface script). +.SH COMPATIBILITY +Unlike the System V printing system, CUPS allows printer names to contain +any printable character except SPACE and TAB. Also, printer and class names are +\fBnot\fR case-sensitive. Finally, the CUPS version of \fIlpadmin\fR may ask the +user for an access password depending on the printing system configuration. +This differs from the System V version which requires the root user to execute +this command. +.SH LIMITATIONS +The CUPS version of \fIlpadmin\fR does not support all of the System V or +Solaris printing system configuration options. +.SH SEE ALSO +accept(8), cancel(1), disable(8), enable(8), lp(1), lpstat(1), reject(8), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lpadmin.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lpc.man b/man/lpc.man new file mode 100644 index 0000000000..4ce0b44944 --- /dev/null +++ b/man/lpc.man @@ -0,0 +1,80 @@ +.\" +.\" "$Id: lpc.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lpc man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lpc 8 "Common UNIX Printing System" "22 September 1999" "Easy Software Products" +.SH NAME +lpc \- line printer control program +.SH SYNOPSIS +.B lpc +[ +.I command +[ +.I parameter(s) +] ] +.SH DESCRIPTION +\fIlpc\fR provides limited control over printer and class queues provided by +CUPS. It can also be used to query the state of queues. +.LP +If no command is specified on the command-line, \fRlpc\fR will display a +prompt and accept commands from the standard input. +.SH COMMANDS +The \fIlpc\fR program accepts a subset of commands accepted by the Berkeley +\fIlpc\fR program of the same name: +.TP 5 +\fIexit +.br +Exits the command interpreter. +.TP 5 +help \fI[command]\fR +.br +Displays a short help message. +.TP 5 +quit +.br +Exits the command interpreter. +.TP 5 +status \fI[queue]\fR +.br +Displays the status of one or more printer or class queues. +.TP 5 +? \fI[command]\fR +.br +Display a short help message. +.SH LIMITATIONS +Since \fIlpc\fR is geared towards the Berkeley printing system, it is impossible +to use \fIlpc\fR to configure printer or class queues provided by CUPS. To +configure printer or class queues you must use the \fIlpadmin(8)\fR command +or another CUPS-compatible client with that functionality. +.SH COMPATIBILITY +The CUPS version of \fIlpc\fR does not implement all of the standard Berkeley +commands. +.SH SEE ALSO +accept(8), cancel(1), disable(8), enable(8), lp(1), lpr(1), lprm(1), +lpstat(1), reject(8), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lpc.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lpinfo.man b/man/lpinfo.man new file mode 100644 index 0000000000..00b7886f99 --- /dev/null +++ b/man/lpinfo.man @@ -0,0 +1,56 @@ +.\" +.\" "$Id: lpinfo.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lpinfo man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lpinfo 8 "Common UNIX Printing System" "10 May 2000" "Easy Software Products" +.SH NAME +lpinfo \- show available devices or drivers +.SH SYNOPSIS +.B lpinfo +[ -l ] [ -m ] [ -v ] +.SH DESCRIPTION +\fBlpinfo\fR lists the available devices or drivers known to the CUPS +server. One of the \fI-m\fR or \fI-v\fR options must be specified to +get any output: +.TP 5 +\-l +.br +Shows a "long" listing of devices or drivers. +.TP 5 +\-m +.br +Shows the available printer drivers on the system. +.TP 5 +\-v +.br +Shows the available printer devices on the system. +.SH COMPATIBILITY +The \fBlpinfo\fR command is unique to CUPS. +.SH SEE ALSO +lpadmin(8), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lpinfo.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lpmove.man b/man/lpmove.man new file mode 100644 index 0000000000..0882991e3d --- /dev/null +++ b/man/lpmove.man @@ -0,0 +1,50 @@ +.\" +.\" "$Id: lpmove.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lpmove man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lpmove 8 "Common UNIX Printing System" "10 May 2000" "Easy Software Products" +.SH NAME +lpmove \- move a job to a new destination +.SH SYNOPSIS +.B lpmove +.I job destination +.SH DESCRIPTION +\fBlpmove\fR moves the specified \fIjob\fR to \fIdestination\fR. \fIjob\fR +can be the job ID number or the old destination and job ID: +.br +.nf + + lpmove 123 newprinter + lpmove oldprinter-123 newprinter +.fi +.SH COMPATIBILITY +The System V version of this command also allows moving of all jobs from one +queue to another. This functionality is currently not supported by CUPS. +.SH SEE ALSO +cancel(1), lp(1), +CUPS Software Users Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lpmove.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lpoptions.man b/man/lpoptions.man new file mode 100644 index 0000000000..f3274b68b5 --- /dev/null +++ b/man/lpoptions.man @@ -0,0 +1,99 @@ +.\" +.\" "$Id: lpoptions.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lpoptions man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lpoptions 1 "Common UNIX Printing System" "10 May 2000" "Easy Software Products" +.SH NAME +lpoptions \- display or set printer options and defaults +.SH SYNOPSIS +.B lpoptions +[ -h +.I server +] -d +.I dest[/instance] +[ -o +.I option=value +] ... [ -o +.I option=value +] +.br +.B lpoptions +[ -h +.I server +] -p +.I dest[/instance] +[ -o +.I option=value +] ... [ -o +.I option=value +] +.br +.B lpoptions +[ -h +.I server +] -x +.I dest[/instance] +.SH DESCRIPTION +\fBlpoptions\fR displays or sets printer options and defaults. +\fBlpoptions\fR shows the default printer options when run with no +arguments. Other options include: +.TP 5 +\-d \fIdest[/instance]\fR +.br +Sets the default printer to \fIdest\fR. If \fIinstance\fR is supplied then +that particular instance is used. This option overrides the system default +printer for the current user. +.TP 5 +\-h \fIserver\fR +.br +Specifies the CUPS server to communicate with. +.TP 5 +\-o \fIoption=value\fR +.br +Specifies a new option for the named destination. +.TP 5 +\-p \fIdest[/instance]\fR +.br +Sets the destination and instance, if specified, for any options that follow. +If the named instance does not exist then it is created. +.TP 5 +\-x \fIdest[/instance]\fR +.br +Removes the options for the named destination and instance, if specified. +If the named instance does not exist then this does nothing. +.LP +If no options are specified using the \fI-o\fR option then the current +options for the named printer are reported on the standard output. +.LP +Options set with the \fBlpoptions\fR command are used by the \fBlp(1)\fR +and \fBlpr(1)\fR commands when submitting jobs. +.SH COMPATIBILITY +The \fBlpoptions\fR command is unique to CUPS. +.SH SEE ALSO +cancel(1), lp(1), +CUPS Software Users Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lpoptions.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lpq.man b/man/lpq.man new file mode 100644 index 0000000000..8342f9018d --- /dev/null +++ b/man/lpq.man @@ -0,0 +1,53 @@ +.\" +.\" "$Id: lpq.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lpq man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lpq 1 "Common UNIX Printing System" "7 December 1999" "Easy Software Products" +.SH NAME +lpq \- show printer queue status +.SH SYNOPSIS +.B lpq +[ \-P +.I dest +] [ \-l ] [ +.I +interval +] +.SH DESCRIPTION +\fIlpq\fR shows the current print queue status on the named printer. +Jobs queued on the default destination will be shown if no printer or +class is specified on the command-line. +.LP +The \fIinterval\fR option allows you to continuously report the jobs +in the queue until the queue is empty; the list of jobs is show one +every \fIinterval\fR seconds. +.LP +The \fI-l\fR option requests a more verbose reporting format. +.SH SEE ALSO +cancel(1), lp(1), lpr(1), lprm(1), lpstat(1) +.br +CUPS Software Users Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lpq.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lpr.man b/man/lpr.man new file mode 100644 index 0000000000..07767516b8 --- /dev/null +++ b/man/lpr.man @@ -0,0 +1,97 @@ +.\" +.\" "$Id: lpr.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lpr man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lpr 1 "Common UNIX Printing System" "9 September 1999" "Easy Software Products" +.SH NAME +lpr \- print files +.SH SYNOPSIS +.B lpr +[ \-P +.I destination +] [ \-# +.I num-copies +[ \-l ] [ \-o +.I option +] [ \-p] [ \-r ] [ \-C/J/T +.I title +] [ +.I file(s) +] +.SH DESCRIPTION +\fBlpr\fR submits files for printing. Files named on the command line are sent +to the named printer (or the system default destination if no destination is +specified). If no files are listed on the command-line \fBlpr\fR reads the +print file from the standard input. +.SH OPTIONS +The following options are recognized by \fBlpr\fR: +.TP 5 +\-P \fIdestination\fR +.br +Prints files to the named printer. +.TP 5 +\-# \fIcopies\fR +.br +Sets the number of copies to print from 1 to 100. +.TP 5 +\-C \fIname\fR +.br +Sets the job name. +.TP 5 +\-J \fIname\fR +.br +Sets the job name. +.TP 5 +\-T \fIname\fR +.br +Sets the job name. +.TP 5 +\-l +.br +Specifies that the print file is already formatted for the destination and +should be sent without filtering. This option is equivalent to "-oraw". +.TP 5 +\-o \fIoption\fR +.br +Sets a job option. +.TP 5 +\-p +.br +Specifies that the print file should be formatted with a shaded header with +the date, time, job name, and page number. This option is equivalent to +"-oprettyprint" and is only useful when printing text files. +.TP 5 +\-r +.br +Specifies that the named print files should be deleted after printing them. +.SH COMPATIBILITY +The "c", "d", "f", "g", "i", "m", "n", "t", "v", and "w" options are not +supported by CUPS and will produce a warning message if used. +.SH SEE ALSO +cancel(1), lp(1), lpstat(1), +CUPS Software Users Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lpr.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lprm.man b/man/lprm.man new file mode 100644 index 0000000000..e5f6a54c3e --- /dev/null +++ b/man/lprm.man @@ -0,0 +1,52 @@ +.\" +.\" "$Id: lprm.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lprm man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lprm 1 "Common UNIX Printing System" "22 September 1999" "Easy Software Products" +.SH NAME +lprm \- cancel print jobs +.SH SYNOPSIS +.B lprm +[ - ] [ -P +.I destination +] [ +.I job ID(s) +] +.SH DESCRIPTION +\fBlprm\fR cancels print jobs that have been queued for printing. The \fI-P\fR +option specifies the destination printer or class. +.LP +If no arguments are supplied, the current job on the default destination is +cancelled. You can specify one or more job ID numbers to cancel those jobs, +or use the \fI\-\fR option to cancel all jobs. +.SH COMPATIBILITY +The CUPS version of \fIlprm\fR is compatible with the standard Berkeley +\fIlprm\fR command. +.SH SEE ALSO +cancel(1), lp(1), lpstat(1), lpr(1), +CUPS Software Users Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lprm.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/lpstat.man b/man/lpstat.man new file mode 100644 index 0000000000..5028aff180 --- /dev/null +++ b/man/lpstat.man @@ -0,0 +1,126 @@ +.\" +.\" "$Id: lpstat.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" lpstat man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH lpstat 1 "Common UNIX Printing System" "1 May 2000" "Easy Software Products" +.SH NAME +lpstat \- print cups status information +.SH SYNOPSIS +.B lpstat +[ -a [ +.I destination(s) +] ] [ -c [ +.I class(es) +] [ -d ] [ -h +.I server +] [ -l ] [ -o [ +.I destination(s) +] ] [ -p [ +.I printer(s) +] ] [ -r ] [ -R ] [ -s ] [ -t ] [ -u [ +.I user(s) +] ] [ -v [ +.I printer(s) +] ] +.SH DESCRIPTION +\fBlpstat\fR displays status information about the current classes, jobs, and +printers. When run with no arguments, \fBlpstat\fR will list jobs queued by +the user. Other options include: +.TP 5 +\-a [\fIprinter(s)\fR] +.br +Shows the accepting state of printer queues. If no printers are +specified then all printers are listed. +.TP 5 +\-c [\fIclass(es)\fR] +.br +Shows the printer classes and the printers that belong to them. If no +classes are specified then all classes are listed. +.TP 5 +\-d +.br +Shows the current default destination. +.TP 5 +\-h \fIserver\fR +.br +Specifies the CUPS server to communicate with. +.TP 5 +\-l +.br +Shows a long listing of printers, classes, or jobs. +.TP 5 +\-o [\fIdestination(s)\fR] +.br +Shows the jobs queue on the specified destinations. If no destinations are +specified all jobs are shown. +.TP 5 +\-p [\fIprinter(s)\fR] +.br +Shows the printers and whether or not they are enabled for printing. If +no printers are specified then all printers are listed. +.TP 5 +\-r +.br +Shows whether or not the CUPS server is running. +.TP 5 +\-R +.br +Shows the ranking of print jobs. +.TP 5 +\-s +.br +Shows a status summary, including the system default destination, a +list of classes and their member printers, and a list of printers and +their associated devices. This is equivalent to using the "-d", "-c", +and "-p" options. +.TP 5 +\-t +.br +Shows all status information. This is equivalent to using the "-r", +"-d", "-c", "-d", "-v", "-a", "-p", and "-o" options. +.TP 5 +\-u [\fIuser(s)\fR] +.br +Shows a list of print jobs queued by the specified users. If no users +are specified, lists the jobs queued by the current user. +.TP 5 +\-v [\fIprinter(s)\fR] +.br +Shows the printers and what device they are attached to. If no printers +are specified then all printers are listed. +.SH COMPATIBILITY +Unlike the System V printing system, CUPS allows printer names to contain +any printable character except SPACE and TAB. Also, printer and class names are +\fBnot\fR case-sensitive. +.LP +The "-h" option is not a standard System V option. +.LP +The Solaris "-f", "-P", and "-S" options are silently ignored. +.SH SEE ALSO +cancel(1), lp(1), +CUPS Software Users Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: lpstat.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/mime.convs.man b/man/mime.convs.man new file mode 100644 index 0000000000..34ad2fa67a --- /dev/null +++ b/man/mime.convs.man @@ -0,0 +1,54 @@ +.\" +.\" "$Id: mime.convs.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" mime.convs man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH mime.convs 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products" +.SH NAME +mime.convs \- mime type conversion file for cups +.SH DESCRIPTION +The \fImime.convs\fR file defines the filters that are available for +converting files from one format to another. The standard filters +support text, PDF, PostScript, HP-GL/2, and many types of image files. +.LP +Additional filters can be added to the \fImime.convs\fR file or to +other files in the configuration directory (\fB/etc/cups\fR) with +the extension ".convs". +.LP +Each line in the \fImime.types\fR file is a comment, blank, or filter +line. Comment lines start with the # character. Filter lines specify +the source and destination MIME types along with a relative cost +associated with the filter and the filter to run: +.br +.nf + +super/type super/type cost filter +application/postscript application/vnd.cups-raster 50 pstoraster +.fi +.SH SEE ALSO +classes.conf(5), cupsd(8), cupsd.conf(5), mime.types(5), printers.conf(5), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: mime.convs.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/mime.types.man b/man/mime.types.man new file mode 100644 index 0000000000..7d2c3e2882 --- /dev/null +++ b/man/mime.types.man @@ -0,0 +1,98 @@ +.\" +.\" "$Id: mime.types.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" mime.types man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH mime.types 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products" +.SH NAME +mime.types \- mime type description file for cups +.SH DESCRIPTION +The \fImime.types\fR file defines the recognized file types. +.LP +Additional file types can be added to \fImime.types\fR or in additional +files in the configuration directory \fB/etc/cups\fR with the extension +".types". +.LP +Each line in the \fImime.types\fR file is a comment, blank, or rule +line. Comment lines start with the # character. Rule lines start with +the MIME type name and are optionally followed by a series of file +recognition rules that are used to automatically identify print and web +files: +.br +.nf + + super/type rule [ ... ruleN] +.fi +The rules may be grouped using parenthesis, joined using "+" for a +logical AND and "," or whitespace for a logical OR, and negated using +"!". +.SH RULES +Rules take two forms - a filename extension by itself and functions with test +values inside parenthesis. The following functions are available: +.TP 5 +match("pattern") +.br +Pattern match on filename +.TP 5 +ascii(offset,length) +.br +True if bytes are valid printable ASCII (CR, NL, TAB, BS, 32-126) +.TP 5 +printable(offset,length) +.br +True if bytes are printable 8-bit chars (CR, NL, TAB, BS, 32-126, 128-254) +.TP 5 +string(offset,"string") +.br +True if bytes are identical to string +.TP 5 +char(offset,value) +.br +True if byte is identical +.TP 5 +short(offset,value) +.br +True if 16-bit integer is identical +.TP 5 +int(offset,value) +.br +True if 32-bit integer is identical +.TP 5 +locale("string") +.br +True if current locale matches string +.TP 5 +contains(offset,range,"string") +.br +True if the range contains the string +.SH STRING CONSTANTS +String constants can be specified inside quotes ("") for strings +containing whitespace and angle brackets (<>) for hexadecimal +strings. +.SH SEE ALSO +classes.conf(5), cupsd(8), cupsd.conf(5), mime.convs(5), printers.conf(5), +CUPS Software Administrators Manual, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: mime.types.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/man/printers.conf.man b/man/printers.conf.man new file mode 100644 index 0000000000..d4ebf658ca --- /dev/null +++ b/man/printers.conf.man @@ -0,0 +1,73 @@ +.\" +.\" "$Id: printers.conf.man 1231 2000-07-20 17:10:57Z mike $" +.\" +.\" printers.conf man page for the Common UNIX Printing System (CUPS). +.\" +.\" Copyright 1997-2000 by Easy Software Products. +.\" +.\" These coded instructions, statements, and computer programs are the +.\" property of Easy Software Products and are protected by Federal +.\" copyright law. Distribution and use rights are outlined in the file +.\" "LICENSE.txt" which should have been included with this file. If this +.\" file is missing or damaged please contact Easy Software Products +.\" at: +.\" +.\" Attn: CUPS Licensing Information +.\" Easy Software Products +.\" 44141 Airport View Drive, Suite 204 +.\" Hollywood, Maryland 20636-3111 USA +.\" +.\" Voice: (301) 373-9603 +.\" EMail: cups-info@cups.org +.\" WWW: http://www.cups.org +.\" +.TH printers.conf 5 "Common UNIX Printing System" "22 June 2000" "Easy Software Products" +.SH NAME +printers.conf \- printer configuration file for cups +.SH DESCRIPTION +The \fIprinters.conf\fR file defines the local printers that are +available. It is normally located in the \fI/etc/cups\fR directory and +is generated automatically by the \fIcupsd(8)\fR program when printers +are added or deleted. +.LP +Each line in the file can be a configuration directive, a blank line, +or a comment. Comment lines start with the # character. +.SH DIRECTIVES +.TP 5 +Accepting +.br +Specifies whether or not the printer is accepting new jobs. +.TP 5 +Info +.br +Specifies human-readable text describing the printer. +.TP 5 +Location +.br +Specifies human-readable text describing the location of the printer. +.TP 5 +DeviceURI +.br +Specifies the device URI for a printer. +.TP 5 + ... +.br +Defines a specific printer. +.TP 5 +State +.br +Specifies the initial state of the printer (Idle or Stopped) +.TP 5 +StateMessage +.br +Specifies the message associated with the state. +.SH SEE ALSO +classes.conf(5), cupsd(8), cupsd.conf(5), mime.convs(5), mime.types(5), +CUPS Software Administrators Manual, +CUPS Interface Design Description, +http://localhost:631/documentation.html +.SH COPYRIGHT +Copyright 1993-2000 by Easy Software Products, All Rights Reserved. +.\" +.\" End of "$Id: printers.conf.man 1231 2000-07-20 17:10:57Z mike $". +.\" diff --git a/pdftops/Array.cxx b/pdftops/Array.cxx new file mode 100644 index 0000000000..9681b6854c --- /dev/null +++ b/pdftops/Array.cxx @@ -0,0 +1,51 @@ +//======================================================================== +// +// Array.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include "gmem.h" +#include "Object.h" +#include "Array.h" + +//------------------------------------------------------------------------ +// Array +//------------------------------------------------------------------------ + +Array::Array() { + elems = NULL; + size = length = 0; + ref = 1; +} + +Array::~Array() { + int i; + + for (i = 0; i < length; ++i) + elems[i].free(); + gfree(elems); +} + +void Array::add(Object *elem) { + if (length + 1 > size) { + size += 8; + elems = (Object *)grealloc(elems, size * sizeof(Object)); + } + elems[length] = *elem; + ++length; +} + +Object *Array::get(int i, Object *obj) { + return elems[i].fetch(obj); +} + +Object *Array::getNF(int i, Object *obj) { + return elems[i].copy(obj); +} diff --git a/pdftops/Array.h b/pdftops/Array.h new file mode 100644 index 0000000000..ecf2eea6fd --- /dev/null +++ b/pdftops/Array.h @@ -0,0 +1,53 @@ +//======================================================================== +// +// Array.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef ARRAY_H +#define ARRAY_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "Object.h" + +//------------------------------------------------------------------------ +// Array +//------------------------------------------------------------------------ + +class Array { +public: + + // Constructor. + Array(); + + // Destructor. + ~Array(); + + // Reference counting. + int incRef() { return ++ref; } + int decRef() { return --ref; } + + // Get number of elements. + int getLength() { return length; } + + // Add an element. + void add(Object *elem); + + // Accessors. + Object *get(int i, Object *obj); + Object *getNF(int i, Object *obj); + +private: + + Object *elems; // array of elements + int size; // size of array + int length; // number of elements in array + int ref; // reference count +}; + +#endif diff --git a/pdftops/CMapInfo.h b/pdftops/CMapInfo.h new file mode 100644 index 0000000000..4842ee1096 --- /dev/null +++ b/pdftops/CMapInfo.h @@ -0,0 +1,31364 @@ +//======================================================================== +// +// CMapInfo.h +// +// This file was automatically generated by makeCMapInfo. +// +// Copyright 1998 Derek B. Noonburg +// +//======================================================================== + +#ifndef CMAPINFO_H +#define CMAPINFO_H + +static Gushort japan1278EUCHMap2[1252] = { + 0x0000, 0x0000, + 0x8ea0, 0x0146, + 0xa1a1, 0x0279, + 0xa2a1, 0x02d7, + 0xa3b0, 0x030c, + 0xa3c1, 0x0316, + 0xa3e1, 0x0330, + 0xa4a1, 0x034a, + 0xa5a1, 0x039d, + 0xa6a1, 0x03f3, + 0xa6c1, 0x040b, + 0xa7a1, 0x0423, + 0xa7d1, 0x0444, + 0xb0a1, 0x0465, + 0xb0a2, 0x1dd1, + 0xb0a3, 0x0467, + 0xb0a9, 0x204a, + 0xb0aa, 0x046e, + 0xb0b2, 0x1f19, + 0xb0b3, 0x1ca2, + 0xb0b4, 0x0478, + 0xb0bb, 0x1dd2, + 0xb0bc, 0x0480, + 0xb0ee, 0x1dd3, + 0xb0ef, 0x04b3, + 0xb0f3, 0x1dd4, + 0xb0f4, 0x04b8, + 0xb0fc, 0x1dd5, + 0xb0fd, 0x04c1, + 0xb1a1, 0x04c3, + 0xb1aa, 0x1dd6, + 0xb1ab, 0x04cd, + 0xb1b5, 0x1dd7, + 0xb1b6, 0x04d8, + 0xb1b9, 0x1dd8, + 0xb1ba, 0x04dc, + 0xb1bd, 0x1dda, + 0xb1be, 0x04e0, + 0xb1c2, 0x1ddb, + 0xb1c3, 0x04e5, + 0xb1eb, 0x1ddc, + 0xb1ec, 0x050e, + 0xb2a1, 0x0521, + 0xb2a8, 0x1ddd, + 0xb2a9, 0x1cc9, + 0xb2aa, 0x1dde, + 0xb2ab, 0x052b, + 0xb2e0, 0x1ddf, + 0xb2e1, 0x0561, + 0xb2fa, 0x1de0, + 0xb2fb, 0x057b, + 0xb2fd, 0x1de1, + 0xb2fe, 0x057e, + 0xb3a1, 0x057f, + 0xb3a2, 0x1de2, + 0xb3a3, 0x0581, + 0xb3c2, 0x1961, + 0xb3c3, 0x05a1, + 0xb3c9, 0x139f, + 0xb3ca, 0x05a8, + 0xb3e5, 0x1de3, + 0xb3e6, 0x05c4, + 0xb3eb, 0x1de4, + 0xb3ec, 0x05ca, + 0xb3f3, 0x1de5, + 0xb3f4, 0x05d2, + 0xb3f6, 0x1731, + 0xb3f7, 0x05d5, + 0xb3fa, 0x1de6, + 0xb3fb, 0x05d9, + 0xb4a1, 0x05dd, + 0xb4c2, 0x1de7, + 0xb4c3, 0x1572, + 0xb4c4, 0x0600, + 0xb4cd, 0x1de8, + 0xb4ce, 0x060a, + 0xb4d2, 0x1a20, + 0xb4d3, 0x060f, + 0xb4e5, 0x1de9, + 0xb4e6, 0x0622, + 0xb5a1, 0x063b, + 0xb5ab, 0x1dea, + 0xb5ac, 0x0646, + 0xb5c0, 0x1deb, + 0xb5c1, 0x065b, + 0xb6a1, 0x0699, + 0xb6a2, 0x1dec, + 0xb6a3, 0x069b, + 0xb6aa, 0x1ded, + 0xb6ab, 0x06a3, + 0xb6c6, 0x1d32, + 0xb6c7, 0x06bf, + 0xb6cf, 0x1dee, + 0xb6d0, 0x06c8, + 0xb6ed, 0x1def, + 0xb6ee, 0x06e6, + 0xb6f4, 0x1df0, + 0xb6f5, 0x06ed, + 0xb6fb, 0x1df1, + 0xb6fc, 0x06f4, + 0xb6fd, 0x1df2, + 0xb6fe, 0x06f6, + 0xb7a1, 0x06f7, + 0xb7a4, 0x1df3, + 0xb7a5, 0x06fb, + 0xb7b7, 0x1df4, + 0xb7b8, 0x070e, + 0xb7c5, 0x1df5, + 0xb7c6, 0x071c, + 0xb7ce, 0x1df6, + 0xb7cf, 0x0725, + 0xb7d2, 0x1df7, + 0xb7d3, 0x0729, + 0xb7d5, 0x1df8, + 0xb7d6, 0x072c, + 0xb7db, 0x1c0d, + 0xb7dc, 0x0732, + 0xb7e4, 0x1df9, + 0xb7e5, 0x073b, + 0xb7f1, 0x1dfa, + 0xb7f2, 0x0748, + 0xb7f9, 0x1dfb, + 0xb7fa, 0x0750, + 0xb7fe, 0x1dfc, + 0xb8a1, 0x0755, + 0xb8b4, 0x1dfd, + 0xb8b5, 0x0769, + 0xb8c1, 0x1dfe, + 0xb8c2, 0x0776, + 0xb9a1, 0x07b3, + 0xb9ab, 0x1dff, + 0xb9ac, 0x07be, + 0xb9b7, 0x1e00, + 0xb9b8, 0x07ca, + 0xb9c2, 0x1e01, + 0xb9c3, 0x07d5, + 0xb9dc, 0x16dd, + 0xb9dd, 0x07ef, + 0xb9ed, 0x1e02, + 0xb9ee, 0x0800, + 0xb9f4, 0x1e03, + 0xb9f5, 0x0807, + 0xb9f9, 0x1e04, + 0xb9fa, 0x080c, + 0xbaa1, 0x0811, + 0xbad3, 0x1e05, + 0xbad4, 0x0844, + 0xbae7, 0x1e06, + 0xbae8, 0x0858, + 0xbaf4, 0x1e07, + 0xbaf5, 0x0865, + 0xbba1, 0x086f, + 0xbba7, 0x1e08, + 0xbba8, 0x0876, + 0xbbaa, 0x1e09, + 0xbbab, 0x0879, + 0xbbac, 0x1e0a, + 0xbbad, 0x087b, + 0xbbb9, 0x1e0b, + 0xbbba, 0x0888, + 0xbca1, 0x08cd, + 0xbcc8, 0x1e0d, + 0xbcc9, 0x1929, + 0xbcca, 0x08f6, + 0xbcd7, 0x1e0e, + 0xbcd8, 0x0904, + 0xbcdd, 0x1e0f, + 0xbcdf, 0x090b, + 0xbda1, 0x092b, + 0xbdab, 0x1e11, + 0xbdac, 0x0936, + 0xbdb6, 0x1e12, + 0xbdb7, 0x0941, + 0xbdec, 0x1e13, + 0xbdee, 0x0978, + 0xbdf2, 0x1e15, + 0xbdf4, 0x097e, + 0xbea1, 0x0989, + 0xbea5, 0x1e17, + 0xbea6, 0x098e, + 0xbeb3, 0x1e18, + 0xbeb4, 0x099c, + 0xbebf, 0x1e19, + 0xbec0, 0x09a8, + 0xbed5, 0x1e1a, + 0xbed6, 0x09be, + 0xbedf, 0x1e1b, + 0xbee0, 0x09c8, + 0xbee4, 0x1e1c, + 0xbee5, 0x09cd, + 0xbfa1, 0x09e7, + 0xbfaa, 0x1e1d, + 0xbfab, 0x09f1, + 0xbfd9, 0x1e1e, + 0xbfda, 0x0a20, + 0xbfe0, 0x1e1f, + 0xbfe1, 0x0a27, + 0xbfe9, 0x1e20, + 0xbfea, 0x0a30, + 0xc0a1, 0x0a45, + 0xc0a2, 0x1e21, + 0xc0a3, 0x0a47, + 0xc0c2, 0x1e22, + 0xc0c3, 0x0a67, + 0xc0e6, 0x1e23, + 0xc0e7, 0x0a8b, + 0xc0f1, 0x1e24, + 0xc0f3, 0x0a97, + 0xc0f9, 0x1e26, + 0xc0fb, 0x0a9f, + 0xc1a1, 0x0aa3, + 0xc1a7, 0x1e28, + 0xc1a8, 0x1a6e, + 0xc1a9, 0x0aab, + 0xc1b9, 0x1e29, + 0xc1ba, 0x0abc, + 0xc1cc, 0x1e2a, + 0xc1cd, 0x0acf, + 0xc1cf, 0x1e2b, + 0xc1d0, 0x0ad2, + 0xc1df, 0x1e2c, + 0xc1e0, 0x0ae2, + 0xc1e9, 0x1e2d, + 0xc1ea, 0x0aec, + 0xc2a1, 0x0b01, + 0xc2bd, 0x1e2e, + 0xc2be, 0x0b1e, + 0xc2cd, 0x1e2f, + 0xc2ce, 0x0b2e, + 0xc2dc, 0x1e30, + 0xc2dd, 0x0b3d, + 0xc2e3, 0x1e31, + 0xc2e4, 0x0b44, + 0xc2ef, 0x1e32, + 0xc2f0, 0x0b50, + 0xc2f5, 0x1e33, + 0xc2f7, 0x0b57, + 0xc2fd, 0x1e35, + 0xc2fe, 0x0b5e, + 0xc3a1, 0x0b5f, + 0xc3a7, 0x1e36, + 0xc3a8, 0x0b66, + 0xc3a9, 0x1e37, + 0xc3ab, 0x0b69, + 0xc3ad, 0x1e39, + 0xc3af, 0x0b6d, + 0xc3bd, 0x1e3b, + 0xc3be, 0x0b7c, + 0xc3f0, 0x1e3c, + 0xc3f1, 0x0baf, + 0xc3f5, 0x1e3d, + 0xc3f6, 0x0bb4, + 0xc3fc, 0x1e3e, + 0xc3fd, 0x0bbb, + 0xc4a1, 0x0bbd, + 0xc4bd, 0x1e3f, + 0xc4be, 0x0bda, + 0xc4c8, 0x1e40, + 0xc4c9, 0x0be5, + 0xc4ca, 0x1e41, + 0xc4cb, 0x0be7, + 0xc4cd, 0x1e42, + 0xc4ce, 0x0bea, + 0xc4cf, 0x1e43, + 0xc4d0, 0x0bec, + 0xc4d4, 0x204b, + 0xc4d5, 0x0bf1, + 0xc4db, 0x11b5, + 0xc4dc, 0x0bf8, + 0xc5a1, 0x0c1b, + 0xc5a2, 0x1e44, + 0xc5a3, 0x0c1d, + 0xc5a7, 0x1e45, + 0xc5a8, 0x0c22, + 0xc5ae, 0x1e46, + 0xc5af, 0x0c29, + 0xc5b6, 0x1e47, + 0xc5b7, 0x0c31, + 0xc5bf, 0x1e48, + 0xc5c0, 0x0c3a, + 0xc5c8, 0x1e49, + 0xc5c9, 0x0c43, + 0xc5cb, 0x1e4a, + 0xc5cc, 0x0c46, + 0xc5d1, 0x1e4b, + 0xc5d3, 0x0c4d, + 0xc5d7, 0x16df, + 0xc5d8, 0x0c52, + 0xc5e4, 0x1e4d, + 0xc5e5, 0x0c5f, + 0xc5ee, 0x1450, + 0xc5ef, 0x0c69, + 0xc5f3, 0x1536, + 0xc5f4, 0x0c6e, + 0xc5f8, 0x1e4e, + 0xc5f9, 0x0c73, + 0xc6a1, 0x0c79, + 0xc6be, 0x1e4f, + 0xc6bf, 0x0c97, + 0xc6c2, 0x1e50, + 0xc6c3, 0x0c9b, + 0xc6d4, 0x1e51, + 0xc6d6, 0x0cae, + 0xc6db, 0x1e53, + 0xc6dd, 0x0cb5, + 0xc6e1, 0x1e55, + 0xc6e2, 0x0cba, + 0xc6e6, 0x1e56, + 0xc6e8, 0x0cc0, + 0xc6ea, 0x1e58, + 0xc6eb, 0x0cc3, + 0xc6f6, 0x1aed, + 0xc6f7, 0x0ccf, + 0xc7a1, 0x0cd7, + 0xc7a9, 0x1e59, + 0xc7aa, 0x0ce0, + 0xc7b9, 0x1e5a, + 0xc7ba, 0x0cf0, + 0xc7d7, 0x1e5b, + 0xc7d8, 0x0d0e, + 0xc7e7, 0x1e5c, + 0xc7e8, 0x1989, + 0xc7e9, 0x1e5d, + 0xc7ea, 0x0d20, + 0xc7ed, 0x1e5e, + 0xc7ee, 0x0d24, + 0xc8a1, 0x0d35, + 0xc8a4, 0x1e5f, + 0xc8a5, 0x0d39, + 0xc8ae, 0x1e60, + 0xc8af, 0x0d43, + 0xc8b0, 0x1e61, + 0xc8b1, 0x0d45, + 0xc8d4, 0x1e62, + 0xc8d5, 0x0d69, + 0xc8e2, 0x1e63, + 0xc8e3, 0x0d77, + 0xc8f5, 0x1e64, + 0xc8f6, 0x0d8a, + 0xc9a1, 0x0d93, + 0xc9a2, 0x1e65, + 0xc9a4, 0x0d96, + 0xc9af, 0x1e67, + 0xc9b0, 0x143b, + 0xc9b1, 0x0da3, + 0xc9b2, 0x1e68, + 0xc9b3, 0x0da5, + 0xc9b5, 0x1e69, + 0xc9b6, 0x0da8, + 0xc9c0, 0x1e6a, + 0xc9c1, 0x0db3, + 0xc9ce, 0x1e6b, + 0xc9cf, 0x0dc1, + 0xc9d1, 0x1e6c, + 0xc9d2, 0x0dc4, + 0xcaa1, 0x0df1, + 0xcac3, 0x1e6d, + 0xcac4, 0x0e14, + 0xcacd, 0x1e6e, + 0xcace, 0x0e1e, + 0xcada, 0x1e6f, + 0xcadb, 0x0e2b, + 0xcaf9, 0x1e70, + 0xcafa, 0x0e4a, + 0xcba1, 0x0e4f, + 0xcba2, 0x1e71, + 0xcba3, 0x0e51, + 0xcba9, 0x1e72, + 0xcbaa, 0x0e58, + 0xcbcb, 0x1e73, + 0xcbcc, 0x0e7a, + 0xcbea, 0x1d33, + 0xcbeb, 0x0e99, + 0xcbf0, 0x1e74, + 0xcbf1, 0x0e9f, + 0xcbf8, 0x1f2c, + 0xcbf9, 0x102f, + 0xcbfa, 0x0ea8, + 0xcca1, 0x0ead, + 0xcccd, 0x1e75, + 0xccce, 0x0eda, + 0xccd9, 0x1e76, + 0xccda, 0x0ee6, + 0xccdf, 0x1e77, + 0xcce0, 0x0eec, + 0xcce2, 0x1e78, + 0xcce3, 0x0eef, + 0xccf9, 0x1935, + 0xccfa, 0x1e79, + 0xccfb, 0x0f07, + 0xccfc, 0x1e7a, + 0xccfd, 0x0f09, + 0xccfe, 0x1e7b, + 0xcda1, 0x0f0b, + 0xcdb2, 0x1e7c, + 0xcdb3, 0x0f1d, + 0xcdd0, 0x1e7d, + 0xcdd1, 0x0f3b, + 0xcdd4, 0x1e7e, + 0xcdd5, 0x0f3f, + 0xcdda, 0x1d34, + 0xcddb, 0x0f45, + 0xcde9, 0x1e7f, + 0xcdea, 0x0f54, + 0xcea1, 0x0f69, + 0xcecb, 0x1e80, + 0xcecc, 0x0f94, + 0xcefa, 0x1e81, + 0xcefc, 0x0fc4, + 0xcfa1, 0x1e83, + 0xcfa2, 0x0fc8, + 0xcfb1, 0x1e84, + 0xcfb2, 0x0fd8, + 0xcfb6, 0x1777, + 0xcfb7, 0x0fdd, + 0xcfb9, 0x1e85, + 0xcfba, 0x0fe0, + 0xd0a1, 0x0ffa, + 0xd0d6, 0x0ea7, + 0xd0d7, 0x1030, + 0xd1a1, 0x1058, + 0xd1bd, 0x1e86, + 0xd1be, 0x1075, + 0xd1c7, 0x1e87, + 0xd1c8, 0x107f, + 0xd1cb, 0x1e88, + 0xd1cc, 0x1083, + 0xd1cd, 0x1e89, + 0xd1ce, 0x1085, + 0xd2a1, 0x10b6, + 0xd3a1, 0x1114, + 0xd3b0, 0x1e8a, + 0xd3b1, 0x1124, + 0xd3ba, 0x1e8b, + 0xd3bb, 0x112e, + 0xd3de, 0x1e8d, + 0xd3df, 0x1152, + 0xd3eb, 0x1e8e, + 0xd3ec, 0x115f, + 0xd4a1, 0x1172, + 0xd4c4, 0x1e8f, + 0xd4c5, 0x1196, + 0xd4e4, 0x0bf7, + 0xd4e5, 0x11b6, + 0xd5a1, 0x11d0, + 0xd5bd, 0x1e90, + 0xd5be, 0x11ed, + 0xd5e3, 0x1e91, + 0xd5e4, 0x1213, + 0xd6a1, 0x122e, + 0xd6a2, 0x1e92, + 0xd6a3, 0x1230, + 0xd7a1, 0x128c, + 0xd8a1, 0x12ea, + 0xd8a4, 0x1e94, + 0xd8a5, 0x12ee, + 0xd9a1, 0x1348, + 0xd9e0, 0x1e95, + 0xd9e1, 0x1388, + 0xd9ec, 0x1e96, + 0xd9ed, 0x1394, + 0xd9f8, 0x05a7, + 0xd9f9, 0x13a0, + 0xdaa1, 0x13a6, + 0xdab9, 0x1e97, + 0xdaba, 0x13bf, + 0xdacd, 0x1e98, + 0xdace, 0x13d3, + 0xdba1, 0x1404, + 0xdbc5, 0x1e99, + 0xdbc6, 0x1429, + 0xdbca, 0x1e9a, + 0xdbcb, 0x142e, + 0xdbd8, 0x0da2, + 0xdbd9, 0x143c, + 0xdbeb, 0x1e9b, + 0xdbec, 0x144f, + 0xdbed, 0x0c68, + 0xdbee, 0x1451, + 0xdbf4, 0x1e9c, + 0xdbf5, 0x1458, + 0xdca1, 0x1462, + 0xdda1, 0x14c0, + 0xdea1, 0x151e, + 0xdeb9, 0x0c6d, + 0xdeba, 0x1537, + 0xded0, 0x1e9d, + 0xded1, 0x154e, + 0xdef5, 0x05ff, + 0xdef6, 0x1573, + 0xdfa1, 0x157c, + 0xe0a1, 0x15da, + 0xe0a6, 0x1e9f, + 0xe0a7, 0x15e0, + 0xe0df, 0x1ea0, + 0xe0e0, 0x1619, + 0xe0f6, 0x1d35, + 0xe0f7, 0x1630, + 0xe1a1, 0x1638, + 0xe1ab, 0x1ea1, + 0xe1ac, 0x1643, + 0xe1b0, 0x1ea2, + 0xe1b2, 0x1649, + 0xe2a1, 0x1696, + 0xe2ab, 0x1ea4, + 0xe2ac, 0x16a1, + 0xe2e8, 0x07ee, + 0xe2e9, 0x16de, + 0xe2ea, 0x0c51, + 0xe2eb, 0x16e0, + 0xe2ef, 0x1ea5, + 0xe2f0, 0x16e5, + 0xe3a1, 0x16f4, + 0xe3ca, 0x1ea6, + 0xe3cb, 0x171e, + 0xe3d4, 0x1ea7, + 0xe3d5, 0x1728, + 0xe3de, 0x05d4, + 0xe3df, 0x1732, + 0xe4a1, 0x1752, + 0xe4b9, 0x1ea8, + 0xe4ba, 0x176b, + 0xe4c6, 0x0fdc, + 0xe4c7, 0x1778, + 0xe4e4, 0x1ea9, + 0xe4e5, 0x1796, + 0xe4ee, 0x1eaa, + 0xe4ef, 0x17a0, + 0xe5a1, 0x17b0, + 0xe5b9, 0x1eab, + 0xe5ba, 0x17c9, + 0xe5bb, 0x1eac, + 0xe5bc, 0x17cb, + 0xe5c6, 0x1ead, + 0xe5c7, 0x17d6, + 0xe6a1, 0x180e, + 0xe6c6, 0x1eae, + 0xe6c7, 0x1834, + 0xe7a1, 0x186c, + 0xe7e4, 0x1eaf, + 0xe7e5, 0x18b0, + 0xe7e9, 0x1eb0, + 0xe7ea, 0x18b5, + 0xe7f2, 0x1eb1, + 0xe7f3, 0x18be, + 0xe8a1, 0x18ca, + 0xe8b4, 0x1eb2, + 0xe8b5, 0x18de, + 0xe8bb, 0x1eb3, + 0xe8bc, 0x18e5, + 0xe8f4, 0x1eb4, + 0xe8f5, 0x191e, + 0xe9a1, 0x1928, + 0xe9a2, 0x08f5, + 0xe9a3, 0x192a, + 0xe9ae, 0x0f05, + 0xe9af, 0x1936, + 0xe9da, 0x05a0, + 0xe9db, 0x1962, + 0xeaa1, 0x1986, + 0xeaa4, 0x0d1e, + 0xeaa5, 0x198a, + 0xeaa7, 0x1eb6, + 0xeaa8, 0x198d, + 0xeabd, 0x1eb7, + 0xeabe, 0x19a3, + 0xeaef, 0x1eb8, + 0xeaf0, 0x19d5, + 0xeba1, 0x19e4, + 0xebb2, 0x1eb9, + 0xebb3, 0x19f6, + 0xebdd, 0x060e, + 0xebde, 0x1a21, + 0xebe6, 0x1eba, + 0xebe7, 0x1a2a, + 0xebf6, 0x1ebb, + 0xebf7, 0x1a3a, + 0xeca1, 0x1a42, + 0xeccd, 0x0aaa, + 0xecce, 0x1a6f, + 0xece9, 0x1ebc, + 0xecea, 0x1a8b, + 0xecf4, 0x1ebd, + 0xecf5, 0x1a96, + 0xeda1, 0x1aa0, + 0xedce, 0x1ebe, + 0xedcf, 0x1ace, + 0xedec, 0x1ebf, + 0xeded, 0x1aec, + 0xedee, 0x1ec0, + 0xedef, 0x1aee, + 0xeea1, 0x1afe, + 0xeea9, 0x1ec1, + 0xeeaa, 0x1b07, + 0xeebd, 0x1ec2, + 0xeebe, 0x1b1b, + 0xeed7, 0x1ec3, + 0xeed8, 0x1b35, + 0xefa1, 0x1b5c, + 0xf0a1, 0x1bba, + 0xf0c5, 0x1ec6, + 0xf0c6, 0x1bdf, + 0xf0d1, 0x1ec7, + 0xf0d2, 0x1beb, + 0xf0d7, 0x1ec8, + 0xf0d8, 0x1bf1, + 0xf0f4, 0x0731, + 0xf0f5, 0x1ec9, + 0xf0f6, 0x1c0f, + 0xf1a1, 0x1c18, + 0xf2a1, 0x1c76, + 0xf2ad, 0x1eca, + 0xf2ae, 0x1c83, + 0xf2bc, 0x1ecb, + 0xf2bd, 0x1c92, + 0xf2cd, 0x0477, + 0xf2ce, 0x1ecc, + 0xf2cf, 0x1ca4, + 0xf2f4, 0x0529, + 0xf2f5, 0x1cca, + 0xf3a1, 0x1cd4, + 0xf3d1, 0x1ecd, + 0xf3d2, 0x1d05, + 0xf3fd, 0x1ece, + 0xf3fe, 0x1d31, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1278EUCHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1278EUCHMap2, 626 +}; + +static Gushort japan1278EUCVMap2[1306] = { + 0x0000, 0x0000, + 0x8ea0, 0x0146, + 0xa1a1, 0x0279, + 0xa2a1, 0x02d7, + 0xa3b0, 0x030c, + 0xa3c1, 0x0316, + 0xa3e1, 0x0330, + 0xa4a1, 0x034a, + 0xa5a1, 0x039d, + 0xa6a1, 0x03f3, + 0xa6c1, 0x040b, + 0xa7a1, 0x0423, + 0xa7d1, 0x0444, + 0xb0a1, 0x0465, + 0xb0a2, 0x1dd1, + 0xb0a3, 0x0467, + 0xb0a9, 0x204a, + 0xb0aa, 0x046e, + 0xb0b2, 0x1f19, + 0xb0b3, 0x1ca2, + 0xb0b4, 0x0478, + 0xb0bb, 0x1dd2, + 0xb0bc, 0x0480, + 0xb0ee, 0x1dd3, + 0xb0ef, 0x04b3, + 0xb0f3, 0x1dd4, + 0xb0f4, 0x04b8, + 0xb0fc, 0x1dd5, + 0xb0fd, 0x04c1, + 0xb1a1, 0x04c3, + 0xb1aa, 0x1dd6, + 0xb1ab, 0x04cd, + 0xb1b5, 0x1dd7, + 0xb1b6, 0x04d8, + 0xb1b9, 0x1dd8, + 0xb1ba, 0x04dc, + 0xb1bd, 0x1dda, + 0xb1be, 0x04e0, + 0xb1c2, 0x1ddb, + 0xb1c3, 0x04e5, + 0xb1eb, 0x1ddc, + 0xb1ec, 0x050e, + 0xb2a1, 0x0521, + 0xb2a8, 0x1ddd, + 0xb2a9, 0x1cc9, + 0xb2aa, 0x1dde, + 0xb2ab, 0x052b, + 0xb2e0, 0x1ddf, + 0xb2e1, 0x0561, + 0xb2fa, 0x1de0, + 0xb2fb, 0x057b, + 0xb2fd, 0x1de1, + 0xb2fe, 0x057e, + 0xb3a1, 0x057f, + 0xb3a2, 0x1de2, + 0xb3a3, 0x0581, + 0xb3c2, 0x1961, + 0xb3c3, 0x05a1, + 0xb3c9, 0x139f, + 0xb3ca, 0x05a8, + 0xb3e5, 0x1de3, + 0xb3e6, 0x05c4, + 0xb3eb, 0x1de4, + 0xb3ec, 0x05ca, + 0xb3f3, 0x1de5, + 0xb3f4, 0x05d2, + 0xb3f6, 0x1731, + 0xb3f7, 0x05d5, + 0xb3fa, 0x1de6, + 0xb3fb, 0x05d9, + 0xb4a1, 0x05dd, + 0xb4c2, 0x1de7, + 0xb4c3, 0x1572, + 0xb4c4, 0x0600, + 0xb4cd, 0x1de8, + 0xb4ce, 0x060a, + 0xb4d2, 0x1a20, + 0xb4d3, 0x060f, + 0xb4e5, 0x1de9, + 0xb4e6, 0x0622, + 0xb5a1, 0x063b, + 0xb5ab, 0x1dea, + 0xb5ac, 0x0646, + 0xb5c0, 0x1deb, + 0xb5c1, 0x065b, + 0xb6a1, 0x0699, + 0xb6a2, 0x1dec, + 0xb6a3, 0x069b, + 0xb6aa, 0x1ded, + 0xb6ab, 0x06a3, + 0xb6c6, 0x1d32, + 0xb6c7, 0x06bf, + 0xb6cf, 0x1dee, + 0xb6d0, 0x06c8, + 0xb6ed, 0x1def, + 0xb6ee, 0x06e6, + 0xb6f4, 0x1df0, + 0xb6f5, 0x06ed, + 0xb6fb, 0x1df1, + 0xb6fc, 0x06f4, + 0xb6fd, 0x1df2, + 0xb6fe, 0x06f6, + 0xb7a1, 0x06f7, + 0xb7a4, 0x1df3, + 0xb7a5, 0x06fb, + 0xb7b7, 0x1df4, + 0xb7b8, 0x070e, + 0xb7c5, 0x1df5, + 0xb7c6, 0x071c, + 0xb7ce, 0x1df6, + 0xb7cf, 0x0725, + 0xb7d2, 0x1df7, + 0xb7d3, 0x0729, + 0xb7d5, 0x1df8, + 0xb7d6, 0x072c, + 0xb7db, 0x1c0d, + 0xb7dc, 0x0732, + 0xb7e4, 0x1df9, + 0xb7e5, 0x073b, + 0xb7f1, 0x1dfa, + 0xb7f2, 0x0748, + 0xb7f9, 0x1dfb, + 0xb7fa, 0x0750, + 0xb7fe, 0x1dfc, + 0xb8a1, 0x0755, + 0xb8b4, 0x1dfd, + 0xb8b5, 0x0769, + 0xb8c1, 0x1dfe, + 0xb8c2, 0x0776, + 0xb9a1, 0x07b3, + 0xb9ab, 0x1dff, + 0xb9ac, 0x07be, + 0xb9b7, 0x1e00, + 0xb9b8, 0x07ca, + 0xb9c2, 0x1e01, + 0xb9c3, 0x07d5, + 0xb9dc, 0x16dd, + 0xb9dd, 0x07ef, + 0xb9ed, 0x1e02, + 0xb9ee, 0x0800, + 0xb9f4, 0x1e03, + 0xb9f5, 0x0807, + 0xb9f9, 0x1e04, + 0xb9fa, 0x080c, + 0xbaa1, 0x0811, + 0xbad3, 0x1e05, + 0xbad4, 0x0844, + 0xbae7, 0x1e06, + 0xbae8, 0x0858, + 0xbaf4, 0x1e07, + 0xbaf5, 0x0865, + 0xbba1, 0x086f, + 0xbba7, 0x1e08, + 0xbba8, 0x0876, + 0xbbaa, 0x1e09, + 0xbbab, 0x0879, + 0xbbac, 0x1e0a, + 0xbbad, 0x087b, + 0xbbb9, 0x1e0b, + 0xbbba, 0x0888, + 0xbca1, 0x08cd, + 0xbcc8, 0x1e0d, + 0xbcc9, 0x1929, + 0xbcca, 0x08f6, + 0xbcd7, 0x1e0e, + 0xbcd8, 0x0904, + 0xbcdd, 0x1e0f, + 0xbcdf, 0x090b, + 0xbda1, 0x092b, + 0xbdab, 0x1e11, + 0xbdac, 0x0936, + 0xbdb6, 0x1e12, + 0xbdb7, 0x0941, + 0xbdec, 0x1e13, + 0xbdee, 0x0978, + 0xbdf2, 0x1e15, + 0xbdf4, 0x097e, + 0xbea1, 0x0989, + 0xbea5, 0x1e17, + 0xbea6, 0x098e, + 0xbeb3, 0x1e18, + 0xbeb4, 0x099c, + 0xbebf, 0x1e19, + 0xbec0, 0x09a8, + 0xbed5, 0x1e1a, + 0xbed6, 0x09be, + 0xbedf, 0x1e1b, + 0xbee0, 0x09c8, + 0xbee4, 0x1e1c, + 0xbee5, 0x09cd, + 0xbfa1, 0x09e7, + 0xbfaa, 0x1e1d, + 0xbfab, 0x09f1, + 0xbfd9, 0x1e1e, + 0xbfda, 0x0a20, + 0xbfe0, 0x1e1f, + 0xbfe1, 0x0a27, + 0xbfe9, 0x1e20, + 0xbfea, 0x0a30, + 0xc0a1, 0x0a45, + 0xc0a2, 0x1e21, + 0xc0a3, 0x0a47, + 0xc0c2, 0x1e22, + 0xc0c3, 0x0a67, + 0xc0e6, 0x1e23, + 0xc0e7, 0x0a8b, + 0xc0f1, 0x1e24, + 0xc0f3, 0x0a97, + 0xc0f9, 0x1e26, + 0xc0fb, 0x0a9f, + 0xc1a1, 0x0aa3, + 0xc1a7, 0x1e28, + 0xc1a8, 0x1a6e, + 0xc1a9, 0x0aab, + 0xc1b9, 0x1e29, + 0xc1ba, 0x0abc, + 0xc1cc, 0x1e2a, + 0xc1cd, 0x0acf, + 0xc1cf, 0x1e2b, + 0xc1d0, 0x0ad2, + 0xc1df, 0x1e2c, + 0xc1e0, 0x0ae2, + 0xc1e9, 0x1e2d, + 0xc1ea, 0x0aec, + 0xc2a1, 0x0b01, + 0xc2bd, 0x1e2e, + 0xc2be, 0x0b1e, + 0xc2cd, 0x1e2f, + 0xc2ce, 0x0b2e, + 0xc2dc, 0x1e30, + 0xc2dd, 0x0b3d, + 0xc2e3, 0x1e31, + 0xc2e4, 0x0b44, + 0xc2ef, 0x1e32, + 0xc2f0, 0x0b50, + 0xc2f5, 0x1e33, + 0xc2f7, 0x0b57, + 0xc2fd, 0x1e35, + 0xc2fe, 0x0b5e, + 0xc3a1, 0x0b5f, + 0xc3a7, 0x1e36, + 0xc3a8, 0x0b66, + 0xc3a9, 0x1e37, + 0xc3ab, 0x0b69, + 0xc3ad, 0x1e39, + 0xc3af, 0x0b6d, + 0xc3bd, 0x1e3b, + 0xc3be, 0x0b7c, + 0xc3f0, 0x1e3c, + 0xc3f1, 0x0baf, + 0xc3f5, 0x1e3d, + 0xc3f6, 0x0bb4, + 0xc3fc, 0x1e3e, + 0xc3fd, 0x0bbb, + 0xc4a1, 0x0bbd, + 0xc4bd, 0x1e3f, + 0xc4be, 0x0bda, + 0xc4c8, 0x1e40, + 0xc4c9, 0x0be5, + 0xc4ca, 0x1e41, + 0xc4cb, 0x0be7, + 0xc4cd, 0x1e42, + 0xc4ce, 0x0bea, + 0xc4cf, 0x1e43, + 0xc4d0, 0x0bec, + 0xc4d4, 0x204b, + 0xc4d5, 0x0bf1, + 0xc4db, 0x11b5, + 0xc4dc, 0x0bf8, + 0xc5a1, 0x0c1b, + 0xc5a2, 0x1e44, + 0xc5a3, 0x0c1d, + 0xc5a7, 0x1e45, + 0xc5a8, 0x0c22, + 0xc5ae, 0x1e46, + 0xc5af, 0x0c29, + 0xc5b6, 0x1e47, + 0xc5b7, 0x0c31, + 0xc5bf, 0x1e48, + 0xc5c0, 0x0c3a, + 0xc5c8, 0x1e49, + 0xc5c9, 0x0c43, + 0xc5cb, 0x1e4a, + 0xc5cc, 0x0c46, + 0xc5d1, 0x1e4b, + 0xc5d3, 0x0c4d, + 0xc5d7, 0x16df, + 0xc5d8, 0x0c52, + 0xc5e4, 0x1e4d, + 0xc5e5, 0x0c5f, + 0xc5ee, 0x1450, + 0xc5ef, 0x0c69, + 0xc5f3, 0x1536, + 0xc5f4, 0x0c6e, + 0xc5f8, 0x1e4e, + 0xc5f9, 0x0c73, + 0xc6a1, 0x0c79, + 0xc6be, 0x1e4f, + 0xc6bf, 0x0c97, + 0xc6c2, 0x1e50, + 0xc6c3, 0x0c9b, + 0xc6d4, 0x1e51, + 0xc6d6, 0x0cae, + 0xc6db, 0x1e53, + 0xc6dd, 0x0cb5, + 0xc6e1, 0x1e55, + 0xc6e2, 0x0cba, + 0xc6e6, 0x1e56, + 0xc6e8, 0x0cc0, + 0xc6ea, 0x1e58, + 0xc6eb, 0x0cc3, + 0xc6f6, 0x1aed, + 0xc6f7, 0x0ccf, + 0xc7a1, 0x0cd7, + 0xc7a9, 0x1e59, + 0xc7aa, 0x0ce0, + 0xc7b9, 0x1e5a, + 0xc7ba, 0x0cf0, + 0xc7d7, 0x1e5b, + 0xc7d8, 0x0d0e, + 0xc7e7, 0x1e5c, + 0xc7e8, 0x1989, + 0xc7e9, 0x1e5d, + 0xc7ea, 0x0d20, + 0xc7ed, 0x1e5e, + 0xc7ee, 0x0d24, + 0xc8a1, 0x0d35, + 0xc8a4, 0x1e5f, + 0xc8a5, 0x0d39, + 0xc8ae, 0x1e60, + 0xc8af, 0x0d43, + 0xc8b0, 0x1e61, + 0xc8b1, 0x0d45, + 0xc8d4, 0x1e62, + 0xc8d5, 0x0d69, + 0xc8e2, 0x1e63, + 0xc8e3, 0x0d77, + 0xc8f5, 0x1e64, + 0xc8f6, 0x0d8a, + 0xc9a1, 0x0d93, + 0xc9a2, 0x1e65, + 0xc9a4, 0x0d96, + 0xc9af, 0x1e67, + 0xc9b0, 0x143b, + 0xc9b1, 0x0da3, + 0xc9b2, 0x1e68, + 0xc9b3, 0x0da5, + 0xc9b5, 0x1e69, + 0xc9b6, 0x0da8, + 0xc9c0, 0x1e6a, + 0xc9c1, 0x0db3, + 0xc9ce, 0x1e6b, + 0xc9cf, 0x0dc1, + 0xc9d1, 0x1e6c, + 0xc9d2, 0x0dc4, + 0xcaa1, 0x0df1, + 0xcac3, 0x1e6d, + 0xcac4, 0x0e14, + 0xcacd, 0x1e6e, + 0xcace, 0x0e1e, + 0xcada, 0x1e6f, + 0xcadb, 0x0e2b, + 0xcaf9, 0x1e70, + 0xcafa, 0x0e4a, + 0xcba1, 0x0e4f, + 0xcba2, 0x1e71, + 0xcba3, 0x0e51, + 0xcba9, 0x1e72, + 0xcbaa, 0x0e58, + 0xcbcb, 0x1e73, + 0xcbcc, 0x0e7a, + 0xcbea, 0x1d33, + 0xcbeb, 0x0e99, + 0xcbf0, 0x1e74, + 0xcbf1, 0x0e9f, + 0xcbf8, 0x1f2c, + 0xcbf9, 0x102f, + 0xcbfa, 0x0ea8, + 0xcca1, 0x0ead, + 0xcccd, 0x1e75, + 0xccce, 0x0eda, + 0xccd9, 0x1e76, + 0xccda, 0x0ee6, + 0xccdf, 0x1e77, + 0xcce0, 0x0eec, + 0xcce2, 0x1e78, + 0xcce3, 0x0eef, + 0xccf9, 0x1935, + 0xccfa, 0x1e79, + 0xccfb, 0x0f07, + 0xccfc, 0x1e7a, + 0xccfd, 0x0f09, + 0xccfe, 0x1e7b, + 0xcda1, 0x0f0b, + 0xcdb2, 0x1e7c, + 0xcdb3, 0x0f1d, + 0xcdd0, 0x1e7d, + 0xcdd1, 0x0f3b, + 0xcdd4, 0x1e7e, + 0xcdd5, 0x0f3f, + 0xcdda, 0x1d34, + 0xcddb, 0x0f45, + 0xcde9, 0x1e7f, + 0xcdea, 0x0f54, + 0xcea1, 0x0f69, + 0xcecb, 0x1e80, + 0xcecc, 0x0f94, + 0xcefa, 0x1e81, + 0xcefc, 0x0fc4, + 0xcfa1, 0x1e83, + 0xcfa2, 0x0fc8, + 0xcfb1, 0x1e84, + 0xcfb2, 0x0fd8, + 0xcfb6, 0x1777, + 0xcfb7, 0x0fdd, + 0xcfb9, 0x1e85, + 0xcfba, 0x0fe0, + 0xd0a1, 0x0ffa, + 0xd0d6, 0x0ea7, + 0xd0d7, 0x1030, + 0xd1a1, 0x1058, + 0xd1bd, 0x1e86, + 0xd1be, 0x1075, + 0xd1c7, 0x1e87, + 0xd1c8, 0x107f, + 0xd1cb, 0x1e88, + 0xd1cc, 0x1083, + 0xd1cd, 0x1e89, + 0xd1ce, 0x1085, + 0xd2a1, 0x10b6, + 0xd3a1, 0x1114, + 0xd3b0, 0x1e8a, + 0xd3b1, 0x1124, + 0xd3ba, 0x1e8b, + 0xd3bb, 0x112e, + 0xd3de, 0x1e8d, + 0xd3df, 0x1152, + 0xd3eb, 0x1e8e, + 0xd3ec, 0x115f, + 0xd4a1, 0x1172, + 0xd4c4, 0x1e8f, + 0xd4c5, 0x1196, + 0xd4e4, 0x0bf7, + 0xd4e5, 0x11b6, + 0xd5a1, 0x11d0, + 0xd5bd, 0x1e90, + 0xd5be, 0x11ed, + 0xd5e3, 0x1e91, + 0xd5e4, 0x1213, + 0xd6a1, 0x122e, + 0xd6a2, 0x1e92, + 0xd6a3, 0x1230, + 0xd7a1, 0x128c, + 0xd8a1, 0x12ea, + 0xd8a4, 0x1e94, + 0xd8a5, 0x12ee, + 0xd9a1, 0x1348, + 0xd9e0, 0x1e95, + 0xd9e1, 0x1388, + 0xd9ec, 0x1e96, + 0xd9ed, 0x1394, + 0xd9f8, 0x05a7, + 0xd9f9, 0x13a0, + 0xdaa1, 0x13a6, + 0xdab9, 0x1e97, + 0xdaba, 0x13bf, + 0xdacd, 0x1e98, + 0xdace, 0x13d3, + 0xdba1, 0x1404, + 0xdbc5, 0x1e99, + 0xdbc6, 0x1429, + 0xdbca, 0x1e9a, + 0xdbcb, 0x142e, + 0xdbd8, 0x0da2, + 0xdbd9, 0x143c, + 0xdbeb, 0x1e9b, + 0xdbec, 0x144f, + 0xdbed, 0x0c68, + 0xdbee, 0x1451, + 0xdbf4, 0x1e9c, + 0xdbf5, 0x1458, + 0xdca1, 0x1462, + 0xdda1, 0x14c0, + 0xdea1, 0x151e, + 0xdeb9, 0x0c6d, + 0xdeba, 0x1537, + 0xded0, 0x1e9d, + 0xded1, 0x154e, + 0xdef5, 0x05ff, + 0xdef6, 0x1573, + 0xdfa1, 0x157c, + 0xe0a1, 0x15da, + 0xe0a6, 0x1e9f, + 0xe0a7, 0x15e0, + 0xe0df, 0x1ea0, + 0xe0e0, 0x1619, + 0xe0f6, 0x1d35, + 0xe0f7, 0x1630, + 0xe1a1, 0x1638, + 0xe1ab, 0x1ea1, + 0xe1ac, 0x1643, + 0xe1b0, 0x1ea2, + 0xe1b2, 0x1649, + 0xe2a1, 0x1696, + 0xe2ab, 0x1ea4, + 0xe2ac, 0x16a1, + 0xe2e8, 0x07ee, + 0xe2e9, 0x16de, + 0xe2ea, 0x0c51, + 0xe2eb, 0x16e0, + 0xe2ef, 0x1ea5, + 0xe2f0, 0x16e5, + 0xe3a1, 0x16f4, + 0xe3ca, 0x1ea6, + 0xe3cb, 0x171e, + 0xe3d4, 0x1ea7, + 0xe3d5, 0x1728, + 0xe3de, 0x05d4, + 0xe3df, 0x1732, + 0xe4a1, 0x1752, + 0xe4b9, 0x1ea8, + 0xe4ba, 0x176b, + 0xe4c6, 0x0fdc, + 0xe4c7, 0x1778, + 0xe4e4, 0x1ea9, + 0xe4e5, 0x1796, + 0xe4ee, 0x1eaa, + 0xe4ef, 0x17a0, + 0xe5a1, 0x17b0, + 0xe5b9, 0x1eab, + 0xe5ba, 0x17c9, + 0xe5bb, 0x1eac, + 0xe5bc, 0x17cb, + 0xe5c6, 0x1ead, + 0xe5c7, 0x17d6, + 0xe6a1, 0x180e, + 0xe6c6, 0x1eae, + 0xe6c7, 0x1834, + 0xe7a1, 0x186c, + 0xe7e4, 0x1eaf, + 0xe7e5, 0x18b0, + 0xe7e9, 0x1eb0, + 0xe7ea, 0x18b5, + 0xe7f2, 0x1eb1, + 0xe7f3, 0x18be, + 0xe8a1, 0x18ca, + 0xe8b4, 0x1eb2, + 0xe8b5, 0x18de, + 0xe8bb, 0x1eb3, + 0xe8bc, 0x18e5, + 0xe8f4, 0x1eb4, + 0xe8f5, 0x191e, + 0xe9a1, 0x1928, + 0xe9a2, 0x08f5, + 0xe9a3, 0x192a, + 0xe9ae, 0x0f05, + 0xe9af, 0x1936, + 0xe9da, 0x05a0, + 0xe9db, 0x1962, + 0xeaa1, 0x1986, + 0xeaa4, 0x0d1e, + 0xeaa5, 0x198a, + 0xeaa7, 0x1eb6, + 0xeaa8, 0x198d, + 0xeabd, 0x1eb7, + 0xeabe, 0x19a3, + 0xeaef, 0x1eb8, + 0xeaf0, 0x19d5, + 0xeba1, 0x19e4, + 0xebb2, 0x1eb9, + 0xebb3, 0x19f6, + 0xebdd, 0x060e, + 0xebde, 0x1a21, + 0xebe6, 0x1eba, + 0xebe7, 0x1a2a, + 0xebf6, 0x1ebb, + 0xebf7, 0x1a3a, + 0xeca1, 0x1a42, + 0xeccd, 0x0aaa, + 0xecce, 0x1a6f, + 0xece9, 0x1ebc, + 0xecea, 0x1a8b, + 0xecf4, 0x1ebd, + 0xecf5, 0x1a96, + 0xeda1, 0x1aa0, + 0xedce, 0x1ebe, + 0xedcf, 0x1ace, + 0xedec, 0x1ebf, + 0xeded, 0x1aec, + 0xedee, 0x1ec0, + 0xedef, 0x1aee, + 0xeea1, 0x1afe, + 0xeea9, 0x1ec1, + 0xeeaa, 0x1b07, + 0xeebd, 0x1ec2, + 0xeebe, 0x1b1b, + 0xeed7, 0x1ec3, + 0xeed8, 0x1b35, + 0xefa1, 0x1b5c, + 0xf0a1, 0x1bba, + 0xf0c5, 0x1ec6, + 0xf0c6, 0x1bdf, + 0xf0d1, 0x1ec7, + 0xf0d2, 0x1beb, + 0xf0d7, 0x1ec8, + 0xf0d8, 0x1bf1, + 0xf0f4, 0x0731, + 0xf0f5, 0x1ec9, + 0xf0f6, 0x1c0f, + 0xf1a1, 0x1c18, + 0xf2a1, 0x1c76, + 0xf2ad, 0x1eca, + 0xf2ae, 0x1c83, + 0xf2bc, 0x1ecb, + 0xf2bd, 0x1c92, + 0xf2cd, 0x0477, + 0xf2ce, 0x1ecc, + 0xf2cf, 0x1ca4, + 0xf2f4, 0x0529, + 0xf2f5, 0x1cca, + 0xf3a1, 0x1cd4, + 0xf3d1, 0x1ecd, + 0xf3d2, 0x1d05, + 0xf3fd, 0x1ece, + 0xf3fe, 0x1d31, + 0xa1a2, 0x1ecf, + 0xa1b1, 0x1ed1, + 0xa1bc, 0x1ed3, + 0xa1c1, 0x1ed6, + 0xa1ca, 0x1edb, + 0xa1e1, 0x1eed, + 0xa4a1, 0x1eee, + 0xa4a3, 0x1eef, + 0xa4a5, 0x1ef0, + 0xa4a7, 0x1ef1, + 0xa4a9, 0x1ef2, + 0xa4c3, 0x1ef3, + 0xa4e3, 0x1ef4, + 0xa4e5, 0x1ef5, + 0xa4e7, 0x1ef6, + 0xa4ee, 0x1ef7, + 0xa5a1, 0x1ef8, + 0xa5a3, 0x1ef9, + 0xa5a5, 0x1efa, + 0xa5a7, 0x1efb, + 0xa5a9, 0x1efc, + 0xa5c3, 0x1efd, + 0xa5e3, 0x1efe, + 0xa5e5, 0x1eff, + 0xa5e7, 0x1f00, + 0xa5ee, 0x1f01, + 0xa5f5, 0x1f02, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1278EUCVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1278EUCVMap2, 653 +}; + +static Gushort japan1278HMap2[1250] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2221, 0x02d7, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x3021, 0x0465, + 0x3022, 0x1dd1, + 0x3023, 0x0467, + 0x3029, 0x204a, + 0x302a, 0x046e, + 0x3032, 0x1f19, + 0x3033, 0x1ca2, + 0x3034, 0x0478, + 0x303b, 0x1dd2, + 0x303c, 0x0480, + 0x306e, 0x1dd3, + 0x306f, 0x04b3, + 0x3073, 0x1dd4, + 0x3074, 0x04b8, + 0x307c, 0x1dd5, + 0x307d, 0x04c1, + 0x3121, 0x04c3, + 0x312a, 0x1dd6, + 0x312b, 0x04cd, + 0x3135, 0x1dd7, + 0x3136, 0x04d8, + 0x3139, 0x1dd8, + 0x313a, 0x04dc, + 0x313d, 0x1dda, + 0x313e, 0x04e0, + 0x3142, 0x1ddb, + 0x3143, 0x04e5, + 0x316b, 0x1ddc, + 0x316c, 0x050e, + 0x3221, 0x0521, + 0x3228, 0x1ddd, + 0x3229, 0x1cc9, + 0x322a, 0x1dde, + 0x322b, 0x052b, + 0x3260, 0x1ddf, + 0x3261, 0x0561, + 0x327a, 0x1de0, + 0x327b, 0x057b, + 0x327d, 0x1de1, + 0x327e, 0x057e, + 0x3321, 0x057f, + 0x3322, 0x1de2, + 0x3323, 0x0581, + 0x3342, 0x1961, + 0x3343, 0x05a1, + 0x3349, 0x139f, + 0x334a, 0x05a8, + 0x3365, 0x1de3, + 0x3366, 0x05c4, + 0x336b, 0x1de4, + 0x336c, 0x05ca, + 0x3373, 0x1de5, + 0x3374, 0x05d2, + 0x3376, 0x1731, + 0x3377, 0x05d5, + 0x337a, 0x1de6, + 0x337b, 0x05d9, + 0x3421, 0x05dd, + 0x3442, 0x1de7, + 0x3443, 0x1572, + 0x3444, 0x0600, + 0x344d, 0x1de8, + 0x344e, 0x060a, + 0x3452, 0x1a20, + 0x3453, 0x060f, + 0x3465, 0x1de9, + 0x3466, 0x0622, + 0x3521, 0x063b, + 0x352b, 0x1dea, + 0x352c, 0x0646, + 0x3540, 0x1deb, + 0x3541, 0x065b, + 0x3621, 0x0699, + 0x3622, 0x1dec, + 0x3623, 0x069b, + 0x362a, 0x1ded, + 0x362b, 0x06a3, + 0x3646, 0x1d32, + 0x3647, 0x06bf, + 0x364f, 0x1dee, + 0x3650, 0x06c8, + 0x366d, 0x1def, + 0x366e, 0x06e6, + 0x3674, 0x1df0, + 0x3675, 0x06ed, + 0x367b, 0x1df1, + 0x367c, 0x06f4, + 0x367d, 0x1df2, + 0x367e, 0x06f6, + 0x3721, 0x06f7, + 0x3724, 0x1df3, + 0x3725, 0x06fb, + 0x3737, 0x1df4, + 0x3738, 0x070e, + 0x3745, 0x1df5, + 0x3746, 0x071c, + 0x374e, 0x1df6, + 0x374f, 0x0725, + 0x3752, 0x1df7, + 0x3753, 0x0729, + 0x3755, 0x1df8, + 0x3756, 0x072c, + 0x375b, 0x1c0d, + 0x375c, 0x0732, + 0x3764, 0x1df9, + 0x3765, 0x073b, + 0x3771, 0x1dfa, + 0x3772, 0x0748, + 0x3779, 0x1dfb, + 0x377a, 0x0750, + 0x377e, 0x1dfc, + 0x3821, 0x0755, + 0x3834, 0x1dfd, + 0x3835, 0x0769, + 0x3841, 0x1dfe, + 0x3842, 0x0776, + 0x3921, 0x07b3, + 0x392b, 0x1dff, + 0x392c, 0x07be, + 0x3937, 0x1e00, + 0x3938, 0x07ca, + 0x3942, 0x1e01, + 0x3943, 0x07d5, + 0x395c, 0x16dd, + 0x395d, 0x07ef, + 0x396d, 0x1e02, + 0x396e, 0x0800, + 0x3974, 0x1e03, + 0x3975, 0x0807, + 0x3979, 0x1e04, + 0x397a, 0x080c, + 0x3a21, 0x0811, + 0x3a53, 0x1e05, + 0x3a54, 0x0844, + 0x3a67, 0x1e06, + 0x3a68, 0x0858, + 0x3a74, 0x1e07, + 0x3a75, 0x0865, + 0x3b21, 0x086f, + 0x3b27, 0x1e08, + 0x3b28, 0x0876, + 0x3b2a, 0x1e09, + 0x3b2b, 0x0879, + 0x3b2c, 0x1e0a, + 0x3b2d, 0x087b, + 0x3b39, 0x1e0b, + 0x3b3a, 0x0888, + 0x3c21, 0x08cd, + 0x3c48, 0x1e0d, + 0x3c49, 0x1929, + 0x3c4a, 0x08f6, + 0x3c57, 0x1e0e, + 0x3c58, 0x0904, + 0x3c5d, 0x1e0f, + 0x3c5f, 0x090b, + 0x3d21, 0x092b, + 0x3d2b, 0x1e11, + 0x3d2c, 0x0936, + 0x3d36, 0x1e12, + 0x3d37, 0x0941, + 0x3d6c, 0x1e13, + 0x3d6e, 0x0978, + 0x3d72, 0x1e15, + 0x3d74, 0x097e, + 0x3e21, 0x0989, + 0x3e25, 0x1e17, + 0x3e26, 0x098e, + 0x3e33, 0x1e18, + 0x3e34, 0x099c, + 0x3e3f, 0x1e19, + 0x3e40, 0x09a8, + 0x3e55, 0x1e1a, + 0x3e56, 0x09be, + 0x3e5f, 0x1e1b, + 0x3e60, 0x09c8, + 0x3e64, 0x1e1c, + 0x3e65, 0x09cd, + 0x3f21, 0x09e7, + 0x3f2a, 0x1e1d, + 0x3f2b, 0x09f1, + 0x3f59, 0x1e1e, + 0x3f5a, 0x0a20, + 0x3f60, 0x1e1f, + 0x3f61, 0x0a27, + 0x3f69, 0x1e20, + 0x3f6a, 0x0a30, + 0x4021, 0x0a45, + 0x4022, 0x1e21, + 0x4023, 0x0a47, + 0x4042, 0x1e22, + 0x4043, 0x0a67, + 0x4066, 0x1e23, + 0x4067, 0x0a8b, + 0x4071, 0x1e24, + 0x4073, 0x0a97, + 0x4079, 0x1e26, + 0x407b, 0x0a9f, + 0x4121, 0x0aa3, + 0x4127, 0x1e28, + 0x4128, 0x1a6e, + 0x4129, 0x0aab, + 0x4139, 0x1e29, + 0x413a, 0x0abc, + 0x414c, 0x1e2a, + 0x414d, 0x0acf, + 0x414f, 0x1e2b, + 0x4150, 0x0ad2, + 0x415f, 0x1e2c, + 0x4160, 0x0ae2, + 0x4169, 0x1e2d, + 0x416a, 0x0aec, + 0x4221, 0x0b01, + 0x423d, 0x1e2e, + 0x423e, 0x0b1e, + 0x424d, 0x1e2f, + 0x424e, 0x0b2e, + 0x425c, 0x1e30, + 0x425d, 0x0b3d, + 0x4263, 0x1e31, + 0x4264, 0x0b44, + 0x426f, 0x1e32, + 0x4270, 0x0b50, + 0x4275, 0x1e33, + 0x4277, 0x0b57, + 0x427d, 0x1e35, + 0x427e, 0x0b5e, + 0x4321, 0x0b5f, + 0x4327, 0x1e36, + 0x4328, 0x0b66, + 0x4329, 0x1e37, + 0x432b, 0x0b69, + 0x432d, 0x1e39, + 0x432f, 0x0b6d, + 0x433d, 0x1e3b, + 0x433e, 0x0b7c, + 0x4370, 0x1e3c, + 0x4371, 0x0baf, + 0x4375, 0x1e3d, + 0x4376, 0x0bb4, + 0x437c, 0x1e3e, + 0x437d, 0x0bbb, + 0x4421, 0x0bbd, + 0x443d, 0x1e3f, + 0x443e, 0x0bda, + 0x4448, 0x1e40, + 0x4449, 0x0be5, + 0x444a, 0x1e41, + 0x444b, 0x0be7, + 0x444d, 0x1e42, + 0x444e, 0x0bea, + 0x444f, 0x1e43, + 0x4450, 0x0bec, + 0x4454, 0x204b, + 0x4455, 0x0bf1, + 0x445b, 0x11b5, + 0x445c, 0x0bf8, + 0x4521, 0x0c1b, + 0x4522, 0x1e44, + 0x4523, 0x0c1d, + 0x4527, 0x1e45, + 0x4528, 0x0c22, + 0x452e, 0x1e46, + 0x452f, 0x0c29, + 0x4536, 0x1e47, + 0x4537, 0x0c31, + 0x453f, 0x1e48, + 0x4540, 0x0c3a, + 0x4548, 0x1e49, + 0x4549, 0x0c43, + 0x454b, 0x1e4a, + 0x454c, 0x0c46, + 0x4551, 0x1e4b, + 0x4553, 0x0c4d, + 0x4557, 0x16df, + 0x4558, 0x0c52, + 0x4564, 0x1e4d, + 0x4565, 0x0c5f, + 0x456e, 0x1450, + 0x456f, 0x0c69, + 0x4573, 0x1536, + 0x4574, 0x0c6e, + 0x4578, 0x1e4e, + 0x4579, 0x0c73, + 0x4621, 0x0c79, + 0x463e, 0x1e4f, + 0x463f, 0x0c97, + 0x4642, 0x1e50, + 0x4643, 0x0c9b, + 0x4654, 0x1e51, + 0x4656, 0x0cae, + 0x465b, 0x1e53, + 0x465d, 0x0cb5, + 0x4661, 0x1e55, + 0x4662, 0x0cba, + 0x4666, 0x1e56, + 0x4668, 0x0cc0, + 0x466a, 0x1e58, + 0x466b, 0x0cc3, + 0x4676, 0x1aed, + 0x4677, 0x0ccf, + 0x4721, 0x0cd7, + 0x4729, 0x1e59, + 0x472a, 0x0ce0, + 0x4739, 0x1e5a, + 0x473a, 0x0cf0, + 0x4757, 0x1e5b, + 0x4758, 0x0d0e, + 0x4767, 0x1e5c, + 0x4768, 0x1989, + 0x4769, 0x1e5d, + 0x476a, 0x0d20, + 0x476d, 0x1e5e, + 0x476e, 0x0d24, + 0x4821, 0x0d35, + 0x4824, 0x1e5f, + 0x4825, 0x0d39, + 0x482e, 0x1e60, + 0x482f, 0x0d43, + 0x4830, 0x1e61, + 0x4831, 0x0d45, + 0x4854, 0x1e62, + 0x4855, 0x0d69, + 0x4862, 0x1e63, + 0x4863, 0x0d77, + 0x4875, 0x1e64, + 0x4876, 0x0d8a, + 0x4921, 0x0d93, + 0x4922, 0x1e65, + 0x4924, 0x0d96, + 0x492f, 0x1e67, + 0x4930, 0x143b, + 0x4931, 0x0da3, + 0x4932, 0x1e68, + 0x4933, 0x0da5, + 0x4935, 0x1e69, + 0x4936, 0x0da8, + 0x4940, 0x1e6a, + 0x4941, 0x0db3, + 0x494e, 0x1e6b, + 0x494f, 0x0dc1, + 0x4951, 0x1e6c, + 0x4952, 0x0dc4, + 0x4a21, 0x0df1, + 0x4a43, 0x1e6d, + 0x4a44, 0x0e14, + 0x4a4d, 0x1e6e, + 0x4a4e, 0x0e1e, + 0x4a5a, 0x1e6f, + 0x4a5b, 0x0e2b, + 0x4a79, 0x1e70, + 0x4a7a, 0x0e4a, + 0x4b21, 0x0e4f, + 0x4b22, 0x1e71, + 0x4b23, 0x0e51, + 0x4b29, 0x1e72, + 0x4b2a, 0x0e58, + 0x4b4b, 0x1e73, + 0x4b4c, 0x0e7a, + 0x4b6a, 0x1d33, + 0x4b6b, 0x0e99, + 0x4b70, 0x1e74, + 0x4b71, 0x0e9f, + 0x4b78, 0x1f2c, + 0x4b79, 0x102f, + 0x4b7a, 0x0ea8, + 0x4c21, 0x0ead, + 0x4c4d, 0x1e75, + 0x4c4e, 0x0eda, + 0x4c59, 0x1e76, + 0x4c5a, 0x0ee6, + 0x4c5f, 0x1e77, + 0x4c60, 0x0eec, + 0x4c62, 0x1e78, + 0x4c63, 0x0eef, + 0x4c79, 0x1935, + 0x4c7a, 0x1e79, + 0x4c7b, 0x0f07, + 0x4c7c, 0x1e7a, + 0x4c7d, 0x0f09, + 0x4c7e, 0x1e7b, + 0x4d21, 0x0f0b, + 0x4d32, 0x1e7c, + 0x4d33, 0x0f1d, + 0x4d50, 0x1e7d, + 0x4d51, 0x0f3b, + 0x4d54, 0x1e7e, + 0x4d55, 0x0f3f, + 0x4d5a, 0x1d34, + 0x4d5b, 0x0f45, + 0x4d69, 0x1e7f, + 0x4d6a, 0x0f54, + 0x4e21, 0x0f69, + 0x4e4b, 0x1e80, + 0x4e4c, 0x0f94, + 0x4e7a, 0x1e81, + 0x4e7c, 0x0fc4, + 0x4f21, 0x1e83, + 0x4f22, 0x0fc8, + 0x4f31, 0x1e84, + 0x4f32, 0x0fd8, + 0x4f36, 0x1777, + 0x4f37, 0x0fdd, + 0x4f39, 0x1e85, + 0x4f3a, 0x0fe0, + 0x5021, 0x0ffa, + 0x5056, 0x0ea7, + 0x5057, 0x1030, + 0x5121, 0x1058, + 0x513d, 0x1e86, + 0x513e, 0x1075, + 0x5147, 0x1e87, + 0x5148, 0x107f, + 0x514b, 0x1e88, + 0x514c, 0x1083, + 0x514d, 0x1e89, + 0x514e, 0x1085, + 0x5221, 0x10b6, + 0x5321, 0x1114, + 0x5330, 0x1e8a, + 0x5331, 0x1124, + 0x533a, 0x1e8b, + 0x533b, 0x112e, + 0x535e, 0x1e8d, + 0x535f, 0x1152, + 0x536b, 0x1e8e, + 0x536c, 0x115f, + 0x5421, 0x1172, + 0x5444, 0x1e8f, + 0x5445, 0x1196, + 0x5464, 0x0bf7, + 0x5465, 0x11b6, + 0x5521, 0x11d0, + 0x553d, 0x1e90, + 0x553e, 0x11ed, + 0x5563, 0x1e91, + 0x5564, 0x1213, + 0x5621, 0x122e, + 0x5622, 0x1e92, + 0x5623, 0x1230, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5824, 0x1e94, + 0x5825, 0x12ee, + 0x5921, 0x1348, + 0x5960, 0x1e95, + 0x5961, 0x1388, + 0x596c, 0x1e96, + 0x596d, 0x1394, + 0x5978, 0x05a7, + 0x5979, 0x13a0, + 0x5a21, 0x13a6, + 0x5a39, 0x1e97, + 0x5a3a, 0x13bf, + 0x5a4d, 0x1e98, + 0x5a4e, 0x13d3, + 0x5b21, 0x1404, + 0x5b45, 0x1e99, + 0x5b46, 0x1429, + 0x5b4a, 0x1e9a, + 0x5b4b, 0x142e, + 0x5b58, 0x0da2, + 0x5b59, 0x143c, + 0x5b6b, 0x1e9b, + 0x5b6c, 0x144f, + 0x5b6d, 0x0c68, + 0x5b6e, 0x1451, + 0x5b74, 0x1e9c, + 0x5b75, 0x1458, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5e21, 0x151e, + 0x5e39, 0x0c6d, + 0x5e3a, 0x1537, + 0x5e50, 0x1e9d, + 0x5e51, 0x154e, + 0x5e75, 0x05ff, + 0x5e76, 0x1573, + 0x5f21, 0x157c, + 0x6021, 0x15da, + 0x6026, 0x1e9f, + 0x6027, 0x15e0, + 0x605f, 0x1ea0, + 0x6060, 0x1619, + 0x6076, 0x1d35, + 0x6077, 0x1630, + 0x6121, 0x1638, + 0x612b, 0x1ea1, + 0x612c, 0x1643, + 0x6130, 0x1ea2, + 0x6132, 0x1649, + 0x6221, 0x1696, + 0x622b, 0x1ea4, + 0x622c, 0x16a1, + 0x6268, 0x07ee, + 0x6269, 0x16de, + 0x626a, 0x0c51, + 0x626b, 0x16e0, + 0x626f, 0x1ea5, + 0x6270, 0x16e5, + 0x6321, 0x16f4, + 0x634a, 0x1ea6, + 0x634b, 0x171e, + 0x6354, 0x1ea7, + 0x6355, 0x1728, + 0x635e, 0x05d4, + 0x635f, 0x1732, + 0x6421, 0x1752, + 0x6439, 0x1ea8, + 0x643a, 0x176b, + 0x6446, 0x0fdc, + 0x6447, 0x1778, + 0x6464, 0x1ea9, + 0x6465, 0x1796, + 0x646e, 0x1eaa, + 0x646f, 0x17a0, + 0x6521, 0x17b0, + 0x6539, 0x1eab, + 0x653a, 0x17c9, + 0x653b, 0x1eac, + 0x653c, 0x17cb, + 0x6546, 0x1ead, + 0x6547, 0x17d6, + 0x6621, 0x180e, + 0x6646, 0x1eae, + 0x6647, 0x1834, + 0x6721, 0x186c, + 0x6764, 0x1eaf, + 0x6765, 0x18b0, + 0x6769, 0x1eb0, + 0x676a, 0x18b5, + 0x6772, 0x1eb1, + 0x6773, 0x18be, + 0x6821, 0x18ca, + 0x6834, 0x1eb2, + 0x6835, 0x18de, + 0x683b, 0x1eb3, + 0x683c, 0x18e5, + 0x6874, 0x1eb4, + 0x6875, 0x191e, + 0x6921, 0x1928, + 0x6922, 0x08f5, + 0x6923, 0x192a, + 0x692e, 0x0f05, + 0x692f, 0x1936, + 0x695a, 0x05a0, + 0x695b, 0x1962, + 0x6a21, 0x1986, + 0x6a24, 0x0d1e, + 0x6a25, 0x198a, + 0x6a27, 0x1eb6, + 0x6a28, 0x198d, + 0x6a3d, 0x1eb7, + 0x6a3e, 0x19a3, + 0x6a6f, 0x1eb8, + 0x6a70, 0x19d5, + 0x6b21, 0x19e4, + 0x6b32, 0x1eb9, + 0x6b33, 0x19f6, + 0x6b5d, 0x060e, + 0x6b5e, 0x1a21, + 0x6b66, 0x1eba, + 0x6b67, 0x1a2a, + 0x6b76, 0x1ebb, + 0x6b77, 0x1a3a, + 0x6c21, 0x1a42, + 0x6c4d, 0x0aaa, + 0x6c4e, 0x1a6f, + 0x6c69, 0x1ebc, + 0x6c6a, 0x1a8b, + 0x6c74, 0x1ebd, + 0x6c75, 0x1a96, + 0x6d21, 0x1aa0, + 0x6d4e, 0x1ebe, + 0x6d4f, 0x1ace, + 0x6d6c, 0x1ebf, + 0x6d6d, 0x1aec, + 0x6d6e, 0x1ec0, + 0x6d6f, 0x1aee, + 0x6e21, 0x1afe, + 0x6e29, 0x1ec1, + 0x6e2a, 0x1b07, + 0x6e3d, 0x1ec2, + 0x6e3e, 0x1b1b, + 0x6e57, 0x1ec3, + 0x6e58, 0x1b35, + 0x6f21, 0x1b5c, + 0x7021, 0x1bba, + 0x7045, 0x1ec6, + 0x7046, 0x1bdf, + 0x7051, 0x1ec7, + 0x7052, 0x1beb, + 0x7057, 0x1ec8, + 0x7058, 0x1bf1, + 0x7074, 0x0731, + 0x7075, 0x1ec9, + 0x7076, 0x1c0f, + 0x7121, 0x1c18, + 0x7221, 0x1c76, + 0x722d, 0x1eca, + 0x722e, 0x1c83, + 0x723c, 0x1ecb, + 0x723d, 0x1c92, + 0x724d, 0x0477, + 0x724e, 0x1ecc, + 0x724f, 0x1ca4, + 0x7274, 0x0529, + 0x7275, 0x1cca, + 0x7321, 0x1cd4, + 0x7351, 0x1ecd, + 0x7352, 0x1d05, + 0x737d, 0x1ece, + 0x737e, 0x1d31, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1278HEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1278HMap2, 625 +}; + +static Gushort japan1278RKSJHMap2[1252] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x889f, 0x0465, + 0x88a0, 0x1dd1, + 0x88a1, 0x0467, + 0x88a7, 0x204a, + 0x88a8, 0x046e, + 0x88b0, 0x1f19, + 0x88b1, 0x1ca2, + 0x88b2, 0x0478, + 0x88b9, 0x1dd2, + 0x88ba, 0x0480, + 0x88ec, 0x1dd3, + 0x88ed, 0x04b3, + 0x88f1, 0x1dd4, + 0x88f2, 0x04b8, + 0x88fa, 0x1dd5, + 0x88fb, 0x04c1, + 0x8940, 0x04c3, + 0x8949, 0x1dd6, + 0x894a, 0x04cd, + 0x8954, 0x1dd7, + 0x8955, 0x04d8, + 0x8958, 0x1dd8, + 0x8959, 0x04dc, + 0x895c, 0x1dda, + 0x895d, 0x04e0, + 0x8961, 0x1ddb, + 0x8962, 0x04e5, + 0x8980, 0x0502, + 0x898b, 0x1ddc, + 0x898c, 0x050e, + 0x89a6, 0x1ddd, + 0x89a7, 0x1cc9, + 0x89a8, 0x1dde, + 0x89a9, 0x052b, + 0x89de, 0x1ddf, + 0x89df, 0x0561, + 0x89f8, 0x1de0, + 0x89f9, 0x057b, + 0x89fb, 0x1de1, + 0x89fc, 0x057e, + 0x8a40, 0x057f, + 0x8a41, 0x1de2, + 0x8a42, 0x0581, + 0x8a61, 0x1961, + 0x8a62, 0x05a1, + 0x8a68, 0x139f, + 0x8a69, 0x05a8, + 0x8a80, 0x05be, + 0x8a85, 0x1de3, + 0x8a86, 0x05c4, + 0x8a8b, 0x1de4, + 0x8a8c, 0x05ca, + 0x8a93, 0x1de5, + 0x8a94, 0x05d2, + 0x8a96, 0x1731, + 0x8a97, 0x05d5, + 0x8a9a, 0x1de6, + 0x8a9b, 0x05d9, + 0x8ac0, 0x1de7, + 0x8ac1, 0x1572, + 0x8ac2, 0x0600, + 0x8acb, 0x1de8, + 0x8acc, 0x060a, + 0x8ad0, 0x1a20, + 0x8ad1, 0x060f, + 0x8ae3, 0x1de9, + 0x8ae4, 0x0622, + 0x8b40, 0x063b, + 0x8b4a, 0x1dea, + 0x8b4b, 0x0646, + 0x8b5f, 0x1deb, + 0x8b60, 0x065b, + 0x8b80, 0x067a, + 0x8ba0, 0x1dec, + 0x8ba1, 0x069b, + 0x8ba8, 0x1ded, + 0x8ba9, 0x06a3, + 0x8bc4, 0x1d32, + 0x8bc5, 0x06bf, + 0x8bcd, 0x1dee, + 0x8bce, 0x06c8, + 0x8beb, 0x1def, + 0x8bec, 0x06e6, + 0x8bf2, 0x1df0, + 0x8bf3, 0x06ed, + 0x8bf9, 0x1df1, + 0x8bfa, 0x06f4, + 0x8bfb, 0x1df2, + 0x8bfc, 0x06f6, + 0x8c40, 0x06f7, + 0x8c43, 0x1df3, + 0x8c44, 0x06fb, + 0x8c56, 0x1df4, + 0x8c57, 0x070e, + 0x8c64, 0x1df5, + 0x8c65, 0x071c, + 0x8c6d, 0x1df6, + 0x8c6e, 0x0725, + 0x8c71, 0x1df7, + 0x8c72, 0x0729, + 0x8c74, 0x1df8, + 0x8c75, 0x072c, + 0x8c7a, 0x1c0d, + 0x8c7b, 0x0732, + 0x8c80, 0x0736, + 0x8c84, 0x1df9, + 0x8c85, 0x073b, + 0x8c91, 0x1dfa, + 0x8c92, 0x0748, + 0x8c99, 0x1dfb, + 0x8c9a, 0x0750, + 0x8c9e, 0x1dfc, + 0x8c9f, 0x0755, + 0x8cb2, 0x1dfd, + 0x8cb3, 0x0769, + 0x8cbf, 0x1dfe, + 0x8cc0, 0x0776, + 0x8d40, 0x07b3, + 0x8d4a, 0x1dff, + 0x8d4b, 0x07be, + 0x8d56, 0x1e00, + 0x8d57, 0x07ca, + 0x8d61, 0x1e01, + 0x8d62, 0x07d5, + 0x8d7b, 0x16dd, + 0x8d7c, 0x07ef, + 0x8d80, 0x07f2, + 0x8d8d, 0x1e02, + 0x8d8e, 0x0800, + 0x8d94, 0x1e03, + 0x8d95, 0x0807, + 0x8d99, 0x1e04, + 0x8d9a, 0x080c, + 0x8dd1, 0x1e05, + 0x8dd2, 0x0844, + 0x8de5, 0x1e06, + 0x8de6, 0x0858, + 0x8df2, 0x1e07, + 0x8df3, 0x0865, + 0x8e40, 0x086f, + 0x8e46, 0x1e08, + 0x8e47, 0x0876, + 0x8e49, 0x1e09, + 0x8e4a, 0x0879, + 0x8e4b, 0x1e0a, + 0x8e4c, 0x087b, + 0x8e58, 0x1e0b, + 0x8e59, 0x0888, + 0x8e80, 0x08ae, + 0x8ec6, 0x1e0d, + 0x8ec7, 0x1929, + 0x8ec8, 0x08f6, + 0x8ed5, 0x1e0e, + 0x8ed6, 0x0904, + 0x8edb, 0x1e0f, + 0x8edd, 0x090b, + 0x8f40, 0x092b, + 0x8f4a, 0x1e11, + 0x8f4b, 0x0936, + 0x8f55, 0x1e12, + 0x8f56, 0x0941, + 0x8f80, 0x096a, + 0x8f8c, 0x1e13, + 0x8f8e, 0x0978, + 0x8f92, 0x1e15, + 0x8f94, 0x097e, + 0x8fa3, 0x1e17, + 0x8fa4, 0x098e, + 0x8fb1, 0x1e18, + 0x8fb2, 0x099c, + 0x8fbd, 0x1e19, + 0x8fbe, 0x09a8, + 0x8fd3, 0x1e1a, + 0x8fd4, 0x09be, + 0x8fdd, 0x1e1b, + 0x8fde, 0x09c8, + 0x8fe2, 0x1e1c, + 0x8fe3, 0x09cd, + 0x9040, 0x09e7, + 0x9049, 0x1e1d, + 0x904a, 0x09f1, + 0x9078, 0x1e1e, + 0x9079, 0x0a20, + 0x9080, 0x1e1f, + 0x9081, 0x0a27, + 0x9089, 0x1e20, + 0x908a, 0x0a30, + 0x90a0, 0x1e21, + 0x90a1, 0x0a47, + 0x90c0, 0x1e22, + 0x90c1, 0x0a67, + 0x90e4, 0x1e23, + 0x90e5, 0x0a8b, + 0x90ef, 0x1e24, + 0x90f1, 0x0a97, + 0x90f7, 0x1e26, + 0x90f9, 0x0a9f, + 0x9140, 0x0aa3, + 0x9146, 0x1e28, + 0x9147, 0x1a6e, + 0x9148, 0x0aab, + 0x9158, 0x1e29, + 0x9159, 0x0abc, + 0x916b, 0x1e2a, + 0x916c, 0x0acf, + 0x916e, 0x1e2b, + 0x916f, 0x0ad2, + 0x917e, 0x1e2c, + 0x9180, 0x0ae2, + 0x9189, 0x1e2d, + 0x918a, 0x0aec, + 0x91bb, 0x1e2e, + 0x91bc, 0x0b1e, + 0x91cb, 0x1e2f, + 0x91cc, 0x0b2e, + 0x91da, 0x1e30, + 0x91db, 0x0b3d, + 0x91e1, 0x1e31, + 0x91e2, 0x0b44, + 0x91ed, 0x1e32, + 0x91ee, 0x0b50, + 0x91f3, 0x1e33, + 0x91f5, 0x0b57, + 0x91fb, 0x1e35, + 0x91fc, 0x0b5e, + 0x9240, 0x0b5f, + 0x9246, 0x1e36, + 0x9247, 0x0b66, + 0x9248, 0x1e37, + 0x924a, 0x0b69, + 0x924c, 0x1e39, + 0x924e, 0x0b6d, + 0x925c, 0x1e3b, + 0x925d, 0x0b7c, + 0x9280, 0x0b9e, + 0x9290, 0x1e3c, + 0x9291, 0x0baf, + 0x9295, 0x1e3d, + 0x9296, 0x0bb4, + 0x929c, 0x1e3e, + 0x929d, 0x0bbb, + 0x92bb, 0x1e3f, + 0x92bc, 0x0bda, + 0x92c6, 0x1e40, + 0x92c7, 0x0be5, + 0x92c8, 0x1e41, + 0x92c9, 0x0be7, + 0x92cb, 0x1e42, + 0x92cc, 0x0bea, + 0x92cd, 0x1e43, + 0x92ce, 0x0bec, + 0x92d2, 0x204b, + 0x92d3, 0x0bf1, + 0x92d9, 0x11b5, + 0x92da, 0x0bf8, + 0x9340, 0x0c1b, + 0x9341, 0x1e44, + 0x9342, 0x0c1d, + 0x9346, 0x1e45, + 0x9347, 0x0c22, + 0x934d, 0x1e46, + 0x934e, 0x0c29, + 0x9355, 0x1e47, + 0x9356, 0x0c31, + 0x935e, 0x1e48, + 0x935f, 0x0c3a, + 0x9367, 0x1e49, + 0x9368, 0x0c43, + 0x936a, 0x1e4a, + 0x936b, 0x0c46, + 0x9370, 0x1e4b, + 0x9372, 0x0c4d, + 0x9376, 0x16df, + 0x9377, 0x0c52, + 0x9380, 0x0c5a, + 0x9384, 0x1e4d, + 0x9385, 0x0c5f, + 0x938e, 0x1450, + 0x938f, 0x0c69, + 0x9393, 0x1536, + 0x9394, 0x0c6e, + 0x9398, 0x1e4e, + 0x9399, 0x0c73, + 0x93bc, 0x1e4f, + 0x93bd, 0x0c97, + 0x93c0, 0x1e50, + 0x93c1, 0x0c9b, + 0x93d2, 0x1e51, + 0x93d4, 0x0cae, + 0x93d9, 0x1e53, + 0x93db, 0x0cb5, + 0x93df, 0x1e55, + 0x93e0, 0x0cba, + 0x93e4, 0x1e56, + 0x93e6, 0x0cc0, + 0x93e8, 0x1e58, + 0x93e9, 0x0cc3, + 0x93f4, 0x1aed, + 0x93f5, 0x0ccf, + 0x9440, 0x0cd7, + 0x9448, 0x1e59, + 0x9449, 0x0ce0, + 0x9458, 0x1e5a, + 0x9459, 0x0cf0, + 0x9476, 0x1e5b, + 0x9477, 0x0d0e, + 0x9480, 0x0d16, + 0x9487, 0x1e5c, + 0x9488, 0x1989, + 0x9489, 0x1e5d, + 0x948a, 0x0d20, + 0x948d, 0x1e5e, + 0x948e, 0x0d24, + 0x94a2, 0x1e5f, + 0x94a3, 0x0d39, + 0x94ac, 0x1e60, + 0x94ad, 0x0d43, + 0x94ae, 0x1e61, + 0x94af, 0x0d45, + 0x94d2, 0x1e62, + 0x94d3, 0x0d69, + 0x94e0, 0x1e63, + 0x94e1, 0x0d77, + 0x94f3, 0x1e64, + 0x94f4, 0x0d8a, + 0x9540, 0x0d93, + 0x9541, 0x1e65, + 0x9543, 0x0d96, + 0x954e, 0x1e67, + 0x954f, 0x143b, + 0x9550, 0x0da3, + 0x9551, 0x1e68, + 0x9552, 0x0da5, + 0x9554, 0x1e69, + 0x9555, 0x0da8, + 0x955f, 0x1e6a, + 0x9560, 0x0db3, + 0x956d, 0x1e6b, + 0x956e, 0x0dc1, + 0x9570, 0x1e6c, + 0x9571, 0x0dc4, + 0x9580, 0x0dd2, + 0x95c1, 0x1e6d, + 0x95c2, 0x0e14, + 0x95cb, 0x1e6e, + 0x95cc, 0x0e1e, + 0x95d8, 0x1e6f, + 0x95d9, 0x0e2b, + 0x95f7, 0x1e70, + 0x95f8, 0x0e4a, + 0x9640, 0x0e4f, + 0x9641, 0x1e71, + 0x9642, 0x0e51, + 0x9648, 0x1e72, + 0x9649, 0x0e58, + 0x966a, 0x1e73, + 0x966b, 0x0e7a, + 0x9680, 0x0e8e, + 0x968a, 0x1d33, + 0x968b, 0x0e99, + 0x9690, 0x1e74, + 0x9691, 0x0e9f, + 0x9698, 0x1f2c, + 0x9699, 0x102f, + 0x969a, 0x0ea8, + 0x96cb, 0x1e75, + 0x96cc, 0x0eda, + 0x96d7, 0x1e76, + 0x96d8, 0x0ee6, + 0x96dd, 0x1e77, + 0x96de, 0x0eec, + 0x96e0, 0x1e78, + 0x96e1, 0x0eef, + 0x96f7, 0x1935, + 0x96f8, 0x1e79, + 0x96f9, 0x0f07, + 0x96fa, 0x1e7a, + 0x96fb, 0x0f09, + 0x96fc, 0x1e7b, + 0x9740, 0x0f0b, + 0x9751, 0x1e7c, + 0x9752, 0x0f1d, + 0x976f, 0x1e7d, + 0x9770, 0x0f3b, + 0x9773, 0x1e7e, + 0x9774, 0x0f3f, + 0x9779, 0x1d34, + 0x977a, 0x0f45, + 0x9780, 0x0f4a, + 0x9789, 0x1e7f, + 0x978a, 0x0f54, + 0x97c9, 0x1e80, + 0x97ca, 0x0f94, + 0x97f8, 0x1e81, + 0x97fa, 0x0fc4, + 0x9840, 0x1e83, + 0x9841, 0x0fc8, + 0x9850, 0x1e84, + 0x9851, 0x0fd8, + 0x9855, 0x1777, + 0x9856, 0x0fdd, + 0x9858, 0x1e85, + 0x9859, 0x0fe0, + 0x989f, 0x0ffa, + 0x98d4, 0x0ea7, + 0x98d5, 0x1030, + 0x9940, 0x1058, + 0x995c, 0x1e86, + 0x995d, 0x1075, + 0x9966, 0x1e87, + 0x9967, 0x107f, + 0x996a, 0x1e88, + 0x996b, 0x1083, + 0x996c, 0x1e89, + 0x996d, 0x1085, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a4f, 0x1e8a, + 0x9a50, 0x1124, + 0x9a59, 0x1e8b, + 0x9a5a, 0x112e, + 0x9a7d, 0x1e8d, + 0x9a7e, 0x1152, + 0x9a80, 0x1153, + 0x9a8b, 0x1e8e, + 0x9a8c, 0x115f, + 0x9ac2, 0x1e8f, + 0x9ac3, 0x1196, + 0x9ae2, 0x0bf7, + 0x9ae3, 0x11b6, + 0x9b40, 0x11d0, + 0x9b5c, 0x1e90, + 0x9b5d, 0x11ed, + 0x9b80, 0x120f, + 0x9b83, 0x1e91, + 0x9b84, 0x1213, + 0x9ba0, 0x1e92, + 0x9ba1, 0x1230, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9ca2, 0x1e94, + 0x9ca3, 0x12ee, + 0x9d40, 0x1348, + 0x9d80, 0x1e95, + 0x9d81, 0x1388, + 0x9d8c, 0x1e96, + 0x9d8d, 0x1394, + 0x9d98, 0x05a7, + 0x9d99, 0x13a0, + 0x9db7, 0x1e97, + 0x9db8, 0x13bf, + 0x9dcb, 0x1e98, + 0x9dcc, 0x13d3, + 0x9e40, 0x1404, + 0x9e64, 0x1e99, + 0x9e65, 0x1429, + 0x9e69, 0x1e9a, + 0x9e6a, 0x142e, + 0x9e77, 0x0da2, + 0x9e78, 0x143c, + 0x9e80, 0x1443, + 0x9e8b, 0x1e9b, + 0x9e8c, 0x144f, + 0x9e8d, 0x0c68, + 0x9e8e, 0x1451, + 0x9e94, 0x1e9c, + 0x9e95, 0x1458, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0x9fb7, 0x0c6d, + 0x9fb8, 0x1537, + 0x9fce, 0x1e9d, + 0x9fcf, 0x154e, + 0x9ff3, 0x05ff, + 0x9ff4, 0x1573, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe0a4, 0x1e9f, + 0xe0a5, 0x15e0, + 0xe0dd, 0x1ea0, + 0xe0de, 0x1619, + 0xe0f4, 0x1d35, + 0xe0f5, 0x1630, + 0xe140, 0x1638, + 0xe14a, 0x1ea1, + 0xe14b, 0x1643, + 0xe14f, 0x1ea2, + 0xe151, 0x1649, + 0xe180, 0x1677, + 0xe1a9, 0x1ea4, + 0xe1aa, 0x16a1, + 0xe1e6, 0x07ee, + 0xe1e7, 0x16de, + 0xe1e8, 0x0c51, + 0xe1e9, 0x16e0, + 0xe1ed, 0x1ea5, + 0xe1ee, 0x16e5, + 0xe240, 0x16f4, + 0xe269, 0x1ea6, + 0xe26a, 0x171e, + 0xe273, 0x1ea7, + 0xe274, 0x1728, + 0xe27d, 0x05d4, + 0xe27e, 0x1732, + 0xe280, 0x1733, + 0xe2b7, 0x1ea8, + 0xe2b8, 0x176b, + 0xe2c4, 0x0fdc, + 0xe2c5, 0x1778, + 0xe2e2, 0x1ea9, + 0xe2e3, 0x1796, + 0xe2ec, 0x1eaa, + 0xe2ed, 0x17a0, + 0xe340, 0x17b0, + 0xe358, 0x1eab, + 0xe359, 0x17c9, + 0xe35a, 0x1eac, + 0xe35b, 0x17cb, + 0xe365, 0x1ead, + 0xe366, 0x17d6, + 0xe380, 0x17ef, + 0xe3c4, 0x1eae, + 0xe3c5, 0x1834, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe484, 0x1eaf, + 0xe485, 0x18b0, + 0xe489, 0x1eb0, + 0xe48a, 0x18b5, + 0xe492, 0x1eb1, + 0xe493, 0x18be, + 0xe4b2, 0x1eb2, + 0xe4b3, 0x18de, + 0xe4b9, 0x1eb3, + 0xe4ba, 0x18e5, + 0xe4f2, 0x1eb4, + 0xe4f3, 0x191e, + 0xe540, 0x1928, + 0xe541, 0x08f5, + 0xe542, 0x192a, + 0xe54d, 0x0f05, + 0xe54e, 0x1936, + 0xe579, 0x05a0, + 0xe57a, 0x1962, + 0xe580, 0x1967, + 0xe5a2, 0x0d1e, + 0xe5a3, 0x198a, + 0xe5a5, 0x1eb6, + 0xe5a6, 0x198d, + 0xe5bb, 0x1eb7, + 0xe5bc, 0x19a3, + 0xe5ed, 0x1eb8, + 0xe5ee, 0x19d5, + 0xe640, 0x19e4, + 0xe651, 0x1eb9, + 0xe652, 0x19f6, + 0xe67c, 0x060e, + 0xe67d, 0x1a21, + 0xe680, 0x1a23, + 0xe686, 0x1eba, + 0xe687, 0x1a2a, + 0xe696, 0x1ebb, + 0xe697, 0x1a3a, + 0xe6cb, 0x0aaa, + 0xe6cc, 0x1a6f, + 0xe6e7, 0x1ebc, + 0xe6e8, 0x1a8b, + 0xe6f2, 0x1ebd, + 0xe6f3, 0x1a96, + 0xe740, 0x1aa0, + 0xe76d, 0x1ebe, + 0xe76e, 0x1ace, + 0xe780, 0x1adf, + 0xe78c, 0x1ebf, + 0xe78d, 0x1aec, + 0xe78e, 0x1ec0, + 0xe78f, 0x1aee, + 0xe7a7, 0x1ec1, + 0xe7a8, 0x1b07, + 0xe7bb, 0x1ec2, + 0xe7bc, 0x1b1b, + 0xe7d5, 0x1ec3, + 0xe7d6, 0x1b35, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe8c3, 0x1ec6, + 0xe8c4, 0x1bdf, + 0xe8cf, 0x1ec7, + 0xe8d0, 0x1beb, + 0xe8d5, 0x1ec8, + 0xe8d6, 0x1bf1, + 0xe8f2, 0x0731, + 0xe8f3, 0x1ec9, + 0xe8f4, 0x1c0f, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xe9ab, 0x1eca, + 0xe9ac, 0x1c83, + 0xe9ba, 0x1ecb, + 0xe9bb, 0x1c92, + 0xe9cb, 0x0477, + 0xe9cc, 0x1ecc, + 0xe9cd, 0x1ca4, + 0xe9f2, 0x0529, + 0xe9f3, 0x1cca, + 0xea40, 0x1cd4, + 0xea70, 0x1ecd, + 0xea71, 0x1d05, + 0xea80, 0x1d13, + 0xea9d, 0x1ece, + 0xea9e, 0x1d31, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1278RKSJHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1278RKSJHMap2, 626 +}; + +static Gushort japan1278RKSJVMap2[1306] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x889f, 0x0465, + 0x88a0, 0x1dd1, + 0x88a1, 0x0467, + 0x88a7, 0x204a, + 0x88a8, 0x046e, + 0x88b0, 0x1f19, + 0x88b1, 0x1ca2, + 0x88b2, 0x0478, + 0x88b9, 0x1dd2, + 0x88ba, 0x0480, + 0x88ec, 0x1dd3, + 0x88ed, 0x04b3, + 0x88f1, 0x1dd4, + 0x88f2, 0x04b8, + 0x88fa, 0x1dd5, + 0x88fb, 0x04c1, + 0x8940, 0x04c3, + 0x8949, 0x1dd6, + 0x894a, 0x04cd, + 0x8954, 0x1dd7, + 0x8955, 0x04d8, + 0x8958, 0x1dd8, + 0x8959, 0x04dc, + 0x895c, 0x1dda, + 0x895d, 0x04e0, + 0x8961, 0x1ddb, + 0x8962, 0x04e5, + 0x8980, 0x0502, + 0x898b, 0x1ddc, + 0x898c, 0x050e, + 0x89a6, 0x1ddd, + 0x89a7, 0x1cc9, + 0x89a8, 0x1dde, + 0x89a9, 0x052b, + 0x89de, 0x1ddf, + 0x89df, 0x0561, + 0x89f8, 0x1de0, + 0x89f9, 0x057b, + 0x89fb, 0x1de1, + 0x89fc, 0x057e, + 0x8a40, 0x057f, + 0x8a41, 0x1de2, + 0x8a42, 0x0581, + 0x8a61, 0x1961, + 0x8a62, 0x05a1, + 0x8a68, 0x139f, + 0x8a69, 0x05a8, + 0x8a80, 0x05be, + 0x8a85, 0x1de3, + 0x8a86, 0x05c4, + 0x8a8b, 0x1de4, + 0x8a8c, 0x05ca, + 0x8a93, 0x1de5, + 0x8a94, 0x05d2, + 0x8a96, 0x1731, + 0x8a97, 0x05d5, + 0x8a9a, 0x1de6, + 0x8a9b, 0x05d9, + 0x8ac0, 0x1de7, + 0x8ac1, 0x1572, + 0x8ac2, 0x0600, + 0x8acb, 0x1de8, + 0x8acc, 0x060a, + 0x8ad0, 0x1a20, + 0x8ad1, 0x060f, + 0x8ae3, 0x1de9, + 0x8ae4, 0x0622, + 0x8b40, 0x063b, + 0x8b4a, 0x1dea, + 0x8b4b, 0x0646, + 0x8b5f, 0x1deb, + 0x8b60, 0x065b, + 0x8b80, 0x067a, + 0x8ba0, 0x1dec, + 0x8ba1, 0x069b, + 0x8ba8, 0x1ded, + 0x8ba9, 0x06a3, + 0x8bc4, 0x1d32, + 0x8bc5, 0x06bf, + 0x8bcd, 0x1dee, + 0x8bce, 0x06c8, + 0x8beb, 0x1def, + 0x8bec, 0x06e6, + 0x8bf2, 0x1df0, + 0x8bf3, 0x06ed, + 0x8bf9, 0x1df1, + 0x8bfa, 0x06f4, + 0x8bfb, 0x1df2, + 0x8bfc, 0x06f6, + 0x8c40, 0x06f7, + 0x8c43, 0x1df3, + 0x8c44, 0x06fb, + 0x8c56, 0x1df4, + 0x8c57, 0x070e, + 0x8c64, 0x1df5, + 0x8c65, 0x071c, + 0x8c6d, 0x1df6, + 0x8c6e, 0x0725, + 0x8c71, 0x1df7, + 0x8c72, 0x0729, + 0x8c74, 0x1df8, + 0x8c75, 0x072c, + 0x8c7a, 0x1c0d, + 0x8c7b, 0x0732, + 0x8c80, 0x0736, + 0x8c84, 0x1df9, + 0x8c85, 0x073b, + 0x8c91, 0x1dfa, + 0x8c92, 0x0748, + 0x8c99, 0x1dfb, + 0x8c9a, 0x0750, + 0x8c9e, 0x1dfc, + 0x8c9f, 0x0755, + 0x8cb2, 0x1dfd, + 0x8cb3, 0x0769, + 0x8cbf, 0x1dfe, + 0x8cc0, 0x0776, + 0x8d40, 0x07b3, + 0x8d4a, 0x1dff, + 0x8d4b, 0x07be, + 0x8d56, 0x1e00, + 0x8d57, 0x07ca, + 0x8d61, 0x1e01, + 0x8d62, 0x07d5, + 0x8d7b, 0x16dd, + 0x8d7c, 0x07ef, + 0x8d80, 0x07f2, + 0x8d8d, 0x1e02, + 0x8d8e, 0x0800, + 0x8d94, 0x1e03, + 0x8d95, 0x0807, + 0x8d99, 0x1e04, + 0x8d9a, 0x080c, + 0x8dd1, 0x1e05, + 0x8dd2, 0x0844, + 0x8de5, 0x1e06, + 0x8de6, 0x0858, + 0x8df2, 0x1e07, + 0x8df3, 0x0865, + 0x8e40, 0x086f, + 0x8e46, 0x1e08, + 0x8e47, 0x0876, + 0x8e49, 0x1e09, + 0x8e4a, 0x0879, + 0x8e4b, 0x1e0a, + 0x8e4c, 0x087b, + 0x8e58, 0x1e0b, + 0x8e59, 0x0888, + 0x8e80, 0x08ae, + 0x8ec6, 0x1e0d, + 0x8ec7, 0x1929, + 0x8ec8, 0x08f6, + 0x8ed5, 0x1e0e, + 0x8ed6, 0x0904, + 0x8edb, 0x1e0f, + 0x8edd, 0x090b, + 0x8f40, 0x092b, + 0x8f4a, 0x1e11, + 0x8f4b, 0x0936, + 0x8f55, 0x1e12, + 0x8f56, 0x0941, + 0x8f80, 0x096a, + 0x8f8c, 0x1e13, + 0x8f8e, 0x0978, + 0x8f92, 0x1e15, + 0x8f94, 0x097e, + 0x8fa3, 0x1e17, + 0x8fa4, 0x098e, + 0x8fb1, 0x1e18, + 0x8fb2, 0x099c, + 0x8fbd, 0x1e19, + 0x8fbe, 0x09a8, + 0x8fd3, 0x1e1a, + 0x8fd4, 0x09be, + 0x8fdd, 0x1e1b, + 0x8fde, 0x09c8, + 0x8fe2, 0x1e1c, + 0x8fe3, 0x09cd, + 0x9040, 0x09e7, + 0x9049, 0x1e1d, + 0x904a, 0x09f1, + 0x9078, 0x1e1e, + 0x9079, 0x0a20, + 0x9080, 0x1e1f, + 0x9081, 0x0a27, + 0x9089, 0x1e20, + 0x908a, 0x0a30, + 0x90a0, 0x1e21, + 0x90a1, 0x0a47, + 0x90c0, 0x1e22, + 0x90c1, 0x0a67, + 0x90e4, 0x1e23, + 0x90e5, 0x0a8b, + 0x90ef, 0x1e24, + 0x90f1, 0x0a97, + 0x90f7, 0x1e26, + 0x90f9, 0x0a9f, + 0x9140, 0x0aa3, + 0x9146, 0x1e28, + 0x9147, 0x1a6e, + 0x9148, 0x0aab, + 0x9158, 0x1e29, + 0x9159, 0x0abc, + 0x916b, 0x1e2a, + 0x916c, 0x0acf, + 0x916e, 0x1e2b, + 0x916f, 0x0ad2, + 0x917e, 0x1e2c, + 0x9180, 0x0ae2, + 0x9189, 0x1e2d, + 0x918a, 0x0aec, + 0x91bb, 0x1e2e, + 0x91bc, 0x0b1e, + 0x91cb, 0x1e2f, + 0x91cc, 0x0b2e, + 0x91da, 0x1e30, + 0x91db, 0x0b3d, + 0x91e1, 0x1e31, + 0x91e2, 0x0b44, + 0x91ed, 0x1e32, + 0x91ee, 0x0b50, + 0x91f3, 0x1e33, + 0x91f5, 0x0b57, + 0x91fb, 0x1e35, + 0x91fc, 0x0b5e, + 0x9240, 0x0b5f, + 0x9246, 0x1e36, + 0x9247, 0x0b66, + 0x9248, 0x1e37, + 0x924a, 0x0b69, + 0x924c, 0x1e39, + 0x924e, 0x0b6d, + 0x925c, 0x1e3b, + 0x925d, 0x0b7c, + 0x9280, 0x0b9e, + 0x9290, 0x1e3c, + 0x9291, 0x0baf, + 0x9295, 0x1e3d, + 0x9296, 0x0bb4, + 0x929c, 0x1e3e, + 0x929d, 0x0bbb, + 0x92bb, 0x1e3f, + 0x92bc, 0x0bda, + 0x92c6, 0x1e40, + 0x92c7, 0x0be5, + 0x92c8, 0x1e41, + 0x92c9, 0x0be7, + 0x92cb, 0x1e42, + 0x92cc, 0x0bea, + 0x92cd, 0x1e43, + 0x92ce, 0x0bec, + 0x92d2, 0x204b, + 0x92d3, 0x0bf1, + 0x92d9, 0x11b5, + 0x92da, 0x0bf8, + 0x9340, 0x0c1b, + 0x9341, 0x1e44, + 0x9342, 0x0c1d, + 0x9346, 0x1e45, + 0x9347, 0x0c22, + 0x934d, 0x1e46, + 0x934e, 0x0c29, + 0x9355, 0x1e47, + 0x9356, 0x0c31, + 0x935e, 0x1e48, + 0x935f, 0x0c3a, + 0x9367, 0x1e49, + 0x9368, 0x0c43, + 0x936a, 0x1e4a, + 0x936b, 0x0c46, + 0x9370, 0x1e4b, + 0x9372, 0x0c4d, + 0x9376, 0x16df, + 0x9377, 0x0c52, + 0x9380, 0x0c5a, + 0x9384, 0x1e4d, + 0x9385, 0x0c5f, + 0x938e, 0x1450, + 0x938f, 0x0c69, + 0x9393, 0x1536, + 0x9394, 0x0c6e, + 0x9398, 0x1e4e, + 0x9399, 0x0c73, + 0x93bc, 0x1e4f, + 0x93bd, 0x0c97, + 0x93c0, 0x1e50, + 0x93c1, 0x0c9b, + 0x93d2, 0x1e51, + 0x93d4, 0x0cae, + 0x93d9, 0x1e53, + 0x93db, 0x0cb5, + 0x93df, 0x1e55, + 0x93e0, 0x0cba, + 0x93e4, 0x1e56, + 0x93e6, 0x0cc0, + 0x93e8, 0x1e58, + 0x93e9, 0x0cc3, + 0x93f4, 0x1aed, + 0x93f5, 0x0ccf, + 0x9440, 0x0cd7, + 0x9448, 0x1e59, + 0x9449, 0x0ce0, + 0x9458, 0x1e5a, + 0x9459, 0x0cf0, + 0x9476, 0x1e5b, + 0x9477, 0x0d0e, + 0x9480, 0x0d16, + 0x9487, 0x1e5c, + 0x9488, 0x1989, + 0x9489, 0x1e5d, + 0x948a, 0x0d20, + 0x948d, 0x1e5e, + 0x948e, 0x0d24, + 0x94a2, 0x1e5f, + 0x94a3, 0x0d39, + 0x94ac, 0x1e60, + 0x94ad, 0x0d43, + 0x94ae, 0x1e61, + 0x94af, 0x0d45, + 0x94d2, 0x1e62, + 0x94d3, 0x0d69, + 0x94e0, 0x1e63, + 0x94e1, 0x0d77, + 0x94f3, 0x1e64, + 0x94f4, 0x0d8a, + 0x9540, 0x0d93, + 0x9541, 0x1e65, + 0x9543, 0x0d96, + 0x954e, 0x1e67, + 0x954f, 0x143b, + 0x9550, 0x0da3, + 0x9551, 0x1e68, + 0x9552, 0x0da5, + 0x9554, 0x1e69, + 0x9555, 0x0da8, + 0x955f, 0x1e6a, + 0x9560, 0x0db3, + 0x956d, 0x1e6b, + 0x956e, 0x0dc1, + 0x9570, 0x1e6c, + 0x9571, 0x0dc4, + 0x9580, 0x0dd2, + 0x95c1, 0x1e6d, + 0x95c2, 0x0e14, + 0x95cb, 0x1e6e, + 0x95cc, 0x0e1e, + 0x95d8, 0x1e6f, + 0x95d9, 0x0e2b, + 0x95f7, 0x1e70, + 0x95f8, 0x0e4a, + 0x9640, 0x0e4f, + 0x9641, 0x1e71, + 0x9642, 0x0e51, + 0x9648, 0x1e72, + 0x9649, 0x0e58, + 0x966a, 0x1e73, + 0x966b, 0x0e7a, + 0x9680, 0x0e8e, + 0x968a, 0x1d33, + 0x968b, 0x0e99, + 0x9690, 0x1e74, + 0x9691, 0x0e9f, + 0x9698, 0x1f2c, + 0x9699, 0x102f, + 0x969a, 0x0ea8, + 0x96cb, 0x1e75, + 0x96cc, 0x0eda, + 0x96d7, 0x1e76, + 0x96d8, 0x0ee6, + 0x96dd, 0x1e77, + 0x96de, 0x0eec, + 0x96e0, 0x1e78, + 0x96e1, 0x0eef, + 0x96f7, 0x1935, + 0x96f8, 0x1e79, + 0x96f9, 0x0f07, + 0x96fa, 0x1e7a, + 0x96fb, 0x0f09, + 0x96fc, 0x1e7b, + 0x9740, 0x0f0b, + 0x9751, 0x1e7c, + 0x9752, 0x0f1d, + 0x976f, 0x1e7d, + 0x9770, 0x0f3b, + 0x9773, 0x1e7e, + 0x9774, 0x0f3f, + 0x9779, 0x1d34, + 0x977a, 0x0f45, + 0x9780, 0x0f4a, + 0x9789, 0x1e7f, + 0x978a, 0x0f54, + 0x97c9, 0x1e80, + 0x97ca, 0x0f94, + 0x97f8, 0x1e81, + 0x97fa, 0x0fc4, + 0x9840, 0x1e83, + 0x9841, 0x0fc8, + 0x9850, 0x1e84, + 0x9851, 0x0fd8, + 0x9855, 0x1777, + 0x9856, 0x0fdd, + 0x9858, 0x1e85, + 0x9859, 0x0fe0, + 0x989f, 0x0ffa, + 0x98d4, 0x0ea7, + 0x98d5, 0x1030, + 0x9940, 0x1058, + 0x995c, 0x1e86, + 0x995d, 0x1075, + 0x9966, 0x1e87, + 0x9967, 0x107f, + 0x996a, 0x1e88, + 0x996b, 0x1083, + 0x996c, 0x1e89, + 0x996d, 0x1085, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a4f, 0x1e8a, + 0x9a50, 0x1124, + 0x9a59, 0x1e8b, + 0x9a5a, 0x112e, + 0x9a7d, 0x1e8d, + 0x9a7e, 0x1152, + 0x9a80, 0x1153, + 0x9a8b, 0x1e8e, + 0x9a8c, 0x115f, + 0x9ac2, 0x1e8f, + 0x9ac3, 0x1196, + 0x9ae2, 0x0bf7, + 0x9ae3, 0x11b6, + 0x9b40, 0x11d0, + 0x9b5c, 0x1e90, + 0x9b5d, 0x11ed, + 0x9b80, 0x120f, + 0x9b83, 0x1e91, + 0x9b84, 0x1213, + 0x9ba0, 0x1e92, + 0x9ba1, 0x1230, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9ca2, 0x1e94, + 0x9ca3, 0x12ee, + 0x9d40, 0x1348, + 0x9d80, 0x1e95, + 0x9d81, 0x1388, + 0x9d8c, 0x1e96, + 0x9d8d, 0x1394, + 0x9d98, 0x05a7, + 0x9d99, 0x13a0, + 0x9db7, 0x1e97, + 0x9db8, 0x13bf, + 0x9dcb, 0x1e98, + 0x9dcc, 0x13d3, + 0x9e40, 0x1404, + 0x9e64, 0x1e99, + 0x9e65, 0x1429, + 0x9e69, 0x1e9a, + 0x9e6a, 0x142e, + 0x9e77, 0x0da2, + 0x9e78, 0x143c, + 0x9e80, 0x1443, + 0x9e8b, 0x1e9b, + 0x9e8c, 0x144f, + 0x9e8d, 0x0c68, + 0x9e8e, 0x1451, + 0x9e94, 0x1e9c, + 0x9e95, 0x1458, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0x9fb7, 0x0c6d, + 0x9fb8, 0x1537, + 0x9fce, 0x1e9d, + 0x9fcf, 0x154e, + 0x9ff3, 0x05ff, + 0x9ff4, 0x1573, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe0a4, 0x1e9f, + 0xe0a5, 0x15e0, + 0xe0dd, 0x1ea0, + 0xe0de, 0x1619, + 0xe0f4, 0x1d35, + 0xe0f5, 0x1630, + 0xe140, 0x1638, + 0xe14a, 0x1ea1, + 0xe14b, 0x1643, + 0xe14f, 0x1ea2, + 0xe151, 0x1649, + 0xe180, 0x1677, + 0xe1a9, 0x1ea4, + 0xe1aa, 0x16a1, + 0xe1e6, 0x07ee, + 0xe1e7, 0x16de, + 0xe1e8, 0x0c51, + 0xe1e9, 0x16e0, + 0xe1ed, 0x1ea5, + 0xe1ee, 0x16e5, + 0xe240, 0x16f4, + 0xe269, 0x1ea6, + 0xe26a, 0x171e, + 0xe273, 0x1ea7, + 0xe274, 0x1728, + 0xe27d, 0x05d4, + 0xe27e, 0x1732, + 0xe280, 0x1733, + 0xe2b7, 0x1ea8, + 0xe2b8, 0x176b, + 0xe2c4, 0x0fdc, + 0xe2c5, 0x1778, + 0xe2e2, 0x1ea9, + 0xe2e3, 0x1796, + 0xe2ec, 0x1eaa, + 0xe2ed, 0x17a0, + 0xe340, 0x17b0, + 0xe358, 0x1eab, + 0xe359, 0x17c9, + 0xe35a, 0x1eac, + 0xe35b, 0x17cb, + 0xe365, 0x1ead, + 0xe366, 0x17d6, + 0xe380, 0x17ef, + 0xe3c4, 0x1eae, + 0xe3c5, 0x1834, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe484, 0x1eaf, + 0xe485, 0x18b0, + 0xe489, 0x1eb0, + 0xe48a, 0x18b5, + 0xe492, 0x1eb1, + 0xe493, 0x18be, + 0xe4b2, 0x1eb2, + 0xe4b3, 0x18de, + 0xe4b9, 0x1eb3, + 0xe4ba, 0x18e5, + 0xe4f2, 0x1eb4, + 0xe4f3, 0x191e, + 0xe540, 0x1928, + 0xe541, 0x08f5, + 0xe542, 0x192a, + 0xe54d, 0x0f05, + 0xe54e, 0x1936, + 0xe579, 0x05a0, + 0xe57a, 0x1962, + 0xe580, 0x1967, + 0xe5a2, 0x0d1e, + 0xe5a3, 0x198a, + 0xe5a5, 0x1eb6, + 0xe5a6, 0x198d, + 0xe5bb, 0x1eb7, + 0xe5bc, 0x19a3, + 0xe5ed, 0x1eb8, + 0xe5ee, 0x19d5, + 0xe640, 0x19e4, + 0xe651, 0x1eb9, + 0xe652, 0x19f6, + 0xe67c, 0x060e, + 0xe67d, 0x1a21, + 0xe680, 0x1a23, + 0xe686, 0x1eba, + 0xe687, 0x1a2a, + 0xe696, 0x1ebb, + 0xe697, 0x1a3a, + 0xe6cb, 0x0aaa, + 0xe6cc, 0x1a6f, + 0xe6e7, 0x1ebc, + 0xe6e8, 0x1a8b, + 0xe6f2, 0x1ebd, + 0xe6f3, 0x1a96, + 0xe740, 0x1aa0, + 0xe76d, 0x1ebe, + 0xe76e, 0x1ace, + 0xe780, 0x1adf, + 0xe78c, 0x1ebf, + 0xe78d, 0x1aec, + 0xe78e, 0x1ec0, + 0xe78f, 0x1aee, + 0xe7a7, 0x1ec1, + 0xe7a8, 0x1b07, + 0xe7bb, 0x1ec2, + 0xe7bc, 0x1b1b, + 0xe7d5, 0x1ec3, + 0xe7d6, 0x1b35, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe8c3, 0x1ec6, + 0xe8c4, 0x1bdf, + 0xe8cf, 0x1ec7, + 0xe8d0, 0x1beb, + 0xe8d5, 0x1ec8, + 0xe8d6, 0x1bf1, + 0xe8f2, 0x0731, + 0xe8f3, 0x1ec9, + 0xe8f4, 0x1c0f, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xe9ab, 0x1eca, + 0xe9ac, 0x1c83, + 0xe9ba, 0x1ecb, + 0xe9bb, 0x1c92, + 0xe9cb, 0x0477, + 0xe9cc, 0x1ecc, + 0xe9cd, 0x1ca4, + 0xe9f2, 0x0529, + 0xe9f3, 0x1cca, + 0xea40, 0x1cd4, + 0xea70, 0x1ecd, + 0xea71, 0x1d05, + 0xea80, 0x1d13, + 0xea9d, 0x1ece, + 0xea9e, 0x1d31, + 0x8141, 0x1ecf, + 0x8150, 0x1ed1, + 0x815b, 0x1ed3, + 0x8160, 0x1ed6, + 0x8169, 0x1edb, + 0x8181, 0x1eed, + 0x829f, 0x1eee, + 0x82a1, 0x1eef, + 0x82a3, 0x1ef0, + 0x82a5, 0x1ef1, + 0x82a7, 0x1ef2, + 0x82c1, 0x1ef3, + 0x82e1, 0x1ef4, + 0x82e3, 0x1ef5, + 0x82e5, 0x1ef6, + 0x82ec, 0x1ef7, + 0x8340, 0x1ef8, + 0x8342, 0x1ef9, + 0x8344, 0x1efa, + 0x8346, 0x1efb, + 0x8348, 0x1efc, + 0x8362, 0x1efd, + 0x8383, 0x1efe, + 0x8385, 0x1eff, + 0x8387, 0x1f00, + 0x838e, 0x1f01, + 0x8395, 0x1f02, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1278RKSJVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1278RKSJVMap2, 653 +}; + +static Gushort japan1278VMap2[1304] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2221, 0x02d7, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x3021, 0x0465, + 0x3022, 0x1dd1, + 0x3023, 0x0467, + 0x3029, 0x204a, + 0x302a, 0x046e, + 0x3032, 0x1f19, + 0x3033, 0x1ca2, + 0x3034, 0x0478, + 0x303b, 0x1dd2, + 0x303c, 0x0480, + 0x306e, 0x1dd3, + 0x306f, 0x04b3, + 0x3073, 0x1dd4, + 0x3074, 0x04b8, + 0x307c, 0x1dd5, + 0x307d, 0x04c1, + 0x3121, 0x04c3, + 0x312a, 0x1dd6, + 0x312b, 0x04cd, + 0x3135, 0x1dd7, + 0x3136, 0x04d8, + 0x3139, 0x1dd8, + 0x313a, 0x04dc, + 0x313d, 0x1dda, + 0x313e, 0x04e0, + 0x3142, 0x1ddb, + 0x3143, 0x04e5, + 0x316b, 0x1ddc, + 0x316c, 0x050e, + 0x3221, 0x0521, + 0x3228, 0x1ddd, + 0x3229, 0x1cc9, + 0x322a, 0x1dde, + 0x322b, 0x052b, + 0x3260, 0x1ddf, + 0x3261, 0x0561, + 0x327a, 0x1de0, + 0x327b, 0x057b, + 0x327d, 0x1de1, + 0x327e, 0x057e, + 0x3321, 0x057f, + 0x3322, 0x1de2, + 0x3323, 0x0581, + 0x3342, 0x1961, + 0x3343, 0x05a1, + 0x3349, 0x139f, + 0x334a, 0x05a8, + 0x3365, 0x1de3, + 0x3366, 0x05c4, + 0x336b, 0x1de4, + 0x336c, 0x05ca, + 0x3373, 0x1de5, + 0x3374, 0x05d2, + 0x3376, 0x1731, + 0x3377, 0x05d5, + 0x337a, 0x1de6, + 0x337b, 0x05d9, + 0x3421, 0x05dd, + 0x3442, 0x1de7, + 0x3443, 0x1572, + 0x3444, 0x0600, + 0x344d, 0x1de8, + 0x344e, 0x060a, + 0x3452, 0x1a20, + 0x3453, 0x060f, + 0x3465, 0x1de9, + 0x3466, 0x0622, + 0x3521, 0x063b, + 0x352b, 0x1dea, + 0x352c, 0x0646, + 0x3540, 0x1deb, + 0x3541, 0x065b, + 0x3621, 0x0699, + 0x3622, 0x1dec, + 0x3623, 0x069b, + 0x362a, 0x1ded, + 0x362b, 0x06a3, + 0x3646, 0x1d32, + 0x3647, 0x06bf, + 0x364f, 0x1dee, + 0x3650, 0x06c8, + 0x366d, 0x1def, + 0x366e, 0x06e6, + 0x3674, 0x1df0, + 0x3675, 0x06ed, + 0x367b, 0x1df1, + 0x367c, 0x06f4, + 0x367d, 0x1df2, + 0x367e, 0x06f6, + 0x3721, 0x06f7, + 0x3724, 0x1df3, + 0x3725, 0x06fb, + 0x3737, 0x1df4, + 0x3738, 0x070e, + 0x3745, 0x1df5, + 0x3746, 0x071c, + 0x374e, 0x1df6, + 0x374f, 0x0725, + 0x3752, 0x1df7, + 0x3753, 0x0729, + 0x3755, 0x1df8, + 0x3756, 0x072c, + 0x375b, 0x1c0d, + 0x375c, 0x0732, + 0x3764, 0x1df9, + 0x3765, 0x073b, + 0x3771, 0x1dfa, + 0x3772, 0x0748, + 0x3779, 0x1dfb, + 0x377a, 0x0750, + 0x377e, 0x1dfc, + 0x3821, 0x0755, + 0x3834, 0x1dfd, + 0x3835, 0x0769, + 0x3841, 0x1dfe, + 0x3842, 0x0776, + 0x3921, 0x07b3, + 0x392b, 0x1dff, + 0x392c, 0x07be, + 0x3937, 0x1e00, + 0x3938, 0x07ca, + 0x3942, 0x1e01, + 0x3943, 0x07d5, + 0x395c, 0x16dd, + 0x395d, 0x07ef, + 0x396d, 0x1e02, + 0x396e, 0x0800, + 0x3974, 0x1e03, + 0x3975, 0x0807, + 0x3979, 0x1e04, + 0x397a, 0x080c, + 0x3a21, 0x0811, + 0x3a53, 0x1e05, + 0x3a54, 0x0844, + 0x3a67, 0x1e06, + 0x3a68, 0x0858, + 0x3a74, 0x1e07, + 0x3a75, 0x0865, + 0x3b21, 0x086f, + 0x3b27, 0x1e08, + 0x3b28, 0x0876, + 0x3b2a, 0x1e09, + 0x3b2b, 0x0879, + 0x3b2c, 0x1e0a, + 0x3b2d, 0x087b, + 0x3b39, 0x1e0b, + 0x3b3a, 0x0888, + 0x3c21, 0x08cd, + 0x3c48, 0x1e0d, + 0x3c49, 0x1929, + 0x3c4a, 0x08f6, + 0x3c57, 0x1e0e, + 0x3c58, 0x0904, + 0x3c5d, 0x1e0f, + 0x3c5f, 0x090b, + 0x3d21, 0x092b, + 0x3d2b, 0x1e11, + 0x3d2c, 0x0936, + 0x3d36, 0x1e12, + 0x3d37, 0x0941, + 0x3d6c, 0x1e13, + 0x3d6e, 0x0978, + 0x3d72, 0x1e15, + 0x3d74, 0x097e, + 0x3e21, 0x0989, + 0x3e25, 0x1e17, + 0x3e26, 0x098e, + 0x3e33, 0x1e18, + 0x3e34, 0x099c, + 0x3e3f, 0x1e19, + 0x3e40, 0x09a8, + 0x3e55, 0x1e1a, + 0x3e56, 0x09be, + 0x3e5f, 0x1e1b, + 0x3e60, 0x09c8, + 0x3e64, 0x1e1c, + 0x3e65, 0x09cd, + 0x3f21, 0x09e7, + 0x3f2a, 0x1e1d, + 0x3f2b, 0x09f1, + 0x3f59, 0x1e1e, + 0x3f5a, 0x0a20, + 0x3f60, 0x1e1f, + 0x3f61, 0x0a27, + 0x3f69, 0x1e20, + 0x3f6a, 0x0a30, + 0x4021, 0x0a45, + 0x4022, 0x1e21, + 0x4023, 0x0a47, + 0x4042, 0x1e22, + 0x4043, 0x0a67, + 0x4066, 0x1e23, + 0x4067, 0x0a8b, + 0x4071, 0x1e24, + 0x4073, 0x0a97, + 0x4079, 0x1e26, + 0x407b, 0x0a9f, + 0x4121, 0x0aa3, + 0x4127, 0x1e28, + 0x4128, 0x1a6e, + 0x4129, 0x0aab, + 0x4139, 0x1e29, + 0x413a, 0x0abc, + 0x414c, 0x1e2a, + 0x414d, 0x0acf, + 0x414f, 0x1e2b, + 0x4150, 0x0ad2, + 0x415f, 0x1e2c, + 0x4160, 0x0ae2, + 0x4169, 0x1e2d, + 0x416a, 0x0aec, + 0x4221, 0x0b01, + 0x423d, 0x1e2e, + 0x423e, 0x0b1e, + 0x424d, 0x1e2f, + 0x424e, 0x0b2e, + 0x425c, 0x1e30, + 0x425d, 0x0b3d, + 0x4263, 0x1e31, + 0x4264, 0x0b44, + 0x426f, 0x1e32, + 0x4270, 0x0b50, + 0x4275, 0x1e33, + 0x4277, 0x0b57, + 0x427d, 0x1e35, + 0x427e, 0x0b5e, + 0x4321, 0x0b5f, + 0x4327, 0x1e36, + 0x4328, 0x0b66, + 0x4329, 0x1e37, + 0x432b, 0x0b69, + 0x432d, 0x1e39, + 0x432f, 0x0b6d, + 0x433d, 0x1e3b, + 0x433e, 0x0b7c, + 0x4370, 0x1e3c, + 0x4371, 0x0baf, + 0x4375, 0x1e3d, + 0x4376, 0x0bb4, + 0x437c, 0x1e3e, + 0x437d, 0x0bbb, + 0x4421, 0x0bbd, + 0x443d, 0x1e3f, + 0x443e, 0x0bda, + 0x4448, 0x1e40, + 0x4449, 0x0be5, + 0x444a, 0x1e41, + 0x444b, 0x0be7, + 0x444d, 0x1e42, + 0x444e, 0x0bea, + 0x444f, 0x1e43, + 0x4450, 0x0bec, + 0x4454, 0x204b, + 0x4455, 0x0bf1, + 0x445b, 0x11b5, + 0x445c, 0x0bf8, + 0x4521, 0x0c1b, + 0x4522, 0x1e44, + 0x4523, 0x0c1d, + 0x4527, 0x1e45, + 0x4528, 0x0c22, + 0x452e, 0x1e46, + 0x452f, 0x0c29, + 0x4536, 0x1e47, + 0x4537, 0x0c31, + 0x453f, 0x1e48, + 0x4540, 0x0c3a, + 0x4548, 0x1e49, + 0x4549, 0x0c43, + 0x454b, 0x1e4a, + 0x454c, 0x0c46, + 0x4551, 0x1e4b, + 0x4553, 0x0c4d, + 0x4557, 0x16df, + 0x4558, 0x0c52, + 0x4564, 0x1e4d, + 0x4565, 0x0c5f, + 0x456e, 0x1450, + 0x456f, 0x0c69, + 0x4573, 0x1536, + 0x4574, 0x0c6e, + 0x4578, 0x1e4e, + 0x4579, 0x0c73, + 0x4621, 0x0c79, + 0x463e, 0x1e4f, + 0x463f, 0x0c97, + 0x4642, 0x1e50, + 0x4643, 0x0c9b, + 0x4654, 0x1e51, + 0x4656, 0x0cae, + 0x465b, 0x1e53, + 0x465d, 0x0cb5, + 0x4661, 0x1e55, + 0x4662, 0x0cba, + 0x4666, 0x1e56, + 0x4668, 0x0cc0, + 0x466a, 0x1e58, + 0x466b, 0x0cc3, + 0x4676, 0x1aed, + 0x4677, 0x0ccf, + 0x4721, 0x0cd7, + 0x4729, 0x1e59, + 0x472a, 0x0ce0, + 0x4739, 0x1e5a, + 0x473a, 0x0cf0, + 0x4757, 0x1e5b, + 0x4758, 0x0d0e, + 0x4767, 0x1e5c, + 0x4768, 0x1989, + 0x4769, 0x1e5d, + 0x476a, 0x0d20, + 0x476d, 0x1e5e, + 0x476e, 0x0d24, + 0x4821, 0x0d35, + 0x4824, 0x1e5f, + 0x4825, 0x0d39, + 0x482e, 0x1e60, + 0x482f, 0x0d43, + 0x4830, 0x1e61, + 0x4831, 0x0d45, + 0x4854, 0x1e62, + 0x4855, 0x0d69, + 0x4862, 0x1e63, + 0x4863, 0x0d77, + 0x4875, 0x1e64, + 0x4876, 0x0d8a, + 0x4921, 0x0d93, + 0x4922, 0x1e65, + 0x4924, 0x0d96, + 0x492f, 0x1e67, + 0x4930, 0x143b, + 0x4931, 0x0da3, + 0x4932, 0x1e68, + 0x4933, 0x0da5, + 0x4935, 0x1e69, + 0x4936, 0x0da8, + 0x4940, 0x1e6a, + 0x4941, 0x0db3, + 0x494e, 0x1e6b, + 0x494f, 0x0dc1, + 0x4951, 0x1e6c, + 0x4952, 0x0dc4, + 0x4a21, 0x0df1, + 0x4a43, 0x1e6d, + 0x4a44, 0x0e14, + 0x4a4d, 0x1e6e, + 0x4a4e, 0x0e1e, + 0x4a5a, 0x1e6f, + 0x4a5b, 0x0e2b, + 0x4a79, 0x1e70, + 0x4a7a, 0x0e4a, + 0x4b21, 0x0e4f, + 0x4b22, 0x1e71, + 0x4b23, 0x0e51, + 0x4b29, 0x1e72, + 0x4b2a, 0x0e58, + 0x4b4b, 0x1e73, + 0x4b4c, 0x0e7a, + 0x4b6a, 0x1d33, + 0x4b6b, 0x0e99, + 0x4b70, 0x1e74, + 0x4b71, 0x0e9f, + 0x4b78, 0x1f2c, + 0x4b79, 0x102f, + 0x4b7a, 0x0ea8, + 0x4c21, 0x0ead, + 0x4c4d, 0x1e75, + 0x4c4e, 0x0eda, + 0x4c59, 0x1e76, + 0x4c5a, 0x0ee6, + 0x4c5f, 0x1e77, + 0x4c60, 0x0eec, + 0x4c62, 0x1e78, + 0x4c63, 0x0eef, + 0x4c79, 0x1935, + 0x4c7a, 0x1e79, + 0x4c7b, 0x0f07, + 0x4c7c, 0x1e7a, + 0x4c7d, 0x0f09, + 0x4c7e, 0x1e7b, + 0x4d21, 0x0f0b, + 0x4d32, 0x1e7c, + 0x4d33, 0x0f1d, + 0x4d50, 0x1e7d, + 0x4d51, 0x0f3b, + 0x4d54, 0x1e7e, + 0x4d55, 0x0f3f, + 0x4d5a, 0x1d34, + 0x4d5b, 0x0f45, + 0x4d69, 0x1e7f, + 0x4d6a, 0x0f54, + 0x4e21, 0x0f69, + 0x4e4b, 0x1e80, + 0x4e4c, 0x0f94, + 0x4e7a, 0x1e81, + 0x4e7c, 0x0fc4, + 0x4f21, 0x1e83, + 0x4f22, 0x0fc8, + 0x4f31, 0x1e84, + 0x4f32, 0x0fd8, + 0x4f36, 0x1777, + 0x4f37, 0x0fdd, + 0x4f39, 0x1e85, + 0x4f3a, 0x0fe0, + 0x5021, 0x0ffa, + 0x5056, 0x0ea7, + 0x5057, 0x1030, + 0x5121, 0x1058, + 0x513d, 0x1e86, + 0x513e, 0x1075, + 0x5147, 0x1e87, + 0x5148, 0x107f, + 0x514b, 0x1e88, + 0x514c, 0x1083, + 0x514d, 0x1e89, + 0x514e, 0x1085, + 0x5221, 0x10b6, + 0x5321, 0x1114, + 0x5330, 0x1e8a, + 0x5331, 0x1124, + 0x533a, 0x1e8b, + 0x533b, 0x112e, + 0x535e, 0x1e8d, + 0x535f, 0x1152, + 0x536b, 0x1e8e, + 0x536c, 0x115f, + 0x5421, 0x1172, + 0x5444, 0x1e8f, + 0x5445, 0x1196, + 0x5464, 0x0bf7, + 0x5465, 0x11b6, + 0x5521, 0x11d0, + 0x553d, 0x1e90, + 0x553e, 0x11ed, + 0x5563, 0x1e91, + 0x5564, 0x1213, + 0x5621, 0x122e, + 0x5622, 0x1e92, + 0x5623, 0x1230, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5824, 0x1e94, + 0x5825, 0x12ee, + 0x5921, 0x1348, + 0x5960, 0x1e95, + 0x5961, 0x1388, + 0x596c, 0x1e96, + 0x596d, 0x1394, + 0x5978, 0x05a7, + 0x5979, 0x13a0, + 0x5a21, 0x13a6, + 0x5a39, 0x1e97, + 0x5a3a, 0x13bf, + 0x5a4d, 0x1e98, + 0x5a4e, 0x13d3, + 0x5b21, 0x1404, + 0x5b45, 0x1e99, + 0x5b46, 0x1429, + 0x5b4a, 0x1e9a, + 0x5b4b, 0x142e, + 0x5b58, 0x0da2, + 0x5b59, 0x143c, + 0x5b6b, 0x1e9b, + 0x5b6c, 0x144f, + 0x5b6d, 0x0c68, + 0x5b6e, 0x1451, + 0x5b74, 0x1e9c, + 0x5b75, 0x1458, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5e21, 0x151e, + 0x5e39, 0x0c6d, + 0x5e3a, 0x1537, + 0x5e50, 0x1e9d, + 0x5e51, 0x154e, + 0x5e75, 0x05ff, + 0x5e76, 0x1573, + 0x5f21, 0x157c, + 0x6021, 0x15da, + 0x6026, 0x1e9f, + 0x6027, 0x15e0, + 0x605f, 0x1ea0, + 0x6060, 0x1619, + 0x6076, 0x1d35, + 0x6077, 0x1630, + 0x6121, 0x1638, + 0x612b, 0x1ea1, + 0x612c, 0x1643, + 0x6130, 0x1ea2, + 0x6132, 0x1649, + 0x6221, 0x1696, + 0x622b, 0x1ea4, + 0x622c, 0x16a1, + 0x6268, 0x07ee, + 0x6269, 0x16de, + 0x626a, 0x0c51, + 0x626b, 0x16e0, + 0x626f, 0x1ea5, + 0x6270, 0x16e5, + 0x6321, 0x16f4, + 0x634a, 0x1ea6, + 0x634b, 0x171e, + 0x6354, 0x1ea7, + 0x6355, 0x1728, + 0x635e, 0x05d4, + 0x635f, 0x1732, + 0x6421, 0x1752, + 0x6439, 0x1ea8, + 0x643a, 0x176b, + 0x6446, 0x0fdc, + 0x6447, 0x1778, + 0x6464, 0x1ea9, + 0x6465, 0x1796, + 0x646e, 0x1eaa, + 0x646f, 0x17a0, + 0x6521, 0x17b0, + 0x6539, 0x1eab, + 0x653a, 0x17c9, + 0x653b, 0x1eac, + 0x653c, 0x17cb, + 0x6546, 0x1ead, + 0x6547, 0x17d6, + 0x6621, 0x180e, + 0x6646, 0x1eae, + 0x6647, 0x1834, + 0x6721, 0x186c, + 0x6764, 0x1eaf, + 0x6765, 0x18b0, + 0x6769, 0x1eb0, + 0x676a, 0x18b5, + 0x6772, 0x1eb1, + 0x6773, 0x18be, + 0x6821, 0x18ca, + 0x6834, 0x1eb2, + 0x6835, 0x18de, + 0x683b, 0x1eb3, + 0x683c, 0x18e5, + 0x6874, 0x1eb4, + 0x6875, 0x191e, + 0x6921, 0x1928, + 0x6922, 0x08f5, + 0x6923, 0x192a, + 0x692e, 0x0f05, + 0x692f, 0x1936, + 0x695a, 0x05a0, + 0x695b, 0x1962, + 0x6a21, 0x1986, + 0x6a24, 0x0d1e, + 0x6a25, 0x198a, + 0x6a27, 0x1eb6, + 0x6a28, 0x198d, + 0x6a3d, 0x1eb7, + 0x6a3e, 0x19a3, + 0x6a6f, 0x1eb8, + 0x6a70, 0x19d5, + 0x6b21, 0x19e4, + 0x6b32, 0x1eb9, + 0x6b33, 0x19f6, + 0x6b5d, 0x060e, + 0x6b5e, 0x1a21, + 0x6b66, 0x1eba, + 0x6b67, 0x1a2a, + 0x6b76, 0x1ebb, + 0x6b77, 0x1a3a, + 0x6c21, 0x1a42, + 0x6c4d, 0x0aaa, + 0x6c4e, 0x1a6f, + 0x6c69, 0x1ebc, + 0x6c6a, 0x1a8b, + 0x6c74, 0x1ebd, + 0x6c75, 0x1a96, + 0x6d21, 0x1aa0, + 0x6d4e, 0x1ebe, + 0x6d4f, 0x1ace, + 0x6d6c, 0x1ebf, + 0x6d6d, 0x1aec, + 0x6d6e, 0x1ec0, + 0x6d6f, 0x1aee, + 0x6e21, 0x1afe, + 0x6e29, 0x1ec1, + 0x6e2a, 0x1b07, + 0x6e3d, 0x1ec2, + 0x6e3e, 0x1b1b, + 0x6e57, 0x1ec3, + 0x6e58, 0x1b35, + 0x6f21, 0x1b5c, + 0x7021, 0x1bba, + 0x7045, 0x1ec6, + 0x7046, 0x1bdf, + 0x7051, 0x1ec7, + 0x7052, 0x1beb, + 0x7057, 0x1ec8, + 0x7058, 0x1bf1, + 0x7074, 0x0731, + 0x7075, 0x1ec9, + 0x7076, 0x1c0f, + 0x7121, 0x1c18, + 0x7221, 0x1c76, + 0x722d, 0x1eca, + 0x722e, 0x1c83, + 0x723c, 0x1ecb, + 0x723d, 0x1c92, + 0x724d, 0x0477, + 0x724e, 0x1ecc, + 0x724f, 0x1ca4, + 0x7274, 0x0529, + 0x7275, 0x1cca, + 0x7321, 0x1cd4, + 0x7351, 0x1ecd, + 0x7352, 0x1d05, + 0x737d, 0x1ece, + 0x737e, 0x1d31, + 0x2122, 0x1ecf, + 0x2131, 0x1ed1, + 0x213c, 0x1ed3, + 0x2141, 0x1ed6, + 0x214a, 0x1edb, + 0x2161, 0x1eed, + 0x2421, 0x1eee, + 0x2423, 0x1eef, + 0x2425, 0x1ef0, + 0x2427, 0x1ef1, + 0x2429, 0x1ef2, + 0x2443, 0x1ef3, + 0x2463, 0x1ef4, + 0x2465, 0x1ef5, + 0x2467, 0x1ef6, + 0x246e, 0x1ef7, + 0x2521, 0x1ef8, + 0x2523, 0x1ef9, + 0x2525, 0x1efa, + 0x2527, 0x1efb, + 0x2529, 0x1efc, + 0x2543, 0x1efd, + 0x2563, 0x1efe, + 0x2565, 0x1eff, + 0x2567, 0x1f00, + 0x256e, 0x1f01, + 0x2575, 0x1f02, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1278VEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1278VMap2, 652 +}; + +static Gushort japan1278msRKSJHMap2[1424] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x8740, 0x1d83, + 0x875f, 0x1da1, + 0x8761, 0x1f66, + 0x8762, 0x1da4, + 0x8763, 0x1f68, + 0x8764, 0x1da6, + 0x8765, 0x1f6a, + 0x8766, 0x1da8, + 0x8768, 0x1f6c, + 0x8769, 0x1dab, + 0x876b, 0x1f6b, + 0x876c, 0x1dae, + 0x876e, 0x1f6f, + 0x876f, 0x1db1, + 0x877e, 0x2083, + 0x8780, 0x1db8, + 0x8784, 0x1f77, + 0x8785, 0x1dbd, + 0x8790, 0x02fa, + 0x8791, 0x02f9, + 0x8792, 0x0301, + 0x8793, 0x1dc8, + 0x879a, 0x0300, + 0x879b, 0x1dcf, + 0x889f, 0x0465, + 0x88a0, 0x1dd1, + 0x88a1, 0x0467, + 0x88a7, 0x204a, + 0x88a8, 0x046e, + 0x88b0, 0x1f19, + 0x88b1, 0x1ca2, + 0x88b2, 0x0478, + 0x88b9, 0x1dd2, + 0x88ba, 0x0480, + 0x88ec, 0x1dd3, + 0x88ed, 0x04b3, + 0x88f1, 0x1dd4, + 0x88f2, 0x04b8, + 0x88fa, 0x1dd5, + 0x88fb, 0x04c1, + 0x8940, 0x04c3, + 0x8949, 0x1dd6, + 0x894a, 0x04cd, + 0x8954, 0x1dd7, + 0x8955, 0x04d8, + 0x8958, 0x1dd8, + 0x8959, 0x04dc, + 0x895c, 0x1dda, + 0x895d, 0x04e0, + 0x8961, 0x1ddb, + 0x8962, 0x04e5, + 0x8980, 0x0502, + 0x898b, 0x1ddc, + 0x898c, 0x050e, + 0x89a6, 0x1ddd, + 0x89a7, 0x1cc9, + 0x89a8, 0x1dde, + 0x89a9, 0x052b, + 0x89de, 0x1ddf, + 0x89df, 0x0561, + 0x89f8, 0x1de0, + 0x89f9, 0x057b, + 0x89fb, 0x1de1, + 0x89fc, 0x057e, + 0x8a40, 0x057f, + 0x8a41, 0x1de2, + 0x8a42, 0x0581, + 0x8a61, 0x1961, + 0x8a62, 0x05a1, + 0x8a68, 0x139f, + 0x8a69, 0x05a8, + 0x8a80, 0x05be, + 0x8a85, 0x1de3, + 0x8a86, 0x05c4, + 0x8a8b, 0x1de4, + 0x8a8c, 0x05ca, + 0x8a93, 0x1de5, + 0x8a94, 0x05d2, + 0x8a96, 0x1731, + 0x8a97, 0x05d5, + 0x8a9a, 0x1de6, + 0x8a9b, 0x05d9, + 0x8ac0, 0x1de7, + 0x8ac1, 0x1572, + 0x8ac2, 0x0600, + 0x8acb, 0x1de8, + 0x8acc, 0x060a, + 0x8ad0, 0x1a20, + 0x8ad1, 0x060f, + 0x8ae3, 0x1de9, + 0x8ae4, 0x0622, + 0x8b40, 0x063b, + 0x8b4a, 0x1dea, + 0x8b4b, 0x0646, + 0x8b5f, 0x1deb, + 0x8b60, 0x065b, + 0x8b80, 0x067a, + 0x8ba0, 0x1dec, + 0x8ba1, 0x069b, + 0x8ba8, 0x1ded, + 0x8ba9, 0x06a3, + 0x8bc4, 0x1d32, + 0x8bc5, 0x06bf, + 0x8bcd, 0x1dee, + 0x8bce, 0x06c8, + 0x8beb, 0x1def, + 0x8bec, 0x06e6, + 0x8bf2, 0x1df0, + 0x8bf3, 0x06ed, + 0x8bf9, 0x1df1, + 0x8bfa, 0x06f4, + 0x8bfb, 0x1df2, + 0x8bfc, 0x06f6, + 0x8c40, 0x06f7, + 0x8c43, 0x1df3, + 0x8c44, 0x06fb, + 0x8c56, 0x1df4, + 0x8c57, 0x070e, + 0x8c64, 0x1df5, + 0x8c65, 0x071c, + 0x8c6d, 0x1df6, + 0x8c6e, 0x0725, + 0x8c71, 0x1df7, + 0x8c72, 0x0729, + 0x8c74, 0x1df8, + 0x8c75, 0x072c, + 0x8c7a, 0x1c0d, + 0x8c7b, 0x0732, + 0x8c80, 0x0736, + 0x8c84, 0x1df9, + 0x8c85, 0x073b, + 0x8c91, 0x1dfa, + 0x8c92, 0x0748, + 0x8c99, 0x1dfb, + 0x8c9a, 0x0750, + 0x8c9e, 0x1dfc, + 0x8c9f, 0x0755, + 0x8cb2, 0x1dfd, + 0x8cb3, 0x0769, + 0x8cbf, 0x1dfe, + 0x8cc0, 0x0776, + 0x8d40, 0x07b3, + 0x8d4a, 0x1dff, + 0x8d4b, 0x07be, + 0x8d56, 0x1e00, + 0x8d57, 0x07ca, + 0x8d61, 0x1e01, + 0x8d62, 0x07d5, + 0x8d7b, 0x16dd, + 0x8d7c, 0x07ef, + 0x8d80, 0x07f2, + 0x8d8d, 0x1e02, + 0x8d8e, 0x0800, + 0x8d94, 0x1e03, + 0x8d95, 0x0807, + 0x8d99, 0x1e04, + 0x8d9a, 0x080c, + 0x8dd1, 0x1e05, + 0x8dd2, 0x0844, + 0x8de5, 0x1e06, + 0x8de6, 0x0858, + 0x8df2, 0x1e07, + 0x8df3, 0x0865, + 0x8e40, 0x086f, + 0x8e46, 0x1e08, + 0x8e47, 0x0876, + 0x8e49, 0x1e09, + 0x8e4a, 0x0879, + 0x8e4b, 0x1e0a, + 0x8e4c, 0x087b, + 0x8e58, 0x1e0b, + 0x8e59, 0x0888, + 0x8e80, 0x08ae, + 0x8ec6, 0x1e0d, + 0x8ec7, 0x1929, + 0x8ec8, 0x08f6, + 0x8ed5, 0x1e0e, + 0x8ed6, 0x0904, + 0x8edb, 0x1e0f, + 0x8edd, 0x090b, + 0x8f40, 0x092b, + 0x8f4a, 0x1e11, + 0x8f4b, 0x0936, + 0x8f55, 0x1e12, + 0x8f56, 0x0941, + 0x8f80, 0x096a, + 0x8f8c, 0x1e13, + 0x8f8e, 0x0978, + 0x8f92, 0x1e15, + 0x8f94, 0x097e, + 0x8fa3, 0x1e17, + 0x8fa4, 0x098e, + 0x8fb1, 0x1e18, + 0x8fb2, 0x099c, + 0x8fbd, 0x1e19, + 0x8fbe, 0x09a8, + 0x8fd3, 0x1e1a, + 0x8fd4, 0x09be, + 0x8fdd, 0x1e1b, + 0x8fde, 0x09c8, + 0x8fe2, 0x1e1c, + 0x8fe3, 0x09cd, + 0x9040, 0x09e7, + 0x9049, 0x1e1d, + 0x904a, 0x09f1, + 0x9078, 0x1e1e, + 0x9079, 0x0a20, + 0x9080, 0x1e1f, + 0x9081, 0x0a27, + 0x9089, 0x1e20, + 0x908a, 0x0a30, + 0x90a0, 0x1e21, + 0x90a1, 0x0a47, + 0x90c0, 0x1e22, + 0x90c1, 0x0a67, + 0x90e4, 0x1e23, + 0x90e5, 0x0a8b, + 0x90ef, 0x1e24, + 0x90f1, 0x0a97, + 0x90f7, 0x1e26, + 0x90f9, 0x0a9f, + 0x9140, 0x0aa3, + 0x9146, 0x1e28, + 0x9147, 0x1a6e, + 0x9148, 0x0aab, + 0x9158, 0x1e29, + 0x9159, 0x0abc, + 0x916b, 0x1e2a, + 0x916c, 0x0acf, + 0x916e, 0x1e2b, + 0x916f, 0x0ad2, + 0x917e, 0x1e2c, + 0x9180, 0x0ae2, + 0x9189, 0x1e2d, + 0x918a, 0x0aec, + 0x91bb, 0x1e2e, + 0x91bc, 0x0b1e, + 0x91cb, 0x1e2f, + 0x91cc, 0x0b2e, + 0x91da, 0x1e30, + 0x91db, 0x0b3d, + 0x91e1, 0x1e31, + 0x91e2, 0x0b44, + 0x91ed, 0x1e32, + 0x91ee, 0x0b50, + 0x91f3, 0x1e33, + 0x91f5, 0x0b57, + 0x91fb, 0x1e35, + 0x91fc, 0x0b5e, + 0x9240, 0x0b5f, + 0x9246, 0x1e36, + 0x9247, 0x0b66, + 0x9248, 0x1e37, + 0x924a, 0x0b69, + 0x924c, 0x1e39, + 0x924e, 0x0b6d, + 0x925c, 0x1e3b, + 0x925d, 0x0b7c, + 0x9280, 0x0b9e, + 0x9290, 0x1e3c, + 0x9291, 0x0baf, + 0x9295, 0x1e3d, + 0x9296, 0x0bb4, + 0x929c, 0x1e3e, + 0x929d, 0x0bbb, + 0x92bb, 0x1e3f, + 0x92bc, 0x0bda, + 0x92c6, 0x1e40, + 0x92c7, 0x0be5, + 0x92c8, 0x1e41, + 0x92c9, 0x0be7, + 0x92cb, 0x1e42, + 0x92cc, 0x0bea, + 0x92cd, 0x1e43, + 0x92ce, 0x0bec, + 0x92d2, 0x204b, + 0x92d3, 0x0bf1, + 0x92d9, 0x11b5, + 0x92da, 0x0bf8, + 0x9340, 0x0c1b, + 0x9341, 0x1e44, + 0x9342, 0x0c1d, + 0x9346, 0x1e45, + 0x9347, 0x0c22, + 0x934d, 0x1e46, + 0x934e, 0x0c29, + 0x9355, 0x1e47, + 0x9356, 0x0c31, + 0x935e, 0x1e48, + 0x935f, 0x0c3a, + 0x9367, 0x1e49, + 0x9368, 0x0c43, + 0x936a, 0x1e4a, + 0x936b, 0x0c46, + 0x9370, 0x1e4b, + 0x9372, 0x0c4d, + 0x9376, 0x16df, + 0x9377, 0x0c52, + 0x9380, 0x0c5a, + 0x9384, 0x1e4d, + 0x9385, 0x0c5f, + 0x938e, 0x1450, + 0x938f, 0x0c69, + 0x9393, 0x1536, + 0x9394, 0x0c6e, + 0x9398, 0x1e4e, + 0x9399, 0x0c73, + 0x93bc, 0x1e4f, + 0x93bd, 0x0c97, + 0x93c0, 0x1e50, + 0x93c1, 0x0c9b, + 0x93d2, 0x1e51, + 0x93d4, 0x0cae, + 0x93d9, 0x1e53, + 0x93db, 0x0cb5, + 0x93df, 0x1e55, + 0x93e0, 0x0cba, + 0x93e4, 0x1e56, + 0x93e6, 0x0cc0, + 0x93e8, 0x1e58, + 0x93e9, 0x0cc3, + 0x93f4, 0x1aed, + 0x93f5, 0x0ccf, + 0x9440, 0x0cd7, + 0x9448, 0x1e59, + 0x9449, 0x0ce0, + 0x9458, 0x1e5a, + 0x9459, 0x0cf0, + 0x9476, 0x1e5b, + 0x9477, 0x0d0e, + 0x9480, 0x0d16, + 0x9487, 0x1e5c, + 0x9488, 0x1989, + 0x9489, 0x1e5d, + 0x948a, 0x0d20, + 0x948d, 0x1e5e, + 0x948e, 0x0d24, + 0x94a2, 0x1e5f, + 0x94a3, 0x0d39, + 0x94ac, 0x1e60, + 0x94ad, 0x0d43, + 0x94ae, 0x1e61, + 0x94af, 0x0d45, + 0x94d2, 0x1e62, + 0x94d3, 0x0d69, + 0x94e0, 0x1e63, + 0x94e1, 0x0d77, + 0x94f3, 0x1e64, + 0x94f4, 0x0d8a, + 0x9540, 0x0d93, + 0x9541, 0x1e65, + 0x9543, 0x0d96, + 0x954e, 0x1e67, + 0x954f, 0x143b, + 0x9550, 0x0da3, + 0x9551, 0x1e68, + 0x9552, 0x0da5, + 0x9554, 0x1e69, + 0x9555, 0x0da8, + 0x955f, 0x1e6a, + 0x9560, 0x0db3, + 0x956d, 0x1e6b, + 0x956e, 0x0dc1, + 0x9570, 0x1e6c, + 0x9571, 0x0dc4, + 0x9580, 0x0dd2, + 0x95c1, 0x1e6d, + 0x95c2, 0x0e14, + 0x95cb, 0x1e6e, + 0x95cc, 0x0e1e, + 0x95d8, 0x1e6f, + 0x95d9, 0x0e2b, + 0x95f7, 0x1e70, + 0x95f8, 0x0e4a, + 0x9640, 0x0e4f, + 0x9641, 0x1e71, + 0x9642, 0x0e51, + 0x9648, 0x1e72, + 0x9649, 0x0e58, + 0x966a, 0x1e73, + 0x966b, 0x0e7a, + 0x9680, 0x0e8e, + 0x968a, 0x1d33, + 0x968b, 0x0e99, + 0x9690, 0x1e74, + 0x9691, 0x0e9f, + 0x9698, 0x1f2c, + 0x9699, 0x102f, + 0x969a, 0x0ea8, + 0x96cb, 0x1e75, + 0x96cc, 0x0eda, + 0x96d7, 0x1e76, + 0x96d8, 0x0ee6, + 0x96dd, 0x1e77, + 0x96de, 0x0eec, + 0x96e0, 0x1e78, + 0x96e1, 0x0eef, + 0x96f7, 0x1935, + 0x96f8, 0x1e79, + 0x96f9, 0x0f07, + 0x96fa, 0x1e7a, + 0x96fb, 0x0f09, + 0x96fc, 0x1e7b, + 0x9740, 0x0f0b, + 0x9751, 0x1e7c, + 0x9752, 0x0f1d, + 0x976f, 0x1e7d, + 0x9770, 0x0f3b, + 0x9773, 0x1e7e, + 0x9774, 0x0f3f, + 0x9779, 0x1d34, + 0x977a, 0x0f45, + 0x9780, 0x0f4a, + 0x9789, 0x1e7f, + 0x978a, 0x0f54, + 0x97c9, 0x1e80, + 0x97ca, 0x0f94, + 0x97f8, 0x1e81, + 0x97fa, 0x0fc4, + 0x9840, 0x1e83, + 0x9841, 0x0fc8, + 0x9850, 0x1e84, + 0x9851, 0x0fd8, + 0x9855, 0x1777, + 0x9856, 0x0fdd, + 0x9858, 0x1e85, + 0x9859, 0x0fe0, + 0x989f, 0x0ffa, + 0x98d4, 0x0ea7, + 0x98d5, 0x1030, + 0x9940, 0x1058, + 0x995c, 0x1e86, + 0x995d, 0x1075, + 0x9966, 0x1e87, + 0x9967, 0x107f, + 0x996a, 0x1e88, + 0x996b, 0x1083, + 0x996c, 0x1e89, + 0x996d, 0x1085, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a4f, 0x1e8a, + 0x9a50, 0x1124, + 0x9a59, 0x1e8b, + 0x9a5a, 0x112e, + 0x9a7d, 0x1e8d, + 0x9a7e, 0x1152, + 0x9a80, 0x1153, + 0x9a8b, 0x1e8e, + 0x9a8c, 0x115f, + 0x9ac2, 0x1e8f, + 0x9ac3, 0x1196, + 0x9ae2, 0x0bf7, + 0x9ae3, 0x11b6, + 0x9b40, 0x11d0, + 0x9b5c, 0x1e90, + 0x9b5d, 0x11ed, + 0x9b80, 0x120f, + 0x9b83, 0x1e91, + 0x9b84, 0x1213, + 0x9ba0, 0x1e92, + 0x9ba1, 0x1230, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9ca2, 0x1e94, + 0x9ca3, 0x12ee, + 0x9d40, 0x1348, + 0x9d80, 0x1e95, + 0x9d81, 0x1388, + 0x9d8c, 0x1e96, + 0x9d8d, 0x1394, + 0x9d98, 0x05a7, + 0x9d99, 0x13a0, + 0x9db7, 0x1e97, + 0x9db8, 0x13bf, + 0x9dcb, 0x1e98, + 0x9dcc, 0x13d3, + 0x9e40, 0x1404, + 0x9e64, 0x1e99, + 0x9e65, 0x1429, + 0x9e69, 0x1e9a, + 0x9e6a, 0x142e, + 0x9e77, 0x0da2, + 0x9e78, 0x143c, + 0x9e80, 0x1443, + 0x9e8b, 0x1e9b, + 0x9e8c, 0x144f, + 0x9e8d, 0x0c68, + 0x9e8e, 0x1451, + 0x9e94, 0x1e9c, + 0x9e95, 0x1458, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0x9fb7, 0x0c6d, + 0x9fb8, 0x1537, + 0x9fce, 0x1e9d, + 0x9fcf, 0x154e, + 0x9ff3, 0x05ff, + 0x9ff4, 0x1573, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe0a4, 0x1e9f, + 0xe0a5, 0x15e0, + 0xe0dd, 0x1ea0, + 0xe0de, 0x1619, + 0xe0f4, 0x1d35, + 0xe0f5, 0x1630, + 0xe140, 0x1638, + 0xe14a, 0x1ea1, + 0xe14b, 0x1643, + 0xe14f, 0x1ea2, + 0xe151, 0x1649, + 0xe180, 0x1677, + 0xe1a9, 0x1ea4, + 0xe1aa, 0x16a1, + 0xe1e6, 0x07ee, + 0xe1e7, 0x16de, + 0xe1e8, 0x0c51, + 0xe1e9, 0x16e0, + 0xe1ed, 0x1ea5, + 0xe1ee, 0x16e5, + 0xe240, 0x16f4, + 0xe269, 0x1ea6, + 0xe26a, 0x171e, + 0xe273, 0x1ea7, + 0xe274, 0x1728, + 0xe27d, 0x05d4, + 0xe27e, 0x1732, + 0xe280, 0x1733, + 0xe2b7, 0x1ea8, + 0xe2b8, 0x176b, + 0xe2c4, 0x0fdc, + 0xe2c5, 0x1778, + 0xe2e2, 0x1ea9, + 0xe2e3, 0x1796, + 0xe2ec, 0x1eaa, + 0xe2ed, 0x17a0, + 0xe340, 0x17b0, + 0xe358, 0x1eab, + 0xe359, 0x17c9, + 0xe35a, 0x1eac, + 0xe35b, 0x17cb, + 0xe365, 0x1ead, + 0xe366, 0x17d6, + 0xe380, 0x17ef, + 0xe3c4, 0x1eae, + 0xe3c5, 0x1834, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe484, 0x1eaf, + 0xe485, 0x18b0, + 0xe489, 0x1eb0, + 0xe48a, 0x18b5, + 0xe492, 0x1eb1, + 0xe493, 0x18be, + 0xe4b2, 0x1eb2, + 0xe4b3, 0x18de, + 0xe4b9, 0x1eb3, + 0xe4ba, 0x18e5, + 0xe4f2, 0x1eb4, + 0xe4f3, 0x191e, + 0xe540, 0x1928, + 0xe541, 0x08f5, + 0xe542, 0x192a, + 0xe54d, 0x0f05, + 0xe54e, 0x1936, + 0xe579, 0x05a0, + 0xe57a, 0x1962, + 0xe580, 0x1967, + 0xe5a2, 0x0d1e, + 0xe5a3, 0x198a, + 0xe5a5, 0x1eb6, + 0xe5a6, 0x198d, + 0xe5bb, 0x1eb7, + 0xe5bc, 0x19a3, + 0xe5ed, 0x1eb8, + 0xe5ee, 0x19d5, + 0xe640, 0x19e4, + 0xe651, 0x1eb9, + 0xe652, 0x19f6, + 0xe67c, 0x060e, + 0xe67d, 0x1a21, + 0xe680, 0x1a23, + 0xe686, 0x1eba, + 0xe687, 0x1a2a, + 0xe696, 0x1ebb, + 0xe697, 0x1a3a, + 0xe6cb, 0x0aaa, + 0xe6cc, 0x1a6f, + 0xe6e7, 0x1ebc, + 0xe6e8, 0x1a8b, + 0xe6f2, 0x1ebd, + 0xe6f3, 0x1a96, + 0xe740, 0x1aa0, + 0xe76d, 0x1ebe, + 0xe76e, 0x1ace, + 0xe780, 0x1adf, + 0xe78c, 0x1ebf, + 0xe78d, 0x1aec, + 0xe78e, 0x1ec0, + 0xe78f, 0x1aee, + 0xe7a7, 0x1ec1, + 0xe7a8, 0x1b07, + 0xe7bb, 0x1ec2, + 0xe7bc, 0x1b1b, + 0xe7d5, 0x1ec3, + 0xe7d6, 0x1b35, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe8c3, 0x1ec6, + 0xe8c4, 0x1bdf, + 0xe8cf, 0x1ec7, + 0xe8d0, 0x1beb, + 0xe8d5, 0x1ec8, + 0xe8d6, 0x1bf1, + 0xe8f2, 0x0731, + 0xe8f3, 0x1ec9, + 0xe8f4, 0x1c0f, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xe9ab, 0x1eca, + 0xe9ac, 0x1c83, + 0xe9ba, 0x1ecb, + 0xe9bb, 0x1c92, + 0xe9cb, 0x0477, + 0xe9cc, 0x1ecc, + 0xe9cd, 0x1ca4, + 0xe9f2, 0x0529, + 0xe9f3, 0x1cca, + 0xea40, 0x1cd4, + 0xea70, 0x1ecd, + 0xea71, 0x1d05, + 0xea80, 0x1d13, + 0xea9d, 0x1ece, + 0xea9e, 0x1d31, + 0xeaa3, 0x205c, + 0xed40, 0x20a7, + 0xed80, 0x20e6, + 0xedb4, 0x07c9, + 0xedb5, 0x211a, + 0xee40, 0x2162, + 0xee80, 0x21a1, + 0xeeef, 0x1f9c, + 0xeef9, 0x02ef, + 0xeefa, 0x1f45, + 0xfa40, 0x1f9c, + 0xfa4a, 0x1d97, + 0xfa54, 0x02ef, + 0xfa55, 0x1f45, + 0xfa58, 0x1dc2, + 0xfa59, 0x1dba, + 0xfa5a, 0x1f77, + 0xfa5b, 0x0300, + 0xfa5c, 0x20a7, + 0xfa80, 0x20ca, + 0xfad0, 0x07c9, + 0xfad1, 0x211a, + 0xfb40, 0x2146, + 0xfb80, 0x2185, + 0xfc40, 0x2202, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1278msRKSJHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0277, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1278msRKSJHMap2, 712 +}; + +static Gushort japan1278msRKSJVMap2[1580] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x8740, 0x1d83, + 0x875f, 0x1da1, + 0x8761, 0x1f66, + 0x8762, 0x1da4, + 0x8763, 0x1f68, + 0x8764, 0x1da6, + 0x8765, 0x1f6a, + 0x8766, 0x1da8, + 0x8768, 0x1f6c, + 0x8769, 0x1dab, + 0x876b, 0x1f6b, + 0x876c, 0x1dae, + 0x876e, 0x1f6f, + 0x876f, 0x1db1, + 0x877e, 0x2083, + 0x8780, 0x1db8, + 0x8784, 0x1f77, + 0x8785, 0x1dbd, + 0x8790, 0x02fa, + 0x8791, 0x02f9, + 0x8792, 0x0301, + 0x8793, 0x1dc8, + 0x879a, 0x0300, + 0x879b, 0x1dcf, + 0x889f, 0x0465, + 0x88a0, 0x1dd1, + 0x88a1, 0x0467, + 0x88a7, 0x204a, + 0x88a8, 0x046e, + 0x88b0, 0x1f19, + 0x88b1, 0x1ca2, + 0x88b2, 0x0478, + 0x88b9, 0x1dd2, + 0x88ba, 0x0480, + 0x88ec, 0x1dd3, + 0x88ed, 0x04b3, + 0x88f1, 0x1dd4, + 0x88f2, 0x04b8, + 0x88fa, 0x1dd5, + 0x88fb, 0x04c1, + 0x8940, 0x04c3, + 0x8949, 0x1dd6, + 0x894a, 0x04cd, + 0x8954, 0x1dd7, + 0x8955, 0x04d8, + 0x8958, 0x1dd8, + 0x8959, 0x04dc, + 0x895c, 0x1dda, + 0x895d, 0x04e0, + 0x8961, 0x1ddb, + 0x8962, 0x04e5, + 0x8980, 0x0502, + 0x898b, 0x1ddc, + 0x898c, 0x050e, + 0x89a6, 0x1ddd, + 0x89a7, 0x1cc9, + 0x89a8, 0x1dde, + 0x89a9, 0x052b, + 0x89de, 0x1ddf, + 0x89df, 0x0561, + 0x89f8, 0x1de0, + 0x89f9, 0x057b, + 0x89fb, 0x1de1, + 0x89fc, 0x057e, + 0x8a40, 0x057f, + 0x8a41, 0x1de2, + 0x8a42, 0x0581, + 0x8a61, 0x1961, + 0x8a62, 0x05a1, + 0x8a68, 0x139f, + 0x8a69, 0x05a8, + 0x8a80, 0x05be, + 0x8a85, 0x1de3, + 0x8a86, 0x05c4, + 0x8a8b, 0x1de4, + 0x8a8c, 0x05ca, + 0x8a93, 0x1de5, + 0x8a94, 0x05d2, + 0x8a96, 0x1731, + 0x8a97, 0x05d5, + 0x8a9a, 0x1de6, + 0x8a9b, 0x05d9, + 0x8ac0, 0x1de7, + 0x8ac1, 0x1572, + 0x8ac2, 0x0600, + 0x8acb, 0x1de8, + 0x8acc, 0x060a, + 0x8ad0, 0x1a20, + 0x8ad1, 0x060f, + 0x8ae3, 0x1de9, + 0x8ae4, 0x0622, + 0x8b40, 0x063b, + 0x8b4a, 0x1dea, + 0x8b4b, 0x0646, + 0x8b5f, 0x1deb, + 0x8b60, 0x065b, + 0x8b80, 0x067a, + 0x8ba0, 0x1dec, + 0x8ba1, 0x069b, + 0x8ba8, 0x1ded, + 0x8ba9, 0x06a3, + 0x8bc4, 0x1d32, + 0x8bc5, 0x06bf, + 0x8bcd, 0x1dee, + 0x8bce, 0x06c8, + 0x8beb, 0x1def, + 0x8bec, 0x06e6, + 0x8bf2, 0x1df0, + 0x8bf3, 0x06ed, + 0x8bf9, 0x1df1, + 0x8bfa, 0x06f4, + 0x8bfb, 0x1df2, + 0x8bfc, 0x06f6, + 0x8c40, 0x06f7, + 0x8c43, 0x1df3, + 0x8c44, 0x06fb, + 0x8c56, 0x1df4, + 0x8c57, 0x070e, + 0x8c64, 0x1df5, + 0x8c65, 0x071c, + 0x8c6d, 0x1df6, + 0x8c6e, 0x0725, + 0x8c71, 0x1df7, + 0x8c72, 0x0729, + 0x8c74, 0x1df8, + 0x8c75, 0x072c, + 0x8c7a, 0x1c0d, + 0x8c7b, 0x0732, + 0x8c80, 0x0736, + 0x8c84, 0x1df9, + 0x8c85, 0x073b, + 0x8c91, 0x1dfa, + 0x8c92, 0x0748, + 0x8c99, 0x1dfb, + 0x8c9a, 0x0750, + 0x8c9e, 0x1dfc, + 0x8c9f, 0x0755, + 0x8cb2, 0x1dfd, + 0x8cb3, 0x0769, + 0x8cbf, 0x1dfe, + 0x8cc0, 0x0776, + 0x8d40, 0x07b3, + 0x8d4a, 0x1dff, + 0x8d4b, 0x07be, + 0x8d56, 0x1e00, + 0x8d57, 0x07ca, + 0x8d61, 0x1e01, + 0x8d62, 0x07d5, + 0x8d7b, 0x16dd, + 0x8d7c, 0x07ef, + 0x8d80, 0x07f2, + 0x8d8d, 0x1e02, + 0x8d8e, 0x0800, + 0x8d94, 0x1e03, + 0x8d95, 0x0807, + 0x8d99, 0x1e04, + 0x8d9a, 0x080c, + 0x8dd1, 0x1e05, + 0x8dd2, 0x0844, + 0x8de5, 0x1e06, + 0x8de6, 0x0858, + 0x8df2, 0x1e07, + 0x8df3, 0x0865, + 0x8e40, 0x086f, + 0x8e46, 0x1e08, + 0x8e47, 0x0876, + 0x8e49, 0x1e09, + 0x8e4a, 0x0879, + 0x8e4b, 0x1e0a, + 0x8e4c, 0x087b, + 0x8e58, 0x1e0b, + 0x8e59, 0x0888, + 0x8e80, 0x08ae, + 0x8ec6, 0x1e0d, + 0x8ec7, 0x1929, + 0x8ec8, 0x08f6, + 0x8ed5, 0x1e0e, + 0x8ed6, 0x0904, + 0x8edb, 0x1e0f, + 0x8edd, 0x090b, + 0x8f40, 0x092b, + 0x8f4a, 0x1e11, + 0x8f4b, 0x0936, + 0x8f55, 0x1e12, + 0x8f56, 0x0941, + 0x8f80, 0x096a, + 0x8f8c, 0x1e13, + 0x8f8e, 0x0978, + 0x8f92, 0x1e15, + 0x8f94, 0x097e, + 0x8fa3, 0x1e17, + 0x8fa4, 0x098e, + 0x8fb1, 0x1e18, + 0x8fb2, 0x099c, + 0x8fbd, 0x1e19, + 0x8fbe, 0x09a8, + 0x8fd3, 0x1e1a, + 0x8fd4, 0x09be, + 0x8fdd, 0x1e1b, + 0x8fde, 0x09c8, + 0x8fe2, 0x1e1c, + 0x8fe3, 0x09cd, + 0x9040, 0x09e7, + 0x9049, 0x1e1d, + 0x904a, 0x09f1, + 0x9078, 0x1e1e, + 0x9079, 0x0a20, + 0x9080, 0x1e1f, + 0x9081, 0x0a27, + 0x9089, 0x1e20, + 0x908a, 0x0a30, + 0x90a0, 0x1e21, + 0x90a1, 0x0a47, + 0x90c0, 0x1e22, + 0x90c1, 0x0a67, + 0x90e4, 0x1e23, + 0x90e5, 0x0a8b, + 0x90ef, 0x1e24, + 0x90f1, 0x0a97, + 0x90f7, 0x1e26, + 0x90f9, 0x0a9f, + 0x9140, 0x0aa3, + 0x9146, 0x1e28, + 0x9147, 0x1a6e, + 0x9148, 0x0aab, + 0x9158, 0x1e29, + 0x9159, 0x0abc, + 0x916b, 0x1e2a, + 0x916c, 0x0acf, + 0x916e, 0x1e2b, + 0x916f, 0x0ad2, + 0x917e, 0x1e2c, + 0x9180, 0x0ae2, + 0x9189, 0x1e2d, + 0x918a, 0x0aec, + 0x91bb, 0x1e2e, + 0x91bc, 0x0b1e, + 0x91cb, 0x1e2f, + 0x91cc, 0x0b2e, + 0x91da, 0x1e30, + 0x91db, 0x0b3d, + 0x91e1, 0x1e31, + 0x91e2, 0x0b44, + 0x91ed, 0x1e32, + 0x91ee, 0x0b50, + 0x91f3, 0x1e33, + 0x91f5, 0x0b57, + 0x91fb, 0x1e35, + 0x91fc, 0x0b5e, + 0x9240, 0x0b5f, + 0x9246, 0x1e36, + 0x9247, 0x0b66, + 0x9248, 0x1e37, + 0x924a, 0x0b69, + 0x924c, 0x1e39, + 0x924e, 0x0b6d, + 0x925c, 0x1e3b, + 0x925d, 0x0b7c, + 0x9280, 0x0b9e, + 0x9290, 0x1e3c, + 0x9291, 0x0baf, + 0x9295, 0x1e3d, + 0x9296, 0x0bb4, + 0x929c, 0x1e3e, + 0x929d, 0x0bbb, + 0x92bb, 0x1e3f, + 0x92bc, 0x0bda, + 0x92c6, 0x1e40, + 0x92c7, 0x0be5, + 0x92c8, 0x1e41, + 0x92c9, 0x0be7, + 0x92cb, 0x1e42, + 0x92cc, 0x0bea, + 0x92cd, 0x1e43, + 0x92ce, 0x0bec, + 0x92d2, 0x204b, + 0x92d3, 0x0bf1, + 0x92d9, 0x11b5, + 0x92da, 0x0bf8, + 0x9340, 0x0c1b, + 0x9341, 0x1e44, + 0x9342, 0x0c1d, + 0x9346, 0x1e45, + 0x9347, 0x0c22, + 0x934d, 0x1e46, + 0x934e, 0x0c29, + 0x9355, 0x1e47, + 0x9356, 0x0c31, + 0x935e, 0x1e48, + 0x935f, 0x0c3a, + 0x9367, 0x1e49, + 0x9368, 0x0c43, + 0x936a, 0x1e4a, + 0x936b, 0x0c46, + 0x9370, 0x1e4b, + 0x9372, 0x0c4d, + 0x9376, 0x16df, + 0x9377, 0x0c52, + 0x9380, 0x0c5a, + 0x9384, 0x1e4d, + 0x9385, 0x0c5f, + 0x938e, 0x1450, + 0x938f, 0x0c69, + 0x9393, 0x1536, + 0x9394, 0x0c6e, + 0x9398, 0x1e4e, + 0x9399, 0x0c73, + 0x93bc, 0x1e4f, + 0x93bd, 0x0c97, + 0x93c0, 0x1e50, + 0x93c1, 0x0c9b, + 0x93d2, 0x1e51, + 0x93d4, 0x0cae, + 0x93d9, 0x1e53, + 0x93db, 0x0cb5, + 0x93df, 0x1e55, + 0x93e0, 0x0cba, + 0x93e4, 0x1e56, + 0x93e6, 0x0cc0, + 0x93e8, 0x1e58, + 0x93e9, 0x0cc3, + 0x93f4, 0x1aed, + 0x93f5, 0x0ccf, + 0x9440, 0x0cd7, + 0x9448, 0x1e59, + 0x9449, 0x0ce0, + 0x9458, 0x1e5a, + 0x9459, 0x0cf0, + 0x9476, 0x1e5b, + 0x9477, 0x0d0e, + 0x9480, 0x0d16, + 0x9487, 0x1e5c, + 0x9488, 0x1989, + 0x9489, 0x1e5d, + 0x948a, 0x0d20, + 0x948d, 0x1e5e, + 0x948e, 0x0d24, + 0x94a2, 0x1e5f, + 0x94a3, 0x0d39, + 0x94ac, 0x1e60, + 0x94ad, 0x0d43, + 0x94ae, 0x1e61, + 0x94af, 0x0d45, + 0x94d2, 0x1e62, + 0x94d3, 0x0d69, + 0x94e0, 0x1e63, + 0x94e1, 0x0d77, + 0x94f3, 0x1e64, + 0x94f4, 0x0d8a, + 0x9540, 0x0d93, + 0x9541, 0x1e65, + 0x9543, 0x0d96, + 0x954e, 0x1e67, + 0x954f, 0x143b, + 0x9550, 0x0da3, + 0x9551, 0x1e68, + 0x9552, 0x0da5, + 0x9554, 0x1e69, + 0x9555, 0x0da8, + 0x955f, 0x1e6a, + 0x9560, 0x0db3, + 0x956d, 0x1e6b, + 0x956e, 0x0dc1, + 0x9570, 0x1e6c, + 0x9571, 0x0dc4, + 0x9580, 0x0dd2, + 0x95c1, 0x1e6d, + 0x95c2, 0x0e14, + 0x95cb, 0x1e6e, + 0x95cc, 0x0e1e, + 0x95d8, 0x1e6f, + 0x95d9, 0x0e2b, + 0x95f7, 0x1e70, + 0x95f8, 0x0e4a, + 0x9640, 0x0e4f, + 0x9641, 0x1e71, + 0x9642, 0x0e51, + 0x9648, 0x1e72, + 0x9649, 0x0e58, + 0x966a, 0x1e73, + 0x966b, 0x0e7a, + 0x9680, 0x0e8e, + 0x968a, 0x1d33, + 0x968b, 0x0e99, + 0x9690, 0x1e74, + 0x9691, 0x0e9f, + 0x9698, 0x1f2c, + 0x9699, 0x102f, + 0x969a, 0x0ea8, + 0x96cb, 0x1e75, + 0x96cc, 0x0eda, + 0x96d7, 0x1e76, + 0x96d8, 0x0ee6, + 0x96dd, 0x1e77, + 0x96de, 0x0eec, + 0x96e0, 0x1e78, + 0x96e1, 0x0eef, + 0x96f7, 0x1935, + 0x96f8, 0x1e79, + 0x96f9, 0x0f07, + 0x96fa, 0x1e7a, + 0x96fb, 0x0f09, + 0x96fc, 0x1e7b, + 0x9740, 0x0f0b, + 0x9751, 0x1e7c, + 0x9752, 0x0f1d, + 0x976f, 0x1e7d, + 0x9770, 0x0f3b, + 0x9773, 0x1e7e, + 0x9774, 0x0f3f, + 0x9779, 0x1d34, + 0x977a, 0x0f45, + 0x9780, 0x0f4a, + 0x9789, 0x1e7f, + 0x978a, 0x0f54, + 0x97c9, 0x1e80, + 0x97ca, 0x0f94, + 0x97f8, 0x1e81, + 0x97fa, 0x0fc4, + 0x9840, 0x1e83, + 0x9841, 0x0fc8, + 0x9850, 0x1e84, + 0x9851, 0x0fd8, + 0x9855, 0x1777, + 0x9856, 0x0fdd, + 0x9858, 0x1e85, + 0x9859, 0x0fe0, + 0x989f, 0x0ffa, + 0x98d4, 0x0ea7, + 0x98d5, 0x1030, + 0x9940, 0x1058, + 0x995c, 0x1e86, + 0x995d, 0x1075, + 0x9966, 0x1e87, + 0x9967, 0x107f, + 0x996a, 0x1e88, + 0x996b, 0x1083, + 0x996c, 0x1e89, + 0x996d, 0x1085, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a4f, 0x1e8a, + 0x9a50, 0x1124, + 0x9a59, 0x1e8b, + 0x9a5a, 0x112e, + 0x9a7d, 0x1e8d, + 0x9a7e, 0x1152, + 0x9a80, 0x1153, + 0x9a8b, 0x1e8e, + 0x9a8c, 0x115f, + 0x9ac2, 0x1e8f, + 0x9ac3, 0x1196, + 0x9ae2, 0x0bf7, + 0x9ae3, 0x11b6, + 0x9b40, 0x11d0, + 0x9b5c, 0x1e90, + 0x9b5d, 0x11ed, + 0x9b80, 0x120f, + 0x9b83, 0x1e91, + 0x9b84, 0x1213, + 0x9ba0, 0x1e92, + 0x9ba1, 0x1230, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9ca2, 0x1e94, + 0x9ca3, 0x12ee, + 0x9d40, 0x1348, + 0x9d80, 0x1e95, + 0x9d81, 0x1388, + 0x9d8c, 0x1e96, + 0x9d8d, 0x1394, + 0x9d98, 0x05a7, + 0x9d99, 0x13a0, + 0x9db7, 0x1e97, + 0x9db8, 0x13bf, + 0x9dcb, 0x1e98, + 0x9dcc, 0x13d3, + 0x9e40, 0x1404, + 0x9e64, 0x1e99, + 0x9e65, 0x1429, + 0x9e69, 0x1e9a, + 0x9e6a, 0x142e, + 0x9e77, 0x0da2, + 0x9e78, 0x143c, + 0x9e80, 0x1443, + 0x9e8b, 0x1e9b, + 0x9e8c, 0x144f, + 0x9e8d, 0x0c68, + 0x9e8e, 0x1451, + 0x9e94, 0x1e9c, + 0x9e95, 0x1458, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0x9fb7, 0x0c6d, + 0x9fb8, 0x1537, + 0x9fce, 0x1e9d, + 0x9fcf, 0x154e, + 0x9ff3, 0x05ff, + 0x9ff4, 0x1573, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe0a4, 0x1e9f, + 0xe0a5, 0x15e0, + 0xe0dd, 0x1ea0, + 0xe0de, 0x1619, + 0xe0f4, 0x1d35, + 0xe0f5, 0x1630, + 0xe140, 0x1638, + 0xe14a, 0x1ea1, + 0xe14b, 0x1643, + 0xe14f, 0x1ea2, + 0xe151, 0x1649, + 0xe180, 0x1677, + 0xe1a9, 0x1ea4, + 0xe1aa, 0x16a1, + 0xe1e6, 0x07ee, + 0xe1e7, 0x16de, + 0xe1e8, 0x0c51, + 0xe1e9, 0x16e0, + 0xe1ed, 0x1ea5, + 0xe1ee, 0x16e5, + 0xe240, 0x16f4, + 0xe269, 0x1ea6, + 0xe26a, 0x171e, + 0xe273, 0x1ea7, + 0xe274, 0x1728, + 0xe27d, 0x05d4, + 0xe27e, 0x1732, + 0xe280, 0x1733, + 0xe2b7, 0x1ea8, + 0xe2b8, 0x176b, + 0xe2c4, 0x0fdc, + 0xe2c5, 0x1778, + 0xe2e2, 0x1ea9, + 0xe2e3, 0x1796, + 0xe2ec, 0x1eaa, + 0xe2ed, 0x17a0, + 0xe340, 0x17b0, + 0xe358, 0x1eab, + 0xe359, 0x17c9, + 0xe35a, 0x1eac, + 0xe35b, 0x17cb, + 0xe365, 0x1ead, + 0xe366, 0x17d6, + 0xe380, 0x17ef, + 0xe3c4, 0x1eae, + 0xe3c5, 0x1834, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe484, 0x1eaf, + 0xe485, 0x18b0, + 0xe489, 0x1eb0, + 0xe48a, 0x18b5, + 0xe492, 0x1eb1, + 0xe493, 0x18be, + 0xe4b2, 0x1eb2, + 0xe4b3, 0x18de, + 0xe4b9, 0x1eb3, + 0xe4ba, 0x18e5, + 0xe4f2, 0x1eb4, + 0xe4f3, 0x191e, + 0xe540, 0x1928, + 0xe541, 0x08f5, + 0xe542, 0x192a, + 0xe54d, 0x0f05, + 0xe54e, 0x1936, + 0xe579, 0x05a0, + 0xe57a, 0x1962, + 0xe580, 0x1967, + 0xe5a2, 0x0d1e, + 0xe5a3, 0x198a, + 0xe5a5, 0x1eb6, + 0xe5a6, 0x198d, + 0xe5bb, 0x1eb7, + 0xe5bc, 0x19a3, + 0xe5ed, 0x1eb8, + 0xe5ee, 0x19d5, + 0xe640, 0x19e4, + 0xe651, 0x1eb9, + 0xe652, 0x19f6, + 0xe67c, 0x060e, + 0xe67d, 0x1a21, + 0xe680, 0x1a23, + 0xe686, 0x1eba, + 0xe687, 0x1a2a, + 0xe696, 0x1ebb, + 0xe697, 0x1a3a, + 0xe6cb, 0x0aaa, + 0xe6cc, 0x1a6f, + 0xe6e7, 0x1ebc, + 0xe6e8, 0x1a8b, + 0xe6f2, 0x1ebd, + 0xe6f3, 0x1a96, + 0xe740, 0x1aa0, + 0xe76d, 0x1ebe, + 0xe76e, 0x1ace, + 0xe780, 0x1adf, + 0xe78c, 0x1ebf, + 0xe78d, 0x1aec, + 0xe78e, 0x1ec0, + 0xe78f, 0x1aee, + 0xe7a7, 0x1ec1, + 0xe7a8, 0x1b07, + 0xe7bb, 0x1ec2, + 0xe7bc, 0x1b1b, + 0xe7d5, 0x1ec3, + 0xe7d6, 0x1b35, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe8c3, 0x1ec6, + 0xe8c4, 0x1bdf, + 0xe8cf, 0x1ec7, + 0xe8d0, 0x1beb, + 0xe8d5, 0x1ec8, + 0xe8d6, 0x1bf1, + 0xe8f2, 0x0731, + 0xe8f3, 0x1ec9, + 0xe8f4, 0x1c0f, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xe9ab, 0x1eca, + 0xe9ac, 0x1c83, + 0xe9ba, 0x1ecb, + 0xe9bb, 0x1c92, + 0xe9cb, 0x0477, + 0xe9cc, 0x1ecc, + 0xe9cd, 0x1ca4, + 0xe9f2, 0x0529, + 0xe9f3, 0x1cca, + 0xea40, 0x1cd4, + 0xea70, 0x1ecd, + 0xea71, 0x1d05, + 0xea80, 0x1d13, + 0xea9d, 0x1ece, + 0xea9e, 0x1d31, + 0xeaa3, 0x205c, + 0xed40, 0x20a7, + 0xed80, 0x20e6, + 0xedb4, 0x07c9, + 0xedb5, 0x211a, + 0xee40, 0x2162, + 0xee80, 0x21a1, + 0xeeef, 0x1f9c, + 0xeef9, 0x02ef, + 0xeefa, 0x1f45, + 0xfa40, 0x1f9c, + 0xfa4a, 0x1d97, + 0xfa54, 0x02ef, + 0xfa55, 0x1f45, + 0xfa58, 0x1dc2, + 0xfa59, 0x1dba, + 0xfa5a, 0x1f77, + 0xfa5b, 0x0300, + 0xfa5c, 0x20a7, + 0xfa80, 0x20ca, + 0xfad0, 0x07c9, + 0xfad1, 0x211a, + 0xfb40, 0x2146, + 0xfb80, 0x2185, + 0xfc40, 0x2202, + 0x8141, 0x1ecf, + 0x8143, 0x204c, + 0x8144, 0x2052, + 0x8150, 0x1ed1, + 0x815b, 0x1ed3, + 0x8160, 0x1ed6, + 0x8169, 0x1edb, + 0x8181, 0x1eed, + 0x81a8, 0x02e3, + 0x81a9, 0x02e2, + 0x81aa, 0x02e0, + 0x81ac, 0x204e, + 0x829f, 0x1eee, + 0x82a1, 0x1eef, + 0x82a3, 0x1ef0, + 0x82a5, 0x1ef1, + 0x82a7, 0x1ef2, + 0x82c1, 0x1ef3, + 0x82e1, 0x1ef4, + 0x82e3, 0x1ef5, + 0x82e5, 0x1ef6, + 0x82ec, 0x1ef7, + 0x8340, 0x1ef8, + 0x8342, 0x1ef9, + 0x8344, 0x1efa, + 0x8346, 0x1efb, + 0x8348, 0x1efc, + 0x8362, 0x1efd, + 0x8383, 0x1efe, + 0x8385, 0x1eff, + 0x8387, 0x1f00, + 0x838e, 0x1f01, + 0x8395, 0x1f02, + 0x849f, 0x1d39, + 0x84a0, 0x1d37, + 0x84a1, 0x1d47, + 0x84a2, 0x1d4f, + 0x84a3, 0x1d4b, + 0x84a4, 0x1d43, + 0x84a5, 0x1d63, + 0x84a6, 0x1d5b, + 0x84a7, 0x1d6b, + 0x84a8, 0x1d53, + 0x84a9, 0x1d73, + 0x84aa, 0x1d3a, + 0x84ab, 0x1d38, + 0x84ac, 0x1d4a, + 0x84ad, 0x1d52, + 0x84ae, 0x1d4e, + 0x84af, 0x1d46, + 0x84b0, 0x1d6a, + 0x84b1, 0x1d62, + 0x84b2, 0x1d72, + 0x84b3, 0x1d5a, + 0x84b4, 0x1d82, + 0x84b5, 0x1d66, + 0x84b6, 0x1d5f, + 0x84b7, 0x1d6e, + 0x84b8, 0x1d57, + 0x84b9, 0x1d79, + 0x84ba, 0x1d67, + 0x84bb, 0x1d5c, + 0x84bc, 0x1d6f, + 0x84bd, 0x1d54, + 0x84be, 0x1d76, + 0x875f, 0x1f04, + 0x8761, 0x2089, + 0x8762, 0x1f07, + 0x8763, 0x2093, + 0x8764, 0x1f09, + 0x8765, 0x2092, + 0x8766, 0x1f0b, + 0x8768, 0x2098, + 0x8769, 0x1f0e, + 0x876b, 0x209c, + 0x876c, 0x1f11, + 0x876e, 0x209d, + 0x8780, 0x1f14, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1278msRKSJVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0277, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1278msRKSJVMap2, 790 +}; + +static Gushort japan1283pvRKSJHMap2[436] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x8540, 0x00e8, + 0x8580, 0x0186, + 0x8581, 0x0128, + 0x859f, 0x0147, + 0x85de, 0x0187, + 0x8640, 0x01a6, + 0x8680, 0x01e5, + 0x8692, 0x0127, + 0x8693, 0x01f7, + 0x86a2, 0x1d37, + 0x8740, 0x1d83, + 0x875f, 0x1da1, + 0x8780, 0x1db8, + 0x8790, 0x02fa, + 0x8791, 0x02f9, + 0x8792, 0x0301, + 0x8793, 0x1dc8, + 0x879a, 0x0300, + 0x879b, 0x1dcf, + 0x889f, 0x0465, + 0x8940, 0x04c3, + 0x8980, 0x0502, + 0x8a40, 0x057f, + 0x8a80, 0x05be, + 0x8b40, 0x063b, + 0x8b80, 0x067a, + 0x8c40, 0x06f7, + 0x8c80, 0x0736, + 0x8d40, 0x07b3, + 0x8d80, 0x07f2, + 0x8e40, 0x086f, + 0x8e80, 0x08ae, + 0x8f40, 0x092b, + 0x8f80, 0x096a, + 0x9040, 0x09e7, + 0x9080, 0x0a26, + 0x9140, 0x0aa3, + 0x9180, 0x0ae2, + 0x9240, 0x0b5f, + 0x9280, 0x0b9e, + 0x9340, 0x0c1b, + 0x9380, 0x0c5a, + 0x9440, 0x0cd7, + 0x9480, 0x0d16, + 0x9540, 0x0d93, + 0x9580, 0x0dd2, + 0x9640, 0x0e4f, + 0x9680, 0x0e8e, + 0x9740, 0x0f0b, + 0x9780, 0x0f4a, + 0x9840, 0x0fc7, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a80, 0x1153, + 0x9b40, 0x11d0, + 0x9b80, 0x120f, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9d40, 0x1348, + 0x9d80, 0x1387, + 0x9e40, 0x1404, + 0x9e80, 0x1443, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe140, 0x1638, + 0xe180, 0x1677, + 0xe240, 0x16f4, + 0xe280, 0x1733, + 0xe340, 0x17b0, + 0xe380, 0x17ef, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe640, 0x19e4, + 0xe680, 0x1a23, + 0xe740, 0x1aa0, + 0xe780, 0x1adf, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xea40, 0x1cd4, + 0xea80, 0x1d13, + 0xeaa3, 0x205c, + 0xeb40, 0x0279, + 0xeb41, 0x1ecf, + 0xeb43, 0x027c, + 0xeb50, 0x1ed1, + 0xeb52, 0x028b, + 0xeb5b, 0x1ed3, + 0xeb5e, 0x0297, + 0xeb60, 0x1ed6, + 0xeb65, 0x029e, + 0xeb69, 0x1edb, + 0xeb7b, 0x02b4, + 0xeb80, 0x02b8, + 0xeb81, 0x1eed, + 0xeb82, 0x02ba, + 0xebb8, 0x02e5, + 0xebc8, 0x02ed, + 0xebda, 0x02f4, + 0xebf0, 0x0303, + 0xebfc, 0x030b, + 0xec4f, 0x030c, + 0xec60, 0x0316, + 0xec81, 0x0330, + 0xec9f, 0x1eee, + 0xeca0, 0x034b, + 0xeca1, 0x1eef, + 0xeca2, 0x034d, + 0xeca3, 0x1ef0, + 0xeca4, 0x034f, + 0xeca5, 0x1ef1, + 0xeca6, 0x0351, + 0xeca7, 0x1ef2, + 0xeca8, 0x0353, + 0xecc1, 0x1ef3, + 0xecc2, 0x036d, + 0xece1, 0x1ef4, + 0xece2, 0x038d, + 0xece3, 0x1ef5, + 0xece4, 0x038f, + 0xece5, 0x1ef6, + 0xece6, 0x0391, + 0xecec, 0x1ef7, + 0xeced, 0x0398, + 0xed40, 0x1ef8, + 0xed41, 0x039e, + 0xed42, 0x1ef9, + 0xed43, 0x03a0, + 0xed44, 0x1efa, + 0xed45, 0x03a2, + 0xed46, 0x1efb, + 0xed47, 0x03a4, + 0xed48, 0x1efc, + 0xed49, 0x03a6, + 0xed62, 0x1efd, + 0xed63, 0x03c0, + 0xed80, 0x03dc, + 0xed83, 0x1efe, + 0xed84, 0x03e0, + 0xed85, 0x1eff, + 0xed86, 0x03e2, + 0xed87, 0x1f00, + 0xed88, 0x03e4, + 0xed8e, 0x1f01, + 0xed8f, 0x03eb, + 0xed95, 0x1f02, + 0xed9f, 0x03f3, + 0xedbf, 0x040b, + 0xee40, 0x1d83, + 0xee5f, 0x1f04, + 0xee6f, 0x1db1, + 0xee80, 0x1f14, + 0xee82, 0x1dba, + 0xee90, 0x02fa, + 0xee91, 0x02f9, + 0xee92, 0x0301, + 0xee93, 0x1dc8, + 0xee9a, 0x0300, + 0xee9b, 0x1dcf, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1283pvRKSJHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, + 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, + 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000, + 0x0061, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0098, 0x00e4, 0x007c }, + japan1283pvRKSJHMap2, 218 +}; + +static Gushort japan1290msRKSJHMap2[340] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x8740, 0x1d83, + 0x875f, 0x1da1, + 0x8761, 0x1f66, + 0x8762, 0x1da4, + 0x8763, 0x1f68, + 0x8764, 0x1da6, + 0x8765, 0x1f6a, + 0x8766, 0x1da8, + 0x8768, 0x1f6c, + 0x8769, 0x1dab, + 0x876b, 0x1f6b, + 0x876c, 0x1dae, + 0x876e, 0x1f6f, + 0x876f, 0x1db1, + 0x877e, 0x2083, + 0x8780, 0x1db8, + 0x8784, 0x1f77, + 0x8785, 0x1dbd, + 0x8790, 0x02fa, + 0x8791, 0x02f9, + 0x8792, 0x0301, + 0x8793, 0x1dc8, + 0x879a, 0x0300, + 0x879b, 0x1dcf, + 0x889f, 0x0465, + 0x8940, 0x04c3, + 0x8980, 0x0502, + 0x8a40, 0x057f, + 0x8a80, 0x05be, + 0x8b40, 0x063b, + 0x8b80, 0x067a, + 0x8c40, 0x06f7, + 0x8c80, 0x0736, + 0x8d40, 0x07b3, + 0x8d80, 0x07f2, + 0x8e40, 0x086f, + 0x8e80, 0x08ae, + 0x8f40, 0x092b, + 0x8f80, 0x096a, + 0x9040, 0x09e7, + 0x9080, 0x0a26, + 0x9140, 0x0aa3, + 0x9180, 0x0ae2, + 0x9240, 0x0b5f, + 0x9280, 0x0b9e, + 0x9340, 0x0c1b, + 0x9380, 0x0c5a, + 0x9440, 0x0cd7, + 0x9480, 0x0d16, + 0x9540, 0x0d93, + 0x9580, 0x0dd2, + 0x9640, 0x0e4f, + 0x9680, 0x0e8e, + 0x9740, 0x0f0b, + 0x9780, 0x0f4a, + 0x9840, 0x0fc7, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a80, 0x1153, + 0x9b40, 0x11d0, + 0x9b80, 0x120f, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9d40, 0x1348, + 0x9d80, 0x1387, + 0x9e40, 0x1404, + 0x9e80, 0x1443, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe140, 0x1638, + 0xe180, 0x1677, + 0xe240, 0x16f4, + 0xe280, 0x1733, + 0xe340, 0x17b0, + 0xe380, 0x17ef, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe640, 0x19e4, + 0xe680, 0x1a23, + 0xe740, 0x1aa0, + 0xe780, 0x1adf, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xea40, 0x1cd4, + 0xea80, 0x1d13, + 0xeaa3, 0x205c, + 0xed40, 0x20a7, + 0xed80, 0x20e6, + 0xedb4, 0x07c9, + 0xedb5, 0x211a, + 0xee40, 0x2162, + 0xee80, 0x21a1, + 0xeeef, 0x1f9c, + 0xeef9, 0x02ef, + 0xeefa, 0x1f45, + 0xfa40, 0x1f9c, + 0xfa4a, 0x1d97, + 0xfa54, 0x02ef, + 0xfa55, 0x1f45, + 0xfa58, 0x1dc2, + 0xfa59, 0x1dba, + 0xfa5a, 0x1f77, + 0xfa5b, 0x0300, + 0xfa5c, 0x20a7, + 0xfa80, 0x20ca, + 0xfad0, 0x07c9, + 0xfad1, 0x211a, + 0xfb40, 0x2146, + 0xfb80, 0x2185, + 0xfc40, 0x2202, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1290msRKSJHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0277, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1290msRKSJHMap2, 170 +}; + +static Gushort japan1290msRKSJVMap2[496] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x8740, 0x1d83, + 0x875f, 0x1da1, + 0x8761, 0x1f66, + 0x8762, 0x1da4, + 0x8763, 0x1f68, + 0x8764, 0x1da6, + 0x8765, 0x1f6a, + 0x8766, 0x1da8, + 0x8768, 0x1f6c, + 0x8769, 0x1dab, + 0x876b, 0x1f6b, + 0x876c, 0x1dae, + 0x876e, 0x1f6f, + 0x876f, 0x1db1, + 0x877e, 0x2083, + 0x8780, 0x1db8, + 0x8784, 0x1f77, + 0x8785, 0x1dbd, + 0x8790, 0x02fa, + 0x8791, 0x02f9, + 0x8792, 0x0301, + 0x8793, 0x1dc8, + 0x879a, 0x0300, + 0x879b, 0x1dcf, + 0x889f, 0x0465, + 0x8940, 0x04c3, + 0x8980, 0x0502, + 0x8a40, 0x057f, + 0x8a80, 0x05be, + 0x8b40, 0x063b, + 0x8b80, 0x067a, + 0x8c40, 0x06f7, + 0x8c80, 0x0736, + 0x8d40, 0x07b3, + 0x8d80, 0x07f2, + 0x8e40, 0x086f, + 0x8e80, 0x08ae, + 0x8f40, 0x092b, + 0x8f80, 0x096a, + 0x9040, 0x09e7, + 0x9080, 0x0a26, + 0x9140, 0x0aa3, + 0x9180, 0x0ae2, + 0x9240, 0x0b5f, + 0x9280, 0x0b9e, + 0x9340, 0x0c1b, + 0x9380, 0x0c5a, + 0x9440, 0x0cd7, + 0x9480, 0x0d16, + 0x9540, 0x0d93, + 0x9580, 0x0dd2, + 0x9640, 0x0e4f, + 0x9680, 0x0e8e, + 0x9740, 0x0f0b, + 0x9780, 0x0f4a, + 0x9840, 0x0fc7, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a80, 0x1153, + 0x9b40, 0x11d0, + 0x9b80, 0x120f, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9d40, 0x1348, + 0x9d80, 0x1387, + 0x9e40, 0x1404, + 0x9e80, 0x1443, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe140, 0x1638, + 0xe180, 0x1677, + 0xe240, 0x16f4, + 0xe280, 0x1733, + 0xe340, 0x17b0, + 0xe380, 0x17ef, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe640, 0x19e4, + 0xe680, 0x1a23, + 0xe740, 0x1aa0, + 0xe780, 0x1adf, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xea40, 0x1cd4, + 0xea80, 0x1d13, + 0xeaa3, 0x205c, + 0xed40, 0x20a7, + 0xed80, 0x20e6, + 0xedb4, 0x07c9, + 0xedb5, 0x211a, + 0xee40, 0x2162, + 0xee80, 0x21a1, + 0xeeef, 0x1f9c, + 0xeef9, 0x02ef, + 0xeefa, 0x1f45, + 0xfa40, 0x1f9c, + 0xfa4a, 0x1d97, + 0xfa54, 0x02ef, + 0xfa55, 0x1f45, + 0xfa58, 0x1dc2, + 0xfa59, 0x1dba, + 0xfa5a, 0x1f77, + 0xfa5b, 0x0300, + 0xfa5c, 0x20a7, + 0xfa80, 0x20ca, + 0xfad0, 0x07c9, + 0xfad1, 0x211a, + 0xfb40, 0x2146, + 0xfb80, 0x2185, + 0xfc40, 0x2202, + 0x8141, 0x1ecf, + 0x8143, 0x204c, + 0x8144, 0x2052, + 0x8150, 0x1ed1, + 0x815b, 0x1ed3, + 0x8160, 0x1ed6, + 0x8169, 0x1edb, + 0x8181, 0x1eed, + 0x81a8, 0x02e3, + 0x81a9, 0x02e2, + 0x81aa, 0x02e0, + 0x81ac, 0x204e, + 0x829f, 0x1eee, + 0x82a1, 0x1eef, + 0x82a3, 0x1ef0, + 0x82a5, 0x1ef1, + 0x82a7, 0x1ef2, + 0x82c1, 0x1ef3, + 0x82e1, 0x1ef4, + 0x82e3, 0x1ef5, + 0x82e5, 0x1ef6, + 0x82ec, 0x1ef7, + 0x8340, 0x1ef8, + 0x8342, 0x1ef9, + 0x8344, 0x1efa, + 0x8346, 0x1efb, + 0x8348, 0x1efc, + 0x8362, 0x1efd, + 0x8383, 0x1efe, + 0x8385, 0x1eff, + 0x8387, 0x1f00, + 0x838e, 0x1f01, + 0x8395, 0x1f02, + 0x849f, 0x1d39, + 0x84a0, 0x1d37, + 0x84a1, 0x1d47, + 0x84a2, 0x1d4f, + 0x84a3, 0x1d4b, + 0x84a4, 0x1d43, + 0x84a5, 0x1d63, + 0x84a6, 0x1d5b, + 0x84a7, 0x1d6b, + 0x84a8, 0x1d53, + 0x84a9, 0x1d73, + 0x84aa, 0x1d3a, + 0x84ab, 0x1d38, + 0x84ac, 0x1d4a, + 0x84ad, 0x1d52, + 0x84ae, 0x1d4e, + 0x84af, 0x1d46, + 0x84b0, 0x1d6a, + 0x84b1, 0x1d62, + 0x84b2, 0x1d72, + 0x84b3, 0x1d5a, + 0x84b4, 0x1d82, + 0x84b5, 0x1d66, + 0x84b6, 0x1d5f, + 0x84b7, 0x1d6e, + 0x84b8, 0x1d57, + 0x84b9, 0x1d79, + 0x84ba, 0x1d67, + 0x84bb, 0x1d5c, + 0x84bc, 0x1d6f, + 0x84bd, 0x1d54, + 0x84be, 0x1d76, + 0x875f, 0x1f04, + 0x8761, 0x2089, + 0x8762, 0x1f07, + 0x8763, 0x2093, + 0x8764, 0x1f09, + 0x8765, 0x2092, + 0x8766, 0x1f0b, + 0x8768, 0x2098, + 0x8769, 0x1f0e, + 0x876b, 0x209c, + 0x876c, 0x1f11, + 0x876e, 0x209d, + 0x8780, 0x1f14, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1290msRKSJVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0277, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1290msRKSJVMap2, 248 +}; + +static Gushort japan1290mspRKSJHMap2[340] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x8740, 0x1d83, + 0x875f, 0x1da1, + 0x8761, 0x1f66, + 0x8762, 0x1da4, + 0x8763, 0x1f68, + 0x8764, 0x1da6, + 0x8765, 0x1f6a, + 0x8766, 0x1da8, + 0x8768, 0x1f6c, + 0x8769, 0x1dab, + 0x876b, 0x1f6b, + 0x876c, 0x1dae, + 0x876e, 0x1f6f, + 0x876f, 0x1db1, + 0x877e, 0x2083, + 0x8780, 0x1db8, + 0x8784, 0x1f77, + 0x8785, 0x1dbd, + 0x8790, 0x02fa, + 0x8791, 0x02f9, + 0x8792, 0x0301, + 0x8793, 0x1dc8, + 0x879a, 0x0300, + 0x879b, 0x1dcf, + 0x889f, 0x0465, + 0x8940, 0x04c3, + 0x8980, 0x0502, + 0x8a40, 0x057f, + 0x8a80, 0x05be, + 0x8b40, 0x063b, + 0x8b80, 0x067a, + 0x8c40, 0x06f7, + 0x8c80, 0x0736, + 0x8d40, 0x07b3, + 0x8d80, 0x07f2, + 0x8e40, 0x086f, + 0x8e80, 0x08ae, + 0x8f40, 0x092b, + 0x8f80, 0x096a, + 0x9040, 0x09e7, + 0x9080, 0x0a26, + 0x9140, 0x0aa3, + 0x9180, 0x0ae2, + 0x9240, 0x0b5f, + 0x9280, 0x0b9e, + 0x9340, 0x0c1b, + 0x9380, 0x0c5a, + 0x9440, 0x0cd7, + 0x9480, 0x0d16, + 0x9540, 0x0d93, + 0x9580, 0x0dd2, + 0x9640, 0x0e4f, + 0x9680, 0x0e8e, + 0x9740, 0x0f0b, + 0x9780, 0x0f4a, + 0x9840, 0x0fc7, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a80, 0x1153, + 0x9b40, 0x11d0, + 0x9b80, 0x120f, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9d40, 0x1348, + 0x9d80, 0x1387, + 0x9e40, 0x1404, + 0x9e80, 0x1443, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe140, 0x1638, + 0xe180, 0x1677, + 0xe240, 0x16f4, + 0xe280, 0x1733, + 0xe340, 0x17b0, + 0xe380, 0x17ef, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe640, 0x19e4, + 0xe680, 0x1a23, + 0xe740, 0x1aa0, + 0xe780, 0x1adf, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xea40, 0x1cd4, + 0xea80, 0x1d13, + 0xeaa3, 0x205c, + 0xed40, 0x20a7, + 0xed80, 0x20e6, + 0xedb4, 0x07c9, + 0xedb5, 0x211a, + 0xee40, 0x2162, + 0xee80, 0x21a1, + 0xeeef, 0x1f9c, + 0xeef9, 0x02ef, + 0xeefa, 0x1f45, + 0xfa40, 0x1f9c, + 0xfa4a, 0x1d97, + 0xfa54, 0x02ef, + 0xfa55, 0x1f45, + 0xfa58, 0x1dc2, + 0xfa59, 0x1dba, + 0xfa5a, 0x1f77, + 0xfa5b, 0x0300, + 0xfa5c, 0x20a7, + 0xfa80, 0x20ca, + 0xfad0, 0x07c9, + 0xfad1, 0x211a, + 0xfb40, 0x2146, + 0xfb80, 0x2185, + 0xfc40, 0x2202, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1290mspRKSJHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, + 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, + 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1290mspRKSJHMap2, 170 +}; + +static Gushort japan1290mspRKSJVMap2[496] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x8740, 0x1d83, + 0x875f, 0x1da1, + 0x8761, 0x1f66, + 0x8762, 0x1da4, + 0x8763, 0x1f68, + 0x8764, 0x1da6, + 0x8765, 0x1f6a, + 0x8766, 0x1da8, + 0x8768, 0x1f6c, + 0x8769, 0x1dab, + 0x876b, 0x1f6b, + 0x876c, 0x1dae, + 0x876e, 0x1f6f, + 0x876f, 0x1db1, + 0x877e, 0x2083, + 0x8780, 0x1db8, + 0x8784, 0x1f77, + 0x8785, 0x1dbd, + 0x8790, 0x02fa, + 0x8791, 0x02f9, + 0x8792, 0x0301, + 0x8793, 0x1dc8, + 0x879a, 0x0300, + 0x879b, 0x1dcf, + 0x889f, 0x0465, + 0x8940, 0x04c3, + 0x8980, 0x0502, + 0x8a40, 0x057f, + 0x8a80, 0x05be, + 0x8b40, 0x063b, + 0x8b80, 0x067a, + 0x8c40, 0x06f7, + 0x8c80, 0x0736, + 0x8d40, 0x07b3, + 0x8d80, 0x07f2, + 0x8e40, 0x086f, + 0x8e80, 0x08ae, + 0x8f40, 0x092b, + 0x8f80, 0x096a, + 0x9040, 0x09e7, + 0x9080, 0x0a26, + 0x9140, 0x0aa3, + 0x9180, 0x0ae2, + 0x9240, 0x0b5f, + 0x9280, 0x0b9e, + 0x9340, 0x0c1b, + 0x9380, 0x0c5a, + 0x9440, 0x0cd7, + 0x9480, 0x0d16, + 0x9540, 0x0d93, + 0x9580, 0x0dd2, + 0x9640, 0x0e4f, + 0x9680, 0x0e8e, + 0x9740, 0x0f0b, + 0x9780, 0x0f4a, + 0x9840, 0x0fc7, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a80, 0x1153, + 0x9b40, 0x11d0, + 0x9b80, 0x120f, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9d40, 0x1348, + 0x9d80, 0x1387, + 0x9e40, 0x1404, + 0x9e80, 0x1443, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe140, 0x1638, + 0xe180, 0x1677, + 0xe240, 0x16f4, + 0xe280, 0x1733, + 0xe340, 0x17b0, + 0xe380, 0x17ef, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe640, 0x19e4, + 0xe680, 0x1a23, + 0xe740, 0x1aa0, + 0xe780, 0x1adf, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xea40, 0x1cd4, + 0xea80, 0x1d13, + 0xeaa3, 0x205c, + 0xed40, 0x20a7, + 0xed80, 0x20e6, + 0xedb4, 0x07c9, + 0xedb5, 0x211a, + 0xee40, 0x2162, + 0xee80, 0x21a1, + 0xeeef, 0x1f9c, + 0xeef9, 0x02ef, + 0xeefa, 0x1f45, + 0xfa40, 0x1f9c, + 0xfa4a, 0x1d97, + 0xfa54, 0x02ef, + 0xfa55, 0x1f45, + 0xfa58, 0x1dc2, + 0xfa59, 0x1dba, + 0xfa5a, 0x1f77, + 0xfa5b, 0x0300, + 0xfa5c, 0x20a7, + 0xfa80, 0x20ca, + 0xfad0, 0x07c9, + 0xfad1, 0x211a, + 0xfb40, 0x2146, + 0xfb80, 0x2185, + 0xfc40, 0x2202, + 0x8141, 0x1ecf, + 0x8143, 0x204c, + 0x8144, 0x2052, + 0x8150, 0x1ed1, + 0x815b, 0x1ed3, + 0x8160, 0x1ed6, + 0x8169, 0x1edb, + 0x8181, 0x1eed, + 0x81a8, 0x02e3, + 0x81a9, 0x02e2, + 0x81aa, 0x02e0, + 0x81ac, 0x204e, + 0x829f, 0x1eee, + 0x82a1, 0x1eef, + 0x82a3, 0x1ef0, + 0x82a5, 0x1ef1, + 0x82a7, 0x1ef2, + 0x82c1, 0x1ef3, + 0x82e1, 0x1ef4, + 0x82e3, 0x1ef5, + 0x82e5, 0x1ef6, + 0x82ec, 0x1ef7, + 0x8340, 0x1ef8, + 0x8342, 0x1ef9, + 0x8344, 0x1efa, + 0x8346, 0x1efb, + 0x8348, 0x1efc, + 0x8362, 0x1efd, + 0x8383, 0x1efe, + 0x8385, 0x1eff, + 0x8387, 0x1f00, + 0x838e, 0x1f01, + 0x8395, 0x1f02, + 0x849f, 0x1d39, + 0x84a0, 0x1d37, + 0x84a1, 0x1d47, + 0x84a2, 0x1d4f, + 0x84a3, 0x1d4b, + 0x84a4, 0x1d43, + 0x84a5, 0x1d63, + 0x84a6, 0x1d5b, + 0x84a7, 0x1d6b, + 0x84a8, 0x1d53, + 0x84a9, 0x1d73, + 0x84aa, 0x1d3a, + 0x84ab, 0x1d38, + 0x84ac, 0x1d4a, + 0x84ad, 0x1d52, + 0x84ae, 0x1d4e, + 0x84af, 0x1d46, + 0x84b0, 0x1d6a, + 0x84b1, 0x1d62, + 0x84b2, 0x1d72, + 0x84b3, 0x1d5a, + 0x84b4, 0x1d82, + 0x84b5, 0x1d66, + 0x84b6, 0x1d5f, + 0x84b7, 0x1d6e, + 0x84b8, 0x1d57, + 0x84b9, 0x1d79, + 0x84ba, 0x1d67, + 0x84bb, 0x1d5c, + 0x84bc, 0x1d6f, + 0x84bd, 0x1d54, + 0x84be, 0x1d76, + 0x875f, 0x1f04, + 0x8761, 0x2089, + 0x8762, 0x1f07, + 0x8763, 0x2093, + 0x8764, 0x1f09, + 0x8765, 0x2092, + 0x8766, 0x1f0b, + 0x8768, 0x2098, + 0x8769, 0x1f0e, + 0x876b, 0x209c, + 0x876c, 0x1f11, + 0x876e, 0x209d, + 0x8780, 0x1f14, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1290mspRKSJVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, + 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, + 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan1290mspRKSJVMap2, 248 +}; + +static Gushort japan1290pvRKSJHMap2[518] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x8540, 0x1d83, + 0x855e, 0x1f87, + 0x857c, 0x205e, + 0x8580, 0x2061, + 0x8591, 0x1f7d, + 0x859f, 0x1d97, + 0x85a9, 0x2021, + 0x85ab, 0x2067, + 0x85b3, 0x1f9c, + 0x85bd, 0x206a, + 0x85db, 0x1fb0, + 0x8640, 0x1db1, + 0x8641, 0x1ffa, + 0x8642, 0x1db2, + 0x8643, 0x1f54, + 0x8644, 0x1f56, + 0x8645, 0x206f, + 0x8646, 0x1db7, + 0x8647, 0x1f57, + 0x8648, 0x1db3, + 0x8649, 0x1f55, + 0x864a, 0x1db4, + 0x864b, 0x2070, + 0x864c, 0x1db5, + 0x864e, 0x1f65, + 0x864f, 0x1f58, + 0x8656, 0x2071, + 0x8657, 0x1f64, + 0x8658, 0x1f62, + 0x865a, 0x1f5f, + 0x865d, 0x2072, + 0x869b, 0x1dba, + 0x869e, 0x2073, + 0x869f, 0x1f52, + 0x86a0, 0x1f50, + 0x86a2, 0x1f53, + 0x86a3, 0x2013, + 0x86a4, 0x2015, + 0x86a5, 0x2014, + 0x86a6, 0x2016, + 0x86b3, 0x1f7a, + 0x86b4, 0x1f78, + 0x86b5, 0x2074, + 0x86c7, 0x201b, + 0x86cb, 0x2075, + 0x86cf, 0x1f4e, + 0x86d0, 0x1f4d, + 0x86d1, 0x1f4c, + 0x86d2, 0x1f4b, + 0x86d3, 0x200e, + 0x8740, 0x2005, + 0x8747, 0x1fd6, + 0x8748, 0x200c, + 0x8749, 0x1fd1, + 0x874a, 0x1fca, + 0x874b, 0x1dc4, + 0x874c, 0x1fd7, + 0x874d, 0x1dc2, + 0x874e, 0x1fd2, + 0x874f, 0x1fcd, + 0x8750, 0x1dc3, + 0x8751, 0x1fd5, + 0x8752, 0x1fd3, + 0x8753, 0x1fcf, + 0x8754, 0x1fd4, + 0x8755, 0x1fd0, + 0x8756, 0x1fcb, + 0x8758, 0x1fce, + 0x8791, 0x207d, + 0x8793, 0x1dbd, + 0x8798, 0x1fda, + 0x8799, 0x1fe5, + 0x879a, 0x207f, + 0x879b, 0x1fde, + 0x879c, 0x1fff, + 0x879d, 0x2080, + 0x879e, 0x201f, + 0x879f, 0x1da1, + 0x87a0, 0x1f66, + 0x87a1, 0x1da4, + 0x87a2, 0x1da2, + 0x87a3, 0x1f67, + 0x87a4, 0x1ff7, + 0x87a5, 0x2087, + 0x87a7, 0x1f6a, + 0x87a8, 0x1da8, + 0x87a9, 0x1f68, + 0x87ab, 0x1da6, + 0x87ac, 0x1da9, + 0x87ad, 0x1daf, + 0x87ae, 0x1f6e, + 0x87af, 0x1f6c, + 0x87b0, 0x1dab, + 0x87b1, 0x1f6d, + 0x87b2, 0x1f6b, + 0x87b3, 0x1dac, + 0x87b4, 0x1f6f, + 0x87b5, 0x1dae, + 0x87bd, 0x1f70, + 0x87be, 0x1f73, + 0x87c0, 0x1f71, + 0x87e5, 0x1dc5, + 0x87e8, 0x2083, + 0x87fa, 0x1f76, + 0x87fb, 0x2081, + 0x8840, 0x1dc8, + 0x8841, 0x1dcd, + 0x8854, 0x1db8, + 0x8868, 0x1f16, + 0x886a, 0x2079, + 0x889f, 0x0465, + 0x8940, 0x04c3, + 0x8980, 0x0502, + 0x8a40, 0x057f, + 0x8a80, 0x05be, + 0x8b40, 0x063b, + 0x8b80, 0x067a, + 0x8c40, 0x06f7, + 0x8c80, 0x0736, + 0x8d40, 0x07b3, + 0x8d80, 0x07f2, + 0x8e40, 0x086f, + 0x8e80, 0x08ae, + 0x8f40, 0x092b, + 0x8f80, 0x096a, + 0x9040, 0x09e7, + 0x9080, 0x0a26, + 0x9140, 0x0aa3, + 0x9180, 0x0ae2, + 0x9240, 0x0b5f, + 0x9280, 0x0b9e, + 0x9340, 0x0c1b, + 0x9380, 0x0c5a, + 0x9440, 0x0cd7, + 0x9480, 0x0d16, + 0x9540, 0x0d93, + 0x9580, 0x0dd2, + 0x9640, 0x0e4f, + 0x9680, 0x0e8e, + 0x9740, 0x0f0b, + 0x9780, 0x0f4a, + 0x9840, 0x0fc7, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a80, 0x1153, + 0x9b40, 0x11d0, + 0x9b80, 0x120f, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9d40, 0x1348, + 0x9d80, 0x1387, + 0x9e40, 0x1404, + 0x9e80, 0x1443, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe140, 0x1638, + 0xe180, 0x1677, + 0xe240, 0x16f4, + 0xe280, 0x1733, + 0xe340, 0x17b0, + 0xe380, 0x17ef, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe640, 0x19e4, + 0xe680, 0x1a23, + 0xe740, 0x1aa0, + 0xe780, 0x1adf, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xea40, 0x1cd4, + 0xea80, 0x1d13, + 0xeaa3, 0x205c, + 0xeb41, 0x1ecf, + 0xeb50, 0x1ed1, + 0xeb5b, 0x1ed3, + 0xeb60, 0x1ed6, + 0xeb69, 0x1edb, + 0xeb81, 0x1eed, + 0xec9f, 0x1eee, + 0xeca1, 0x1eef, + 0xeca3, 0x1ef0, + 0xeca5, 0x1ef1, + 0xeca7, 0x1ef2, + 0xecc1, 0x1ef3, + 0xece1, 0x1ef4, + 0xece3, 0x1ef5, + 0xece5, 0x1ef6, + 0xecec, 0x1ef7, + 0xed40, 0x1ef8, + 0xed42, 0x1ef9, + 0xed44, 0x1efa, + 0xed46, 0x1efb, + 0xed48, 0x1efc, + 0xed62, 0x1efd, + 0xed83, 0x1efe, + 0xed85, 0x1eff, + 0xed87, 0x1f00, + 0xed8e, 0x1f01, + 0xed95, 0x1f02, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1290pvRKSJHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, + 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, + 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000, + 0x0061, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0098, 0x00e4, 0x007c }, + japan1290pvRKSJHMap2, 259 +}; + +static Gushort japan1290pvRKSJVMap2[620] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x8540, 0x1d83, + 0x855e, 0x1f87, + 0x857c, 0x205e, + 0x8580, 0x2061, + 0x8591, 0x1f7d, + 0x859f, 0x1d97, + 0x85a9, 0x2021, + 0x85ab, 0x2067, + 0x85b3, 0x1f9c, + 0x85bd, 0x206a, + 0x85db, 0x1fb0, + 0x8640, 0x1db1, + 0x8641, 0x1ffa, + 0x8642, 0x1db2, + 0x8643, 0x1f54, + 0x8644, 0x1f56, + 0x8645, 0x206f, + 0x8646, 0x1db7, + 0x8647, 0x1f57, + 0x8648, 0x1db3, + 0x8649, 0x1f55, + 0x864a, 0x1db4, + 0x864b, 0x2070, + 0x864c, 0x1db5, + 0x864e, 0x1f65, + 0x864f, 0x1f58, + 0x8656, 0x2071, + 0x8657, 0x1f64, + 0x8658, 0x1f62, + 0x865a, 0x1f5f, + 0x865d, 0x2072, + 0x869b, 0x1dba, + 0x869e, 0x2073, + 0x869f, 0x1f52, + 0x86a0, 0x1f50, + 0x86a2, 0x1f53, + 0x86a3, 0x2013, + 0x86a4, 0x2015, + 0x86a5, 0x2014, + 0x86a6, 0x2016, + 0x86b3, 0x1f7a, + 0x86b4, 0x1f78, + 0x86b5, 0x2074, + 0x86c7, 0x201b, + 0x86cb, 0x2075, + 0x86cf, 0x1f4e, + 0x86d0, 0x1f4d, + 0x86d1, 0x1f4c, + 0x86d2, 0x1f4b, + 0x86d3, 0x200e, + 0x8740, 0x2005, + 0x8747, 0x1fd6, + 0x8748, 0x200c, + 0x8749, 0x1fd1, + 0x874a, 0x1fca, + 0x874b, 0x1dc4, + 0x874c, 0x1fd7, + 0x874d, 0x1dc2, + 0x874e, 0x1fd2, + 0x874f, 0x1fcd, + 0x8750, 0x1dc3, + 0x8751, 0x1fd5, + 0x8752, 0x1fd3, + 0x8753, 0x1fcf, + 0x8754, 0x1fd4, + 0x8755, 0x1fd0, + 0x8756, 0x1fcb, + 0x8758, 0x1fce, + 0x8791, 0x207d, + 0x8793, 0x1dbd, + 0x8798, 0x1fda, + 0x8799, 0x1fe5, + 0x879a, 0x207f, + 0x879b, 0x1fde, + 0x879c, 0x1fff, + 0x879d, 0x2080, + 0x879e, 0x201f, + 0x879f, 0x1da1, + 0x87a0, 0x1f66, + 0x87a1, 0x1da4, + 0x87a2, 0x1da2, + 0x87a3, 0x1f67, + 0x87a4, 0x1ff7, + 0x87a5, 0x2087, + 0x87a7, 0x1f6a, + 0x87a8, 0x1da8, + 0x87a9, 0x1f68, + 0x87ab, 0x1da6, + 0x87ac, 0x1da9, + 0x87ad, 0x1daf, + 0x87ae, 0x1f6e, + 0x87af, 0x1f6c, + 0x87b0, 0x1dab, + 0x87b1, 0x1f6d, + 0x87b2, 0x1f6b, + 0x87b3, 0x1dac, + 0x87b4, 0x1f6f, + 0x87b5, 0x1dae, + 0x87bd, 0x1f70, + 0x87be, 0x1f73, + 0x87c0, 0x1f71, + 0x87e5, 0x1dc5, + 0x87e8, 0x2083, + 0x87fa, 0x1f76, + 0x87fb, 0x2081, + 0x8840, 0x1dc8, + 0x8841, 0x1dcd, + 0x8854, 0x1db8, + 0x8868, 0x1f16, + 0x886a, 0x2079, + 0x889f, 0x0465, + 0x8940, 0x04c3, + 0x8980, 0x0502, + 0x8a40, 0x057f, + 0x8a80, 0x05be, + 0x8b40, 0x063b, + 0x8b80, 0x067a, + 0x8c40, 0x06f7, + 0x8c80, 0x0736, + 0x8d40, 0x07b3, + 0x8d80, 0x07f2, + 0x8e40, 0x086f, + 0x8e80, 0x08ae, + 0x8f40, 0x092b, + 0x8f80, 0x096a, + 0x9040, 0x09e7, + 0x9080, 0x0a26, + 0x9140, 0x0aa3, + 0x9180, 0x0ae2, + 0x9240, 0x0b5f, + 0x9280, 0x0b9e, + 0x9340, 0x0c1b, + 0x9380, 0x0c5a, + 0x9440, 0x0cd7, + 0x9480, 0x0d16, + 0x9540, 0x0d93, + 0x9580, 0x0dd2, + 0x9640, 0x0e4f, + 0x9680, 0x0e8e, + 0x9740, 0x0f0b, + 0x9780, 0x0f4a, + 0x9840, 0x0fc7, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a80, 0x1153, + 0x9b40, 0x11d0, + 0x9b80, 0x120f, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9d40, 0x1348, + 0x9d80, 0x1387, + 0x9e40, 0x1404, + 0x9e80, 0x1443, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe140, 0x1638, + 0xe180, 0x1677, + 0xe240, 0x16f4, + 0xe280, 0x1733, + 0xe340, 0x17b0, + 0xe380, 0x17ef, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe640, 0x19e4, + 0xe680, 0x1a23, + 0xe740, 0x1aa0, + 0xe780, 0x1adf, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xea40, 0x1cd4, + 0xea80, 0x1d13, + 0xeaa3, 0x205c, + 0xeb41, 0x1ecf, + 0xeb50, 0x1ed1, + 0xeb5b, 0x1ed3, + 0xeb60, 0x1ed6, + 0xeb69, 0x1edb, + 0xeb81, 0x1eed, + 0xec9f, 0x1eee, + 0xeca1, 0x1eef, + 0xeca3, 0x1ef0, + 0xeca5, 0x1ef1, + 0xeca7, 0x1ef2, + 0xecc1, 0x1ef3, + 0xece1, 0x1ef4, + 0xece3, 0x1ef5, + 0xece5, 0x1ef6, + 0xecec, 0x1ef7, + 0xed40, 0x1ef8, + 0xed42, 0x1ef9, + 0xed44, 0x1efa, + 0xed46, 0x1efb, + 0xed48, 0x1efc, + 0xed62, 0x1efd, + 0xed83, 0x1efe, + 0xed85, 0x1eff, + 0xed87, 0x1f00, + 0xed8e, 0x1f01, + 0xed95, 0x1f02, + 0x8141, 0x1ecf, + 0x8150, 0x1ed1, + 0x815b, 0x1ed3, + 0x8160, 0x1ed6, + 0x8169, 0x1edb, + 0x8181, 0x1eed, + 0x829f, 0x1eee, + 0x82a1, 0x1eef, + 0x82a3, 0x1ef0, + 0x82a5, 0x1ef1, + 0x82a7, 0x1ef2, + 0x82c1, 0x1ef3, + 0x82e1, 0x1ef4, + 0x82e3, 0x1ef5, + 0x82e5, 0x1ef6, + 0x82ec, 0x1ef7, + 0x8340, 0x1ef8, + 0x8342, 0x1ef9, + 0x8344, 0x1efa, + 0x8346, 0x1efb, + 0x8348, 0x1efc, + 0x8362, 0x1efd, + 0x8383, 0x1efe, + 0x8385, 0x1eff, + 0x8387, 0x1f00, + 0x838e, 0x1f01, + 0x8395, 0x1f02, + 0x879f, 0x1f04, + 0x87a0, 0x2089, + 0x87a1, 0x1f07, + 0x87a2, 0x1f05, + 0x87a3, 0x208a, + 0x87a4, 0x208d, + 0x87a6, 0x2091, + 0x87a8, 0x1f0b, + 0x87a9, 0x2093, + 0x87ab, 0x1f09, + 0x87ac, 0x1f0c, + 0x87ad, 0x1f12, + 0x87ae, 0x2097, + 0x87b0, 0x1f0e, + 0x87b1, 0x209b, + 0x87b3, 0x1f0f, + 0x87b4, 0x209d, + 0x87b5, 0x1f11, + 0x87bd, 0x209e, + 0x87be, 0x20a1, + 0x87bf, 0x20a4, + 0x87c0, 0x20a6, + 0x87c1, 0x20a5, + 0x87fa, 0x2084, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan1290pvRKSJVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, + 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f, 0x0010, + 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, 0x0018, + 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f, 0x0020, + 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, 0x0028, + 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f, 0x0030, + 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, + 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, + 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, 0x0048, + 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f, 0x0050, + 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, 0x0058, + 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f, 0x0000, + 0x0061, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0098, 0x00e4, 0x007c }, + japan1290pvRKSJVMap2, 310 +}; + +static Gushort japan12AddHMap2[1266] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2221, 0x02d7, + 0x223a, 0x02e5, + 0x224a, 0x02ed, + 0x225c, 0x02f4, + 0x2272, 0x0303, + 0x227e, 0x030b, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2474, 0x1f16, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x2821, 0x1d37, + 0x2822, 0x1d39, + 0x2823, 0x1d43, + 0x2824, 0x1d47, + 0x2825, 0x1d4f, + 0x2826, 0x1d4b, + 0x2827, 0x1d53, + 0x2828, 0x1d63, + 0x2829, 0x1d5b, + 0x282a, 0x1d6b, + 0x282b, 0x1d73, + 0x282c, 0x1d38, + 0x282d, 0x1d3a, + 0x282e, 0x1d46, + 0x282f, 0x1d4a, + 0x2830, 0x1d52, + 0x2831, 0x1d4e, + 0x2832, 0x1d5a, + 0x2833, 0x1d6a, + 0x2834, 0x1d62, + 0x2835, 0x1d72, + 0x2836, 0x1d82, + 0x2837, 0x1d57, + 0x2838, 0x1d66, + 0x2839, 0x1d5f, + 0x283a, 0x1d6e, + 0x283b, 0x1d76, + 0x283c, 0x1d54, + 0x283d, 0x1d67, + 0x283e, 0x1d5c, + 0x283f, 0x1d6f, + 0x2840, 0x1d79, + 0x3021, 0x0465, + 0x3022, 0x1dd1, + 0x3023, 0x0467, + 0x3032, 0x1f19, + 0x3033, 0x0477, + 0x303b, 0x1dd2, + 0x303c, 0x0480, + 0x306e, 0x1dd3, + 0x306f, 0x04b3, + 0x3071, 0x1f1a, + 0x3072, 0x04b6, + 0x3073, 0x1dd4, + 0x3074, 0x04b8, + 0x307c, 0x1dd5, + 0x307d, 0x04c1, + 0x3121, 0x04c3, + 0x312a, 0x1dd6, + 0x312b, 0x04cd, + 0x3133, 0x1f1b, + 0x3134, 0x04d6, + 0x3135, 0x1dd7, + 0x3136, 0x04d8, + 0x3139, 0x1f1c, + 0x313a, 0x04dc, + 0x313d, 0x1dda, + 0x313e, 0x04e0, + 0x3142, 0x1ddb, + 0x3143, 0x04e5, + 0x316b, 0x1ddc, + 0x316c, 0x050e, + 0x3221, 0x0521, + 0x3228, 0x1ddd, + 0x3229, 0x0529, + 0x322a, 0x1dde, + 0x322b, 0x052b, + 0x3260, 0x1ddf, + 0x3261, 0x0561, + 0x3267, 0x1f1d, + 0x3268, 0x0568, + 0x327a, 0x1de0, + 0x327b, 0x057b, + 0x3321, 0x057f, + 0x3322, 0x1de2, + 0x3323, 0x0581, + 0x336b, 0x1de4, + 0x336c, 0x05ca, + 0x3373, 0x1de5, + 0x3374, 0x05d2, + 0x337a, 0x1de6, + 0x337b, 0x05d9, + 0x3421, 0x05dd, + 0x3442, 0x1de7, + 0x3443, 0x05ff, + 0x344d, 0x1de8, + 0x344e, 0x060a, + 0x3465, 0x1de9, + 0x3466, 0x0622, + 0x3521, 0x063b, + 0x352b, 0x1dea, + 0x352c, 0x0646, + 0x3540, 0x1deb, + 0x3541, 0x065b, + 0x3562, 0x1f1e, + 0x3563, 0x067d, + 0x3568, 0x1f1f, + 0x3569, 0x0683, + 0x3621, 0x0699, + 0x3622, 0x1dec, + 0x3623, 0x069b, + 0x362a, 0x1ded, + 0x362b, 0x06a3, + 0x3642, 0x1f20, + 0x3643, 0x06bb, + 0x364f, 0x1dee, + 0x3650, 0x06c8, + 0x366d, 0x1def, + 0x366e, 0x06e6, + 0x3674, 0x1df0, + 0x3675, 0x06ed, + 0x367b, 0x1df1, + 0x367c, 0x06f4, + 0x367d, 0x1df2, + 0x367e, 0x06f6, + 0x3721, 0x06f7, + 0x3737, 0x1df4, + 0x3738, 0x070e, + 0x3752, 0x1df7, + 0x3753, 0x0729, + 0x3771, 0x1dfa, + 0x3772, 0x0748, + 0x377d, 0x1f21, + 0x377e, 0x1dfc, + 0x3821, 0x0755, + 0x3834, 0x1dfd, + 0x3835, 0x0769, + 0x3841, 0x1dfe, + 0x3842, 0x0776, + 0x3921, 0x07b3, + 0x392b, 0x1dff, + 0x392c, 0x07be, + 0x396d, 0x1e02, + 0x396e, 0x0800, + 0x3974, 0x1e03, + 0x3975, 0x0807, + 0x3979, 0x1e04, + 0x397a, 0x080c, + 0x3a21, 0x0811, + 0x3a53, 0x1e05, + 0x3a54, 0x0844, + 0x3a67, 0x1e06, + 0x3a68, 0x0858, + 0x3a74, 0x1e07, + 0x3a75, 0x0865, + 0x3b21, 0x086f, + 0x3b27, 0x1e08, + 0x3b28, 0x0876, + 0x3b2a, 0x1e09, + 0x3b2b, 0x0879, + 0x3b2c, 0x1e0a, + 0x3b2d, 0x087b, + 0x3b39, 0x1e0b, + 0x3b3a, 0x0888, + 0x3b41, 0x1f22, + 0x3b42, 0x0890, + 0x3c21, 0x08cd, + 0x3c48, 0x1e0d, + 0x3c49, 0x08f5, + 0x3c5d, 0x1e0f, + 0x3c5f, 0x090b, + 0x3d21, 0x092b, + 0x3d2b, 0x1e11, + 0x3d2c, 0x0936, + 0x3d36, 0x1e12, + 0x3d37, 0x0941, + 0x3d6c, 0x1e13, + 0x3d6d, 0x0977, + 0x3d72, 0x1e15, + 0x3d74, 0x097e, + 0x3e21, 0x0989, + 0x3e25, 0x1e17, + 0x3e26, 0x098e, + 0x3e33, 0x1e18, + 0x3e34, 0x099c, + 0x3e55, 0x1e1a, + 0x3e56, 0x09be, + 0x3e5f, 0x1e1b, + 0x3e60, 0x09c8, + 0x3e64, 0x1e1c, + 0x3e65, 0x09cd, + 0x3f21, 0x09e7, + 0x3f2a, 0x1e1d, + 0x3f2b, 0x09f1, + 0x3f59, 0x1f23, + 0x3f5a, 0x0a20, + 0x3f60, 0x1e1f, + 0x3f61, 0x0a27, + 0x4021, 0x0a45, + 0x4022, 0x1e21, + 0x4023, 0x0a47, + 0x4066, 0x1e23, + 0x4067, 0x0a8b, + 0x4071, 0x1e24, + 0x4072, 0x0a96, + 0x4079, 0x1e26, + 0x407a, 0x1f24, + 0x407b, 0x0a9f, + 0x407c, 0x1f25, + 0x407e, 0x0aa2, + 0x4121, 0x0aa3, + 0x4127, 0x1e28, + 0x4128, 0x0aaa, + 0x4139, 0x1e29, + 0x413a, 0x0abc, + 0x414c, 0x1e2a, + 0x414d, 0x0acf, + 0x414f, 0x1e2b, + 0x4150, 0x0ad2, + 0x415f, 0x1e2c, + 0x4160, 0x0ae2, + 0x4169, 0x1e2d, + 0x416a, 0x0aec, + 0x4221, 0x0b01, + 0x4237, 0x1f27, + 0x4238, 0x0b18, + 0x423d, 0x1e2e, + 0x423e, 0x0b1e, + 0x424d, 0x1e2f, + 0x424e, 0x0b2e, + 0x425c, 0x1e30, + 0x425d, 0x0b3d, + 0x4263, 0x1e31, + 0x4264, 0x0b44, + 0x426f, 0x1e32, + 0x4270, 0x0b50, + 0x427d, 0x1e35, + 0x427e, 0x0b5e, + 0x4321, 0x0b5f, + 0x4327, 0x1e36, + 0x4328, 0x0b66, + 0x4329, 0x1e37, + 0x432a, 0x0b68, + 0x432d, 0x1e39, + 0x432f, 0x0b6d, + 0x433d, 0x1e3b, + 0x433e, 0x0b7c, + 0x4370, 0x1e3c, + 0x4371, 0x0baf, + 0x4375, 0x1e3d, + 0x4376, 0x0bb4, + 0x437c, 0x1e3e, + 0x437d, 0x0bbb, + 0x4421, 0x0bbd, + 0x443d, 0x1e3f, + 0x443e, 0x0bda, + 0x4448, 0x1e40, + 0x4449, 0x0be5, + 0x444a, 0x1e41, + 0x444b, 0x0be7, + 0x444f, 0x1e43, + 0x4450, 0x0bec, + 0x4521, 0x0c1b, + 0x4522, 0x1e44, + 0x4523, 0x0c1d, + 0x4527, 0x1e45, + 0x4528, 0x0c22, + 0x452e, 0x1e46, + 0x452f, 0x0c29, + 0x4536, 0x1e47, + 0x4537, 0x0c31, + 0x453f, 0x1e48, + 0x4540, 0x0c3a, + 0x4548, 0x1e49, + 0x4549, 0x0c43, + 0x454b, 0x1e4a, + 0x454c, 0x0c46, + 0x4551, 0x1f28, + 0x4552, 0x1e4c, + 0x4553, 0x0c4d, + 0x4564, 0x1e4d, + 0x4565, 0x0c5f, + 0x4578, 0x1e4e, + 0x4579, 0x0c73, + 0x4621, 0x0c79, + 0x4642, 0x1e50, + 0x4643, 0x0c9b, + 0x4654, 0x1e51, + 0x4655, 0x0cad, + 0x465b, 0x1e53, + 0x465c, 0x0cb4, + 0x4666, 0x1e56, + 0x4668, 0x0cc0, + 0x466a, 0x1e58, + 0x466b, 0x0cc3, + 0x4676, 0x1ec0, + 0x4677, 0x0ccf, + 0x4721, 0x0cd7, + 0x4729, 0x1e59, + 0x472a, 0x1f29, + 0x472b, 0x0ce1, + 0x4739, 0x1e5a, + 0x473a, 0x0cf0, + 0x4757, 0x1e5b, + 0x4758, 0x0d0e, + 0x4767, 0x1e5c, + 0x4768, 0x0d1e, + 0x4769, 0x1e5d, + 0x476a, 0x0d20, + 0x476d, 0x1e5e, + 0x476e, 0x0d24, + 0x4821, 0x0d35, + 0x4824, 0x1e5f, + 0x4825, 0x0d39, + 0x482e, 0x1e60, + 0x482f, 0x0d43, + 0x4830, 0x1e61, + 0x4831, 0x0d45, + 0x4840, 0x1f2a, + 0x4841, 0x0d55, + 0x4854, 0x1e62, + 0x4855, 0x0d69, + 0x4875, 0x1e64, + 0x4876, 0x0d8a, + 0x4921, 0x0d93, + 0x4922, 0x1e65, + 0x4924, 0x0d96, + 0x492f, 0x1e67, + 0x4930, 0x0da2, + 0x4932, 0x1e68, + 0x4933, 0x0da5, + 0x4935, 0x1e69, + 0x4936, 0x0da8, + 0x4940, 0x1e6a, + 0x4941, 0x0db3, + 0x494e, 0x1e6b, + 0x494f, 0x0dc1, + 0x4a21, 0x0df1, + 0x4a43, 0x1e6d, + 0x4a44, 0x0e14, + 0x4a4d, 0x1e6e, + 0x4a4e, 0x0e1e, + 0x4a53, 0x1f2b, + 0x4a54, 0x0e24, + 0x4a5a, 0x1e6f, + 0x4a5b, 0x0e2b, + 0x4a79, 0x1e70, + 0x4a7a, 0x0e4a, + 0x4b21, 0x0e4f, + 0x4b29, 0x1e72, + 0x4b2a, 0x0e58, + 0x4b4b, 0x1e73, + 0x4b4c, 0x0e7a, + 0x4b70, 0x1e74, + 0x4b71, 0x0e9f, + 0x4b78, 0x1f2c, + 0x4b79, 0x0ea7, + 0x4c21, 0x0ead, + 0x4c4d, 0x1e75, + 0x4c4e, 0x0eda, + 0x4c59, 0x1e76, + 0x4c5a, 0x0ee6, + 0x4c5f, 0x1e77, + 0x4c60, 0x0eec, + 0x4c62, 0x1e78, + 0x4c63, 0x0eef, + 0x4c7a, 0x1e79, + 0x4c7b, 0x0f07, + 0x4c7c, 0x1e7a, + 0x4c7d, 0x0f09, + 0x4d21, 0x0f0b, + 0x4d32, 0x1e7c, + 0x4d33, 0x0f1d, + 0x4d50, 0x1e7d, + 0x4d51, 0x0f3b, + 0x4d54, 0x1e7e, + 0x4d55, 0x0f3f, + 0x4d69, 0x1e7f, + 0x4d6a, 0x0f54, + 0x4e21, 0x0f69, + 0x4e7a, 0x1e81, + 0x4e7c, 0x1f2d, + 0x4e7d, 0x0fc5, + 0x4f21, 0x1e83, + 0x4f22, 0x0fc8, + 0x4f31, 0x1e84, + 0x4f32, 0x0fd8, + 0x4f39, 0x1e85, + 0x4f3a, 0x0fe0, + 0x5021, 0x0ffa, + 0x5121, 0x1058, + 0x5122, 0x1f2e, + 0x5123, 0x105a, + 0x513d, 0x1e86, + 0x513e, 0x1075, + 0x514d, 0x1e89, + 0x514e, 0x1085, + 0x5221, 0x10b6, + 0x5238, 0x1f2f, + 0x5239, 0x10ce, + 0x5321, 0x1114, + 0x5330, 0x1e8a, + 0x5331, 0x1124, + 0x533a, 0x1e8b, + 0x533b, 0x112e, + 0x5348, 0x1f30, + 0x5349, 0x113c, + 0x535e, 0x1e8d, + 0x535f, 0x1152, + 0x536b, 0x1e8e, + 0x536c, 0x1f31, + 0x536d, 0x1160, + 0x5421, 0x1172, + 0x5444, 0x1e8f, + 0x5445, 0x1f32, + 0x5446, 0x1197, + 0x546c, 0x1f33, + 0x546d, 0x11be, + 0x5521, 0x11d0, + 0x553d, 0x1e90, + 0x553e, 0x11ed, + 0x5563, 0x1e91, + 0x5564, 0x1213, + 0x5578, 0x1f34, + 0x5579, 0x1228, + 0x5621, 0x122e, + 0x5622, 0x1e92, + 0x5623, 0x1230, + 0x567d, 0x1f35, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5824, 0x1e94, + 0x5825, 0x12ee, + 0x5921, 0x1348, + 0x5928, 0x1f37, + 0x5929, 0x1350, + 0x5960, 0x1e95, + 0x5961, 0x1388, + 0x596c, 0x1e96, + 0x596d, 0x1394, + 0x5a21, 0x13a6, + 0x5a39, 0x1e97, + 0x5a3a, 0x13bf, + 0x5a7a, 0x1f38, + 0x5a7b, 0x1400, + 0x5b21, 0x1404, + 0x5b45, 0x1e99, + 0x5b46, 0x1429, + 0x5b6b, 0x1e9b, + 0x5b6c, 0x144f, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5d61, 0x1f39, + 0x5d62, 0x1501, + 0x5e21, 0x151e, + 0x5e50, 0x1e9d, + 0x5e51, 0x154e, + 0x5e56, 0x1f3a, + 0x5e57, 0x1554, + 0x5e76, 0x1f3b, + 0x5e77, 0x1574, + 0x5f21, 0x157c, + 0x5f73, 0x1e9e, + 0x5f74, 0x15cf, + 0x6021, 0x15da, + 0x6026, 0x1e9f, + 0x6027, 0x15e0, + 0x605f, 0x1ea0, + 0x6060, 0x1619, + 0x6121, 0x1638, + 0x612b, 0x1ea1, + 0x612c, 0x1643, + 0x6221, 0x1696, + 0x626f, 0x1ea5, + 0x6270, 0x16e5, + 0x6321, 0x16f4, + 0x634a, 0x1ea6, + 0x634b, 0x171e, + 0x6354, 0x1ea7, + 0x6355, 0x1728, + 0x6359, 0x1f3c, + 0x635a, 0x172d, + 0x6421, 0x1752, + 0x6439, 0x1ea8, + 0x643a, 0x176b, + 0x6440, 0x1f3d, + 0x6441, 0x1772, + 0x6464, 0x1ea9, + 0x6465, 0x1796, + 0x646e, 0x1eaa, + 0x646f, 0x17a0, + 0x6521, 0x17b0, + 0x6539, 0x1eab, + 0x653a, 0x17c9, + 0x653b, 0x1eac, + 0x653c, 0x17cb, + 0x6546, 0x1ead, + 0x6547, 0x17d6, + 0x6621, 0x180e, + 0x6649, 0x1f3e, + 0x664a, 0x1837, + 0x6721, 0x186c, + 0x6764, 0x1eaf, + 0x6765, 0x18b0, + 0x6769, 0x1eb0, + 0x676a, 0x18b5, + 0x6772, 0x1eb1, + 0x6773, 0x18be, + 0x6821, 0x18ca, + 0x683b, 0x1eb3, + 0x683c, 0x18e5, + 0x684d, 0x1f3f, + 0x684e, 0x18f7, + 0x6921, 0x1928, + 0x697e, 0x1f40, + 0x6a21, 0x1986, + 0x6a3c, 0x1f41, + 0x6a3e, 0x19a3, + 0x6a6f, 0x1eb8, + 0x6a70, 0x19d5, + 0x6b21, 0x19e4, + 0x6b32, 0x1eb9, + 0x6b33, 0x19f6, + 0x6b66, 0x1eba, + 0x6b67, 0x1a2a, + 0x6c21, 0x1a42, + 0x6c69, 0x1ebc, + 0x6c6a, 0x1a8b, + 0x6d21, 0x1aa0, + 0x6d4e, 0x1ebe, + 0x6d4f, 0x1ace, + 0x6e21, 0x1afe, + 0x6e29, 0x1ec1, + 0x6e2a, 0x1b07, + 0x6e3d, 0x1ec2, + 0x6e3e, 0x1b1b, + 0x6f21, 0x1b5c, + 0x7021, 0x1bba, + 0x7051, 0x1ec7, + 0x7052, 0x1beb, + 0x7121, 0x1c18, + 0x7159, 0x1f43, + 0x715a, 0x1c51, + 0x7221, 0x1c76, + 0x722d, 0x1eca, + 0x722e, 0x1c83, + 0x723c, 0x1ecb, + 0x723d, 0x1c92, + 0x724e, 0x1ecc, + 0x724f, 0x1ca4, + 0x7321, 0x1cd4, + 0x7351, 0x1ecd, + 0x7352, 0x1f44, + 0x7353, 0x1d06, + 0x737d, 0x1ece, + 0x737e, 0x1d31, + 0x7421, 0x1d32, + 0x7425, 0x205c, + 0x7721, 0x1f45, + 0x7727, 0x1f48, + 0x7728, 0x0300, + 0x7729, 0x02fa, + 0x772a, 0x02f9, + 0x772e, 0x1f49, + 0x773c, 0x1db1, + 0x773f, 0x1f54, + 0x7740, 0x1db7, + 0x7741, 0x1f55, + 0x7744, 0x1db4, + 0x7747, 0x1f58, + 0x7751, 0x0303, + 0x7752, 0x1f62, + 0x7753, 0x0304, + 0x7754, 0x1f63, + 0x7757, 0x1f65, + 0x7759, 0x1da4, + 0x775a, 0x1da1, + 0x775b, 0x1f66, + 0x775c, 0x1da2, + 0x775d, 0x1f67, + 0x7760, 0x1da6, + 0x7761, 0x1f6a, + 0x7762, 0x1da8, + 0x7763, 0x1dac, + 0x7764, 0x1f6b, + 0x7765, 0x1dae, + 0x7766, 0x1dab, + 0x7767, 0x1f6c, + 0x7769, 0x1daf, + 0x776a, 0x1f6e, + 0x7774, 0x1f75, + 0x777a, 0x1dba, + 0x777b, 0x1f7b, + 0x777e, 0x1f7c, + 0x7829, 0x1f7d, + 0x7834, 0x1f87, + 0x7849, 0x1d83, + 0x785d, 0x1f9b, + 0x785e, 0x1d97, + 0x786b, 0x1f9c, + 0x7921, 0x1fb0, + 0x7945, 0x1f16, + 0x7949, 0x1fca, + 0x794b, 0x1dc4, + 0x794c, 0x1fcc, + 0x794f, 0x1dc3, + 0x7950, 0x1fcf, + 0x7955, 0x1dc2, + 0x7956, 0x1fd4, + 0x795d, 0x1fd8, + 0x796f, 0x1fe6, + 0x7d21, 0x1ecf, + 0x7d23, 0x204c, + 0x7d24, 0x2052, + 0x7d25, 0x1ed1, + 0x7d2f, 0x205a, + 0x7d30, 0x2053, + 0x7d31, 0x2058, + 0x7d32, 0x2055, + 0x7d33, 0x1edb, + 0x7d45, 0x1eee, + 0x7d5b, 0x2048, + 0x7d6d, 0x02e0, + 0x7d71, 0x1ff6, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12AddHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12AddHMap2, 633 +}; + +static Gushort japan12AddRKSJHMap2[1270] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x82f2, 0x1f16, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x889f, 0x0465, + 0x88a0, 0x1dd1, + 0x88a1, 0x0467, + 0x88b0, 0x1f19, + 0x88b1, 0x0477, + 0x88b9, 0x1dd2, + 0x88ba, 0x0480, + 0x88ec, 0x1dd3, + 0x88ed, 0x04b3, + 0x88ef, 0x1f1a, + 0x88f0, 0x04b6, + 0x88f1, 0x1dd4, + 0x88f2, 0x04b8, + 0x88fa, 0x1dd5, + 0x88fb, 0x04c1, + 0x8940, 0x04c3, + 0x8949, 0x1dd6, + 0x894a, 0x04cd, + 0x8952, 0x1f1b, + 0x8953, 0x04d6, + 0x8954, 0x1dd7, + 0x8955, 0x04d8, + 0x8958, 0x1f1c, + 0x8959, 0x04dc, + 0x895c, 0x1dda, + 0x895d, 0x04e0, + 0x8961, 0x1ddb, + 0x8962, 0x04e5, + 0x8980, 0x0502, + 0x898b, 0x1ddc, + 0x898c, 0x050e, + 0x89a6, 0x1ddd, + 0x89a7, 0x0529, + 0x89a8, 0x1dde, + 0x89a9, 0x052b, + 0x89de, 0x1ddf, + 0x89df, 0x0561, + 0x89e5, 0x1f1d, + 0x89e6, 0x0568, + 0x89f8, 0x1de0, + 0x89f9, 0x057b, + 0x8a40, 0x057f, + 0x8a41, 0x1de2, + 0x8a42, 0x0581, + 0x8a80, 0x05be, + 0x8a8b, 0x1de4, + 0x8a8c, 0x05ca, + 0x8a93, 0x1de5, + 0x8a94, 0x05d2, + 0x8a9a, 0x1de6, + 0x8a9b, 0x05d9, + 0x8ac0, 0x1de7, + 0x8ac1, 0x05ff, + 0x8acb, 0x1de8, + 0x8acc, 0x060a, + 0x8ae3, 0x1de9, + 0x8ae4, 0x0622, + 0x8b40, 0x063b, + 0x8b4a, 0x1dea, + 0x8b4b, 0x0646, + 0x8b5f, 0x1deb, + 0x8b60, 0x065b, + 0x8b80, 0x067a, + 0x8b82, 0x1f1e, + 0x8b83, 0x067d, + 0x8b88, 0x1f1f, + 0x8b89, 0x0683, + 0x8ba0, 0x1dec, + 0x8ba1, 0x069b, + 0x8ba8, 0x1ded, + 0x8ba9, 0x06a3, + 0x8bc0, 0x1f20, + 0x8bc1, 0x06bb, + 0x8bcd, 0x1dee, + 0x8bce, 0x06c8, + 0x8beb, 0x1def, + 0x8bec, 0x06e6, + 0x8bf2, 0x1df0, + 0x8bf3, 0x06ed, + 0x8bf9, 0x1df1, + 0x8bfa, 0x06f4, + 0x8bfb, 0x1df2, + 0x8bfc, 0x06f6, + 0x8c40, 0x06f7, + 0x8c56, 0x1df4, + 0x8c57, 0x070e, + 0x8c71, 0x1df7, + 0x8c72, 0x0729, + 0x8c80, 0x0736, + 0x8c91, 0x1dfa, + 0x8c92, 0x0748, + 0x8c9d, 0x1f21, + 0x8c9e, 0x1dfc, + 0x8c9f, 0x0755, + 0x8cb2, 0x1dfd, + 0x8cb3, 0x0769, + 0x8cbf, 0x1dfe, + 0x8cc0, 0x0776, + 0x8d40, 0x07b3, + 0x8d4a, 0x1dff, + 0x8d4b, 0x07be, + 0x8d80, 0x07f2, + 0x8d8d, 0x1e02, + 0x8d8e, 0x0800, + 0x8d94, 0x1e03, + 0x8d95, 0x0807, + 0x8d99, 0x1e04, + 0x8d9a, 0x080c, + 0x8dd1, 0x1e05, + 0x8dd2, 0x0844, + 0x8de5, 0x1e06, + 0x8de6, 0x0858, + 0x8df2, 0x1e07, + 0x8df3, 0x0865, + 0x8e40, 0x086f, + 0x8e46, 0x1e08, + 0x8e47, 0x0876, + 0x8e49, 0x1e09, + 0x8e4a, 0x0879, + 0x8e4b, 0x1e0a, + 0x8e4c, 0x087b, + 0x8e58, 0x1e0b, + 0x8e59, 0x0888, + 0x8e60, 0x1f22, + 0x8e61, 0x0890, + 0x8e80, 0x08ae, + 0x8ec6, 0x1e0d, + 0x8ec7, 0x08f5, + 0x8edb, 0x1e0f, + 0x8edd, 0x090b, + 0x8f40, 0x092b, + 0x8f4a, 0x1e11, + 0x8f4b, 0x0936, + 0x8f55, 0x1e12, + 0x8f56, 0x0941, + 0x8f80, 0x096a, + 0x8f8c, 0x1e13, + 0x8f8d, 0x0977, + 0x8f92, 0x1e15, + 0x8f94, 0x097e, + 0x8fa3, 0x1e17, + 0x8fa4, 0x098e, + 0x8fb1, 0x1e18, + 0x8fb2, 0x099c, + 0x8fd3, 0x1e1a, + 0x8fd4, 0x09be, + 0x8fdd, 0x1e1b, + 0x8fde, 0x09c8, + 0x8fe2, 0x1e1c, + 0x8fe3, 0x09cd, + 0x9040, 0x09e7, + 0x9049, 0x1e1d, + 0x904a, 0x09f1, + 0x9078, 0x1f23, + 0x9079, 0x0a20, + 0x9080, 0x1e1f, + 0x9081, 0x0a27, + 0x90a0, 0x1e21, + 0x90a1, 0x0a47, + 0x90e4, 0x1e23, + 0x90e5, 0x0a8b, + 0x90ef, 0x1e24, + 0x90f0, 0x0a96, + 0x90f7, 0x1e26, + 0x90f8, 0x1f24, + 0x90f9, 0x0a9f, + 0x90fa, 0x1f25, + 0x90fc, 0x0aa2, + 0x9140, 0x0aa3, + 0x9146, 0x1e28, + 0x9147, 0x0aaa, + 0x9158, 0x1e29, + 0x9159, 0x0abc, + 0x916b, 0x1e2a, + 0x916c, 0x0acf, + 0x916e, 0x1e2b, + 0x916f, 0x0ad2, + 0x917e, 0x1e2c, + 0x9180, 0x0ae2, + 0x9189, 0x1e2d, + 0x918a, 0x0aec, + 0x91b5, 0x1f27, + 0x91b6, 0x0b18, + 0x91bb, 0x1e2e, + 0x91bc, 0x0b1e, + 0x91cb, 0x1e2f, + 0x91cc, 0x0b2e, + 0x91da, 0x1e30, + 0x91db, 0x0b3d, + 0x91e1, 0x1e31, + 0x91e2, 0x0b44, + 0x91ed, 0x1e32, + 0x91ee, 0x0b50, + 0x91fb, 0x1e35, + 0x91fc, 0x0b5e, + 0x9240, 0x0b5f, + 0x9246, 0x1e36, + 0x9247, 0x0b66, + 0x9248, 0x1e37, + 0x9249, 0x0b68, + 0x924c, 0x1e39, + 0x924e, 0x0b6d, + 0x925c, 0x1e3b, + 0x925d, 0x0b7c, + 0x9280, 0x0b9e, + 0x9290, 0x1e3c, + 0x9291, 0x0baf, + 0x9295, 0x1e3d, + 0x9296, 0x0bb4, + 0x929c, 0x1e3e, + 0x929d, 0x0bbb, + 0x92bb, 0x1e3f, + 0x92bc, 0x0bda, + 0x92c6, 0x1e40, + 0x92c7, 0x0be5, + 0x92c8, 0x1e41, + 0x92c9, 0x0be7, + 0x92cd, 0x1e43, + 0x92ce, 0x0bec, + 0x9340, 0x0c1b, + 0x9341, 0x1e44, + 0x9342, 0x0c1d, + 0x9346, 0x1e45, + 0x9347, 0x0c22, + 0x934d, 0x1e46, + 0x934e, 0x0c29, + 0x9355, 0x1e47, + 0x9356, 0x0c31, + 0x935e, 0x1e48, + 0x935f, 0x0c3a, + 0x9367, 0x1e49, + 0x9368, 0x0c43, + 0x936a, 0x1e4a, + 0x936b, 0x0c46, + 0x9370, 0x1f28, + 0x9371, 0x1e4c, + 0x9372, 0x0c4d, + 0x9380, 0x0c5a, + 0x9384, 0x1e4d, + 0x9385, 0x0c5f, + 0x9398, 0x1e4e, + 0x9399, 0x0c73, + 0x93c0, 0x1e50, + 0x93c1, 0x0c9b, + 0x93d2, 0x1e51, + 0x93d3, 0x0cad, + 0x93d9, 0x1e53, + 0x93da, 0x0cb4, + 0x93e4, 0x1e56, + 0x93e6, 0x0cc0, + 0x93e8, 0x1e58, + 0x93e9, 0x0cc3, + 0x93f4, 0x1ec0, + 0x93f5, 0x0ccf, + 0x9440, 0x0cd7, + 0x9448, 0x1e59, + 0x9449, 0x1f29, + 0x944a, 0x0ce1, + 0x9458, 0x1e5a, + 0x9459, 0x0cf0, + 0x9476, 0x1e5b, + 0x9477, 0x0d0e, + 0x9480, 0x0d16, + 0x9487, 0x1e5c, + 0x9488, 0x0d1e, + 0x9489, 0x1e5d, + 0x948a, 0x0d20, + 0x948d, 0x1e5e, + 0x948e, 0x0d24, + 0x94a2, 0x1e5f, + 0x94a3, 0x0d39, + 0x94ac, 0x1e60, + 0x94ad, 0x0d43, + 0x94ae, 0x1e61, + 0x94af, 0x0d45, + 0x94be, 0x1f2a, + 0x94bf, 0x0d55, + 0x94d2, 0x1e62, + 0x94d3, 0x0d69, + 0x94f3, 0x1e64, + 0x94f4, 0x0d8a, + 0x9540, 0x0d93, + 0x9541, 0x1e65, + 0x9543, 0x0d96, + 0x954e, 0x1e67, + 0x954f, 0x0da2, + 0x9551, 0x1e68, + 0x9552, 0x0da5, + 0x9554, 0x1e69, + 0x9555, 0x0da8, + 0x955f, 0x1e6a, + 0x9560, 0x0db3, + 0x956d, 0x1e6b, + 0x956e, 0x0dc1, + 0x9580, 0x0dd2, + 0x95c1, 0x1e6d, + 0x95c2, 0x0e14, + 0x95cb, 0x1e6e, + 0x95cc, 0x0e1e, + 0x95d1, 0x1f2b, + 0x95d2, 0x0e24, + 0x95d8, 0x1e6f, + 0x95d9, 0x0e2b, + 0x95f7, 0x1e70, + 0x95f8, 0x0e4a, + 0x9640, 0x0e4f, + 0x9648, 0x1e72, + 0x9649, 0x0e58, + 0x966a, 0x1e73, + 0x966b, 0x0e7a, + 0x9680, 0x0e8e, + 0x9690, 0x1e74, + 0x9691, 0x0e9f, + 0x9698, 0x1f2c, + 0x9699, 0x0ea7, + 0x96cb, 0x1e75, + 0x96cc, 0x0eda, + 0x96d7, 0x1e76, + 0x96d8, 0x0ee6, + 0x96dd, 0x1e77, + 0x96de, 0x0eec, + 0x96e0, 0x1e78, + 0x96e1, 0x0eef, + 0x96f8, 0x1e79, + 0x96f9, 0x0f07, + 0x96fa, 0x1e7a, + 0x96fb, 0x0f09, + 0x9740, 0x0f0b, + 0x9751, 0x1e7c, + 0x9752, 0x0f1d, + 0x976f, 0x1e7d, + 0x9770, 0x0f3b, + 0x9773, 0x1e7e, + 0x9774, 0x0f3f, + 0x9780, 0x0f4a, + 0x9789, 0x1e7f, + 0x978a, 0x0f54, + 0x97f8, 0x1e81, + 0x97fa, 0x1f2d, + 0x97fb, 0x0fc5, + 0x9840, 0x1e83, + 0x9841, 0x0fc8, + 0x9850, 0x1e84, + 0x9851, 0x0fd8, + 0x9858, 0x1e85, + 0x9859, 0x0fe0, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9941, 0x1f2e, + 0x9942, 0x105a, + 0x995c, 0x1e86, + 0x995d, 0x1075, + 0x996c, 0x1e89, + 0x996d, 0x1085, + 0x9980, 0x1097, + 0x99b6, 0x1f2f, + 0x99b7, 0x10ce, + 0x9a40, 0x1114, + 0x9a4f, 0x1e8a, + 0x9a50, 0x1124, + 0x9a59, 0x1e8b, + 0x9a5a, 0x112e, + 0x9a67, 0x1f30, + 0x9a68, 0x113c, + 0x9a7d, 0x1e8d, + 0x9a7e, 0x1152, + 0x9a80, 0x1153, + 0x9a8b, 0x1e8e, + 0x9a8c, 0x1f31, + 0x9a8d, 0x1160, + 0x9ac2, 0x1e8f, + 0x9ac3, 0x1f32, + 0x9ac4, 0x1197, + 0x9aea, 0x1f33, + 0x9aeb, 0x11be, + 0x9b40, 0x11d0, + 0x9b5c, 0x1e90, + 0x9b5d, 0x11ed, + 0x9b80, 0x120f, + 0x9b83, 0x1e91, + 0x9b84, 0x1213, + 0x9b98, 0x1f34, + 0x9b99, 0x1228, + 0x9ba0, 0x1e92, + 0x9ba1, 0x1230, + 0x9bfb, 0x1f35, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9ca2, 0x1e94, + 0x9ca3, 0x12ee, + 0x9d40, 0x1348, + 0x9d47, 0x1f37, + 0x9d48, 0x1350, + 0x9d80, 0x1e95, + 0x9d81, 0x1388, + 0x9d8c, 0x1e96, + 0x9d8d, 0x1394, + 0x9db7, 0x1e97, + 0x9db8, 0x13bf, + 0x9df8, 0x1f38, + 0x9df9, 0x1400, + 0x9e40, 0x1404, + 0x9e64, 0x1e99, + 0x9e65, 0x1429, + 0x9e80, 0x1443, + 0x9e8b, 0x1e9b, + 0x9e8c, 0x144f, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0x9f81, 0x1f39, + 0x9f82, 0x1501, + 0x9fce, 0x1e9d, + 0x9fcf, 0x154e, + 0x9fd4, 0x1f3a, + 0x9fd5, 0x1554, + 0x9ff4, 0x1f3b, + 0x9ff5, 0x1574, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe093, 0x1e9e, + 0xe094, 0x15cf, + 0xe0a4, 0x1e9f, + 0xe0a5, 0x15e0, + 0xe0dd, 0x1ea0, + 0xe0de, 0x1619, + 0xe140, 0x1638, + 0xe14a, 0x1ea1, + 0xe14b, 0x1643, + 0xe180, 0x1677, + 0xe1ed, 0x1ea5, + 0xe1ee, 0x16e5, + 0xe240, 0x16f4, + 0xe269, 0x1ea6, + 0xe26a, 0x171e, + 0xe273, 0x1ea7, + 0xe274, 0x1728, + 0xe278, 0x1f3c, + 0xe279, 0x172d, + 0xe280, 0x1733, + 0xe2b7, 0x1ea8, + 0xe2b8, 0x176b, + 0xe2be, 0x1f3d, + 0xe2bf, 0x1772, + 0xe2e2, 0x1ea9, + 0xe2e3, 0x1796, + 0xe2ec, 0x1eaa, + 0xe2ed, 0x17a0, + 0xe340, 0x17b0, + 0xe358, 0x1eab, + 0xe359, 0x17c9, + 0xe35a, 0x1eac, + 0xe35b, 0x17cb, + 0xe365, 0x1ead, + 0xe366, 0x17d6, + 0xe380, 0x17ef, + 0xe3c7, 0x1f3e, + 0xe3c8, 0x1837, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe484, 0x1eaf, + 0xe485, 0x18b0, + 0xe489, 0x1eb0, + 0xe48a, 0x18b5, + 0xe492, 0x1eb1, + 0xe493, 0x18be, + 0xe4b9, 0x1eb3, + 0xe4ba, 0x18e5, + 0xe4cb, 0x1f3f, + 0xe4cc, 0x18f7, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe59e, 0x1f40, + 0xe59f, 0x1986, + 0xe5ba, 0x1f41, + 0xe5bc, 0x19a3, + 0xe5ed, 0x1eb8, + 0xe5ee, 0x19d5, + 0xe640, 0x19e4, + 0xe651, 0x1eb9, + 0xe652, 0x19f6, + 0xe680, 0x1a23, + 0xe686, 0x1eba, + 0xe687, 0x1a2a, + 0xe6e7, 0x1ebc, + 0xe6e8, 0x1a8b, + 0xe740, 0x1aa0, + 0xe76d, 0x1ebe, + 0xe76e, 0x1ace, + 0xe780, 0x1adf, + 0xe7a7, 0x1ec1, + 0xe7a8, 0x1b07, + 0xe7bb, 0x1ec2, + 0xe7bc, 0x1b1b, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe8cf, 0x1ec7, + 0xe8d0, 0x1beb, + 0xe940, 0x1c18, + 0xe978, 0x1f43, + 0xe979, 0x1c51, + 0xe980, 0x1c57, + 0xe9ab, 0x1eca, + 0xe9ac, 0x1c83, + 0xe9ba, 0x1ecb, + 0xe9bb, 0x1c92, + 0xe9cc, 0x1ecc, + 0xe9cd, 0x1ca4, + 0xea40, 0x1cd4, + 0xea70, 0x1ecd, + 0xea71, 0x1f44, + 0xea72, 0x1d06, + 0xea80, 0x1d13, + 0xea9d, 0x1ece, + 0xea9e, 0x1d31, + 0xeaa3, 0x205c, + 0xec40, 0x1f45, + 0xec46, 0x1f48, + 0xec47, 0x0300, + 0xec48, 0x02fa, + 0xec49, 0x02f9, + 0xec4d, 0x1f49, + 0xec5b, 0x1db1, + 0xec5e, 0x1f54, + 0xec5f, 0x1db7, + 0xec60, 0x1f55, + 0xec63, 0x1db4, + 0xec66, 0x1f58, + 0xec70, 0x0303, + 0xec71, 0x1f62, + 0xec72, 0x0304, + 0xec73, 0x1f63, + 0xec76, 0x1f65, + 0xec78, 0x1da4, + 0xec79, 0x1da1, + 0xec7a, 0x1f66, + 0xec7b, 0x1da2, + 0xec7c, 0x1f67, + 0xec80, 0x1da6, + 0xec81, 0x1f6a, + 0xec82, 0x1da8, + 0xec83, 0x1dac, + 0xec84, 0x1f6b, + 0xec85, 0x1dae, + 0xec86, 0x1dab, + 0xec87, 0x1f6c, + 0xec89, 0x1daf, + 0xec8a, 0x1f6e, + 0xec94, 0x1f75, + 0xec9a, 0x1dba, + 0xec9b, 0x1f7b, + 0xec9e, 0x1f7c, + 0xeca7, 0x1f7d, + 0xecb2, 0x1f87, + 0xecc7, 0x1d83, + 0xecdb, 0x1f9b, + 0xecdc, 0x1d97, + 0xece9, 0x1f9c, + 0xed40, 0x1fb0, + 0xed64, 0x1f16, + 0xed68, 0x1fca, + 0xed6a, 0x1dc4, + 0xed6b, 0x1fcc, + 0xed6e, 0x1dc3, + 0xed6f, 0x1fcf, + 0xed74, 0x1dc2, + 0xed75, 0x1fd4, + 0xed7c, 0x1fd8, + 0xed80, 0x1fdb, + 0xed8f, 0x1fe6, + 0xef40, 0x1ecf, + 0xef42, 0x204c, + 0xef43, 0x2052, + 0xef44, 0x1ed1, + 0xef4e, 0x205a, + 0xef4f, 0x2053, + 0xef50, 0x2058, + 0xef51, 0x2055, + 0xef52, 0x1edb, + 0xef64, 0x1eee, + 0xef7a, 0x2048, + 0xef8d, 0x02e0, + 0xef91, 0x1ff6, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12AddRKSJHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12AddRKSJHMap2, 635 +}; + +static Gushort japan12AddRKSJVMap2[1384] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x82f2, 0x1f16, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x889f, 0x0465, + 0x88a0, 0x1dd1, + 0x88a1, 0x0467, + 0x88b0, 0x1f19, + 0x88b1, 0x0477, + 0x88b9, 0x1dd2, + 0x88ba, 0x0480, + 0x88ec, 0x1dd3, + 0x88ed, 0x04b3, + 0x88ef, 0x1f1a, + 0x88f0, 0x04b6, + 0x88f1, 0x1dd4, + 0x88f2, 0x04b8, + 0x88fa, 0x1dd5, + 0x88fb, 0x04c1, + 0x8940, 0x04c3, + 0x8949, 0x1dd6, + 0x894a, 0x04cd, + 0x8952, 0x1f1b, + 0x8953, 0x04d6, + 0x8954, 0x1dd7, + 0x8955, 0x04d8, + 0x8958, 0x1f1c, + 0x8959, 0x04dc, + 0x895c, 0x1dda, + 0x895d, 0x04e0, + 0x8961, 0x1ddb, + 0x8962, 0x04e5, + 0x8980, 0x0502, + 0x898b, 0x1ddc, + 0x898c, 0x050e, + 0x89a6, 0x1ddd, + 0x89a7, 0x0529, + 0x89a8, 0x1dde, + 0x89a9, 0x052b, + 0x89de, 0x1ddf, + 0x89df, 0x0561, + 0x89e5, 0x1f1d, + 0x89e6, 0x0568, + 0x89f8, 0x1de0, + 0x89f9, 0x057b, + 0x8a40, 0x057f, + 0x8a41, 0x1de2, + 0x8a42, 0x0581, + 0x8a80, 0x05be, + 0x8a8b, 0x1de4, + 0x8a8c, 0x05ca, + 0x8a93, 0x1de5, + 0x8a94, 0x05d2, + 0x8a9a, 0x1de6, + 0x8a9b, 0x05d9, + 0x8ac0, 0x1de7, + 0x8ac1, 0x05ff, + 0x8acb, 0x1de8, + 0x8acc, 0x060a, + 0x8ae3, 0x1de9, + 0x8ae4, 0x0622, + 0x8b40, 0x063b, + 0x8b4a, 0x1dea, + 0x8b4b, 0x0646, + 0x8b5f, 0x1deb, + 0x8b60, 0x065b, + 0x8b80, 0x067a, + 0x8b82, 0x1f1e, + 0x8b83, 0x067d, + 0x8b88, 0x1f1f, + 0x8b89, 0x0683, + 0x8ba0, 0x1dec, + 0x8ba1, 0x069b, + 0x8ba8, 0x1ded, + 0x8ba9, 0x06a3, + 0x8bc0, 0x1f20, + 0x8bc1, 0x06bb, + 0x8bcd, 0x1dee, + 0x8bce, 0x06c8, + 0x8beb, 0x1def, + 0x8bec, 0x06e6, + 0x8bf2, 0x1df0, + 0x8bf3, 0x06ed, + 0x8bf9, 0x1df1, + 0x8bfa, 0x06f4, + 0x8bfb, 0x1df2, + 0x8bfc, 0x06f6, + 0x8c40, 0x06f7, + 0x8c56, 0x1df4, + 0x8c57, 0x070e, + 0x8c71, 0x1df7, + 0x8c72, 0x0729, + 0x8c80, 0x0736, + 0x8c91, 0x1dfa, + 0x8c92, 0x0748, + 0x8c9d, 0x1f21, + 0x8c9e, 0x1dfc, + 0x8c9f, 0x0755, + 0x8cb2, 0x1dfd, + 0x8cb3, 0x0769, + 0x8cbf, 0x1dfe, + 0x8cc0, 0x0776, + 0x8d40, 0x07b3, + 0x8d4a, 0x1dff, + 0x8d4b, 0x07be, + 0x8d80, 0x07f2, + 0x8d8d, 0x1e02, + 0x8d8e, 0x0800, + 0x8d94, 0x1e03, + 0x8d95, 0x0807, + 0x8d99, 0x1e04, + 0x8d9a, 0x080c, + 0x8dd1, 0x1e05, + 0x8dd2, 0x0844, + 0x8de5, 0x1e06, + 0x8de6, 0x0858, + 0x8df2, 0x1e07, + 0x8df3, 0x0865, + 0x8e40, 0x086f, + 0x8e46, 0x1e08, + 0x8e47, 0x0876, + 0x8e49, 0x1e09, + 0x8e4a, 0x0879, + 0x8e4b, 0x1e0a, + 0x8e4c, 0x087b, + 0x8e58, 0x1e0b, + 0x8e59, 0x0888, + 0x8e60, 0x1f22, + 0x8e61, 0x0890, + 0x8e80, 0x08ae, + 0x8ec6, 0x1e0d, + 0x8ec7, 0x08f5, + 0x8edb, 0x1e0f, + 0x8edd, 0x090b, + 0x8f40, 0x092b, + 0x8f4a, 0x1e11, + 0x8f4b, 0x0936, + 0x8f55, 0x1e12, + 0x8f56, 0x0941, + 0x8f80, 0x096a, + 0x8f8c, 0x1e13, + 0x8f8d, 0x0977, + 0x8f92, 0x1e15, + 0x8f94, 0x097e, + 0x8fa3, 0x1e17, + 0x8fa4, 0x098e, + 0x8fb1, 0x1e18, + 0x8fb2, 0x099c, + 0x8fd3, 0x1e1a, + 0x8fd4, 0x09be, + 0x8fdd, 0x1e1b, + 0x8fde, 0x09c8, + 0x8fe2, 0x1e1c, + 0x8fe3, 0x09cd, + 0x9040, 0x09e7, + 0x9049, 0x1e1d, + 0x904a, 0x09f1, + 0x9078, 0x1f23, + 0x9079, 0x0a20, + 0x9080, 0x1e1f, + 0x9081, 0x0a27, + 0x90a0, 0x1e21, + 0x90a1, 0x0a47, + 0x90e4, 0x1e23, + 0x90e5, 0x0a8b, + 0x90ef, 0x1e24, + 0x90f0, 0x0a96, + 0x90f7, 0x1e26, + 0x90f8, 0x1f24, + 0x90f9, 0x0a9f, + 0x90fa, 0x1f25, + 0x90fc, 0x0aa2, + 0x9140, 0x0aa3, + 0x9146, 0x1e28, + 0x9147, 0x0aaa, + 0x9158, 0x1e29, + 0x9159, 0x0abc, + 0x916b, 0x1e2a, + 0x916c, 0x0acf, + 0x916e, 0x1e2b, + 0x916f, 0x0ad2, + 0x917e, 0x1e2c, + 0x9180, 0x0ae2, + 0x9189, 0x1e2d, + 0x918a, 0x0aec, + 0x91b5, 0x1f27, + 0x91b6, 0x0b18, + 0x91bb, 0x1e2e, + 0x91bc, 0x0b1e, + 0x91cb, 0x1e2f, + 0x91cc, 0x0b2e, + 0x91da, 0x1e30, + 0x91db, 0x0b3d, + 0x91e1, 0x1e31, + 0x91e2, 0x0b44, + 0x91ed, 0x1e32, + 0x91ee, 0x0b50, + 0x91fb, 0x1e35, + 0x91fc, 0x0b5e, + 0x9240, 0x0b5f, + 0x9246, 0x1e36, + 0x9247, 0x0b66, + 0x9248, 0x1e37, + 0x9249, 0x0b68, + 0x924c, 0x1e39, + 0x924e, 0x0b6d, + 0x925c, 0x1e3b, + 0x925d, 0x0b7c, + 0x9280, 0x0b9e, + 0x9290, 0x1e3c, + 0x9291, 0x0baf, + 0x9295, 0x1e3d, + 0x9296, 0x0bb4, + 0x929c, 0x1e3e, + 0x929d, 0x0bbb, + 0x92bb, 0x1e3f, + 0x92bc, 0x0bda, + 0x92c6, 0x1e40, + 0x92c7, 0x0be5, + 0x92c8, 0x1e41, + 0x92c9, 0x0be7, + 0x92cd, 0x1e43, + 0x92ce, 0x0bec, + 0x9340, 0x0c1b, + 0x9341, 0x1e44, + 0x9342, 0x0c1d, + 0x9346, 0x1e45, + 0x9347, 0x0c22, + 0x934d, 0x1e46, + 0x934e, 0x0c29, + 0x9355, 0x1e47, + 0x9356, 0x0c31, + 0x935e, 0x1e48, + 0x935f, 0x0c3a, + 0x9367, 0x1e49, + 0x9368, 0x0c43, + 0x936a, 0x1e4a, + 0x936b, 0x0c46, + 0x9370, 0x1f28, + 0x9371, 0x1e4c, + 0x9372, 0x0c4d, + 0x9380, 0x0c5a, + 0x9384, 0x1e4d, + 0x9385, 0x0c5f, + 0x9398, 0x1e4e, + 0x9399, 0x0c73, + 0x93c0, 0x1e50, + 0x93c1, 0x0c9b, + 0x93d2, 0x1e51, + 0x93d3, 0x0cad, + 0x93d9, 0x1e53, + 0x93da, 0x0cb4, + 0x93e4, 0x1e56, + 0x93e6, 0x0cc0, + 0x93e8, 0x1e58, + 0x93e9, 0x0cc3, + 0x93f4, 0x1ec0, + 0x93f5, 0x0ccf, + 0x9440, 0x0cd7, + 0x9448, 0x1e59, + 0x9449, 0x1f29, + 0x944a, 0x0ce1, + 0x9458, 0x1e5a, + 0x9459, 0x0cf0, + 0x9476, 0x1e5b, + 0x9477, 0x0d0e, + 0x9480, 0x0d16, + 0x9487, 0x1e5c, + 0x9488, 0x0d1e, + 0x9489, 0x1e5d, + 0x948a, 0x0d20, + 0x948d, 0x1e5e, + 0x948e, 0x0d24, + 0x94a2, 0x1e5f, + 0x94a3, 0x0d39, + 0x94ac, 0x1e60, + 0x94ad, 0x0d43, + 0x94ae, 0x1e61, + 0x94af, 0x0d45, + 0x94be, 0x1f2a, + 0x94bf, 0x0d55, + 0x94d2, 0x1e62, + 0x94d3, 0x0d69, + 0x94f3, 0x1e64, + 0x94f4, 0x0d8a, + 0x9540, 0x0d93, + 0x9541, 0x1e65, + 0x9543, 0x0d96, + 0x954e, 0x1e67, + 0x954f, 0x0da2, + 0x9551, 0x1e68, + 0x9552, 0x0da5, + 0x9554, 0x1e69, + 0x9555, 0x0da8, + 0x955f, 0x1e6a, + 0x9560, 0x0db3, + 0x956d, 0x1e6b, + 0x956e, 0x0dc1, + 0x9580, 0x0dd2, + 0x95c1, 0x1e6d, + 0x95c2, 0x0e14, + 0x95cb, 0x1e6e, + 0x95cc, 0x0e1e, + 0x95d1, 0x1f2b, + 0x95d2, 0x0e24, + 0x95d8, 0x1e6f, + 0x95d9, 0x0e2b, + 0x95f7, 0x1e70, + 0x95f8, 0x0e4a, + 0x9640, 0x0e4f, + 0x9648, 0x1e72, + 0x9649, 0x0e58, + 0x966a, 0x1e73, + 0x966b, 0x0e7a, + 0x9680, 0x0e8e, + 0x9690, 0x1e74, + 0x9691, 0x0e9f, + 0x9698, 0x1f2c, + 0x9699, 0x0ea7, + 0x96cb, 0x1e75, + 0x96cc, 0x0eda, + 0x96d7, 0x1e76, + 0x96d8, 0x0ee6, + 0x96dd, 0x1e77, + 0x96de, 0x0eec, + 0x96e0, 0x1e78, + 0x96e1, 0x0eef, + 0x96f8, 0x1e79, + 0x96f9, 0x0f07, + 0x96fa, 0x1e7a, + 0x96fb, 0x0f09, + 0x9740, 0x0f0b, + 0x9751, 0x1e7c, + 0x9752, 0x0f1d, + 0x976f, 0x1e7d, + 0x9770, 0x0f3b, + 0x9773, 0x1e7e, + 0x9774, 0x0f3f, + 0x9780, 0x0f4a, + 0x9789, 0x1e7f, + 0x978a, 0x0f54, + 0x97f8, 0x1e81, + 0x97fa, 0x1f2d, + 0x97fb, 0x0fc5, + 0x9840, 0x1e83, + 0x9841, 0x0fc8, + 0x9850, 0x1e84, + 0x9851, 0x0fd8, + 0x9858, 0x1e85, + 0x9859, 0x0fe0, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9941, 0x1f2e, + 0x9942, 0x105a, + 0x995c, 0x1e86, + 0x995d, 0x1075, + 0x996c, 0x1e89, + 0x996d, 0x1085, + 0x9980, 0x1097, + 0x99b6, 0x1f2f, + 0x99b7, 0x10ce, + 0x9a40, 0x1114, + 0x9a4f, 0x1e8a, + 0x9a50, 0x1124, + 0x9a59, 0x1e8b, + 0x9a5a, 0x112e, + 0x9a67, 0x1f30, + 0x9a68, 0x113c, + 0x9a7d, 0x1e8d, + 0x9a7e, 0x1152, + 0x9a80, 0x1153, + 0x9a8b, 0x1e8e, + 0x9a8c, 0x1f31, + 0x9a8d, 0x1160, + 0x9ac2, 0x1e8f, + 0x9ac3, 0x1f32, + 0x9ac4, 0x1197, + 0x9aea, 0x1f33, + 0x9aeb, 0x11be, + 0x9b40, 0x11d0, + 0x9b5c, 0x1e90, + 0x9b5d, 0x11ed, + 0x9b80, 0x120f, + 0x9b83, 0x1e91, + 0x9b84, 0x1213, + 0x9b98, 0x1f34, + 0x9b99, 0x1228, + 0x9ba0, 0x1e92, + 0x9ba1, 0x1230, + 0x9bfb, 0x1f35, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9ca2, 0x1e94, + 0x9ca3, 0x12ee, + 0x9d40, 0x1348, + 0x9d47, 0x1f37, + 0x9d48, 0x1350, + 0x9d80, 0x1e95, + 0x9d81, 0x1388, + 0x9d8c, 0x1e96, + 0x9d8d, 0x1394, + 0x9db7, 0x1e97, + 0x9db8, 0x13bf, + 0x9df8, 0x1f38, + 0x9df9, 0x1400, + 0x9e40, 0x1404, + 0x9e64, 0x1e99, + 0x9e65, 0x1429, + 0x9e80, 0x1443, + 0x9e8b, 0x1e9b, + 0x9e8c, 0x144f, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0x9f81, 0x1f39, + 0x9f82, 0x1501, + 0x9fce, 0x1e9d, + 0x9fcf, 0x154e, + 0x9fd4, 0x1f3a, + 0x9fd5, 0x1554, + 0x9ff4, 0x1f3b, + 0x9ff5, 0x1574, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe093, 0x1e9e, + 0xe094, 0x15cf, + 0xe0a4, 0x1e9f, + 0xe0a5, 0x15e0, + 0xe0dd, 0x1ea0, + 0xe0de, 0x1619, + 0xe140, 0x1638, + 0xe14a, 0x1ea1, + 0xe14b, 0x1643, + 0xe180, 0x1677, + 0xe1ed, 0x1ea5, + 0xe1ee, 0x16e5, + 0xe240, 0x16f4, + 0xe269, 0x1ea6, + 0xe26a, 0x171e, + 0xe273, 0x1ea7, + 0xe274, 0x1728, + 0xe278, 0x1f3c, + 0xe279, 0x172d, + 0xe280, 0x1733, + 0xe2b7, 0x1ea8, + 0xe2b8, 0x176b, + 0xe2be, 0x1f3d, + 0xe2bf, 0x1772, + 0xe2e2, 0x1ea9, + 0xe2e3, 0x1796, + 0xe2ec, 0x1eaa, + 0xe2ed, 0x17a0, + 0xe340, 0x17b0, + 0xe358, 0x1eab, + 0xe359, 0x17c9, + 0xe35a, 0x1eac, + 0xe35b, 0x17cb, + 0xe365, 0x1ead, + 0xe366, 0x17d6, + 0xe380, 0x17ef, + 0xe3c7, 0x1f3e, + 0xe3c8, 0x1837, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe484, 0x1eaf, + 0xe485, 0x18b0, + 0xe489, 0x1eb0, + 0xe48a, 0x18b5, + 0xe492, 0x1eb1, + 0xe493, 0x18be, + 0xe4b9, 0x1eb3, + 0xe4ba, 0x18e5, + 0xe4cb, 0x1f3f, + 0xe4cc, 0x18f7, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe59e, 0x1f40, + 0xe59f, 0x1986, + 0xe5ba, 0x1f41, + 0xe5bc, 0x19a3, + 0xe5ed, 0x1eb8, + 0xe5ee, 0x19d5, + 0xe640, 0x19e4, + 0xe651, 0x1eb9, + 0xe652, 0x19f6, + 0xe680, 0x1a23, + 0xe686, 0x1eba, + 0xe687, 0x1a2a, + 0xe6e7, 0x1ebc, + 0xe6e8, 0x1a8b, + 0xe740, 0x1aa0, + 0xe76d, 0x1ebe, + 0xe76e, 0x1ace, + 0xe780, 0x1adf, + 0xe7a7, 0x1ec1, + 0xe7a8, 0x1b07, + 0xe7bb, 0x1ec2, + 0xe7bc, 0x1b1b, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe8cf, 0x1ec7, + 0xe8d0, 0x1beb, + 0xe940, 0x1c18, + 0xe978, 0x1f43, + 0xe979, 0x1c51, + 0xe980, 0x1c57, + 0xe9ab, 0x1eca, + 0xe9ac, 0x1c83, + 0xe9ba, 0x1ecb, + 0xe9bb, 0x1c92, + 0xe9cc, 0x1ecc, + 0xe9cd, 0x1ca4, + 0xea40, 0x1cd4, + 0xea70, 0x1ecd, + 0xea71, 0x1f44, + 0xea72, 0x1d06, + 0xea80, 0x1d13, + 0xea9d, 0x1ece, + 0xea9e, 0x1d31, + 0xeaa3, 0x205c, + 0xec40, 0x1f45, + 0xec46, 0x1f48, + 0xec47, 0x0300, + 0xec48, 0x02fa, + 0xec49, 0x02f9, + 0xec4d, 0x1f49, + 0xec5b, 0x1db1, + 0xec5e, 0x1f54, + 0xec5f, 0x1db7, + 0xec60, 0x1f55, + 0xec63, 0x1db4, + 0xec66, 0x1f58, + 0xec70, 0x0303, + 0xec71, 0x1f62, + 0xec72, 0x0304, + 0xec73, 0x1f63, + 0xec76, 0x1f65, + 0xec78, 0x1da4, + 0xec79, 0x1da1, + 0xec7a, 0x1f66, + 0xec7b, 0x1da2, + 0xec7c, 0x1f67, + 0xec80, 0x1da6, + 0xec81, 0x1f6a, + 0xec82, 0x1da8, + 0xec83, 0x1dac, + 0xec84, 0x1f6b, + 0xec85, 0x1dae, + 0xec86, 0x1dab, + 0xec87, 0x1f6c, + 0xec89, 0x1daf, + 0xec8a, 0x1f6e, + 0xec94, 0x1f75, + 0xec9a, 0x1dba, + 0xec9b, 0x1f7b, + 0xec9e, 0x1f7c, + 0xeca7, 0x1f7d, + 0xecb2, 0x1f87, + 0xecc7, 0x1d83, + 0xecdb, 0x1f9b, + 0xecdc, 0x1d97, + 0xece9, 0x1f9c, + 0xed40, 0x1fb0, + 0xed64, 0x1f16, + 0xed68, 0x1fca, + 0xed6a, 0x1dc4, + 0xed6b, 0x1fcc, + 0xed6e, 0x1dc3, + 0xed6f, 0x1fcf, + 0xed74, 0x1dc2, + 0xed75, 0x1fd4, + 0xed7c, 0x1fd8, + 0xed80, 0x1fdb, + 0xed8f, 0x1fe6, + 0xef40, 0x1ecf, + 0xef42, 0x204c, + 0xef43, 0x2052, + 0xef44, 0x1ed1, + 0xef4e, 0x205a, + 0xef4f, 0x2053, + 0xef50, 0x2058, + 0xef51, 0x2055, + 0xef52, 0x1edb, + 0xef64, 0x1eee, + 0xef7a, 0x2048, + 0xef8d, 0x02e0, + 0xef91, 0x1ff6, + 0x8141, 0x1ecf, + 0x8143, 0x204c, + 0x8144, 0x2052, + 0x8150, 0x1ed1, + 0x815b, 0x1ed3, + 0x8160, 0x1ed6, + 0x8165, 0x205a, + 0x8166, 0x2053, + 0x8167, 0x2058, + 0x8168, 0x2055, + 0x8169, 0x1edb, + 0x829f, 0x1eee, + 0x82a1, 0x1eef, + 0x82a3, 0x1ef0, + 0x82a5, 0x1ef1, + 0x82a7, 0x1ef2, + 0x82c1, 0x1ef3, + 0x82e1, 0x1ef4, + 0x82e3, 0x1ef5, + 0x82e5, 0x1ef6, + 0x82ec, 0x1ef7, + 0x82f3, 0x2048, + 0x8340, 0x1ef8, + 0x8342, 0x1ef9, + 0x8344, 0x1efa, + 0x8346, 0x1efb, + 0x8348, 0x1efc, + 0x8362, 0x1efd, + 0x8383, 0x1efe, + 0x8385, 0x1eff, + 0x8387, 0x1f00, + 0x838e, 0x1f01, + 0x8395, 0x1f02, + 0xec78, 0x1f07, + 0xec79, 0x1f04, + 0xec7a, 0x2089, + 0xec7b, 0x1f05, + 0xec7c, 0x208a, + 0xec7d, 0x2093, + 0xec80, 0x1f09, + 0xec81, 0x2092, + 0xec82, 0x1f0b, + 0xec83, 0x1f0f, + 0xec84, 0x209c, + 0xec85, 0x1f11, + 0xec86, 0x1f0e, + 0xec87, 0x2098, + 0xec88, 0x209b, + 0xec89, 0x1f12, + 0xec8a, 0x2097, + 0xec8b, 0x209d, + 0xec8d, 0x20a6, + 0xec8e, 0x20a5, + 0xec8f, 0x20a1, + 0xec90, 0x20a4, + 0xec95, 0x2084, + 0xef92, 0x208d, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12AddRKSJVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12AddRKSJVMap2, 692 +}; + +static Gushort japan12AddVMap2[1380] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2221, 0x02d7, + 0x223a, 0x02e5, + 0x224a, 0x02ed, + 0x225c, 0x02f4, + 0x2272, 0x0303, + 0x227e, 0x030b, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2474, 0x1f16, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x2821, 0x1d37, + 0x2822, 0x1d39, + 0x2823, 0x1d43, + 0x2824, 0x1d47, + 0x2825, 0x1d4f, + 0x2826, 0x1d4b, + 0x2827, 0x1d53, + 0x2828, 0x1d63, + 0x2829, 0x1d5b, + 0x282a, 0x1d6b, + 0x282b, 0x1d73, + 0x282c, 0x1d38, + 0x282d, 0x1d3a, + 0x282e, 0x1d46, + 0x282f, 0x1d4a, + 0x2830, 0x1d52, + 0x2831, 0x1d4e, + 0x2832, 0x1d5a, + 0x2833, 0x1d6a, + 0x2834, 0x1d62, + 0x2835, 0x1d72, + 0x2836, 0x1d82, + 0x2837, 0x1d57, + 0x2838, 0x1d66, + 0x2839, 0x1d5f, + 0x283a, 0x1d6e, + 0x283b, 0x1d76, + 0x283c, 0x1d54, + 0x283d, 0x1d67, + 0x283e, 0x1d5c, + 0x283f, 0x1d6f, + 0x2840, 0x1d79, + 0x3021, 0x0465, + 0x3022, 0x1dd1, + 0x3023, 0x0467, + 0x3032, 0x1f19, + 0x3033, 0x0477, + 0x303b, 0x1dd2, + 0x303c, 0x0480, + 0x306e, 0x1dd3, + 0x306f, 0x04b3, + 0x3071, 0x1f1a, + 0x3072, 0x04b6, + 0x3073, 0x1dd4, + 0x3074, 0x04b8, + 0x307c, 0x1dd5, + 0x307d, 0x04c1, + 0x3121, 0x04c3, + 0x312a, 0x1dd6, + 0x312b, 0x04cd, + 0x3133, 0x1f1b, + 0x3134, 0x04d6, + 0x3135, 0x1dd7, + 0x3136, 0x04d8, + 0x3139, 0x1f1c, + 0x313a, 0x04dc, + 0x313d, 0x1dda, + 0x313e, 0x04e0, + 0x3142, 0x1ddb, + 0x3143, 0x04e5, + 0x316b, 0x1ddc, + 0x316c, 0x050e, + 0x3221, 0x0521, + 0x3228, 0x1ddd, + 0x3229, 0x0529, + 0x322a, 0x1dde, + 0x322b, 0x052b, + 0x3260, 0x1ddf, + 0x3261, 0x0561, + 0x3267, 0x1f1d, + 0x3268, 0x0568, + 0x327a, 0x1de0, + 0x327b, 0x057b, + 0x3321, 0x057f, + 0x3322, 0x1de2, + 0x3323, 0x0581, + 0x336b, 0x1de4, + 0x336c, 0x05ca, + 0x3373, 0x1de5, + 0x3374, 0x05d2, + 0x337a, 0x1de6, + 0x337b, 0x05d9, + 0x3421, 0x05dd, + 0x3442, 0x1de7, + 0x3443, 0x05ff, + 0x344d, 0x1de8, + 0x344e, 0x060a, + 0x3465, 0x1de9, + 0x3466, 0x0622, + 0x3521, 0x063b, + 0x352b, 0x1dea, + 0x352c, 0x0646, + 0x3540, 0x1deb, + 0x3541, 0x065b, + 0x3562, 0x1f1e, + 0x3563, 0x067d, + 0x3568, 0x1f1f, + 0x3569, 0x0683, + 0x3621, 0x0699, + 0x3622, 0x1dec, + 0x3623, 0x069b, + 0x362a, 0x1ded, + 0x362b, 0x06a3, + 0x3642, 0x1f20, + 0x3643, 0x06bb, + 0x364f, 0x1dee, + 0x3650, 0x06c8, + 0x366d, 0x1def, + 0x366e, 0x06e6, + 0x3674, 0x1df0, + 0x3675, 0x06ed, + 0x367b, 0x1df1, + 0x367c, 0x06f4, + 0x367d, 0x1df2, + 0x367e, 0x06f6, + 0x3721, 0x06f7, + 0x3737, 0x1df4, + 0x3738, 0x070e, + 0x3752, 0x1df7, + 0x3753, 0x0729, + 0x3771, 0x1dfa, + 0x3772, 0x0748, + 0x377d, 0x1f21, + 0x377e, 0x1dfc, + 0x3821, 0x0755, + 0x3834, 0x1dfd, + 0x3835, 0x0769, + 0x3841, 0x1dfe, + 0x3842, 0x0776, + 0x3921, 0x07b3, + 0x392b, 0x1dff, + 0x392c, 0x07be, + 0x396d, 0x1e02, + 0x396e, 0x0800, + 0x3974, 0x1e03, + 0x3975, 0x0807, + 0x3979, 0x1e04, + 0x397a, 0x080c, + 0x3a21, 0x0811, + 0x3a53, 0x1e05, + 0x3a54, 0x0844, + 0x3a67, 0x1e06, + 0x3a68, 0x0858, + 0x3a74, 0x1e07, + 0x3a75, 0x0865, + 0x3b21, 0x086f, + 0x3b27, 0x1e08, + 0x3b28, 0x0876, + 0x3b2a, 0x1e09, + 0x3b2b, 0x0879, + 0x3b2c, 0x1e0a, + 0x3b2d, 0x087b, + 0x3b39, 0x1e0b, + 0x3b3a, 0x0888, + 0x3b41, 0x1f22, + 0x3b42, 0x0890, + 0x3c21, 0x08cd, + 0x3c48, 0x1e0d, + 0x3c49, 0x08f5, + 0x3c5d, 0x1e0f, + 0x3c5f, 0x090b, + 0x3d21, 0x092b, + 0x3d2b, 0x1e11, + 0x3d2c, 0x0936, + 0x3d36, 0x1e12, + 0x3d37, 0x0941, + 0x3d6c, 0x1e13, + 0x3d6d, 0x0977, + 0x3d72, 0x1e15, + 0x3d74, 0x097e, + 0x3e21, 0x0989, + 0x3e25, 0x1e17, + 0x3e26, 0x098e, + 0x3e33, 0x1e18, + 0x3e34, 0x099c, + 0x3e55, 0x1e1a, + 0x3e56, 0x09be, + 0x3e5f, 0x1e1b, + 0x3e60, 0x09c8, + 0x3e64, 0x1e1c, + 0x3e65, 0x09cd, + 0x3f21, 0x09e7, + 0x3f2a, 0x1e1d, + 0x3f2b, 0x09f1, + 0x3f59, 0x1f23, + 0x3f5a, 0x0a20, + 0x3f60, 0x1e1f, + 0x3f61, 0x0a27, + 0x4021, 0x0a45, + 0x4022, 0x1e21, + 0x4023, 0x0a47, + 0x4066, 0x1e23, + 0x4067, 0x0a8b, + 0x4071, 0x1e24, + 0x4072, 0x0a96, + 0x4079, 0x1e26, + 0x407a, 0x1f24, + 0x407b, 0x0a9f, + 0x407c, 0x1f25, + 0x407e, 0x0aa2, + 0x4121, 0x0aa3, + 0x4127, 0x1e28, + 0x4128, 0x0aaa, + 0x4139, 0x1e29, + 0x413a, 0x0abc, + 0x414c, 0x1e2a, + 0x414d, 0x0acf, + 0x414f, 0x1e2b, + 0x4150, 0x0ad2, + 0x415f, 0x1e2c, + 0x4160, 0x0ae2, + 0x4169, 0x1e2d, + 0x416a, 0x0aec, + 0x4221, 0x0b01, + 0x4237, 0x1f27, + 0x4238, 0x0b18, + 0x423d, 0x1e2e, + 0x423e, 0x0b1e, + 0x424d, 0x1e2f, + 0x424e, 0x0b2e, + 0x425c, 0x1e30, + 0x425d, 0x0b3d, + 0x4263, 0x1e31, + 0x4264, 0x0b44, + 0x426f, 0x1e32, + 0x4270, 0x0b50, + 0x427d, 0x1e35, + 0x427e, 0x0b5e, + 0x4321, 0x0b5f, + 0x4327, 0x1e36, + 0x4328, 0x0b66, + 0x4329, 0x1e37, + 0x432a, 0x0b68, + 0x432d, 0x1e39, + 0x432f, 0x0b6d, + 0x433d, 0x1e3b, + 0x433e, 0x0b7c, + 0x4370, 0x1e3c, + 0x4371, 0x0baf, + 0x4375, 0x1e3d, + 0x4376, 0x0bb4, + 0x437c, 0x1e3e, + 0x437d, 0x0bbb, + 0x4421, 0x0bbd, + 0x443d, 0x1e3f, + 0x443e, 0x0bda, + 0x4448, 0x1e40, + 0x4449, 0x0be5, + 0x444a, 0x1e41, + 0x444b, 0x0be7, + 0x444f, 0x1e43, + 0x4450, 0x0bec, + 0x4521, 0x0c1b, + 0x4522, 0x1e44, + 0x4523, 0x0c1d, + 0x4527, 0x1e45, + 0x4528, 0x0c22, + 0x452e, 0x1e46, + 0x452f, 0x0c29, + 0x4536, 0x1e47, + 0x4537, 0x0c31, + 0x453f, 0x1e48, + 0x4540, 0x0c3a, + 0x4548, 0x1e49, + 0x4549, 0x0c43, + 0x454b, 0x1e4a, + 0x454c, 0x0c46, + 0x4551, 0x1f28, + 0x4552, 0x1e4c, + 0x4553, 0x0c4d, + 0x4564, 0x1e4d, + 0x4565, 0x0c5f, + 0x4578, 0x1e4e, + 0x4579, 0x0c73, + 0x4621, 0x0c79, + 0x4642, 0x1e50, + 0x4643, 0x0c9b, + 0x4654, 0x1e51, + 0x4655, 0x0cad, + 0x465b, 0x1e53, + 0x465c, 0x0cb4, + 0x4666, 0x1e56, + 0x4668, 0x0cc0, + 0x466a, 0x1e58, + 0x466b, 0x0cc3, + 0x4676, 0x1ec0, + 0x4677, 0x0ccf, + 0x4721, 0x0cd7, + 0x4729, 0x1e59, + 0x472a, 0x1f29, + 0x472b, 0x0ce1, + 0x4739, 0x1e5a, + 0x473a, 0x0cf0, + 0x4757, 0x1e5b, + 0x4758, 0x0d0e, + 0x4767, 0x1e5c, + 0x4768, 0x0d1e, + 0x4769, 0x1e5d, + 0x476a, 0x0d20, + 0x476d, 0x1e5e, + 0x476e, 0x0d24, + 0x4821, 0x0d35, + 0x4824, 0x1e5f, + 0x4825, 0x0d39, + 0x482e, 0x1e60, + 0x482f, 0x0d43, + 0x4830, 0x1e61, + 0x4831, 0x0d45, + 0x4840, 0x1f2a, + 0x4841, 0x0d55, + 0x4854, 0x1e62, + 0x4855, 0x0d69, + 0x4875, 0x1e64, + 0x4876, 0x0d8a, + 0x4921, 0x0d93, + 0x4922, 0x1e65, + 0x4924, 0x0d96, + 0x492f, 0x1e67, + 0x4930, 0x0da2, + 0x4932, 0x1e68, + 0x4933, 0x0da5, + 0x4935, 0x1e69, + 0x4936, 0x0da8, + 0x4940, 0x1e6a, + 0x4941, 0x0db3, + 0x494e, 0x1e6b, + 0x494f, 0x0dc1, + 0x4a21, 0x0df1, + 0x4a43, 0x1e6d, + 0x4a44, 0x0e14, + 0x4a4d, 0x1e6e, + 0x4a4e, 0x0e1e, + 0x4a53, 0x1f2b, + 0x4a54, 0x0e24, + 0x4a5a, 0x1e6f, + 0x4a5b, 0x0e2b, + 0x4a79, 0x1e70, + 0x4a7a, 0x0e4a, + 0x4b21, 0x0e4f, + 0x4b29, 0x1e72, + 0x4b2a, 0x0e58, + 0x4b4b, 0x1e73, + 0x4b4c, 0x0e7a, + 0x4b70, 0x1e74, + 0x4b71, 0x0e9f, + 0x4b78, 0x1f2c, + 0x4b79, 0x0ea7, + 0x4c21, 0x0ead, + 0x4c4d, 0x1e75, + 0x4c4e, 0x0eda, + 0x4c59, 0x1e76, + 0x4c5a, 0x0ee6, + 0x4c5f, 0x1e77, + 0x4c60, 0x0eec, + 0x4c62, 0x1e78, + 0x4c63, 0x0eef, + 0x4c7a, 0x1e79, + 0x4c7b, 0x0f07, + 0x4c7c, 0x1e7a, + 0x4c7d, 0x0f09, + 0x4d21, 0x0f0b, + 0x4d32, 0x1e7c, + 0x4d33, 0x0f1d, + 0x4d50, 0x1e7d, + 0x4d51, 0x0f3b, + 0x4d54, 0x1e7e, + 0x4d55, 0x0f3f, + 0x4d69, 0x1e7f, + 0x4d6a, 0x0f54, + 0x4e21, 0x0f69, + 0x4e7a, 0x1e81, + 0x4e7c, 0x1f2d, + 0x4e7d, 0x0fc5, + 0x4f21, 0x1e83, + 0x4f22, 0x0fc8, + 0x4f31, 0x1e84, + 0x4f32, 0x0fd8, + 0x4f39, 0x1e85, + 0x4f3a, 0x0fe0, + 0x5021, 0x0ffa, + 0x5121, 0x1058, + 0x5122, 0x1f2e, + 0x5123, 0x105a, + 0x513d, 0x1e86, + 0x513e, 0x1075, + 0x514d, 0x1e89, + 0x514e, 0x1085, + 0x5221, 0x10b6, + 0x5238, 0x1f2f, + 0x5239, 0x10ce, + 0x5321, 0x1114, + 0x5330, 0x1e8a, + 0x5331, 0x1124, + 0x533a, 0x1e8b, + 0x533b, 0x112e, + 0x5348, 0x1f30, + 0x5349, 0x113c, + 0x535e, 0x1e8d, + 0x535f, 0x1152, + 0x536b, 0x1e8e, + 0x536c, 0x1f31, + 0x536d, 0x1160, + 0x5421, 0x1172, + 0x5444, 0x1e8f, + 0x5445, 0x1f32, + 0x5446, 0x1197, + 0x546c, 0x1f33, + 0x546d, 0x11be, + 0x5521, 0x11d0, + 0x553d, 0x1e90, + 0x553e, 0x11ed, + 0x5563, 0x1e91, + 0x5564, 0x1213, + 0x5578, 0x1f34, + 0x5579, 0x1228, + 0x5621, 0x122e, + 0x5622, 0x1e92, + 0x5623, 0x1230, + 0x567d, 0x1f35, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5824, 0x1e94, + 0x5825, 0x12ee, + 0x5921, 0x1348, + 0x5928, 0x1f37, + 0x5929, 0x1350, + 0x5960, 0x1e95, + 0x5961, 0x1388, + 0x596c, 0x1e96, + 0x596d, 0x1394, + 0x5a21, 0x13a6, + 0x5a39, 0x1e97, + 0x5a3a, 0x13bf, + 0x5a7a, 0x1f38, + 0x5a7b, 0x1400, + 0x5b21, 0x1404, + 0x5b45, 0x1e99, + 0x5b46, 0x1429, + 0x5b6b, 0x1e9b, + 0x5b6c, 0x144f, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5d61, 0x1f39, + 0x5d62, 0x1501, + 0x5e21, 0x151e, + 0x5e50, 0x1e9d, + 0x5e51, 0x154e, + 0x5e56, 0x1f3a, + 0x5e57, 0x1554, + 0x5e76, 0x1f3b, + 0x5e77, 0x1574, + 0x5f21, 0x157c, + 0x5f73, 0x1e9e, + 0x5f74, 0x15cf, + 0x6021, 0x15da, + 0x6026, 0x1e9f, + 0x6027, 0x15e0, + 0x605f, 0x1ea0, + 0x6060, 0x1619, + 0x6121, 0x1638, + 0x612b, 0x1ea1, + 0x612c, 0x1643, + 0x6221, 0x1696, + 0x626f, 0x1ea5, + 0x6270, 0x16e5, + 0x6321, 0x16f4, + 0x634a, 0x1ea6, + 0x634b, 0x171e, + 0x6354, 0x1ea7, + 0x6355, 0x1728, + 0x6359, 0x1f3c, + 0x635a, 0x172d, + 0x6421, 0x1752, + 0x6439, 0x1ea8, + 0x643a, 0x176b, + 0x6440, 0x1f3d, + 0x6441, 0x1772, + 0x6464, 0x1ea9, + 0x6465, 0x1796, + 0x646e, 0x1eaa, + 0x646f, 0x17a0, + 0x6521, 0x17b0, + 0x6539, 0x1eab, + 0x653a, 0x17c9, + 0x653b, 0x1eac, + 0x653c, 0x17cb, + 0x6546, 0x1ead, + 0x6547, 0x17d6, + 0x6621, 0x180e, + 0x6649, 0x1f3e, + 0x664a, 0x1837, + 0x6721, 0x186c, + 0x6764, 0x1eaf, + 0x6765, 0x18b0, + 0x6769, 0x1eb0, + 0x676a, 0x18b5, + 0x6772, 0x1eb1, + 0x6773, 0x18be, + 0x6821, 0x18ca, + 0x683b, 0x1eb3, + 0x683c, 0x18e5, + 0x684d, 0x1f3f, + 0x684e, 0x18f7, + 0x6921, 0x1928, + 0x697e, 0x1f40, + 0x6a21, 0x1986, + 0x6a3c, 0x1f41, + 0x6a3e, 0x19a3, + 0x6a6f, 0x1eb8, + 0x6a70, 0x19d5, + 0x6b21, 0x19e4, + 0x6b32, 0x1eb9, + 0x6b33, 0x19f6, + 0x6b66, 0x1eba, + 0x6b67, 0x1a2a, + 0x6c21, 0x1a42, + 0x6c69, 0x1ebc, + 0x6c6a, 0x1a8b, + 0x6d21, 0x1aa0, + 0x6d4e, 0x1ebe, + 0x6d4f, 0x1ace, + 0x6e21, 0x1afe, + 0x6e29, 0x1ec1, + 0x6e2a, 0x1b07, + 0x6e3d, 0x1ec2, + 0x6e3e, 0x1b1b, + 0x6f21, 0x1b5c, + 0x7021, 0x1bba, + 0x7051, 0x1ec7, + 0x7052, 0x1beb, + 0x7121, 0x1c18, + 0x7159, 0x1f43, + 0x715a, 0x1c51, + 0x7221, 0x1c76, + 0x722d, 0x1eca, + 0x722e, 0x1c83, + 0x723c, 0x1ecb, + 0x723d, 0x1c92, + 0x724e, 0x1ecc, + 0x724f, 0x1ca4, + 0x7321, 0x1cd4, + 0x7351, 0x1ecd, + 0x7352, 0x1f44, + 0x7353, 0x1d06, + 0x737d, 0x1ece, + 0x737e, 0x1d31, + 0x7421, 0x1d32, + 0x7425, 0x205c, + 0x7721, 0x1f45, + 0x7727, 0x1f48, + 0x7728, 0x0300, + 0x7729, 0x02fa, + 0x772a, 0x02f9, + 0x772e, 0x1f49, + 0x773c, 0x1db1, + 0x773f, 0x1f54, + 0x7740, 0x1db7, + 0x7741, 0x1f55, + 0x7744, 0x1db4, + 0x7747, 0x1f58, + 0x7751, 0x0303, + 0x7752, 0x1f62, + 0x7753, 0x0304, + 0x7754, 0x1f63, + 0x7757, 0x1f65, + 0x7759, 0x1da4, + 0x775a, 0x1da1, + 0x775b, 0x1f66, + 0x775c, 0x1da2, + 0x775d, 0x1f67, + 0x7760, 0x1da6, + 0x7761, 0x1f6a, + 0x7762, 0x1da8, + 0x7763, 0x1dac, + 0x7764, 0x1f6b, + 0x7765, 0x1dae, + 0x7766, 0x1dab, + 0x7767, 0x1f6c, + 0x7769, 0x1daf, + 0x776a, 0x1f6e, + 0x7774, 0x1f75, + 0x777a, 0x1dba, + 0x777b, 0x1f7b, + 0x777e, 0x1f7c, + 0x7829, 0x1f7d, + 0x7834, 0x1f87, + 0x7849, 0x1d83, + 0x785d, 0x1f9b, + 0x785e, 0x1d97, + 0x786b, 0x1f9c, + 0x7921, 0x1fb0, + 0x7945, 0x1f16, + 0x7949, 0x1fca, + 0x794b, 0x1dc4, + 0x794c, 0x1fcc, + 0x794f, 0x1dc3, + 0x7950, 0x1fcf, + 0x7955, 0x1dc2, + 0x7956, 0x1fd4, + 0x795d, 0x1fd8, + 0x796f, 0x1fe6, + 0x7d21, 0x1ecf, + 0x7d23, 0x204c, + 0x7d24, 0x2052, + 0x7d25, 0x1ed1, + 0x7d2f, 0x205a, + 0x7d30, 0x2053, + 0x7d31, 0x2058, + 0x7d32, 0x2055, + 0x7d33, 0x1edb, + 0x7d45, 0x1eee, + 0x7d5b, 0x2048, + 0x7d6d, 0x02e0, + 0x7d71, 0x1ff6, + 0x2122, 0x1ecf, + 0x2124, 0x204c, + 0x2125, 0x2052, + 0x2131, 0x1ed1, + 0x213c, 0x1ed3, + 0x2141, 0x1ed6, + 0x2146, 0x205a, + 0x2147, 0x2053, + 0x2148, 0x2058, + 0x2149, 0x2055, + 0x214a, 0x1edb, + 0x2421, 0x1eee, + 0x2423, 0x1eef, + 0x2425, 0x1ef0, + 0x2427, 0x1ef1, + 0x2429, 0x1ef2, + 0x2443, 0x1ef3, + 0x2463, 0x1ef4, + 0x2465, 0x1ef5, + 0x2467, 0x1ef6, + 0x246e, 0x1ef7, + 0x2475, 0x2048, + 0x2521, 0x1ef8, + 0x2523, 0x1ef9, + 0x2525, 0x1efa, + 0x2527, 0x1efb, + 0x2529, 0x1efc, + 0x2543, 0x1efd, + 0x2563, 0x1efe, + 0x2565, 0x1eff, + 0x2567, 0x1f00, + 0x256e, 0x1f01, + 0x2575, 0x1f02, + 0x7759, 0x1f07, + 0x775a, 0x1f04, + 0x775b, 0x2089, + 0x775c, 0x1f05, + 0x775d, 0x208a, + 0x775e, 0x2093, + 0x7760, 0x1f09, + 0x7761, 0x2092, + 0x7762, 0x1f0b, + 0x7763, 0x1f0f, + 0x7764, 0x209c, + 0x7765, 0x1f11, + 0x7766, 0x1f0e, + 0x7767, 0x2098, + 0x7768, 0x209b, + 0x7769, 0x1f12, + 0x776a, 0x2097, + 0x776b, 0x209d, + 0x776d, 0x20a6, + 0x776e, 0x20a5, + 0x776f, 0x20a1, + 0x7770, 0x20a4, + 0x7775, 0x2084, + 0x7d72, 0x208d, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12AddVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12AddVMap2, 690 +}; + +static Gushort japan12AdobeJapan10Map2[70] = { + 0x0000, 0x0000, + 0x0000, 0x0000, + 0x0100, 0x0100, + 0x0200, 0x0200, + 0x0300, 0x0300, + 0x0400, 0x0400, + 0x0500, 0x0500, + 0x0600, 0x0600, + 0x0700, 0x0700, + 0x0800, 0x0800, + 0x0900, 0x0900, + 0x0a00, 0x0a00, + 0x0b00, 0x0b00, + 0x0c00, 0x0c00, + 0x0d00, 0x0d00, + 0x0e00, 0x0e00, + 0x0f00, 0x0f00, + 0x1000, 0x1000, + 0x1100, 0x1100, + 0x1200, 0x1200, + 0x1300, 0x1300, + 0x1400, 0x1400, + 0x1500, 0x1500, + 0x1600, 0x1600, + 0x1700, 0x1700, + 0x1800, 0x1800, + 0x1900, 0x1900, + 0x1a00, 0x1a00, + 0x1b00, 0x1b00, + 0x1c00, 0x1c00, + 0x1d00, 0x1d00, + 0x1e00, 0x1e00, + 0x1f00, 0x1f00, + 0x2000, 0x2000, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12AdobeJapan10Enc16 = { + 0, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12AdobeJapan10Map2, 35 +}; + +static Gushort japan12AdobeJapan11Map2[70] = { + 0x0000, 0x0000, + 0x0000, 0x0000, + 0x0100, 0x0100, + 0x0200, 0x0200, + 0x0300, 0x0300, + 0x0400, 0x0400, + 0x0500, 0x0500, + 0x0600, 0x0600, + 0x0700, 0x0700, + 0x0800, 0x0800, + 0x0900, 0x0900, + 0x0a00, 0x0a00, + 0x0b00, 0x0b00, + 0x0c00, 0x0c00, + 0x0d00, 0x0d00, + 0x0e00, 0x0e00, + 0x0f00, 0x0f00, + 0x1000, 0x1000, + 0x1100, 0x1100, + 0x1200, 0x1200, + 0x1300, 0x1300, + 0x1400, 0x1400, + 0x1500, 0x1500, + 0x1600, 0x1600, + 0x1700, 0x1700, + 0x1800, 0x1800, + 0x1900, 0x1900, + 0x1a00, 0x1a00, + 0x1b00, 0x1b00, + 0x1c00, 0x1c00, + 0x1d00, 0x1d00, + 0x1e00, 0x1e00, + 0x1f00, 0x1f00, + 0x2000, 0x2000, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12AdobeJapan11Enc16 = { + 0, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12AdobeJapan11Map2, 35 +}; + +static Gushort japan12AdobeJapan12Map2[74] = { + 0x0000, 0x0000, + 0x0000, 0x0000, + 0x0100, 0x0100, + 0x0200, 0x0200, + 0x0300, 0x0300, + 0x0400, 0x0400, + 0x0500, 0x0500, + 0x0600, 0x0600, + 0x0700, 0x0700, + 0x0800, 0x0800, + 0x0900, 0x0900, + 0x0a00, 0x0a00, + 0x0b00, 0x0b00, + 0x0c00, 0x0c00, + 0x0d00, 0x0d00, + 0x0e00, 0x0e00, + 0x0f00, 0x0f00, + 0x1000, 0x1000, + 0x1100, 0x1100, + 0x1200, 0x1200, + 0x1300, 0x1300, + 0x1400, 0x1400, + 0x1500, 0x1500, + 0x1600, 0x1600, + 0x1700, 0x1700, + 0x1800, 0x1800, + 0x1900, 0x1900, + 0x1a00, 0x1a00, + 0x1b00, 0x1b00, + 0x1c00, 0x1c00, + 0x1d00, 0x1d00, + 0x1e00, 0x1e00, + 0x1f00, 0x1f00, + 0x2000, 0x2000, + 0x2100, 0x2100, + 0x2200, 0x2200, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12AdobeJapan12Enc16 = { + 0, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12AdobeJapan12Map2, 37 +}; + +static Gushort japan12EUCHMap2[242] = { + 0x0000, 0x0000, + 0x8ea0, 0x0146, + 0xa1a1, 0x0279, + 0xa2a1, 0x02d7, + 0xa2ba, 0x02e5, + 0xa2ca, 0x02ed, + 0xa2dc, 0x02f4, + 0xa2f2, 0x0303, + 0xa2fe, 0x030b, + 0xa3b0, 0x030c, + 0xa3c1, 0x0316, + 0xa3e1, 0x0330, + 0xa4a1, 0x034a, + 0xa5a1, 0x039d, + 0xa6a1, 0x03f3, + 0xa6c1, 0x040b, + 0xa7a1, 0x0423, + 0xa7d1, 0x0444, + 0xa8a1, 0x1d37, + 0xa8a2, 0x1d39, + 0xa8a3, 0x1d43, + 0xa8a4, 0x1d47, + 0xa8a5, 0x1d4f, + 0xa8a6, 0x1d4b, + 0xa8a7, 0x1d53, + 0xa8a8, 0x1d63, + 0xa8a9, 0x1d5b, + 0xa8aa, 0x1d6b, + 0xa8ab, 0x1d73, + 0xa8ac, 0x1d38, + 0xa8ad, 0x1d3a, + 0xa8ae, 0x1d46, + 0xa8af, 0x1d4a, + 0xa8b0, 0x1d52, + 0xa8b1, 0x1d4e, + 0xa8b2, 0x1d5a, + 0xa8b3, 0x1d6a, + 0xa8b4, 0x1d62, + 0xa8b5, 0x1d72, + 0xa8b6, 0x1d82, + 0xa8b7, 0x1d57, + 0xa8b8, 0x1d66, + 0xa8b9, 0x1d5f, + 0xa8ba, 0x1d6e, + 0xa8bb, 0x1d76, + 0xa8bc, 0x1d54, + 0xa8bd, 0x1d67, + 0xa8be, 0x1d5c, + 0xa8bf, 0x1d6f, + 0xa8c0, 0x1d79, + 0xb0a1, 0x0465, + 0xb1a1, 0x04c3, + 0xb2a1, 0x0521, + 0xb3a1, 0x057f, + 0xb4a1, 0x05dd, + 0xb5a1, 0x063b, + 0xb6a1, 0x0699, + 0xb7a1, 0x06f7, + 0xb8a1, 0x0755, + 0xb9a1, 0x07b3, + 0xbaa1, 0x0811, + 0xbba1, 0x086f, + 0xbca1, 0x08cd, + 0xbda1, 0x092b, + 0xbea1, 0x0989, + 0xbfa1, 0x09e7, + 0xc0a1, 0x0a45, + 0xc1a1, 0x0aa3, + 0xc2a1, 0x0b01, + 0xc3a1, 0x0b5f, + 0xc4a1, 0x0bbd, + 0xc5a1, 0x0c1b, + 0xc6a1, 0x0c79, + 0xc7a1, 0x0cd7, + 0xc8a1, 0x0d35, + 0xc9a1, 0x0d93, + 0xcaa1, 0x0df1, + 0xcba1, 0x0e4f, + 0xcca1, 0x0ead, + 0xcda1, 0x0f0b, + 0xcea1, 0x0f69, + 0xcfa1, 0x0fc7, + 0xd0a1, 0x0ffa, + 0xd1a1, 0x1058, + 0xd2a1, 0x10b6, + 0xd3a1, 0x1114, + 0xd4a1, 0x1172, + 0xd5a1, 0x11d0, + 0xd6a1, 0x122e, + 0xd7a1, 0x128c, + 0xd8a1, 0x12ea, + 0xd9a1, 0x1348, + 0xdaa1, 0x13a6, + 0xdba1, 0x1404, + 0xdca1, 0x1462, + 0xdda1, 0x14c0, + 0xdea1, 0x151e, + 0xdfa1, 0x157c, + 0xe0a1, 0x15da, + 0xe1a1, 0x1638, + 0xe2a1, 0x1696, + 0xe3a1, 0x16f4, + 0xe4a1, 0x1752, + 0xe5a1, 0x17b0, + 0xe6a1, 0x180e, + 0xe7a1, 0x186c, + 0xe8a1, 0x18ca, + 0xe9a1, 0x1928, + 0xeaa1, 0x1986, + 0xeba1, 0x19e4, + 0xeca1, 0x1a42, + 0xeda1, 0x1aa0, + 0xeea1, 0x1afe, + 0xefa1, 0x1b5c, + 0xf0a1, 0x1bba, + 0xf1a1, 0x1c18, + 0xf2a1, 0x1c76, + 0xf3a1, 0x1cd4, + 0xf4a1, 0x1d32, + 0xf4a5, 0x205c, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12EUCHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12EUCHMap2, 121 +}; + +static Gushort japan12EUCVMap2[296] = { + 0x0000, 0x0000, + 0x8ea0, 0x0146, + 0xa1a1, 0x0279, + 0xa2a1, 0x02d7, + 0xa2ba, 0x02e5, + 0xa2ca, 0x02ed, + 0xa2dc, 0x02f4, + 0xa2f2, 0x0303, + 0xa2fe, 0x030b, + 0xa3b0, 0x030c, + 0xa3c1, 0x0316, + 0xa3e1, 0x0330, + 0xa4a1, 0x034a, + 0xa5a1, 0x039d, + 0xa6a1, 0x03f3, + 0xa6c1, 0x040b, + 0xa7a1, 0x0423, + 0xa7d1, 0x0444, + 0xa8a1, 0x1d37, + 0xa8a2, 0x1d39, + 0xa8a3, 0x1d43, + 0xa8a4, 0x1d47, + 0xa8a5, 0x1d4f, + 0xa8a6, 0x1d4b, + 0xa8a7, 0x1d53, + 0xa8a8, 0x1d63, + 0xa8a9, 0x1d5b, + 0xa8aa, 0x1d6b, + 0xa8ab, 0x1d73, + 0xa8ac, 0x1d38, + 0xa8ad, 0x1d3a, + 0xa8ae, 0x1d46, + 0xa8af, 0x1d4a, + 0xa8b0, 0x1d52, + 0xa8b1, 0x1d4e, + 0xa8b2, 0x1d5a, + 0xa8b3, 0x1d6a, + 0xa8b4, 0x1d62, + 0xa8b5, 0x1d72, + 0xa8b6, 0x1d82, + 0xa8b7, 0x1d57, + 0xa8b8, 0x1d66, + 0xa8b9, 0x1d5f, + 0xa8ba, 0x1d6e, + 0xa8bb, 0x1d76, + 0xa8bc, 0x1d54, + 0xa8bd, 0x1d67, + 0xa8be, 0x1d5c, + 0xa8bf, 0x1d6f, + 0xa8c0, 0x1d79, + 0xb0a1, 0x0465, + 0xb1a1, 0x04c3, + 0xb2a1, 0x0521, + 0xb3a1, 0x057f, + 0xb4a1, 0x05dd, + 0xb5a1, 0x063b, + 0xb6a1, 0x0699, + 0xb7a1, 0x06f7, + 0xb8a1, 0x0755, + 0xb9a1, 0x07b3, + 0xbaa1, 0x0811, + 0xbba1, 0x086f, + 0xbca1, 0x08cd, + 0xbda1, 0x092b, + 0xbea1, 0x0989, + 0xbfa1, 0x09e7, + 0xc0a1, 0x0a45, + 0xc1a1, 0x0aa3, + 0xc2a1, 0x0b01, + 0xc3a1, 0x0b5f, + 0xc4a1, 0x0bbd, + 0xc5a1, 0x0c1b, + 0xc6a1, 0x0c79, + 0xc7a1, 0x0cd7, + 0xc8a1, 0x0d35, + 0xc9a1, 0x0d93, + 0xcaa1, 0x0df1, + 0xcba1, 0x0e4f, + 0xcca1, 0x0ead, + 0xcda1, 0x0f0b, + 0xcea1, 0x0f69, + 0xcfa1, 0x0fc7, + 0xd0a1, 0x0ffa, + 0xd1a1, 0x1058, + 0xd2a1, 0x10b6, + 0xd3a1, 0x1114, + 0xd4a1, 0x1172, + 0xd5a1, 0x11d0, + 0xd6a1, 0x122e, + 0xd7a1, 0x128c, + 0xd8a1, 0x12ea, + 0xd9a1, 0x1348, + 0xdaa1, 0x13a6, + 0xdba1, 0x1404, + 0xdca1, 0x1462, + 0xdda1, 0x14c0, + 0xdea1, 0x151e, + 0xdfa1, 0x157c, + 0xe0a1, 0x15da, + 0xe1a1, 0x1638, + 0xe2a1, 0x1696, + 0xe3a1, 0x16f4, + 0xe4a1, 0x1752, + 0xe5a1, 0x17b0, + 0xe6a1, 0x180e, + 0xe7a1, 0x186c, + 0xe8a1, 0x18ca, + 0xe9a1, 0x1928, + 0xeaa1, 0x1986, + 0xeba1, 0x19e4, + 0xeca1, 0x1a42, + 0xeda1, 0x1aa0, + 0xeea1, 0x1afe, + 0xefa1, 0x1b5c, + 0xf0a1, 0x1bba, + 0xf1a1, 0x1c18, + 0xf2a1, 0x1c76, + 0xf3a1, 0x1cd4, + 0xf4a1, 0x1d32, + 0xf4a5, 0x205c, + 0xa1a2, 0x1ecf, + 0xa1b1, 0x1ed1, + 0xa1bc, 0x1ed3, + 0xa1c1, 0x1ed6, + 0xa1ca, 0x1edb, + 0xa1e1, 0x1eed, + 0xa4a1, 0x1eee, + 0xa4a3, 0x1eef, + 0xa4a5, 0x1ef0, + 0xa4a7, 0x1ef1, + 0xa4a9, 0x1ef2, + 0xa4c3, 0x1ef3, + 0xa4e3, 0x1ef4, + 0xa4e5, 0x1ef5, + 0xa4e7, 0x1ef6, + 0xa4ee, 0x1ef7, + 0xa5a1, 0x1ef8, + 0xa5a3, 0x1ef9, + 0xa5a5, 0x1efa, + 0xa5a7, 0x1efb, + 0xa5a9, 0x1efc, + 0xa5c3, 0x1efd, + 0xa5e3, 0x1efe, + 0xa5e5, 0x1eff, + 0xa5e7, 0x1f00, + 0xa5ee, 0x1f01, + 0xa5f5, 0x1f02, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12EUCVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12EUCVMap2, 148 +}; + +static Gushort japan12ExtHMap2[1326] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2169, 0x1d36, + 0x216a, 0x02c2, + 0x2221, 0x02d7, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x2921, 0x00e8, + 0x2960, 0x0186, + 0x2961, 0x0128, + 0x2a21, 0x0147, + 0x2a60, 0x0187, + 0x2b21, 0x01a6, + 0x2b72, 0x0127, + 0x2b73, 0x01f7, + 0x2c24, 0x1d37, + 0x2d21, 0x1d83, + 0x2d40, 0x1da1, + 0x2d5f, 0x2083, + 0x2d60, 0x1db8, + 0x2d70, 0x02fa, + 0x2d71, 0x02f9, + 0x2d72, 0x0301, + 0x2d73, 0x1dc8, + 0x2d7a, 0x0300, + 0x2d7b, 0x1dcf, + 0x3021, 0x0465, + 0x3022, 0x1dd1, + 0x3023, 0x0467, + 0x3033, 0x1ca2, + 0x3034, 0x0478, + 0x303b, 0x1dd2, + 0x303c, 0x0480, + 0x306e, 0x1dd3, + 0x306f, 0x04b3, + 0x3073, 0x1dd4, + 0x3074, 0x04b8, + 0x307c, 0x1dd5, + 0x307d, 0x04c1, + 0x3121, 0x04c3, + 0x312a, 0x1dd6, + 0x312b, 0x04cd, + 0x3135, 0x1dd7, + 0x3136, 0x04d8, + 0x3139, 0x1dd8, + 0x313a, 0x04dc, + 0x313c, 0x1dd9, + 0x313e, 0x04e0, + 0x3142, 0x1ddb, + 0x3143, 0x04e5, + 0x316b, 0x1ddc, + 0x316c, 0x050e, + 0x3221, 0x0521, + 0x3228, 0x1ddd, + 0x3229, 0x1cc9, + 0x322a, 0x1dde, + 0x322b, 0x052b, + 0x3260, 0x1ddf, + 0x3261, 0x0561, + 0x327a, 0x1de0, + 0x327b, 0x057b, + 0x327d, 0x1de1, + 0x327e, 0x057e, + 0x3321, 0x057f, + 0x3322, 0x1de2, + 0x3323, 0x0581, + 0x3342, 0x1961, + 0x3343, 0x05a1, + 0x3349, 0x139f, + 0x334a, 0x05a8, + 0x3365, 0x1de3, + 0x3366, 0x05c4, + 0x336b, 0x1de4, + 0x336c, 0x05ca, + 0x3373, 0x1de5, + 0x3374, 0x05d2, + 0x3376, 0x1731, + 0x3377, 0x05d5, + 0x337a, 0x1de6, + 0x337b, 0x05d9, + 0x3421, 0x05dd, + 0x3442, 0x1de7, + 0x3443, 0x1572, + 0x3444, 0x0600, + 0x344d, 0x1de8, + 0x344e, 0x060a, + 0x3452, 0x1a20, + 0x3453, 0x060f, + 0x3465, 0x1de9, + 0x3466, 0x0622, + 0x3521, 0x063b, + 0x352b, 0x1dea, + 0x352c, 0x0646, + 0x3540, 0x1deb, + 0x3541, 0x065b, + 0x3621, 0x0699, + 0x3622, 0x1dec, + 0x3623, 0x069b, + 0x362a, 0x1ded, + 0x362b, 0x06a3, + 0x3646, 0x1d32, + 0x3647, 0x06bf, + 0x364f, 0x1dee, + 0x3650, 0x06c8, + 0x366d, 0x1def, + 0x366e, 0x06e6, + 0x3674, 0x1df0, + 0x3675, 0x06ed, + 0x367b, 0x1df1, + 0x367c, 0x06f4, + 0x367d, 0x1df2, + 0x367e, 0x06f6, + 0x3721, 0x06f7, + 0x3724, 0x1df3, + 0x3725, 0x06fb, + 0x3737, 0x1df4, + 0x3738, 0x070e, + 0x3745, 0x1df5, + 0x3746, 0x071c, + 0x374e, 0x1df6, + 0x374f, 0x0725, + 0x3752, 0x1df7, + 0x3753, 0x0729, + 0x3755, 0x1df8, + 0x3756, 0x072c, + 0x375b, 0x1c0d, + 0x375c, 0x0732, + 0x3764, 0x1df9, + 0x3765, 0x073b, + 0x3771, 0x1dfa, + 0x3772, 0x0748, + 0x3779, 0x1dfb, + 0x377a, 0x0750, + 0x377e, 0x1dfc, + 0x3821, 0x0755, + 0x3834, 0x1dfd, + 0x3835, 0x0769, + 0x3841, 0x1dfe, + 0x3842, 0x0776, + 0x3921, 0x07b3, + 0x392b, 0x1dff, + 0x392c, 0x07be, + 0x3937, 0x1e00, + 0x3938, 0x07ca, + 0x3942, 0x1e01, + 0x3943, 0x07d5, + 0x395c, 0x16dd, + 0x395d, 0x07ef, + 0x396d, 0x1e02, + 0x396e, 0x0800, + 0x3974, 0x1e03, + 0x3975, 0x0807, + 0x3979, 0x1e04, + 0x397a, 0x080c, + 0x3a21, 0x0811, + 0x3a53, 0x1e05, + 0x3a54, 0x0844, + 0x3a67, 0x1e06, + 0x3a68, 0x0858, + 0x3a74, 0x1e07, + 0x3a75, 0x0865, + 0x3b21, 0x086f, + 0x3b27, 0x1e08, + 0x3b28, 0x0876, + 0x3b2a, 0x1e09, + 0x3b2b, 0x0879, + 0x3b2c, 0x1e0a, + 0x3b2d, 0x087b, + 0x3b39, 0x1e0b, + 0x3b3a, 0x0888, + 0x3c21, 0x08cd, + 0x3c38, 0x1e0c, + 0x3c39, 0x08e5, + 0x3c48, 0x1e0d, + 0x3c49, 0x1929, + 0x3c4a, 0x08f6, + 0x3c57, 0x1e0e, + 0x3c58, 0x0904, + 0x3c5d, 0x1e0f, + 0x3c5f, 0x090b, + 0x3d21, 0x092b, + 0x3d2b, 0x1e11, + 0x3d2c, 0x0936, + 0x3d36, 0x1e12, + 0x3d37, 0x0941, + 0x3d6c, 0x1e13, + 0x3d6e, 0x0978, + 0x3d72, 0x1e15, + 0x3d74, 0x097e, + 0x3e21, 0x0989, + 0x3e25, 0x1e17, + 0x3e26, 0x098e, + 0x3e33, 0x1e18, + 0x3e34, 0x099c, + 0x3e3f, 0x1e19, + 0x3e40, 0x09a8, + 0x3e55, 0x1e1a, + 0x3e56, 0x09be, + 0x3e5f, 0x1e1b, + 0x3e60, 0x09c8, + 0x3e64, 0x1e1c, + 0x3e65, 0x09cd, + 0x3f21, 0x09e7, + 0x3f2a, 0x1e1d, + 0x3f2b, 0x09f1, + 0x3f59, 0x1e1e, + 0x3f5a, 0x0a20, + 0x3f60, 0x1e1f, + 0x3f61, 0x0a27, + 0x3f69, 0x1e20, + 0x3f6a, 0x0a30, + 0x4021, 0x0a45, + 0x4022, 0x1e21, + 0x4023, 0x0a47, + 0x4042, 0x1e22, + 0x4043, 0x0a67, + 0x4066, 0x1e23, + 0x4067, 0x0a8b, + 0x4071, 0x1e24, + 0x4073, 0x0a97, + 0x4079, 0x1e26, + 0x407b, 0x0a9f, + 0x4121, 0x0aa3, + 0x4127, 0x1e28, + 0x4128, 0x1a6e, + 0x4129, 0x0aab, + 0x4139, 0x1e29, + 0x413a, 0x0abc, + 0x414c, 0x1e2a, + 0x414d, 0x0acf, + 0x414f, 0x1e2b, + 0x4150, 0x0ad2, + 0x415f, 0x1e2c, + 0x4160, 0x0ae2, + 0x4169, 0x1e2d, + 0x416a, 0x0aec, + 0x4221, 0x0b01, + 0x423d, 0x1e2e, + 0x423e, 0x0b1e, + 0x424d, 0x1e2f, + 0x424e, 0x0b2e, + 0x425c, 0x1e30, + 0x425d, 0x0b3d, + 0x4263, 0x1e31, + 0x4264, 0x0b44, + 0x426f, 0x1e32, + 0x4270, 0x0b50, + 0x4275, 0x1e33, + 0x4277, 0x0b57, + 0x427d, 0x1e35, + 0x427e, 0x0b5e, + 0x4321, 0x0b5f, + 0x4327, 0x1e36, + 0x4328, 0x0b66, + 0x4329, 0x1e37, + 0x432b, 0x0b69, + 0x432d, 0x1e39, + 0x432f, 0x0b6d, + 0x433d, 0x1e3b, + 0x433e, 0x0b7c, + 0x4370, 0x1e3c, + 0x4371, 0x0baf, + 0x4375, 0x1e3d, + 0x4376, 0x0bb4, + 0x437c, 0x1e3e, + 0x437d, 0x0bbb, + 0x4421, 0x0bbd, + 0x443d, 0x1e3f, + 0x443e, 0x0bda, + 0x4448, 0x1e40, + 0x4449, 0x0be5, + 0x444a, 0x1e41, + 0x444b, 0x0be7, + 0x444d, 0x1e42, + 0x444e, 0x0bea, + 0x444f, 0x1e43, + 0x4450, 0x0bec, + 0x445b, 0x11b5, + 0x445c, 0x0bf8, + 0x4521, 0x0c1b, + 0x4522, 0x1e44, + 0x4523, 0x0c1d, + 0x4527, 0x1e45, + 0x4528, 0x0c22, + 0x452e, 0x1e46, + 0x452f, 0x0c29, + 0x4536, 0x1e47, + 0x4537, 0x0c31, + 0x453f, 0x1e48, + 0x4540, 0x0c3a, + 0x4548, 0x1e49, + 0x4549, 0x0c43, + 0x454b, 0x1e4a, + 0x454c, 0x0c46, + 0x4551, 0x1e4b, + 0x4553, 0x0c4d, + 0x4557, 0x16df, + 0x4558, 0x0c52, + 0x4564, 0x1e4d, + 0x4565, 0x0c5f, + 0x456e, 0x1450, + 0x456f, 0x0c69, + 0x4573, 0x1536, + 0x4574, 0x0c6e, + 0x4578, 0x1e4e, + 0x4579, 0x0c73, + 0x4621, 0x0c79, + 0x463e, 0x1e4f, + 0x463f, 0x0c97, + 0x4642, 0x1e50, + 0x4643, 0x0c9b, + 0x4654, 0x1e51, + 0x4656, 0x0cae, + 0x465b, 0x1e53, + 0x465d, 0x0cb5, + 0x4661, 0x1e55, + 0x4662, 0x0cba, + 0x4666, 0x1e56, + 0x4668, 0x0cc0, + 0x466a, 0x1e58, + 0x466b, 0x0cc3, + 0x4676, 0x1aed, + 0x4677, 0x0ccf, + 0x4721, 0x0cd7, + 0x4729, 0x1e59, + 0x472a, 0x0ce0, + 0x4739, 0x1e5a, + 0x473a, 0x0cf0, + 0x4757, 0x1e5b, + 0x4758, 0x0d0e, + 0x4767, 0x1e5c, + 0x4768, 0x1989, + 0x4769, 0x1e5d, + 0x476a, 0x0d20, + 0x476d, 0x1e5e, + 0x476e, 0x0d24, + 0x4821, 0x0d35, + 0x4824, 0x1e5f, + 0x4825, 0x0d39, + 0x482e, 0x1e60, + 0x482f, 0x0d43, + 0x4830, 0x1e61, + 0x4831, 0x0d45, + 0x4854, 0x1e62, + 0x4855, 0x0d69, + 0x4862, 0x1e63, + 0x4863, 0x0d77, + 0x4875, 0x1e64, + 0x4876, 0x0d8a, + 0x4921, 0x0d93, + 0x4922, 0x1e65, + 0x4924, 0x0d96, + 0x492f, 0x1e67, + 0x4930, 0x143b, + 0x4931, 0x0da3, + 0x4932, 0x1e68, + 0x4933, 0x0da5, + 0x4935, 0x1e69, + 0x4936, 0x0da8, + 0x4940, 0x1e6a, + 0x4941, 0x0db3, + 0x494e, 0x1e6b, + 0x494f, 0x0dc1, + 0x4951, 0x1e6c, + 0x4952, 0x0dc4, + 0x4a21, 0x0df1, + 0x4a43, 0x1e6d, + 0x4a44, 0x0e14, + 0x4a4d, 0x1e6e, + 0x4a4e, 0x0e1e, + 0x4a5a, 0x1e6f, + 0x4a5b, 0x0e2b, + 0x4a79, 0x1e70, + 0x4a7a, 0x0e4a, + 0x4b21, 0x0e4f, + 0x4b22, 0x1e71, + 0x4b23, 0x0e51, + 0x4b29, 0x1e72, + 0x4b2a, 0x0e58, + 0x4b4b, 0x1e73, + 0x4b4c, 0x0e7a, + 0x4b6a, 0x1d33, + 0x4b6b, 0x0e99, + 0x4b70, 0x1e74, + 0x4b71, 0x0e9f, + 0x4b79, 0x102f, + 0x4b7a, 0x0ea8, + 0x4c21, 0x0ead, + 0x4c4d, 0x1e75, + 0x4c4e, 0x0eda, + 0x4c59, 0x1e76, + 0x4c5a, 0x0ee6, + 0x4c5f, 0x1e77, + 0x4c60, 0x0eec, + 0x4c62, 0x1e78, + 0x4c63, 0x0eef, + 0x4c79, 0x1935, + 0x4c7a, 0x1e79, + 0x4c7b, 0x0f07, + 0x4c7c, 0x1e7a, + 0x4c7d, 0x0f09, + 0x4c7e, 0x1e7b, + 0x4d21, 0x0f0b, + 0x4d32, 0x1e7c, + 0x4d33, 0x0f1d, + 0x4d50, 0x1e7d, + 0x4d51, 0x0f3b, + 0x4d54, 0x1e7e, + 0x4d55, 0x0f3f, + 0x4d5a, 0x1d34, + 0x4d5b, 0x0f45, + 0x4d69, 0x1e7f, + 0x4d6a, 0x0f54, + 0x4e21, 0x0f69, + 0x4e4b, 0x1e80, + 0x4e4c, 0x0f94, + 0x4e7a, 0x1e81, + 0x4e7c, 0x0fc4, + 0x4f21, 0x1e83, + 0x4f22, 0x0fc8, + 0x4f31, 0x1e84, + 0x4f32, 0x0fd8, + 0x4f36, 0x1777, + 0x4f37, 0x0fdd, + 0x4f39, 0x1e85, + 0x4f3a, 0x0fe0, + 0x5021, 0x0ffa, + 0x5056, 0x0ea7, + 0x5057, 0x1030, + 0x5121, 0x1058, + 0x513d, 0x1e86, + 0x513e, 0x1075, + 0x5147, 0x1e87, + 0x5148, 0x107f, + 0x514b, 0x1e88, + 0x514c, 0x1083, + 0x514d, 0x1e89, + 0x514e, 0x1085, + 0x5221, 0x10b6, + 0x5321, 0x1114, + 0x5330, 0x1e8a, + 0x5331, 0x1124, + 0x533a, 0x1e8b, + 0x533b, 0x112e, + 0x5350, 0x1e8c, + 0x5351, 0x1144, + 0x535e, 0x1e8d, + 0x535f, 0x1152, + 0x536b, 0x1e8e, + 0x536c, 0x115f, + 0x5421, 0x1172, + 0x5444, 0x1e8f, + 0x5445, 0x1196, + 0x5464, 0x0bf7, + 0x5465, 0x11b6, + 0x5521, 0x11d0, + 0x553d, 0x1e90, + 0x553e, 0x11ed, + 0x5563, 0x1e91, + 0x5564, 0x1213, + 0x5621, 0x122e, + 0x5622, 0x1e92, + 0x5623, 0x1230, + 0x5672, 0x1e93, + 0x5673, 0x1280, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5824, 0x1e94, + 0x5825, 0x12ee, + 0x5921, 0x1348, + 0x5960, 0x1e95, + 0x5961, 0x1388, + 0x596c, 0x1e96, + 0x596d, 0x1394, + 0x5978, 0x05a7, + 0x5979, 0x13a0, + 0x5a21, 0x13a6, + 0x5a39, 0x1e97, + 0x5a3a, 0x13bf, + 0x5a4d, 0x1e98, + 0x5a4e, 0x13d3, + 0x5b21, 0x1404, + 0x5b45, 0x1e99, + 0x5b46, 0x1429, + 0x5b4a, 0x1e9a, + 0x5b4b, 0x142e, + 0x5b58, 0x0da2, + 0x5b59, 0x143c, + 0x5b6b, 0x1e9b, + 0x5b6c, 0x144f, + 0x5b6d, 0x0c68, + 0x5b6e, 0x1451, + 0x5b74, 0x1e9c, + 0x5b75, 0x1458, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5e21, 0x151e, + 0x5e39, 0x0c6d, + 0x5e3a, 0x1537, + 0x5e50, 0x1e9d, + 0x5e51, 0x154e, + 0x5e75, 0x05ff, + 0x5e76, 0x1573, + 0x5f21, 0x157c, + 0x5f73, 0x1e9e, + 0x5f74, 0x15cf, + 0x6021, 0x15da, + 0x6026, 0x1e9f, + 0x6027, 0x15e0, + 0x605f, 0x1ea0, + 0x6060, 0x1619, + 0x6076, 0x1d35, + 0x6077, 0x1630, + 0x6121, 0x1638, + 0x612b, 0x1ea1, + 0x612c, 0x1643, + 0x6130, 0x1ea2, + 0x6132, 0x1649, + 0x6221, 0x1696, + 0x622b, 0x1ea4, + 0x622c, 0x16a1, + 0x6268, 0x07ee, + 0x6269, 0x16de, + 0x626a, 0x0c51, + 0x626b, 0x16e0, + 0x626f, 0x1ea5, + 0x6270, 0x16e5, + 0x6321, 0x16f4, + 0x634a, 0x1ea6, + 0x634b, 0x171e, + 0x6354, 0x1ea7, + 0x6355, 0x1728, + 0x635e, 0x05d4, + 0x635f, 0x1732, + 0x6421, 0x1752, + 0x6439, 0x1ea8, + 0x643a, 0x176b, + 0x6446, 0x0fdc, + 0x6447, 0x1778, + 0x6464, 0x1ea9, + 0x6465, 0x1796, + 0x646e, 0x1eaa, + 0x646f, 0x17a0, + 0x6521, 0x17b0, + 0x6539, 0x1eab, + 0x653a, 0x17c9, + 0x653b, 0x1eac, + 0x653c, 0x17cb, + 0x6546, 0x1ead, + 0x6547, 0x17d6, + 0x6621, 0x180e, + 0x6646, 0x1eae, + 0x6647, 0x1834, + 0x6721, 0x186c, + 0x6764, 0x1eaf, + 0x6765, 0x18b0, + 0x6769, 0x1eb0, + 0x676a, 0x18b5, + 0x6772, 0x1eb1, + 0x6773, 0x18be, + 0x6821, 0x18ca, + 0x6834, 0x1eb2, + 0x6835, 0x18de, + 0x683b, 0x1eb3, + 0x683c, 0x18e5, + 0x6874, 0x1eb4, + 0x6875, 0x191e, + 0x6921, 0x1928, + 0x6922, 0x08f5, + 0x6923, 0x192a, + 0x692e, 0x0f05, + 0x692f, 0x1936, + 0x693c, 0x1eb5, + 0x693d, 0x1944, + 0x695a, 0x05a0, + 0x695b, 0x1962, + 0x6a21, 0x1986, + 0x6a24, 0x0d1e, + 0x6a25, 0x198a, + 0x6a27, 0x1eb6, + 0x6a28, 0x198d, + 0x6a3d, 0x1eb7, + 0x6a3e, 0x19a3, + 0x6a6f, 0x1eb8, + 0x6a70, 0x19d5, + 0x6b21, 0x19e4, + 0x6b32, 0x1eb9, + 0x6b33, 0x19f6, + 0x6b5d, 0x060e, + 0x6b5e, 0x1a21, + 0x6b66, 0x1eba, + 0x6b67, 0x1a2a, + 0x6b76, 0x1ebb, + 0x6b77, 0x1a3a, + 0x6c21, 0x1a42, + 0x6c4d, 0x0aaa, + 0x6c4e, 0x1a6f, + 0x6c69, 0x1ebc, + 0x6c6a, 0x1a8b, + 0x6c74, 0x1ebd, + 0x6c75, 0x1a96, + 0x6d21, 0x1aa0, + 0x6d4e, 0x1ebe, + 0x6d4f, 0x1ace, + 0x6d6c, 0x1ebf, + 0x6d6d, 0x1aec, + 0x6d6e, 0x1ec0, + 0x6d6f, 0x1aee, + 0x6e21, 0x1afe, + 0x6e29, 0x1ec1, + 0x6e2a, 0x1b07, + 0x6e3d, 0x1ec2, + 0x6e3e, 0x1b1b, + 0x6e57, 0x1ec3, + 0x6e58, 0x1b35, + 0x6f21, 0x1b5c, + 0x6f65, 0x1ec4, + 0x6f66, 0x1ba1, + 0x7021, 0x1bba, + 0x7033, 0x1ec5, + 0x7034, 0x1bcd, + 0x7045, 0x1ec6, + 0x7046, 0x1bdf, + 0x7051, 0x1ec7, + 0x7052, 0x1beb, + 0x7057, 0x1ec8, + 0x7058, 0x1bf1, + 0x7074, 0x0731, + 0x7075, 0x1ec9, + 0x7076, 0x1c0f, + 0x7121, 0x1c18, + 0x7221, 0x1c76, + 0x722d, 0x1eca, + 0x722e, 0x1c83, + 0x723c, 0x1ecb, + 0x723d, 0x1c92, + 0x724d, 0x0477, + 0x724e, 0x1ecc, + 0x724f, 0x1ca4, + 0x7274, 0x0529, + 0x7275, 0x1cca, + 0x7321, 0x1cd4, + 0x7351, 0x1ecd, + 0x7352, 0x1d05, + 0x737d, 0x1ece, + 0x737e, 0x1d31, + 0x7921, 0x20a7, + 0x7a21, 0x2105, + 0x7a36, 0x07c9, + 0x7a37, 0x211a, + 0x7b21, 0x2162, + 0x7c21, 0x21c0, + 0x7c71, 0x1f9c, + 0x7c7b, 0x02ef, + 0x7c7c, 0x1f45, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12ExtHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12ExtHMap2, 663 +}; + +static Gushort japan12ExtRKSJHMap2[1330] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x8189, 0x1d36, + 0x818a, 0x02c2, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x8540, 0x00e8, + 0x8580, 0x0186, + 0x8581, 0x0128, + 0x859f, 0x0147, + 0x85de, 0x0187, + 0x8640, 0x01a6, + 0x8680, 0x01e5, + 0x8692, 0x0127, + 0x8693, 0x01f7, + 0x86a2, 0x1d37, + 0x8740, 0x1d83, + 0x875f, 0x1da1, + 0x877e, 0x2083, + 0x8780, 0x1db8, + 0x8790, 0x02fa, + 0x8791, 0x02f9, + 0x8792, 0x0301, + 0x8793, 0x1dc8, + 0x879a, 0x0300, + 0x879b, 0x1dcf, + 0x889f, 0x0465, + 0x88a0, 0x1dd1, + 0x88a1, 0x0467, + 0x88b1, 0x1ca2, + 0x88b2, 0x0478, + 0x88b9, 0x1dd2, + 0x88ba, 0x0480, + 0x88ec, 0x1dd3, + 0x88ed, 0x04b3, + 0x88f1, 0x1dd4, + 0x88f2, 0x04b8, + 0x88fa, 0x1dd5, + 0x88fb, 0x04c1, + 0x8940, 0x04c3, + 0x8949, 0x1dd6, + 0x894a, 0x04cd, + 0x8954, 0x1dd7, + 0x8955, 0x04d8, + 0x8958, 0x1dd8, + 0x8959, 0x04dc, + 0x895b, 0x1dd9, + 0x895d, 0x04e0, + 0x8961, 0x1ddb, + 0x8962, 0x04e5, + 0x8980, 0x0502, + 0x898b, 0x1ddc, + 0x898c, 0x050e, + 0x89a6, 0x1ddd, + 0x89a7, 0x1cc9, + 0x89a8, 0x1dde, + 0x89a9, 0x052b, + 0x89de, 0x1ddf, + 0x89df, 0x0561, + 0x89f8, 0x1de0, + 0x89f9, 0x057b, + 0x89fb, 0x1de1, + 0x89fc, 0x057e, + 0x8a40, 0x057f, + 0x8a41, 0x1de2, + 0x8a42, 0x0581, + 0x8a61, 0x1961, + 0x8a62, 0x05a1, + 0x8a68, 0x139f, + 0x8a69, 0x05a8, + 0x8a80, 0x05be, + 0x8a85, 0x1de3, + 0x8a86, 0x05c4, + 0x8a8b, 0x1de4, + 0x8a8c, 0x05ca, + 0x8a93, 0x1de5, + 0x8a94, 0x05d2, + 0x8a96, 0x1731, + 0x8a97, 0x05d5, + 0x8a9a, 0x1de6, + 0x8a9b, 0x05d9, + 0x8ac0, 0x1de7, + 0x8ac1, 0x1572, + 0x8ac2, 0x0600, + 0x8acb, 0x1de8, + 0x8acc, 0x060a, + 0x8ad0, 0x1a20, + 0x8ad1, 0x060f, + 0x8ae3, 0x1de9, + 0x8ae4, 0x0622, + 0x8b40, 0x063b, + 0x8b4a, 0x1dea, + 0x8b4b, 0x0646, + 0x8b5f, 0x1deb, + 0x8b60, 0x065b, + 0x8b80, 0x067a, + 0x8ba0, 0x1dec, + 0x8ba1, 0x069b, + 0x8ba8, 0x1ded, + 0x8ba9, 0x06a3, + 0x8bc4, 0x1d32, + 0x8bc5, 0x06bf, + 0x8bcd, 0x1dee, + 0x8bce, 0x06c8, + 0x8beb, 0x1def, + 0x8bec, 0x06e6, + 0x8bf2, 0x1df0, + 0x8bf3, 0x06ed, + 0x8bf9, 0x1df1, + 0x8bfa, 0x06f4, + 0x8bfb, 0x1df2, + 0x8bfc, 0x06f6, + 0x8c40, 0x06f7, + 0x8c43, 0x1df3, + 0x8c44, 0x06fb, + 0x8c56, 0x1df4, + 0x8c57, 0x070e, + 0x8c64, 0x1df5, + 0x8c65, 0x071c, + 0x8c6d, 0x1df6, + 0x8c6e, 0x0725, + 0x8c71, 0x1df7, + 0x8c72, 0x0729, + 0x8c74, 0x1df8, + 0x8c75, 0x072c, + 0x8c7a, 0x1c0d, + 0x8c7b, 0x0732, + 0x8c80, 0x0736, + 0x8c84, 0x1df9, + 0x8c85, 0x073b, + 0x8c91, 0x1dfa, + 0x8c92, 0x0748, + 0x8c99, 0x1dfb, + 0x8c9a, 0x0750, + 0x8c9e, 0x1dfc, + 0x8c9f, 0x0755, + 0x8cb2, 0x1dfd, + 0x8cb3, 0x0769, + 0x8cbf, 0x1dfe, + 0x8cc0, 0x0776, + 0x8d40, 0x07b3, + 0x8d4a, 0x1dff, + 0x8d4b, 0x07be, + 0x8d56, 0x1e00, + 0x8d57, 0x07ca, + 0x8d61, 0x1e01, + 0x8d62, 0x07d5, + 0x8d7b, 0x16dd, + 0x8d7c, 0x07ef, + 0x8d80, 0x07f2, + 0x8d8d, 0x1e02, + 0x8d8e, 0x0800, + 0x8d94, 0x1e03, + 0x8d95, 0x0807, + 0x8d99, 0x1e04, + 0x8d9a, 0x080c, + 0x8dd1, 0x1e05, + 0x8dd2, 0x0844, + 0x8de5, 0x1e06, + 0x8de6, 0x0858, + 0x8df2, 0x1e07, + 0x8df3, 0x0865, + 0x8e40, 0x086f, + 0x8e46, 0x1e08, + 0x8e47, 0x0876, + 0x8e49, 0x1e09, + 0x8e4a, 0x0879, + 0x8e4b, 0x1e0a, + 0x8e4c, 0x087b, + 0x8e58, 0x1e0b, + 0x8e59, 0x0888, + 0x8e80, 0x08ae, + 0x8eb6, 0x1e0c, + 0x8eb7, 0x08e5, + 0x8ec6, 0x1e0d, + 0x8ec7, 0x1929, + 0x8ec8, 0x08f6, + 0x8ed5, 0x1e0e, + 0x8ed6, 0x0904, + 0x8edb, 0x1e0f, + 0x8edd, 0x090b, + 0x8f40, 0x092b, + 0x8f4a, 0x1e11, + 0x8f4b, 0x0936, + 0x8f55, 0x1e12, + 0x8f56, 0x0941, + 0x8f80, 0x096a, + 0x8f8c, 0x1e13, + 0x8f8e, 0x0978, + 0x8f92, 0x1e15, + 0x8f94, 0x097e, + 0x8fa3, 0x1e17, + 0x8fa4, 0x098e, + 0x8fb1, 0x1e18, + 0x8fb2, 0x099c, + 0x8fbd, 0x1e19, + 0x8fbe, 0x09a8, + 0x8fd3, 0x1e1a, + 0x8fd4, 0x09be, + 0x8fdd, 0x1e1b, + 0x8fde, 0x09c8, + 0x8fe2, 0x1e1c, + 0x8fe3, 0x09cd, + 0x9040, 0x09e7, + 0x9049, 0x1e1d, + 0x904a, 0x09f1, + 0x9078, 0x1e1e, + 0x9079, 0x0a20, + 0x9080, 0x1e1f, + 0x9081, 0x0a27, + 0x9089, 0x1e20, + 0x908a, 0x0a30, + 0x90a0, 0x1e21, + 0x90a1, 0x0a47, + 0x90c0, 0x1e22, + 0x90c1, 0x0a67, + 0x90e4, 0x1e23, + 0x90e5, 0x0a8b, + 0x90ef, 0x1e24, + 0x90f1, 0x0a97, + 0x90f7, 0x1e26, + 0x90f9, 0x0a9f, + 0x9140, 0x0aa3, + 0x9146, 0x1e28, + 0x9147, 0x1a6e, + 0x9148, 0x0aab, + 0x9158, 0x1e29, + 0x9159, 0x0abc, + 0x916b, 0x1e2a, + 0x916c, 0x0acf, + 0x916e, 0x1e2b, + 0x916f, 0x0ad2, + 0x917e, 0x1e2c, + 0x9180, 0x0ae2, + 0x9189, 0x1e2d, + 0x918a, 0x0aec, + 0x91bb, 0x1e2e, + 0x91bc, 0x0b1e, + 0x91cb, 0x1e2f, + 0x91cc, 0x0b2e, + 0x91da, 0x1e30, + 0x91db, 0x0b3d, + 0x91e1, 0x1e31, + 0x91e2, 0x0b44, + 0x91ed, 0x1e32, + 0x91ee, 0x0b50, + 0x91f3, 0x1e33, + 0x91f5, 0x0b57, + 0x91fb, 0x1e35, + 0x91fc, 0x0b5e, + 0x9240, 0x0b5f, + 0x9246, 0x1e36, + 0x9247, 0x0b66, + 0x9248, 0x1e37, + 0x924a, 0x0b69, + 0x924c, 0x1e39, + 0x924e, 0x0b6d, + 0x925c, 0x1e3b, + 0x925d, 0x0b7c, + 0x9280, 0x0b9e, + 0x9290, 0x1e3c, + 0x9291, 0x0baf, + 0x9295, 0x1e3d, + 0x9296, 0x0bb4, + 0x929c, 0x1e3e, + 0x929d, 0x0bbb, + 0x92bb, 0x1e3f, + 0x92bc, 0x0bda, + 0x92c6, 0x1e40, + 0x92c7, 0x0be5, + 0x92c8, 0x1e41, + 0x92c9, 0x0be7, + 0x92cb, 0x1e42, + 0x92cc, 0x0bea, + 0x92cd, 0x1e43, + 0x92ce, 0x0bec, + 0x92d9, 0x11b5, + 0x92da, 0x0bf8, + 0x9340, 0x0c1b, + 0x9341, 0x1e44, + 0x9342, 0x0c1d, + 0x9346, 0x1e45, + 0x9347, 0x0c22, + 0x934d, 0x1e46, + 0x934e, 0x0c29, + 0x9355, 0x1e47, + 0x9356, 0x0c31, + 0x935e, 0x1e48, + 0x935f, 0x0c3a, + 0x9367, 0x1e49, + 0x9368, 0x0c43, + 0x936a, 0x1e4a, + 0x936b, 0x0c46, + 0x9370, 0x1e4b, + 0x9372, 0x0c4d, + 0x9376, 0x16df, + 0x9377, 0x0c52, + 0x9380, 0x0c5a, + 0x9384, 0x1e4d, + 0x9385, 0x0c5f, + 0x938e, 0x1450, + 0x938f, 0x0c69, + 0x9393, 0x1536, + 0x9394, 0x0c6e, + 0x9398, 0x1e4e, + 0x9399, 0x0c73, + 0x93bc, 0x1e4f, + 0x93bd, 0x0c97, + 0x93c0, 0x1e50, + 0x93c1, 0x0c9b, + 0x93d2, 0x1e51, + 0x93d4, 0x0cae, + 0x93d9, 0x1e53, + 0x93db, 0x0cb5, + 0x93df, 0x1e55, + 0x93e0, 0x0cba, + 0x93e4, 0x1e56, + 0x93e6, 0x0cc0, + 0x93e8, 0x1e58, + 0x93e9, 0x0cc3, + 0x93f4, 0x1aed, + 0x93f5, 0x0ccf, + 0x9440, 0x0cd7, + 0x9448, 0x1e59, + 0x9449, 0x0ce0, + 0x9458, 0x1e5a, + 0x9459, 0x0cf0, + 0x9476, 0x1e5b, + 0x9477, 0x0d0e, + 0x9480, 0x0d16, + 0x9487, 0x1e5c, + 0x9488, 0x1989, + 0x9489, 0x1e5d, + 0x948a, 0x0d20, + 0x948d, 0x1e5e, + 0x948e, 0x0d24, + 0x94a2, 0x1e5f, + 0x94a3, 0x0d39, + 0x94ac, 0x1e60, + 0x94ad, 0x0d43, + 0x94ae, 0x1e61, + 0x94af, 0x0d45, + 0x94d2, 0x1e62, + 0x94d3, 0x0d69, + 0x94e0, 0x1e63, + 0x94e1, 0x0d77, + 0x94f3, 0x1e64, + 0x94f4, 0x0d8a, + 0x9540, 0x0d93, + 0x9541, 0x1e65, + 0x9543, 0x0d96, + 0x954e, 0x1e67, + 0x954f, 0x143b, + 0x9550, 0x0da3, + 0x9551, 0x1e68, + 0x9552, 0x0da5, + 0x9554, 0x1e69, + 0x9555, 0x0da8, + 0x955f, 0x1e6a, + 0x9560, 0x0db3, + 0x956d, 0x1e6b, + 0x956e, 0x0dc1, + 0x9570, 0x1e6c, + 0x9571, 0x0dc4, + 0x9580, 0x0dd2, + 0x95c1, 0x1e6d, + 0x95c2, 0x0e14, + 0x95cb, 0x1e6e, + 0x95cc, 0x0e1e, + 0x95d8, 0x1e6f, + 0x95d9, 0x0e2b, + 0x95f7, 0x1e70, + 0x95f8, 0x0e4a, + 0x9640, 0x0e4f, + 0x9641, 0x1e71, + 0x9642, 0x0e51, + 0x9648, 0x1e72, + 0x9649, 0x0e58, + 0x966a, 0x1e73, + 0x966b, 0x0e7a, + 0x9680, 0x0e8e, + 0x968a, 0x1d33, + 0x968b, 0x0e99, + 0x9690, 0x1e74, + 0x9691, 0x0e9f, + 0x9699, 0x102f, + 0x969a, 0x0ea8, + 0x96cb, 0x1e75, + 0x96cc, 0x0eda, + 0x96d7, 0x1e76, + 0x96d8, 0x0ee6, + 0x96dd, 0x1e77, + 0x96de, 0x0eec, + 0x96e0, 0x1e78, + 0x96e1, 0x0eef, + 0x96f7, 0x1935, + 0x96f8, 0x1e79, + 0x96f9, 0x0f07, + 0x96fa, 0x1e7a, + 0x96fb, 0x0f09, + 0x96fc, 0x1e7b, + 0x9740, 0x0f0b, + 0x9751, 0x1e7c, + 0x9752, 0x0f1d, + 0x976f, 0x1e7d, + 0x9770, 0x0f3b, + 0x9773, 0x1e7e, + 0x9774, 0x0f3f, + 0x9779, 0x1d34, + 0x977a, 0x0f45, + 0x9780, 0x0f4a, + 0x9789, 0x1e7f, + 0x978a, 0x0f54, + 0x97c9, 0x1e80, + 0x97ca, 0x0f94, + 0x97f8, 0x1e81, + 0x97fa, 0x0fc4, + 0x9840, 0x1e83, + 0x9841, 0x0fc8, + 0x9850, 0x1e84, + 0x9851, 0x0fd8, + 0x9855, 0x1777, + 0x9856, 0x0fdd, + 0x9858, 0x1e85, + 0x9859, 0x0fe0, + 0x989f, 0x0ffa, + 0x98d4, 0x0ea7, + 0x98d5, 0x1030, + 0x9940, 0x1058, + 0x995c, 0x1e86, + 0x995d, 0x1075, + 0x9966, 0x1e87, + 0x9967, 0x107f, + 0x996a, 0x1e88, + 0x996b, 0x1083, + 0x996c, 0x1e89, + 0x996d, 0x1085, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a4f, 0x1e8a, + 0x9a50, 0x1124, + 0x9a59, 0x1e8b, + 0x9a5a, 0x112e, + 0x9a6f, 0x1e8c, + 0x9a70, 0x1144, + 0x9a7d, 0x1e8d, + 0x9a7e, 0x1152, + 0x9a80, 0x1153, + 0x9a8b, 0x1e8e, + 0x9a8c, 0x115f, + 0x9ac2, 0x1e8f, + 0x9ac3, 0x1196, + 0x9ae2, 0x0bf7, + 0x9ae3, 0x11b6, + 0x9b40, 0x11d0, + 0x9b5c, 0x1e90, + 0x9b5d, 0x11ed, + 0x9b80, 0x120f, + 0x9b83, 0x1e91, + 0x9b84, 0x1213, + 0x9ba0, 0x1e92, + 0x9ba1, 0x1230, + 0x9bf0, 0x1e93, + 0x9bf1, 0x1280, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9ca2, 0x1e94, + 0x9ca3, 0x12ee, + 0x9d40, 0x1348, + 0x9d80, 0x1e95, + 0x9d81, 0x1388, + 0x9d8c, 0x1e96, + 0x9d8d, 0x1394, + 0x9d98, 0x05a7, + 0x9d99, 0x13a0, + 0x9db7, 0x1e97, + 0x9db8, 0x13bf, + 0x9dcb, 0x1e98, + 0x9dcc, 0x13d3, + 0x9e40, 0x1404, + 0x9e64, 0x1e99, + 0x9e65, 0x1429, + 0x9e69, 0x1e9a, + 0x9e6a, 0x142e, + 0x9e77, 0x0da2, + 0x9e78, 0x143c, + 0x9e80, 0x1443, + 0x9e8b, 0x1e9b, + 0x9e8c, 0x144f, + 0x9e8d, 0x0c68, + 0x9e8e, 0x1451, + 0x9e94, 0x1e9c, + 0x9e95, 0x1458, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0x9fb7, 0x0c6d, + 0x9fb8, 0x1537, + 0x9fce, 0x1e9d, + 0x9fcf, 0x154e, + 0x9ff3, 0x05ff, + 0x9ff4, 0x1573, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe093, 0x1e9e, + 0xe094, 0x15cf, + 0xe0a4, 0x1e9f, + 0xe0a5, 0x15e0, + 0xe0dd, 0x1ea0, + 0xe0de, 0x1619, + 0xe0f4, 0x1d35, + 0xe0f5, 0x1630, + 0xe140, 0x1638, + 0xe14a, 0x1ea1, + 0xe14b, 0x1643, + 0xe14f, 0x1ea2, + 0xe151, 0x1649, + 0xe180, 0x1677, + 0xe1a9, 0x1ea4, + 0xe1aa, 0x16a1, + 0xe1e6, 0x07ee, + 0xe1e7, 0x16de, + 0xe1e8, 0x0c51, + 0xe1e9, 0x16e0, + 0xe1ed, 0x1ea5, + 0xe1ee, 0x16e5, + 0xe240, 0x16f4, + 0xe269, 0x1ea6, + 0xe26a, 0x171e, + 0xe273, 0x1ea7, + 0xe274, 0x1728, + 0xe27d, 0x05d4, + 0xe27e, 0x1732, + 0xe280, 0x1733, + 0xe2b7, 0x1ea8, + 0xe2b8, 0x176b, + 0xe2c4, 0x0fdc, + 0xe2c5, 0x1778, + 0xe2e2, 0x1ea9, + 0xe2e3, 0x1796, + 0xe2ec, 0x1eaa, + 0xe2ed, 0x17a0, + 0xe340, 0x17b0, + 0xe358, 0x1eab, + 0xe359, 0x17c9, + 0xe35a, 0x1eac, + 0xe35b, 0x17cb, + 0xe365, 0x1ead, + 0xe366, 0x17d6, + 0xe380, 0x17ef, + 0xe3c4, 0x1eae, + 0xe3c5, 0x1834, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe484, 0x1eaf, + 0xe485, 0x18b0, + 0xe489, 0x1eb0, + 0xe48a, 0x18b5, + 0xe492, 0x1eb1, + 0xe493, 0x18be, + 0xe4b2, 0x1eb2, + 0xe4b3, 0x18de, + 0xe4b9, 0x1eb3, + 0xe4ba, 0x18e5, + 0xe4f2, 0x1eb4, + 0xe4f3, 0x191e, + 0xe540, 0x1928, + 0xe541, 0x08f5, + 0xe542, 0x192a, + 0xe54d, 0x0f05, + 0xe54e, 0x1936, + 0xe55b, 0x1eb5, + 0xe55c, 0x1944, + 0xe579, 0x05a0, + 0xe57a, 0x1962, + 0xe580, 0x1967, + 0xe5a2, 0x0d1e, + 0xe5a3, 0x198a, + 0xe5a5, 0x1eb6, + 0xe5a6, 0x198d, + 0xe5bb, 0x1eb7, + 0xe5bc, 0x19a3, + 0xe5ed, 0x1eb8, + 0xe5ee, 0x19d5, + 0xe640, 0x19e4, + 0xe651, 0x1eb9, + 0xe652, 0x19f6, + 0xe67c, 0x060e, + 0xe67d, 0x1a21, + 0xe680, 0x1a23, + 0xe686, 0x1eba, + 0xe687, 0x1a2a, + 0xe696, 0x1ebb, + 0xe697, 0x1a3a, + 0xe6cb, 0x0aaa, + 0xe6cc, 0x1a6f, + 0xe6e7, 0x1ebc, + 0xe6e8, 0x1a8b, + 0xe6f2, 0x1ebd, + 0xe6f3, 0x1a96, + 0xe740, 0x1aa0, + 0xe76d, 0x1ebe, + 0xe76e, 0x1ace, + 0xe780, 0x1adf, + 0xe78c, 0x1ebf, + 0xe78d, 0x1aec, + 0xe78e, 0x1ec0, + 0xe78f, 0x1aee, + 0xe7a7, 0x1ec1, + 0xe7a8, 0x1b07, + 0xe7bb, 0x1ec2, + 0xe7bc, 0x1b1b, + 0xe7d5, 0x1ec3, + 0xe7d6, 0x1b35, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe885, 0x1ec4, + 0xe886, 0x1ba1, + 0xe8b1, 0x1ec5, + 0xe8b2, 0x1bcd, + 0xe8c3, 0x1ec6, + 0xe8c4, 0x1bdf, + 0xe8cf, 0x1ec7, + 0xe8d0, 0x1beb, + 0xe8d5, 0x1ec8, + 0xe8d6, 0x1bf1, + 0xe8f2, 0x0731, + 0xe8f3, 0x1ec9, + 0xe8f4, 0x1c0f, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xe9ab, 0x1eca, + 0xe9ac, 0x1c83, + 0xe9ba, 0x1ecb, + 0xe9bb, 0x1c92, + 0xe9cb, 0x0477, + 0xe9cc, 0x1ecc, + 0xe9cd, 0x1ca4, + 0xe9f2, 0x0529, + 0xe9f3, 0x1cca, + 0xea40, 0x1cd4, + 0xea70, 0x1ecd, + 0xea71, 0x1d05, + 0xea80, 0x1d13, + 0xea9d, 0x1ece, + 0xea9e, 0x1d31, + 0xed40, 0x20a7, + 0xed80, 0x20e6, + 0xedb4, 0x07c9, + 0xedb5, 0x211a, + 0xee40, 0x2162, + 0xee80, 0x21a1, + 0xeeef, 0x1f9c, + 0xeef9, 0x02ef, + 0xeefa, 0x1f45, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12ExtRKSJHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12ExtRKSJHMap2, 665 +}; + +static Gushort japan12ExtRKSJVMap2[1408] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x8189, 0x1d36, + 0x818a, 0x02c2, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x8540, 0x00e8, + 0x8580, 0x0186, + 0x8581, 0x0128, + 0x859f, 0x0147, + 0x85de, 0x0187, + 0x8640, 0x01a6, + 0x8680, 0x01e5, + 0x8692, 0x0127, + 0x8693, 0x01f7, + 0x86a2, 0x1d37, + 0x8740, 0x1d83, + 0x875f, 0x1da1, + 0x877e, 0x2083, + 0x8780, 0x1db8, + 0x8790, 0x02fa, + 0x8791, 0x02f9, + 0x8792, 0x0301, + 0x8793, 0x1dc8, + 0x879a, 0x0300, + 0x879b, 0x1dcf, + 0x889f, 0x0465, + 0x88a0, 0x1dd1, + 0x88a1, 0x0467, + 0x88b1, 0x1ca2, + 0x88b2, 0x0478, + 0x88b9, 0x1dd2, + 0x88ba, 0x0480, + 0x88ec, 0x1dd3, + 0x88ed, 0x04b3, + 0x88f1, 0x1dd4, + 0x88f2, 0x04b8, + 0x88fa, 0x1dd5, + 0x88fb, 0x04c1, + 0x8940, 0x04c3, + 0x8949, 0x1dd6, + 0x894a, 0x04cd, + 0x8954, 0x1dd7, + 0x8955, 0x04d8, + 0x8958, 0x1dd8, + 0x8959, 0x04dc, + 0x895b, 0x1dd9, + 0x895d, 0x04e0, + 0x8961, 0x1ddb, + 0x8962, 0x04e5, + 0x8980, 0x0502, + 0x898b, 0x1ddc, + 0x898c, 0x050e, + 0x89a6, 0x1ddd, + 0x89a7, 0x1cc9, + 0x89a8, 0x1dde, + 0x89a9, 0x052b, + 0x89de, 0x1ddf, + 0x89df, 0x0561, + 0x89f8, 0x1de0, + 0x89f9, 0x057b, + 0x89fb, 0x1de1, + 0x89fc, 0x057e, + 0x8a40, 0x057f, + 0x8a41, 0x1de2, + 0x8a42, 0x0581, + 0x8a61, 0x1961, + 0x8a62, 0x05a1, + 0x8a68, 0x139f, + 0x8a69, 0x05a8, + 0x8a80, 0x05be, + 0x8a85, 0x1de3, + 0x8a86, 0x05c4, + 0x8a8b, 0x1de4, + 0x8a8c, 0x05ca, + 0x8a93, 0x1de5, + 0x8a94, 0x05d2, + 0x8a96, 0x1731, + 0x8a97, 0x05d5, + 0x8a9a, 0x1de6, + 0x8a9b, 0x05d9, + 0x8ac0, 0x1de7, + 0x8ac1, 0x1572, + 0x8ac2, 0x0600, + 0x8acb, 0x1de8, + 0x8acc, 0x060a, + 0x8ad0, 0x1a20, + 0x8ad1, 0x060f, + 0x8ae3, 0x1de9, + 0x8ae4, 0x0622, + 0x8b40, 0x063b, + 0x8b4a, 0x1dea, + 0x8b4b, 0x0646, + 0x8b5f, 0x1deb, + 0x8b60, 0x065b, + 0x8b80, 0x067a, + 0x8ba0, 0x1dec, + 0x8ba1, 0x069b, + 0x8ba8, 0x1ded, + 0x8ba9, 0x06a3, + 0x8bc4, 0x1d32, + 0x8bc5, 0x06bf, + 0x8bcd, 0x1dee, + 0x8bce, 0x06c8, + 0x8beb, 0x1def, + 0x8bec, 0x06e6, + 0x8bf2, 0x1df0, + 0x8bf3, 0x06ed, + 0x8bf9, 0x1df1, + 0x8bfa, 0x06f4, + 0x8bfb, 0x1df2, + 0x8bfc, 0x06f6, + 0x8c40, 0x06f7, + 0x8c43, 0x1df3, + 0x8c44, 0x06fb, + 0x8c56, 0x1df4, + 0x8c57, 0x070e, + 0x8c64, 0x1df5, + 0x8c65, 0x071c, + 0x8c6d, 0x1df6, + 0x8c6e, 0x0725, + 0x8c71, 0x1df7, + 0x8c72, 0x0729, + 0x8c74, 0x1df8, + 0x8c75, 0x072c, + 0x8c7a, 0x1c0d, + 0x8c7b, 0x0732, + 0x8c80, 0x0736, + 0x8c84, 0x1df9, + 0x8c85, 0x073b, + 0x8c91, 0x1dfa, + 0x8c92, 0x0748, + 0x8c99, 0x1dfb, + 0x8c9a, 0x0750, + 0x8c9e, 0x1dfc, + 0x8c9f, 0x0755, + 0x8cb2, 0x1dfd, + 0x8cb3, 0x0769, + 0x8cbf, 0x1dfe, + 0x8cc0, 0x0776, + 0x8d40, 0x07b3, + 0x8d4a, 0x1dff, + 0x8d4b, 0x07be, + 0x8d56, 0x1e00, + 0x8d57, 0x07ca, + 0x8d61, 0x1e01, + 0x8d62, 0x07d5, + 0x8d7b, 0x16dd, + 0x8d7c, 0x07ef, + 0x8d80, 0x07f2, + 0x8d8d, 0x1e02, + 0x8d8e, 0x0800, + 0x8d94, 0x1e03, + 0x8d95, 0x0807, + 0x8d99, 0x1e04, + 0x8d9a, 0x080c, + 0x8dd1, 0x1e05, + 0x8dd2, 0x0844, + 0x8de5, 0x1e06, + 0x8de6, 0x0858, + 0x8df2, 0x1e07, + 0x8df3, 0x0865, + 0x8e40, 0x086f, + 0x8e46, 0x1e08, + 0x8e47, 0x0876, + 0x8e49, 0x1e09, + 0x8e4a, 0x0879, + 0x8e4b, 0x1e0a, + 0x8e4c, 0x087b, + 0x8e58, 0x1e0b, + 0x8e59, 0x0888, + 0x8e80, 0x08ae, + 0x8eb6, 0x1e0c, + 0x8eb7, 0x08e5, + 0x8ec6, 0x1e0d, + 0x8ec7, 0x1929, + 0x8ec8, 0x08f6, + 0x8ed5, 0x1e0e, + 0x8ed6, 0x0904, + 0x8edb, 0x1e0f, + 0x8edd, 0x090b, + 0x8f40, 0x092b, + 0x8f4a, 0x1e11, + 0x8f4b, 0x0936, + 0x8f55, 0x1e12, + 0x8f56, 0x0941, + 0x8f80, 0x096a, + 0x8f8c, 0x1e13, + 0x8f8e, 0x0978, + 0x8f92, 0x1e15, + 0x8f94, 0x097e, + 0x8fa3, 0x1e17, + 0x8fa4, 0x098e, + 0x8fb1, 0x1e18, + 0x8fb2, 0x099c, + 0x8fbd, 0x1e19, + 0x8fbe, 0x09a8, + 0x8fd3, 0x1e1a, + 0x8fd4, 0x09be, + 0x8fdd, 0x1e1b, + 0x8fde, 0x09c8, + 0x8fe2, 0x1e1c, + 0x8fe3, 0x09cd, + 0x9040, 0x09e7, + 0x9049, 0x1e1d, + 0x904a, 0x09f1, + 0x9078, 0x1e1e, + 0x9079, 0x0a20, + 0x9080, 0x1e1f, + 0x9081, 0x0a27, + 0x9089, 0x1e20, + 0x908a, 0x0a30, + 0x90a0, 0x1e21, + 0x90a1, 0x0a47, + 0x90c0, 0x1e22, + 0x90c1, 0x0a67, + 0x90e4, 0x1e23, + 0x90e5, 0x0a8b, + 0x90ef, 0x1e24, + 0x90f1, 0x0a97, + 0x90f7, 0x1e26, + 0x90f9, 0x0a9f, + 0x9140, 0x0aa3, + 0x9146, 0x1e28, + 0x9147, 0x1a6e, + 0x9148, 0x0aab, + 0x9158, 0x1e29, + 0x9159, 0x0abc, + 0x916b, 0x1e2a, + 0x916c, 0x0acf, + 0x916e, 0x1e2b, + 0x916f, 0x0ad2, + 0x917e, 0x1e2c, + 0x9180, 0x0ae2, + 0x9189, 0x1e2d, + 0x918a, 0x0aec, + 0x91bb, 0x1e2e, + 0x91bc, 0x0b1e, + 0x91cb, 0x1e2f, + 0x91cc, 0x0b2e, + 0x91da, 0x1e30, + 0x91db, 0x0b3d, + 0x91e1, 0x1e31, + 0x91e2, 0x0b44, + 0x91ed, 0x1e32, + 0x91ee, 0x0b50, + 0x91f3, 0x1e33, + 0x91f5, 0x0b57, + 0x91fb, 0x1e35, + 0x91fc, 0x0b5e, + 0x9240, 0x0b5f, + 0x9246, 0x1e36, + 0x9247, 0x0b66, + 0x9248, 0x1e37, + 0x924a, 0x0b69, + 0x924c, 0x1e39, + 0x924e, 0x0b6d, + 0x925c, 0x1e3b, + 0x925d, 0x0b7c, + 0x9280, 0x0b9e, + 0x9290, 0x1e3c, + 0x9291, 0x0baf, + 0x9295, 0x1e3d, + 0x9296, 0x0bb4, + 0x929c, 0x1e3e, + 0x929d, 0x0bbb, + 0x92bb, 0x1e3f, + 0x92bc, 0x0bda, + 0x92c6, 0x1e40, + 0x92c7, 0x0be5, + 0x92c8, 0x1e41, + 0x92c9, 0x0be7, + 0x92cb, 0x1e42, + 0x92cc, 0x0bea, + 0x92cd, 0x1e43, + 0x92ce, 0x0bec, + 0x92d9, 0x11b5, + 0x92da, 0x0bf8, + 0x9340, 0x0c1b, + 0x9341, 0x1e44, + 0x9342, 0x0c1d, + 0x9346, 0x1e45, + 0x9347, 0x0c22, + 0x934d, 0x1e46, + 0x934e, 0x0c29, + 0x9355, 0x1e47, + 0x9356, 0x0c31, + 0x935e, 0x1e48, + 0x935f, 0x0c3a, + 0x9367, 0x1e49, + 0x9368, 0x0c43, + 0x936a, 0x1e4a, + 0x936b, 0x0c46, + 0x9370, 0x1e4b, + 0x9372, 0x0c4d, + 0x9376, 0x16df, + 0x9377, 0x0c52, + 0x9380, 0x0c5a, + 0x9384, 0x1e4d, + 0x9385, 0x0c5f, + 0x938e, 0x1450, + 0x938f, 0x0c69, + 0x9393, 0x1536, + 0x9394, 0x0c6e, + 0x9398, 0x1e4e, + 0x9399, 0x0c73, + 0x93bc, 0x1e4f, + 0x93bd, 0x0c97, + 0x93c0, 0x1e50, + 0x93c1, 0x0c9b, + 0x93d2, 0x1e51, + 0x93d4, 0x0cae, + 0x93d9, 0x1e53, + 0x93db, 0x0cb5, + 0x93df, 0x1e55, + 0x93e0, 0x0cba, + 0x93e4, 0x1e56, + 0x93e6, 0x0cc0, + 0x93e8, 0x1e58, + 0x93e9, 0x0cc3, + 0x93f4, 0x1aed, + 0x93f5, 0x0ccf, + 0x9440, 0x0cd7, + 0x9448, 0x1e59, + 0x9449, 0x0ce0, + 0x9458, 0x1e5a, + 0x9459, 0x0cf0, + 0x9476, 0x1e5b, + 0x9477, 0x0d0e, + 0x9480, 0x0d16, + 0x9487, 0x1e5c, + 0x9488, 0x1989, + 0x9489, 0x1e5d, + 0x948a, 0x0d20, + 0x948d, 0x1e5e, + 0x948e, 0x0d24, + 0x94a2, 0x1e5f, + 0x94a3, 0x0d39, + 0x94ac, 0x1e60, + 0x94ad, 0x0d43, + 0x94ae, 0x1e61, + 0x94af, 0x0d45, + 0x94d2, 0x1e62, + 0x94d3, 0x0d69, + 0x94e0, 0x1e63, + 0x94e1, 0x0d77, + 0x94f3, 0x1e64, + 0x94f4, 0x0d8a, + 0x9540, 0x0d93, + 0x9541, 0x1e65, + 0x9543, 0x0d96, + 0x954e, 0x1e67, + 0x954f, 0x143b, + 0x9550, 0x0da3, + 0x9551, 0x1e68, + 0x9552, 0x0da5, + 0x9554, 0x1e69, + 0x9555, 0x0da8, + 0x955f, 0x1e6a, + 0x9560, 0x0db3, + 0x956d, 0x1e6b, + 0x956e, 0x0dc1, + 0x9570, 0x1e6c, + 0x9571, 0x0dc4, + 0x9580, 0x0dd2, + 0x95c1, 0x1e6d, + 0x95c2, 0x0e14, + 0x95cb, 0x1e6e, + 0x95cc, 0x0e1e, + 0x95d8, 0x1e6f, + 0x95d9, 0x0e2b, + 0x95f7, 0x1e70, + 0x95f8, 0x0e4a, + 0x9640, 0x0e4f, + 0x9641, 0x1e71, + 0x9642, 0x0e51, + 0x9648, 0x1e72, + 0x9649, 0x0e58, + 0x966a, 0x1e73, + 0x966b, 0x0e7a, + 0x9680, 0x0e8e, + 0x968a, 0x1d33, + 0x968b, 0x0e99, + 0x9690, 0x1e74, + 0x9691, 0x0e9f, + 0x9699, 0x102f, + 0x969a, 0x0ea8, + 0x96cb, 0x1e75, + 0x96cc, 0x0eda, + 0x96d7, 0x1e76, + 0x96d8, 0x0ee6, + 0x96dd, 0x1e77, + 0x96de, 0x0eec, + 0x96e0, 0x1e78, + 0x96e1, 0x0eef, + 0x96f7, 0x1935, + 0x96f8, 0x1e79, + 0x96f9, 0x0f07, + 0x96fa, 0x1e7a, + 0x96fb, 0x0f09, + 0x96fc, 0x1e7b, + 0x9740, 0x0f0b, + 0x9751, 0x1e7c, + 0x9752, 0x0f1d, + 0x976f, 0x1e7d, + 0x9770, 0x0f3b, + 0x9773, 0x1e7e, + 0x9774, 0x0f3f, + 0x9779, 0x1d34, + 0x977a, 0x0f45, + 0x9780, 0x0f4a, + 0x9789, 0x1e7f, + 0x978a, 0x0f54, + 0x97c9, 0x1e80, + 0x97ca, 0x0f94, + 0x97f8, 0x1e81, + 0x97fa, 0x0fc4, + 0x9840, 0x1e83, + 0x9841, 0x0fc8, + 0x9850, 0x1e84, + 0x9851, 0x0fd8, + 0x9855, 0x1777, + 0x9856, 0x0fdd, + 0x9858, 0x1e85, + 0x9859, 0x0fe0, + 0x989f, 0x0ffa, + 0x98d4, 0x0ea7, + 0x98d5, 0x1030, + 0x9940, 0x1058, + 0x995c, 0x1e86, + 0x995d, 0x1075, + 0x9966, 0x1e87, + 0x9967, 0x107f, + 0x996a, 0x1e88, + 0x996b, 0x1083, + 0x996c, 0x1e89, + 0x996d, 0x1085, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a4f, 0x1e8a, + 0x9a50, 0x1124, + 0x9a59, 0x1e8b, + 0x9a5a, 0x112e, + 0x9a6f, 0x1e8c, + 0x9a70, 0x1144, + 0x9a7d, 0x1e8d, + 0x9a7e, 0x1152, + 0x9a80, 0x1153, + 0x9a8b, 0x1e8e, + 0x9a8c, 0x115f, + 0x9ac2, 0x1e8f, + 0x9ac3, 0x1196, + 0x9ae2, 0x0bf7, + 0x9ae3, 0x11b6, + 0x9b40, 0x11d0, + 0x9b5c, 0x1e90, + 0x9b5d, 0x11ed, + 0x9b80, 0x120f, + 0x9b83, 0x1e91, + 0x9b84, 0x1213, + 0x9ba0, 0x1e92, + 0x9ba1, 0x1230, + 0x9bf0, 0x1e93, + 0x9bf1, 0x1280, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9ca2, 0x1e94, + 0x9ca3, 0x12ee, + 0x9d40, 0x1348, + 0x9d80, 0x1e95, + 0x9d81, 0x1388, + 0x9d8c, 0x1e96, + 0x9d8d, 0x1394, + 0x9d98, 0x05a7, + 0x9d99, 0x13a0, + 0x9db7, 0x1e97, + 0x9db8, 0x13bf, + 0x9dcb, 0x1e98, + 0x9dcc, 0x13d3, + 0x9e40, 0x1404, + 0x9e64, 0x1e99, + 0x9e65, 0x1429, + 0x9e69, 0x1e9a, + 0x9e6a, 0x142e, + 0x9e77, 0x0da2, + 0x9e78, 0x143c, + 0x9e80, 0x1443, + 0x9e8b, 0x1e9b, + 0x9e8c, 0x144f, + 0x9e8d, 0x0c68, + 0x9e8e, 0x1451, + 0x9e94, 0x1e9c, + 0x9e95, 0x1458, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0x9fb7, 0x0c6d, + 0x9fb8, 0x1537, + 0x9fce, 0x1e9d, + 0x9fcf, 0x154e, + 0x9ff3, 0x05ff, + 0x9ff4, 0x1573, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe093, 0x1e9e, + 0xe094, 0x15cf, + 0xe0a4, 0x1e9f, + 0xe0a5, 0x15e0, + 0xe0dd, 0x1ea0, + 0xe0de, 0x1619, + 0xe0f4, 0x1d35, + 0xe0f5, 0x1630, + 0xe140, 0x1638, + 0xe14a, 0x1ea1, + 0xe14b, 0x1643, + 0xe14f, 0x1ea2, + 0xe151, 0x1649, + 0xe180, 0x1677, + 0xe1a9, 0x1ea4, + 0xe1aa, 0x16a1, + 0xe1e6, 0x07ee, + 0xe1e7, 0x16de, + 0xe1e8, 0x0c51, + 0xe1e9, 0x16e0, + 0xe1ed, 0x1ea5, + 0xe1ee, 0x16e5, + 0xe240, 0x16f4, + 0xe269, 0x1ea6, + 0xe26a, 0x171e, + 0xe273, 0x1ea7, + 0xe274, 0x1728, + 0xe27d, 0x05d4, + 0xe27e, 0x1732, + 0xe280, 0x1733, + 0xe2b7, 0x1ea8, + 0xe2b8, 0x176b, + 0xe2c4, 0x0fdc, + 0xe2c5, 0x1778, + 0xe2e2, 0x1ea9, + 0xe2e3, 0x1796, + 0xe2ec, 0x1eaa, + 0xe2ed, 0x17a0, + 0xe340, 0x17b0, + 0xe358, 0x1eab, + 0xe359, 0x17c9, + 0xe35a, 0x1eac, + 0xe35b, 0x17cb, + 0xe365, 0x1ead, + 0xe366, 0x17d6, + 0xe380, 0x17ef, + 0xe3c4, 0x1eae, + 0xe3c5, 0x1834, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe484, 0x1eaf, + 0xe485, 0x18b0, + 0xe489, 0x1eb0, + 0xe48a, 0x18b5, + 0xe492, 0x1eb1, + 0xe493, 0x18be, + 0xe4b2, 0x1eb2, + 0xe4b3, 0x18de, + 0xe4b9, 0x1eb3, + 0xe4ba, 0x18e5, + 0xe4f2, 0x1eb4, + 0xe4f3, 0x191e, + 0xe540, 0x1928, + 0xe541, 0x08f5, + 0xe542, 0x192a, + 0xe54d, 0x0f05, + 0xe54e, 0x1936, + 0xe55b, 0x1eb5, + 0xe55c, 0x1944, + 0xe579, 0x05a0, + 0xe57a, 0x1962, + 0xe580, 0x1967, + 0xe5a2, 0x0d1e, + 0xe5a3, 0x198a, + 0xe5a5, 0x1eb6, + 0xe5a6, 0x198d, + 0xe5bb, 0x1eb7, + 0xe5bc, 0x19a3, + 0xe5ed, 0x1eb8, + 0xe5ee, 0x19d5, + 0xe640, 0x19e4, + 0xe651, 0x1eb9, + 0xe652, 0x19f6, + 0xe67c, 0x060e, + 0xe67d, 0x1a21, + 0xe680, 0x1a23, + 0xe686, 0x1eba, + 0xe687, 0x1a2a, + 0xe696, 0x1ebb, + 0xe697, 0x1a3a, + 0xe6cb, 0x0aaa, + 0xe6cc, 0x1a6f, + 0xe6e7, 0x1ebc, + 0xe6e8, 0x1a8b, + 0xe6f2, 0x1ebd, + 0xe6f3, 0x1a96, + 0xe740, 0x1aa0, + 0xe76d, 0x1ebe, + 0xe76e, 0x1ace, + 0xe780, 0x1adf, + 0xe78c, 0x1ebf, + 0xe78d, 0x1aec, + 0xe78e, 0x1ec0, + 0xe78f, 0x1aee, + 0xe7a7, 0x1ec1, + 0xe7a8, 0x1b07, + 0xe7bb, 0x1ec2, + 0xe7bc, 0x1b1b, + 0xe7d5, 0x1ec3, + 0xe7d6, 0x1b35, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe885, 0x1ec4, + 0xe886, 0x1ba1, + 0xe8b1, 0x1ec5, + 0xe8b2, 0x1bcd, + 0xe8c3, 0x1ec6, + 0xe8c4, 0x1bdf, + 0xe8cf, 0x1ec7, + 0xe8d0, 0x1beb, + 0xe8d5, 0x1ec8, + 0xe8d6, 0x1bf1, + 0xe8f2, 0x0731, + 0xe8f3, 0x1ec9, + 0xe8f4, 0x1c0f, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xe9ab, 0x1eca, + 0xe9ac, 0x1c83, + 0xe9ba, 0x1ecb, + 0xe9bb, 0x1c92, + 0xe9cb, 0x0477, + 0xe9cc, 0x1ecc, + 0xe9cd, 0x1ca4, + 0xe9f2, 0x0529, + 0xe9f3, 0x1cca, + 0xea40, 0x1cd4, + 0xea70, 0x1ecd, + 0xea71, 0x1d05, + 0xea80, 0x1d13, + 0xea9d, 0x1ece, + 0xea9e, 0x1d31, + 0xed40, 0x20a7, + 0xed80, 0x20e6, + 0xedb4, 0x07c9, + 0xedb5, 0x211a, + 0xee40, 0x2162, + 0xee80, 0x21a1, + 0xeeef, 0x1f9c, + 0xeef9, 0x02ef, + 0xeefa, 0x1f45, + 0x8141, 0x1ecf, + 0x8143, 0x204c, + 0x8144, 0x2052, + 0x814a, 0x2050, + 0x814b, 0x204f, + 0x815b, 0x1ed3, + 0x8160, 0x1ed6, + 0x8165, 0x2059, + 0x8166, 0x2054, + 0x8167, 0x2057, + 0x8168, 0x2056, + 0x8169, 0x1edb, + 0x818b, 0x204d, + 0x818c, 0x2051, + 0x818d, 0x205b, + 0x81ac, 0x204e, + 0x829f, 0x1eee, + 0x82a1, 0x1eef, + 0x82a3, 0x1ef0, + 0x82a5, 0x1ef1, + 0x82a7, 0x1ef2, + 0x82c1, 0x1ef3, + 0x82e1, 0x1ef4, + 0x82e3, 0x1ef5, + 0x82e5, 0x1ef6, + 0x82ec, 0x1ef7, + 0x8340, 0x1ef8, + 0x8342, 0x1ef9, + 0x8344, 0x1efa, + 0x8346, 0x1efb, + 0x8348, 0x1efc, + 0x8362, 0x1efd, + 0x8383, 0x1efe, + 0x8385, 0x1eff, + 0x8387, 0x1f00, + 0x838e, 0x1f01, + 0x8395, 0x1f02, + 0x875f, 0x1f04, + 0x8780, 0x1f14, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12ExtRKSJVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12ExtRKSJVMap2, 704 +}; + +static Gushort japan12ExtVMap2[1404] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2169, 0x1d36, + 0x216a, 0x02c2, + 0x2221, 0x02d7, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x2921, 0x00e8, + 0x2960, 0x0186, + 0x2961, 0x0128, + 0x2a21, 0x0147, + 0x2a60, 0x0187, + 0x2b21, 0x01a6, + 0x2b72, 0x0127, + 0x2b73, 0x01f7, + 0x2c24, 0x1d37, + 0x2d21, 0x1d83, + 0x2d40, 0x1da1, + 0x2d5f, 0x2083, + 0x2d60, 0x1db8, + 0x2d70, 0x02fa, + 0x2d71, 0x02f9, + 0x2d72, 0x0301, + 0x2d73, 0x1dc8, + 0x2d7a, 0x0300, + 0x2d7b, 0x1dcf, + 0x3021, 0x0465, + 0x3022, 0x1dd1, + 0x3023, 0x0467, + 0x3033, 0x1ca2, + 0x3034, 0x0478, + 0x303b, 0x1dd2, + 0x303c, 0x0480, + 0x306e, 0x1dd3, + 0x306f, 0x04b3, + 0x3073, 0x1dd4, + 0x3074, 0x04b8, + 0x307c, 0x1dd5, + 0x307d, 0x04c1, + 0x3121, 0x04c3, + 0x312a, 0x1dd6, + 0x312b, 0x04cd, + 0x3135, 0x1dd7, + 0x3136, 0x04d8, + 0x3139, 0x1dd8, + 0x313a, 0x04dc, + 0x313c, 0x1dd9, + 0x313e, 0x04e0, + 0x3142, 0x1ddb, + 0x3143, 0x04e5, + 0x316b, 0x1ddc, + 0x316c, 0x050e, + 0x3221, 0x0521, + 0x3228, 0x1ddd, + 0x3229, 0x1cc9, + 0x322a, 0x1dde, + 0x322b, 0x052b, + 0x3260, 0x1ddf, + 0x3261, 0x0561, + 0x327a, 0x1de0, + 0x327b, 0x057b, + 0x327d, 0x1de1, + 0x327e, 0x057e, + 0x3321, 0x057f, + 0x3322, 0x1de2, + 0x3323, 0x0581, + 0x3342, 0x1961, + 0x3343, 0x05a1, + 0x3349, 0x139f, + 0x334a, 0x05a8, + 0x3365, 0x1de3, + 0x3366, 0x05c4, + 0x336b, 0x1de4, + 0x336c, 0x05ca, + 0x3373, 0x1de5, + 0x3374, 0x05d2, + 0x3376, 0x1731, + 0x3377, 0x05d5, + 0x337a, 0x1de6, + 0x337b, 0x05d9, + 0x3421, 0x05dd, + 0x3442, 0x1de7, + 0x3443, 0x1572, + 0x3444, 0x0600, + 0x344d, 0x1de8, + 0x344e, 0x060a, + 0x3452, 0x1a20, + 0x3453, 0x060f, + 0x3465, 0x1de9, + 0x3466, 0x0622, + 0x3521, 0x063b, + 0x352b, 0x1dea, + 0x352c, 0x0646, + 0x3540, 0x1deb, + 0x3541, 0x065b, + 0x3621, 0x0699, + 0x3622, 0x1dec, + 0x3623, 0x069b, + 0x362a, 0x1ded, + 0x362b, 0x06a3, + 0x3646, 0x1d32, + 0x3647, 0x06bf, + 0x364f, 0x1dee, + 0x3650, 0x06c8, + 0x366d, 0x1def, + 0x366e, 0x06e6, + 0x3674, 0x1df0, + 0x3675, 0x06ed, + 0x367b, 0x1df1, + 0x367c, 0x06f4, + 0x367d, 0x1df2, + 0x367e, 0x06f6, + 0x3721, 0x06f7, + 0x3724, 0x1df3, + 0x3725, 0x06fb, + 0x3737, 0x1df4, + 0x3738, 0x070e, + 0x3745, 0x1df5, + 0x3746, 0x071c, + 0x374e, 0x1df6, + 0x374f, 0x0725, + 0x3752, 0x1df7, + 0x3753, 0x0729, + 0x3755, 0x1df8, + 0x3756, 0x072c, + 0x375b, 0x1c0d, + 0x375c, 0x0732, + 0x3764, 0x1df9, + 0x3765, 0x073b, + 0x3771, 0x1dfa, + 0x3772, 0x0748, + 0x3779, 0x1dfb, + 0x377a, 0x0750, + 0x377e, 0x1dfc, + 0x3821, 0x0755, + 0x3834, 0x1dfd, + 0x3835, 0x0769, + 0x3841, 0x1dfe, + 0x3842, 0x0776, + 0x3921, 0x07b3, + 0x392b, 0x1dff, + 0x392c, 0x07be, + 0x3937, 0x1e00, + 0x3938, 0x07ca, + 0x3942, 0x1e01, + 0x3943, 0x07d5, + 0x395c, 0x16dd, + 0x395d, 0x07ef, + 0x396d, 0x1e02, + 0x396e, 0x0800, + 0x3974, 0x1e03, + 0x3975, 0x0807, + 0x3979, 0x1e04, + 0x397a, 0x080c, + 0x3a21, 0x0811, + 0x3a53, 0x1e05, + 0x3a54, 0x0844, + 0x3a67, 0x1e06, + 0x3a68, 0x0858, + 0x3a74, 0x1e07, + 0x3a75, 0x0865, + 0x3b21, 0x086f, + 0x3b27, 0x1e08, + 0x3b28, 0x0876, + 0x3b2a, 0x1e09, + 0x3b2b, 0x0879, + 0x3b2c, 0x1e0a, + 0x3b2d, 0x087b, + 0x3b39, 0x1e0b, + 0x3b3a, 0x0888, + 0x3c21, 0x08cd, + 0x3c38, 0x1e0c, + 0x3c39, 0x08e5, + 0x3c48, 0x1e0d, + 0x3c49, 0x1929, + 0x3c4a, 0x08f6, + 0x3c57, 0x1e0e, + 0x3c58, 0x0904, + 0x3c5d, 0x1e0f, + 0x3c5f, 0x090b, + 0x3d21, 0x092b, + 0x3d2b, 0x1e11, + 0x3d2c, 0x0936, + 0x3d36, 0x1e12, + 0x3d37, 0x0941, + 0x3d6c, 0x1e13, + 0x3d6e, 0x0978, + 0x3d72, 0x1e15, + 0x3d74, 0x097e, + 0x3e21, 0x0989, + 0x3e25, 0x1e17, + 0x3e26, 0x098e, + 0x3e33, 0x1e18, + 0x3e34, 0x099c, + 0x3e3f, 0x1e19, + 0x3e40, 0x09a8, + 0x3e55, 0x1e1a, + 0x3e56, 0x09be, + 0x3e5f, 0x1e1b, + 0x3e60, 0x09c8, + 0x3e64, 0x1e1c, + 0x3e65, 0x09cd, + 0x3f21, 0x09e7, + 0x3f2a, 0x1e1d, + 0x3f2b, 0x09f1, + 0x3f59, 0x1e1e, + 0x3f5a, 0x0a20, + 0x3f60, 0x1e1f, + 0x3f61, 0x0a27, + 0x3f69, 0x1e20, + 0x3f6a, 0x0a30, + 0x4021, 0x0a45, + 0x4022, 0x1e21, + 0x4023, 0x0a47, + 0x4042, 0x1e22, + 0x4043, 0x0a67, + 0x4066, 0x1e23, + 0x4067, 0x0a8b, + 0x4071, 0x1e24, + 0x4073, 0x0a97, + 0x4079, 0x1e26, + 0x407b, 0x0a9f, + 0x4121, 0x0aa3, + 0x4127, 0x1e28, + 0x4128, 0x1a6e, + 0x4129, 0x0aab, + 0x4139, 0x1e29, + 0x413a, 0x0abc, + 0x414c, 0x1e2a, + 0x414d, 0x0acf, + 0x414f, 0x1e2b, + 0x4150, 0x0ad2, + 0x415f, 0x1e2c, + 0x4160, 0x0ae2, + 0x4169, 0x1e2d, + 0x416a, 0x0aec, + 0x4221, 0x0b01, + 0x423d, 0x1e2e, + 0x423e, 0x0b1e, + 0x424d, 0x1e2f, + 0x424e, 0x0b2e, + 0x425c, 0x1e30, + 0x425d, 0x0b3d, + 0x4263, 0x1e31, + 0x4264, 0x0b44, + 0x426f, 0x1e32, + 0x4270, 0x0b50, + 0x4275, 0x1e33, + 0x4277, 0x0b57, + 0x427d, 0x1e35, + 0x427e, 0x0b5e, + 0x4321, 0x0b5f, + 0x4327, 0x1e36, + 0x4328, 0x0b66, + 0x4329, 0x1e37, + 0x432b, 0x0b69, + 0x432d, 0x1e39, + 0x432f, 0x0b6d, + 0x433d, 0x1e3b, + 0x433e, 0x0b7c, + 0x4370, 0x1e3c, + 0x4371, 0x0baf, + 0x4375, 0x1e3d, + 0x4376, 0x0bb4, + 0x437c, 0x1e3e, + 0x437d, 0x0bbb, + 0x4421, 0x0bbd, + 0x443d, 0x1e3f, + 0x443e, 0x0bda, + 0x4448, 0x1e40, + 0x4449, 0x0be5, + 0x444a, 0x1e41, + 0x444b, 0x0be7, + 0x444d, 0x1e42, + 0x444e, 0x0bea, + 0x444f, 0x1e43, + 0x4450, 0x0bec, + 0x445b, 0x11b5, + 0x445c, 0x0bf8, + 0x4521, 0x0c1b, + 0x4522, 0x1e44, + 0x4523, 0x0c1d, + 0x4527, 0x1e45, + 0x4528, 0x0c22, + 0x452e, 0x1e46, + 0x452f, 0x0c29, + 0x4536, 0x1e47, + 0x4537, 0x0c31, + 0x453f, 0x1e48, + 0x4540, 0x0c3a, + 0x4548, 0x1e49, + 0x4549, 0x0c43, + 0x454b, 0x1e4a, + 0x454c, 0x0c46, + 0x4551, 0x1e4b, + 0x4553, 0x0c4d, + 0x4557, 0x16df, + 0x4558, 0x0c52, + 0x4564, 0x1e4d, + 0x4565, 0x0c5f, + 0x456e, 0x1450, + 0x456f, 0x0c69, + 0x4573, 0x1536, + 0x4574, 0x0c6e, + 0x4578, 0x1e4e, + 0x4579, 0x0c73, + 0x4621, 0x0c79, + 0x463e, 0x1e4f, + 0x463f, 0x0c97, + 0x4642, 0x1e50, + 0x4643, 0x0c9b, + 0x4654, 0x1e51, + 0x4656, 0x0cae, + 0x465b, 0x1e53, + 0x465d, 0x0cb5, + 0x4661, 0x1e55, + 0x4662, 0x0cba, + 0x4666, 0x1e56, + 0x4668, 0x0cc0, + 0x466a, 0x1e58, + 0x466b, 0x0cc3, + 0x4676, 0x1aed, + 0x4677, 0x0ccf, + 0x4721, 0x0cd7, + 0x4729, 0x1e59, + 0x472a, 0x0ce0, + 0x4739, 0x1e5a, + 0x473a, 0x0cf0, + 0x4757, 0x1e5b, + 0x4758, 0x0d0e, + 0x4767, 0x1e5c, + 0x4768, 0x1989, + 0x4769, 0x1e5d, + 0x476a, 0x0d20, + 0x476d, 0x1e5e, + 0x476e, 0x0d24, + 0x4821, 0x0d35, + 0x4824, 0x1e5f, + 0x4825, 0x0d39, + 0x482e, 0x1e60, + 0x482f, 0x0d43, + 0x4830, 0x1e61, + 0x4831, 0x0d45, + 0x4854, 0x1e62, + 0x4855, 0x0d69, + 0x4862, 0x1e63, + 0x4863, 0x0d77, + 0x4875, 0x1e64, + 0x4876, 0x0d8a, + 0x4921, 0x0d93, + 0x4922, 0x1e65, + 0x4924, 0x0d96, + 0x492f, 0x1e67, + 0x4930, 0x143b, + 0x4931, 0x0da3, + 0x4932, 0x1e68, + 0x4933, 0x0da5, + 0x4935, 0x1e69, + 0x4936, 0x0da8, + 0x4940, 0x1e6a, + 0x4941, 0x0db3, + 0x494e, 0x1e6b, + 0x494f, 0x0dc1, + 0x4951, 0x1e6c, + 0x4952, 0x0dc4, + 0x4a21, 0x0df1, + 0x4a43, 0x1e6d, + 0x4a44, 0x0e14, + 0x4a4d, 0x1e6e, + 0x4a4e, 0x0e1e, + 0x4a5a, 0x1e6f, + 0x4a5b, 0x0e2b, + 0x4a79, 0x1e70, + 0x4a7a, 0x0e4a, + 0x4b21, 0x0e4f, + 0x4b22, 0x1e71, + 0x4b23, 0x0e51, + 0x4b29, 0x1e72, + 0x4b2a, 0x0e58, + 0x4b4b, 0x1e73, + 0x4b4c, 0x0e7a, + 0x4b6a, 0x1d33, + 0x4b6b, 0x0e99, + 0x4b70, 0x1e74, + 0x4b71, 0x0e9f, + 0x4b79, 0x102f, + 0x4b7a, 0x0ea8, + 0x4c21, 0x0ead, + 0x4c4d, 0x1e75, + 0x4c4e, 0x0eda, + 0x4c59, 0x1e76, + 0x4c5a, 0x0ee6, + 0x4c5f, 0x1e77, + 0x4c60, 0x0eec, + 0x4c62, 0x1e78, + 0x4c63, 0x0eef, + 0x4c79, 0x1935, + 0x4c7a, 0x1e79, + 0x4c7b, 0x0f07, + 0x4c7c, 0x1e7a, + 0x4c7d, 0x0f09, + 0x4c7e, 0x1e7b, + 0x4d21, 0x0f0b, + 0x4d32, 0x1e7c, + 0x4d33, 0x0f1d, + 0x4d50, 0x1e7d, + 0x4d51, 0x0f3b, + 0x4d54, 0x1e7e, + 0x4d55, 0x0f3f, + 0x4d5a, 0x1d34, + 0x4d5b, 0x0f45, + 0x4d69, 0x1e7f, + 0x4d6a, 0x0f54, + 0x4e21, 0x0f69, + 0x4e4b, 0x1e80, + 0x4e4c, 0x0f94, + 0x4e7a, 0x1e81, + 0x4e7c, 0x0fc4, + 0x4f21, 0x1e83, + 0x4f22, 0x0fc8, + 0x4f31, 0x1e84, + 0x4f32, 0x0fd8, + 0x4f36, 0x1777, + 0x4f37, 0x0fdd, + 0x4f39, 0x1e85, + 0x4f3a, 0x0fe0, + 0x5021, 0x0ffa, + 0x5056, 0x0ea7, + 0x5057, 0x1030, + 0x5121, 0x1058, + 0x513d, 0x1e86, + 0x513e, 0x1075, + 0x5147, 0x1e87, + 0x5148, 0x107f, + 0x514b, 0x1e88, + 0x514c, 0x1083, + 0x514d, 0x1e89, + 0x514e, 0x1085, + 0x5221, 0x10b6, + 0x5321, 0x1114, + 0x5330, 0x1e8a, + 0x5331, 0x1124, + 0x533a, 0x1e8b, + 0x533b, 0x112e, + 0x5350, 0x1e8c, + 0x5351, 0x1144, + 0x535e, 0x1e8d, + 0x535f, 0x1152, + 0x536b, 0x1e8e, + 0x536c, 0x115f, + 0x5421, 0x1172, + 0x5444, 0x1e8f, + 0x5445, 0x1196, + 0x5464, 0x0bf7, + 0x5465, 0x11b6, + 0x5521, 0x11d0, + 0x553d, 0x1e90, + 0x553e, 0x11ed, + 0x5563, 0x1e91, + 0x5564, 0x1213, + 0x5621, 0x122e, + 0x5622, 0x1e92, + 0x5623, 0x1230, + 0x5672, 0x1e93, + 0x5673, 0x1280, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5824, 0x1e94, + 0x5825, 0x12ee, + 0x5921, 0x1348, + 0x5960, 0x1e95, + 0x5961, 0x1388, + 0x596c, 0x1e96, + 0x596d, 0x1394, + 0x5978, 0x05a7, + 0x5979, 0x13a0, + 0x5a21, 0x13a6, + 0x5a39, 0x1e97, + 0x5a3a, 0x13bf, + 0x5a4d, 0x1e98, + 0x5a4e, 0x13d3, + 0x5b21, 0x1404, + 0x5b45, 0x1e99, + 0x5b46, 0x1429, + 0x5b4a, 0x1e9a, + 0x5b4b, 0x142e, + 0x5b58, 0x0da2, + 0x5b59, 0x143c, + 0x5b6b, 0x1e9b, + 0x5b6c, 0x144f, + 0x5b6d, 0x0c68, + 0x5b6e, 0x1451, + 0x5b74, 0x1e9c, + 0x5b75, 0x1458, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5e21, 0x151e, + 0x5e39, 0x0c6d, + 0x5e3a, 0x1537, + 0x5e50, 0x1e9d, + 0x5e51, 0x154e, + 0x5e75, 0x05ff, + 0x5e76, 0x1573, + 0x5f21, 0x157c, + 0x5f73, 0x1e9e, + 0x5f74, 0x15cf, + 0x6021, 0x15da, + 0x6026, 0x1e9f, + 0x6027, 0x15e0, + 0x605f, 0x1ea0, + 0x6060, 0x1619, + 0x6076, 0x1d35, + 0x6077, 0x1630, + 0x6121, 0x1638, + 0x612b, 0x1ea1, + 0x612c, 0x1643, + 0x6130, 0x1ea2, + 0x6132, 0x1649, + 0x6221, 0x1696, + 0x622b, 0x1ea4, + 0x622c, 0x16a1, + 0x6268, 0x07ee, + 0x6269, 0x16de, + 0x626a, 0x0c51, + 0x626b, 0x16e0, + 0x626f, 0x1ea5, + 0x6270, 0x16e5, + 0x6321, 0x16f4, + 0x634a, 0x1ea6, + 0x634b, 0x171e, + 0x6354, 0x1ea7, + 0x6355, 0x1728, + 0x635e, 0x05d4, + 0x635f, 0x1732, + 0x6421, 0x1752, + 0x6439, 0x1ea8, + 0x643a, 0x176b, + 0x6446, 0x0fdc, + 0x6447, 0x1778, + 0x6464, 0x1ea9, + 0x6465, 0x1796, + 0x646e, 0x1eaa, + 0x646f, 0x17a0, + 0x6521, 0x17b0, + 0x6539, 0x1eab, + 0x653a, 0x17c9, + 0x653b, 0x1eac, + 0x653c, 0x17cb, + 0x6546, 0x1ead, + 0x6547, 0x17d6, + 0x6621, 0x180e, + 0x6646, 0x1eae, + 0x6647, 0x1834, + 0x6721, 0x186c, + 0x6764, 0x1eaf, + 0x6765, 0x18b0, + 0x6769, 0x1eb0, + 0x676a, 0x18b5, + 0x6772, 0x1eb1, + 0x6773, 0x18be, + 0x6821, 0x18ca, + 0x6834, 0x1eb2, + 0x6835, 0x18de, + 0x683b, 0x1eb3, + 0x683c, 0x18e5, + 0x6874, 0x1eb4, + 0x6875, 0x191e, + 0x6921, 0x1928, + 0x6922, 0x08f5, + 0x6923, 0x192a, + 0x692e, 0x0f05, + 0x692f, 0x1936, + 0x693c, 0x1eb5, + 0x693d, 0x1944, + 0x695a, 0x05a0, + 0x695b, 0x1962, + 0x6a21, 0x1986, + 0x6a24, 0x0d1e, + 0x6a25, 0x198a, + 0x6a27, 0x1eb6, + 0x6a28, 0x198d, + 0x6a3d, 0x1eb7, + 0x6a3e, 0x19a3, + 0x6a6f, 0x1eb8, + 0x6a70, 0x19d5, + 0x6b21, 0x19e4, + 0x6b32, 0x1eb9, + 0x6b33, 0x19f6, + 0x6b5d, 0x060e, + 0x6b5e, 0x1a21, + 0x6b66, 0x1eba, + 0x6b67, 0x1a2a, + 0x6b76, 0x1ebb, + 0x6b77, 0x1a3a, + 0x6c21, 0x1a42, + 0x6c4d, 0x0aaa, + 0x6c4e, 0x1a6f, + 0x6c69, 0x1ebc, + 0x6c6a, 0x1a8b, + 0x6c74, 0x1ebd, + 0x6c75, 0x1a96, + 0x6d21, 0x1aa0, + 0x6d4e, 0x1ebe, + 0x6d4f, 0x1ace, + 0x6d6c, 0x1ebf, + 0x6d6d, 0x1aec, + 0x6d6e, 0x1ec0, + 0x6d6f, 0x1aee, + 0x6e21, 0x1afe, + 0x6e29, 0x1ec1, + 0x6e2a, 0x1b07, + 0x6e3d, 0x1ec2, + 0x6e3e, 0x1b1b, + 0x6e57, 0x1ec3, + 0x6e58, 0x1b35, + 0x6f21, 0x1b5c, + 0x6f65, 0x1ec4, + 0x6f66, 0x1ba1, + 0x7021, 0x1bba, + 0x7033, 0x1ec5, + 0x7034, 0x1bcd, + 0x7045, 0x1ec6, + 0x7046, 0x1bdf, + 0x7051, 0x1ec7, + 0x7052, 0x1beb, + 0x7057, 0x1ec8, + 0x7058, 0x1bf1, + 0x7074, 0x0731, + 0x7075, 0x1ec9, + 0x7076, 0x1c0f, + 0x7121, 0x1c18, + 0x7221, 0x1c76, + 0x722d, 0x1eca, + 0x722e, 0x1c83, + 0x723c, 0x1ecb, + 0x723d, 0x1c92, + 0x724d, 0x0477, + 0x724e, 0x1ecc, + 0x724f, 0x1ca4, + 0x7274, 0x0529, + 0x7275, 0x1cca, + 0x7321, 0x1cd4, + 0x7351, 0x1ecd, + 0x7352, 0x1d05, + 0x737d, 0x1ece, + 0x737e, 0x1d31, + 0x7921, 0x20a7, + 0x7a21, 0x2105, + 0x7a36, 0x07c9, + 0x7a37, 0x211a, + 0x7b21, 0x2162, + 0x7c21, 0x21c0, + 0x7c71, 0x1f9c, + 0x7c7b, 0x02ef, + 0x7c7c, 0x1f45, + 0x2122, 0x1ecf, + 0x2124, 0x204c, + 0x2125, 0x2052, + 0x212b, 0x2050, + 0x212c, 0x204f, + 0x213c, 0x1ed3, + 0x2141, 0x1ed6, + 0x2146, 0x2059, + 0x2147, 0x2054, + 0x2148, 0x2057, + 0x2149, 0x2056, + 0x214a, 0x1edb, + 0x216b, 0x204d, + 0x216c, 0x2051, + 0x216d, 0x205b, + 0x222e, 0x204e, + 0x2421, 0x1eee, + 0x2423, 0x1eef, + 0x2425, 0x1ef0, + 0x2427, 0x1ef1, + 0x2429, 0x1ef2, + 0x2443, 0x1ef3, + 0x2463, 0x1ef4, + 0x2465, 0x1ef5, + 0x2467, 0x1ef6, + 0x246e, 0x1ef7, + 0x2521, 0x1ef8, + 0x2523, 0x1ef9, + 0x2525, 0x1efa, + 0x2527, 0x1efb, + 0x2529, 0x1efc, + 0x2543, 0x1efd, + 0x2563, 0x1efe, + 0x2565, 0x1eff, + 0x2567, 0x1f00, + 0x256e, 0x1f01, + 0x2575, 0x1f02, + 0x2d40, 0x1f04, + 0x2d60, 0x1f14, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12ExtVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12ExtVMap2, 702 +}; + +static Gushort japan12HMap2[240] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2221, 0x02d7, + 0x223a, 0x02e5, + 0x224a, 0x02ed, + 0x225c, 0x02f4, + 0x2272, 0x0303, + 0x227e, 0x030b, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x2821, 0x1d37, + 0x2822, 0x1d39, + 0x2823, 0x1d43, + 0x2824, 0x1d47, + 0x2825, 0x1d4f, + 0x2826, 0x1d4b, + 0x2827, 0x1d53, + 0x2828, 0x1d63, + 0x2829, 0x1d5b, + 0x282a, 0x1d6b, + 0x282b, 0x1d73, + 0x282c, 0x1d38, + 0x282d, 0x1d3a, + 0x282e, 0x1d46, + 0x282f, 0x1d4a, + 0x2830, 0x1d52, + 0x2831, 0x1d4e, + 0x2832, 0x1d5a, + 0x2833, 0x1d6a, + 0x2834, 0x1d62, + 0x2835, 0x1d72, + 0x2836, 0x1d82, + 0x2837, 0x1d57, + 0x2838, 0x1d66, + 0x2839, 0x1d5f, + 0x283a, 0x1d6e, + 0x283b, 0x1d76, + 0x283c, 0x1d54, + 0x283d, 0x1d67, + 0x283e, 0x1d5c, + 0x283f, 0x1d6f, + 0x2840, 0x1d79, + 0x3021, 0x0465, + 0x3121, 0x04c3, + 0x3221, 0x0521, + 0x3321, 0x057f, + 0x3421, 0x05dd, + 0x3521, 0x063b, + 0x3621, 0x0699, + 0x3721, 0x06f7, + 0x3821, 0x0755, + 0x3921, 0x07b3, + 0x3a21, 0x0811, + 0x3b21, 0x086f, + 0x3c21, 0x08cd, + 0x3d21, 0x092b, + 0x3e21, 0x0989, + 0x3f21, 0x09e7, + 0x4021, 0x0a45, + 0x4121, 0x0aa3, + 0x4221, 0x0b01, + 0x4321, 0x0b5f, + 0x4421, 0x0bbd, + 0x4521, 0x0c1b, + 0x4621, 0x0c79, + 0x4721, 0x0cd7, + 0x4821, 0x0d35, + 0x4921, 0x0d93, + 0x4a21, 0x0df1, + 0x4b21, 0x0e4f, + 0x4c21, 0x0ead, + 0x4d21, 0x0f0b, + 0x4e21, 0x0f69, + 0x4f21, 0x0fc7, + 0x5021, 0x0ffa, + 0x5121, 0x1058, + 0x5221, 0x10b6, + 0x5321, 0x1114, + 0x5421, 0x1172, + 0x5521, 0x11d0, + 0x5621, 0x122e, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5921, 0x1348, + 0x5a21, 0x13a6, + 0x5b21, 0x1404, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5e21, 0x151e, + 0x5f21, 0x157c, + 0x6021, 0x15da, + 0x6121, 0x1638, + 0x6221, 0x1696, + 0x6321, 0x16f4, + 0x6421, 0x1752, + 0x6521, 0x17b0, + 0x6621, 0x180e, + 0x6721, 0x186c, + 0x6821, 0x18ca, + 0x6921, 0x1928, + 0x6a21, 0x1986, + 0x6b21, 0x19e4, + 0x6c21, 0x1a42, + 0x6d21, 0x1aa0, + 0x6e21, 0x1afe, + 0x6f21, 0x1b5c, + 0x7021, 0x1bba, + 0x7121, 0x1c18, + 0x7221, 0x1c76, + 0x7321, 0x1cd4, + 0x7421, 0x1d32, + 0x7425, 0x205c, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12HEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12HMap2, 120 +}; + +static Gushort japan12HankakuMap2[4] = { + 0x0000, 0x0000, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12HankakuEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x00e7, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x0204, 0x0205, + 0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020b, 0x020c, 0x020d, + 0x0156, 0x020e, 0x020f, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, + 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021a, 0x021b, 0x021c, + 0x0000, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x021d, 0x021e, 0x021f, 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, + 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022a, 0x022b, 0x022c, + 0x022d, 0x022e, 0x022f, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, + 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x023a, 0x0184, 0x0185 }, + japan12HankakuMap2, 2 +}; + +static Gushort japan12HiraganaMap2[4] = { + 0x0000, 0x0000, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12HiraganaEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0203, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x0204, 0x0205, + 0x0206, 0x0207, 0x0208, 0x0209, 0x020a, 0x020b, 0x020c, 0x020d, + 0x0156, 0x020e, 0x020f, 0x0210, 0x0211, 0x0212, 0x0213, 0x0214, + 0x0215, 0x0216, 0x0217, 0x0218, 0x0219, 0x021a, 0x021b, 0x021c, + 0x021d, 0x021e, 0x021f, 0x0220, 0x0221, 0x0222, 0x0223, 0x0224, + 0x0225, 0x0226, 0x0227, 0x0228, 0x0229, 0x022a, 0x022b, 0x022c, + 0x022d, 0x022e, 0x022f, 0x0230, 0x0231, 0x0232, 0x0233, 0x0234, + 0x0235, 0x0236, 0x0237, 0x0238, 0x0239, 0x023a, 0x0184, 0x0185, + 0x023b, 0x023c, 0x023d, 0x0000, 0x0000, 0x0000, 0x023e, 0x023f, + 0x0240, 0x0241, 0x0242, 0x0243, 0x0244, 0x0245, 0x0246, 0x0247, + 0x0248, 0x0249, 0x024a, 0x024b, 0x024c, 0x024d, 0x024e, 0x024f, + 0x0250, 0x0251, 0x0252, 0x0253, 0x0254, 0x0255, 0x0256, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12HiraganaMap2, 2 +}; + +static Gushort japan12KatakanaMap2[4] = { + 0x0000, 0x0000, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12KatakanaEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0187, 0x0188, 0x0189, 0x018a, 0x018b, 0x018c, 0x018d, 0x018e, + 0x018f, 0x0190, 0x0191, 0x0192, 0x0193, 0x0194, 0x0195, 0x0196, + 0x0197, 0x0198, 0x0199, 0x019a, 0x019b, 0x019c, 0x019d, 0x019e, + 0x019f, 0x01a0, 0x01a1, 0x01a2, 0x01a3, 0x01a4, 0x01a5, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12KatakanaMap2, 2 +}; + +static Gushort japan12NWPHMap2[1522] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2169, 0x1d36, + 0x216a, 0x02c2, + 0x2221, 0x02d7, + 0x223a, 0x02e5, + 0x224a, 0x02ed, + 0x225c, 0x02f4, + 0x2272, 0x0303, + 0x227e, 0x030b, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x2921, 0x00e8, + 0x2960, 0x0186, + 0x2961, 0x0128, + 0x2a21, 0x0147, + 0x2a60, 0x0187, + 0x2b21, 0x01a6, + 0x2b72, 0x0127, + 0x2b73, 0x01f7, + 0x2c24, 0x1d37, + 0x2d21, 0x1d83, + 0x2d40, 0x1da1, + 0x2d60, 0x1db8, + 0x2d70, 0x02fa, + 0x2d71, 0x02f9, + 0x2d72, 0x0301, + 0x2d73, 0x1dc8, + 0x2d7a, 0x0300, + 0x2d7b, 0x1dcf, + 0x2e21, 0x0282, + 0x2e22, 0x02a1, + 0x2e23, 0x0305, + 0x2e24, 0x02c8, + 0x2e25, 0x02cb, + 0x2e26, 0x02cd, + 0x2e27, 0x029f, + 0x2e28, 0x02a2, + 0x2e2a, 0x02ce, + 0x2e2b, 0x02b4, + 0x2e2c, 0x027c, + 0x2e2d, 0x02b5, + 0x2e2e, 0x027d, + 0x2e2f, 0x0297, + 0x2e30, 0x030c, + 0x2e3a, 0x027f, + 0x2e3c, 0x02bb, + 0x2e3d, 0x02b9, + 0x2e3e, 0x02bc, + 0x2e3f, 0x0281, + 0x2e40, 0x02cf, + 0x2e41, 0x0316, + 0x2e5b, 0x02a6, + 0x2e5c, 0x02c7, + 0x2e5d, 0x02a7, + 0x2e5e, 0x0288, + 0x2e5f, 0x028a, + 0x2e60, 0x0286, + 0x2e61, 0x0330, + 0x2e7b, 0x02a8, + 0x2e7c, 0x029b, + 0x2e7d, 0x02a9, + 0x2e7e, 0x0289, + 0x2f21, 0x027b, + 0x2f22, 0x02ae, + 0x2f24, 0x027a, + 0x2f25, 0x027e, + 0x2f26, 0x03ee, + 0x2f27, 0x039d, + 0x2f28, 0x039f, + 0x2f29, 0x03a1, + 0x2f2a, 0x03a3, + 0x2f2b, 0x03a5, + 0x2f2c, 0x03df, + 0x2f2d, 0x03e1, + 0x2f2e, 0x03e3, + 0x2f2f, 0x03bf, + 0x2f30, 0x0294, + 0x2f31, 0x039e, + 0x2f32, 0x03a0, + 0x2f33, 0x03a2, + 0x2f34, 0x03a4, + 0x2f35, 0x03a6, + 0x2f37, 0x03a9, + 0x2f38, 0x03ab, + 0x2f39, 0x03ad, + 0x2f3a, 0x03af, + 0x2f3b, 0x03b1, + 0x2f3c, 0x03b3, + 0x2f3d, 0x03b5, + 0x2f3e, 0x03b7, + 0x2f3f, 0x03b9, + 0x2f40, 0x03bb, + 0x2f41, 0x03bd, + 0x2f42, 0x03c0, + 0x2f43, 0x03c2, + 0x2f44, 0x03c4, + 0x2f45, 0x03c6, + 0x2f4b, 0x03ce, + 0x2f4c, 0x03d1, + 0x2f4d, 0x03d4, + 0x2f4e, 0x03d7, + 0x2f4f, 0x03da, + 0x2f54, 0x03e0, + 0x2f55, 0x03e2, + 0x2f56, 0x03e4, + 0x2f5c, 0x03eb, + 0x2f5d, 0x03ef, + 0x2f5e, 0x0283, + 0x2f60, 0x03ec, + 0x2f62, 0x03ea, + 0x2f63, 0x03f1, + 0x2f65, 0x03f0, + 0x2f66, 0x03a8, + 0x2f67, 0x03aa, + 0x2f68, 0x03ac, + 0x2f69, 0x03ae, + 0x2f6a, 0x03b0, + 0x2f6b, 0x03b2, + 0x2f6c, 0x03b4, + 0x2f6d, 0x03b6, + 0x2f6e, 0x03b8, + 0x2f6f, 0x03ba, + 0x2f70, 0x03bc, + 0x2f71, 0x03be, + 0x2f72, 0x03c1, + 0x2f73, 0x03c3, + 0x2f74, 0x03c5, + 0x2f75, 0x03cc, + 0x2f77, 0x03cf, + 0x2f79, 0x03d2, + 0x2f7b, 0x03d5, + 0x2f7d, 0x03d8, + 0x3021, 0x0465, + 0x3022, 0x1dd1, + 0x3023, 0x0467, + 0x3033, 0x1ca2, + 0x3034, 0x0478, + 0x303b, 0x1dd2, + 0x303c, 0x0480, + 0x306e, 0x1dd3, + 0x306f, 0x04b3, + 0x3073, 0x1dd4, + 0x3074, 0x04b8, + 0x307c, 0x1dd5, + 0x307d, 0x04c1, + 0x3121, 0x04c3, + 0x312a, 0x1dd6, + 0x312b, 0x04cd, + 0x3135, 0x1dd7, + 0x3136, 0x04d8, + 0x3139, 0x1dd8, + 0x313a, 0x04dc, + 0x313c, 0x1dd9, + 0x313e, 0x04e0, + 0x3142, 0x1ddb, + 0x3143, 0x04e5, + 0x316b, 0x1ddc, + 0x316c, 0x050e, + 0x3221, 0x0521, + 0x3228, 0x1ddd, + 0x3229, 0x1cc9, + 0x322a, 0x1dde, + 0x322b, 0x052b, + 0x3260, 0x1ddf, + 0x3261, 0x0561, + 0x327a, 0x1de0, + 0x327b, 0x057b, + 0x327d, 0x1de1, + 0x327e, 0x057e, + 0x3321, 0x057f, + 0x3322, 0x1de2, + 0x3323, 0x0581, + 0x3342, 0x1961, + 0x3343, 0x05a1, + 0x3349, 0x139f, + 0x334a, 0x05a8, + 0x3365, 0x1de3, + 0x3366, 0x05c4, + 0x336b, 0x1de4, + 0x336c, 0x05ca, + 0x3373, 0x1de5, + 0x3374, 0x05d2, + 0x3376, 0x1731, + 0x3377, 0x05d5, + 0x337a, 0x1de6, + 0x337b, 0x05d9, + 0x3421, 0x05dd, + 0x3442, 0x1de7, + 0x3443, 0x1572, + 0x3444, 0x0600, + 0x344d, 0x1de8, + 0x344e, 0x060a, + 0x3452, 0x1a20, + 0x3453, 0x060f, + 0x3465, 0x1de9, + 0x3466, 0x0622, + 0x3521, 0x063b, + 0x352b, 0x1dea, + 0x352c, 0x0646, + 0x3540, 0x1deb, + 0x3541, 0x065b, + 0x3621, 0x0699, + 0x3622, 0x1dec, + 0x3623, 0x069b, + 0x362a, 0x1ded, + 0x362b, 0x06a3, + 0x3646, 0x1d32, + 0x3647, 0x06bf, + 0x364f, 0x1dee, + 0x3650, 0x06c8, + 0x366d, 0x1def, + 0x366e, 0x06e6, + 0x3674, 0x1df0, + 0x3675, 0x06ed, + 0x367b, 0x1df1, + 0x367c, 0x06f4, + 0x367d, 0x1df2, + 0x367e, 0x06f6, + 0x3721, 0x06f7, + 0x3724, 0x1df3, + 0x3725, 0x06fb, + 0x3737, 0x1df4, + 0x3738, 0x070e, + 0x3745, 0x1df5, + 0x3746, 0x071c, + 0x374e, 0x1df6, + 0x374f, 0x0725, + 0x3752, 0x1df7, + 0x3753, 0x0729, + 0x3755, 0x1df8, + 0x3756, 0x072c, + 0x375b, 0x1c0d, + 0x375c, 0x0732, + 0x3764, 0x1df9, + 0x3765, 0x073b, + 0x3771, 0x1dfa, + 0x3772, 0x0748, + 0x3779, 0x1dfb, + 0x377a, 0x0750, + 0x377e, 0x1dfc, + 0x3821, 0x0755, + 0x3834, 0x1dfd, + 0x3835, 0x0769, + 0x3841, 0x1dfe, + 0x3842, 0x0776, + 0x3921, 0x07b3, + 0x392b, 0x1dff, + 0x392c, 0x07be, + 0x3937, 0x1e00, + 0x3938, 0x07ca, + 0x3942, 0x1e01, + 0x3943, 0x07d5, + 0x395c, 0x16dd, + 0x395d, 0x07ef, + 0x396d, 0x1e02, + 0x396e, 0x0800, + 0x3974, 0x1e03, + 0x3975, 0x0807, + 0x3979, 0x1e04, + 0x397a, 0x080c, + 0x3a21, 0x0811, + 0x3a53, 0x1e05, + 0x3a54, 0x0844, + 0x3a67, 0x1e06, + 0x3a68, 0x0858, + 0x3a74, 0x1e07, + 0x3a75, 0x0865, + 0x3b21, 0x086f, + 0x3b27, 0x1e08, + 0x3b28, 0x0876, + 0x3b2a, 0x1e09, + 0x3b2b, 0x0879, + 0x3b2c, 0x1e0a, + 0x3b2d, 0x087b, + 0x3b39, 0x1e0b, + 0x3b3a, 0x0888, + 0x3c21, 0x08cd, + 0x3c38, 0x1e0c, + 0x3c39, 0x08e5, + 0x3c48, 0x1e0d, + 0x3c49, 0x1929, + 0x3c4a, 0x08f6, + 0x3c57, 0x1e0e, + 0x3c58, 0x0904, + 0x3c5d, 0x1e0f, + 0x3c5f, 0x090b, + 0x3d21, 0x092b, + 0x3d2b, 0x1e11, + 0x3d2c, 0x0936, + 0x3d36, 0x1e12, + 0x3d37, 0x0941, + 0x3d6c, 0x1e13, + 0x3d6e, 0x0978, + 0x3d72, 0x1e15, + 0x3d74, 0x097e, + 0x3e21, 0x0989, + 0x3e25, 0x1e17, + 0x3e26, 0x098e, + 0x3e33, 0x1e18, + 0x3e34, 0x099c, + 0x3e3f, 0x1e19, + 0x3e40, 0x09a8, + 0x3e55, 0x1e1a, + 0x3e56, 0x09be, + 0x3e5f, 0x1e1b, + 0x3e60, 0x09c8, + 0x3e64, 0x1e1c, + 0x3e65, 0x09cd, + 0x3f21, 0x09e7, + 0x3f2a, 0x1e1d, + 0x3f2b, 0x09f1, + 0x3f59, 0x1e1e, + 0x3f5a, 0x0a20, + 0x3f60, 0x1e1f, + 0x3f61, 0x0a27, + 0x3f69, 0x1e20, + 0x3f6a, 0x0a30, + 0x4021, 0x0a45, + 0x4022, 0x1e21, + 0x4023, 0x0a47, + 0x4042, 0x1e22, + 0x4043, 0x0a67, + 0x4066, 0x1e23, + 0x4067, 0x0a8b, + 0x4071, 0x1e24, + 0x4073, 0x0a97, + 0x4079, 0x1e26, + 0x407b, 0x0a9f, + 0x4121, 0x0aa3, + 0x4127, 0x1e28, + 0x4128, 0x1a6e, + 0x4129, 0x0aab, + 0x4139, 0x1e29, + 0x413a, 0x0abc, + 0x414c, 0x1e2a, + 0x414d, 0x0acf, + 0x414f, 0x1e2b, + 0x4150, 0x0ad2, + 0x415f, 0x1e2c, + 0x4160, 0x0ae2, + 0x4169, 0x1e2d, + 0x416a, 0x0aec, + 0x4221, 0x0b01, + 0x423d, 0x1e2e, + 0x423e, 0x0b1e, + 0x424d, 0x1e2f, + 0x424e, 0x0b2e, + 0x425c, 0x1e30, + 0x425d, 0x0b3d, + 0x4263, 0x1e31, + 0x4264, 0x0b44, + 0x426f, 0x1e32, + 0x4270, 0x0b50, + 0x4275, 0x1e33, + 0x4277, 0x0b57, + 0x427d, 0x1e35, + 0x427e, 0x0b5e, + 0x4321, 0x0b5f, + 0x4327, 0x1e36, + 0x4328, 0x0b66, + 0x4329, 0x1e37, + 0x432b, 0x0b69, + 0x432d, 0x1e39, + 0x432f, 0x0b6d, + 0x433d, 0x1e3b, + 0x433e, 0x0b7c, + 0x4370, 0x1e3c, + 0x4371, 0x0baf, + 0x4375, 0x1e3d, + 0x4376, 0x0bb4, + 0x437c, 0x1e3e, + 0x437d, 0x0bbb, + 0x4421, 0x0bbd, + 0x443d, 0x1e3f, + 0x443e, 0x0bda, + 0x4448, 0x1e40, + 0x4449, 0x0be5, + 0x444a, 0x1e41, + 0x444b, 0x0be7, + 0x444d, 0x1e42, + 0x444e, 0x0bea, + 0x444f, 0x1e43, + 0x4450, 0x0bec, + 0x445b, 0x11b5, + 0x445c, 0x0bf8, + 0x4521, 0x0c1b, + 0x4522, 0x1e44, + 0x4523, 0x0c1d, + 0x4527, 0x1e45, + 0x4528, 0x0c22, + 0x452e, 0x1e46, + 0x452f, 0x0c29, + 0x4536, 0x1e47, + 0x4537, 0x0c31, + 0x453f, 0x1e48, + 0x4540, 0x0c3a, + 0x4548, 0x1e49, + 0x4549, 0x0c43, + 0x454b, 0x1e4a, + 0x454c, 0x0c46, + 0x4551, 0x1e4b, + 0x4553, 0x0c4d, + 0x4557, 0x16df, + 0x4558, 0x0c52, + 0x4564, 0x1e4d, + 0x4565, 0x0c5f, + 0x456e, 0x1450, + 0x456f, 0x0c69, + 0x4573, 0x1536, + 0x4574, 0x0c6e, + 0x4578, 0x1e4e, + 0x4579, 0x0c73, + 0x4621, 0x0c79, + 0x463e, 0x1e4f, + 0x463f, 0x0c97, + 0x4642, 0x1e50, + 0x4643, 0x0c9b, + 0x4654, 0x1e51, + 0x4656, 0x0cae, + 0x465b, 0x1e53, + 0x465d, 0x0cb5, + 0x4661, 0x1e55, + 0x4662, 0x0cba, + 0x4666, 0x1e56, + 0x4668, 0x0cc0, + 0x466a, 0x1e58, + 0x466b, 0x0cc3, + 0x4676, 0x1aed, + 0x4677, 0x0ccf, + 0x4721, 0x0cd7, + 0x4729, 0x1e59, + 0x472a, 0x0ce0, + 0x4739, 0x1e5a, + 0x473a, 0x0cf0, + 0x4757, 0x1e5b, + 0x4758, 0x0d0e, + 0x4767, 0x1e5c, + 0x4768, 0x1989, + 0x4769, 0x1e5d, + 0x476a, 0x0d20, + 0x476d, 0x1e5e, + 0x476e, 0x0d24, + 0x4821, 0x0d35, + 0x4824, 0x1e5f, + 0x4825, 0x0d39, + 0x482e, 0x1e60, + 0x482f, 0x0d43, + 0x4830, 0x1e61, + 0x4831, 0x0d45, + 0x4854, 0x1e62, + 0x4855, 0x0d69, + 0x4862, 0x1e63, + 0x4863, 0x0d77, + 0x4875, 0x1e64, + 0x4876, 0x0d8a, + 0x4921, 0x0d93, + 0x4922, 0x1e65, + 0x4924, 0x0d96, + 0x492f, 0x1e67, + 0x4930, 0x143b, + 0x4931, 0x0da3, + 0x4932, 0x1e68, + 0x4933, 0x0da5, + 0x4935, 0x1e69, + 0x4936, 0x0da8, + 0x4940, 0x1e6a, + 0x4941, 0x0db3, + 0x494e, 0x1e6b, + 0x494f, 0x0dc1, + 0x4951, 0x1e6c, + 0x4952, 0x0dc4, + 0x4a21, 0x0df1, + 0x4a43, 0x1e6d, + 0x4a44, 0x0e14, + 0x4a4d, 0x1e6e, + 0x4a4e, 0x0e1e, + 0x4a5a, 0x1e6f, + 0x4a5b, 0x0e2b, + 0x4a79, 0x1e70, + 0x4a7a, 0x0e4a, + 0x4b21, 0x0e4f, + 0x4b22, 0x1e71, + 0x4b23, 0x0e51, + 0x4b29, 0x1e72, + 0x4b2a, 0x0e58, + 0x4b4b, 0x1e73, + 0x4b4c, 0x0e7a, + 0x4b6a, 0x1d33, + 0x4b6b, 0x0e99, + 0x4b70, 0x1e74, + 0x4b71, 0x0e9f, + 0x4b79, 0x102f, + 0x4b7a, 0x0ea8, + 0x4c21, 0x0ead, + 0x4c4d, 0x1e75, + 0x4c4e, 0x0eda, + 0x4c59, 0x1e76, + 0x4c5a, 0x0ee6, + 0x4c5f, 0x1e77, + 0x4c60, 0x0eec, + 0x4c62, 0x1e78, + 0x4c63, 0x0eef, + 0x4c79, 0x1935, + 0x4c7a, 0x1e79, + 0x4c7b, 0x0f07, + 0x4c7c, 0x1e7a, + 0x4c7d, 0x0f09, + 0x4c7e, 0x1e7b, + 0x4d21, 0x0f0b, + 0x4d32, 0x1e7c, + 0x4d33, 0x0f1d, + 0x4d50, 0x1e7d, + 0x4d51, 0x0f3b, + 0x4d54, 0x1e7e, + 0x4d55, 0x0f3f, + 0x4d5a, 0x1d34, + 0x4d5b, 0x0f45, + 0x4d69, 0x1e7f, + 0x4d6a, 0x0f54, + 0x4e21, 0x0f69, + 0x4e4b, 0x1e80, + 0x4e4c, 0x0f94, + 0x4e7a, 0x1e81, + 0x4e7c, 0x0fc4, + 0x4f21, 0x1e83, + 0x4f22, 0x0fc8, + 0x4f31, 0x1e84, + 0x4f32, 0x0fd8, + 0x4f36, 0x1777, + 0x4f37, 0x0fdd, + 0x4f39, 0x1e85, + 0x4f3a, 0x0fe0, + 0x5021, 0x0ffa, + 0x5056, 0x0ea7, + 0x5057, 0x1030, + 0x5121, 0x1058, + 0x513d, 0x1e86, + 0x513e, 0x1075, + 0x5147, 0x1e87, + 0x5148, 0x107f, + 0x514b, 0x1e88, + 0x514c, 0x1083, + 0x514d, 0x1e89, + 0x514e, 0x1085, + 0x5221, 0x10b6, + 0x5321, 0x1114, + 0x5330, 0x1e8a, + 0x5331, 0x1124, + 0x533a, 0x1e8b, + 0x533b, 0x112e, + 0x5350, 0x1e8c, + 0x5351, 0x1144, + 0x535e, 0x1e8d, + 0x535f, 0x1152, + 0x536b, 0x1e8e, + 0x536c, 0x115f, + 0x5421, 0x1172, + 0x5444, 0x1e8f, + 0x5445, 0x1196, + 0x5464, 0x0bf7, + 0x5465, 0x11b6, + 0x5521, 0x11d0, + 0x553d, 0x1e90, + 0x553e, 0x11ed, + 0x5563, 0x1e91, + 0x5564, 0x1213, + 0x5621, 0x122e, + 0x5622, 0x1e92, + 0x5623, 0x1230, + 0x5672, 0x1e93, + 0x5673, 0x1280, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5824, 0x1e94, + 0x5825, 0x12ee, + 0x5921, 0x1348, + 0x5960, 0x1e95, + 0x5961, 0x1388, + 0x596c, 0x1e96, + 0x596d, 0x1394, + 0x5978, 0x05a7, + 0x5979, 0x13a0, + 0x5a21, 0x13a6, + 0x5a39, 0x1e97, + 0x5a3a, 0x13bf, + 0x5a4d, 0x1e98, + 0x5a4e, 0x13d3, + 0x5b21, 0x1404, + 0x5b45, 0x1e99, + 0x5b46, 0x1429, + 0x5b4a, 0x1e9a, + 0x5b4b, 0x142e, + 0x5b58, 0x0da2, + 0x5b59, 0x143c, + 0x5b6b, 0x1e9b, + 0x5b6c, 0x144f, + 0x5b6d, 0x0c68, + 0x5b6e, 0x1451, + 0x5b74, 0x1e9c, + 0x5b75, 0x1458, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5e21, 0x151e, + 0x5e39, 0x0c6d, + 0x5e3a, 0x1537, + 0x5e50, 0x1e9d, + 0x5e51, 0x154e, + 0x5e75, 0x05ff, + 0x5e76, 0x1573, + 0x5f21, 0x157c, + 0x5f73, 0x1e9e, + 0x5f74, 0x15cf, + 0x6021, 0x15da, + 0x6026, 0x1e9f, + 0x6027, 0x15e0, + 0x605f, 0x1ea0, + 0x6060, 0x1619, + 0x6076, 0x1d35, + 0x6077, 0x1630, + 0x6121, 0x1638, + 0x612b, 0x1ea1, + 0x612c, 0x1643, + 0x6130, 0x1ea2, + 0x6132, 0x1649, + 0x6221, 0x1696, + 0x622b, 0x1ea4, + 0x622c, 0x16a1, + 0x6268, 0x07ee, + 0x6269, 0x16de, + 0x626a, 0x0c51, + 0x626b, 0x16e0, + 0x626f, 0x1ea5, + 0x6270, 0x16e5, + 0x6321, 0x16f4, + 0x634a, 0x1ea6, + 0x634b, 0x171e, + 0x6354, 0x1ea7, + 0x6355, 0x1728, + 0x635e, 0x05d4, + 0x635f, 0x1732, + 0x6421, 0x1752, + 0x6439, 0x1ea8, + 0x643a, 0x176b, + 0x6446, 0x0fdc, + 0x6447, 0x1778, + 0x6464, 0x1ea9, + 0x6465, 0x1796, + 0x646e, 0x1eaa, + 0x646f, 0x17a0, + 0x6521, 0x17b0, + 0x6539, 0x1eab, + 0x653a, 0x17c9, + 0x653b, 0x1eac, + 0x653c, 0x17cb, + 0x6546, 0x1ead, + 0x6547, 0x17d6, + 0x6621, 0x180e, + 0x6646, 0x1eae, + 0x6647, 0x1834, + 0x6721, 0x186c, + 0x6764, 0x1eaf, + 0x6765, 0x18b0, + 0x6769, 0x1eb0, + 0x676a, 0x18b5, + 0x6772, 0x1eb1, + 0x6773, 0x18be, + 0x6821, 0x18ca, + 0x6834, 0x1eb2, + 0x6835, 0x18de, + 0x683b, 0x1eb3, + 0x683c, 0x18e5, + 0x6874, 0x1eb4, + 0x6875, 0x191e, + 0x6921, 0x1928, + 0x6922, 0x08f5, + 0x6923, 0x192a, + 0x692e, 0x0f05, + 0x692f, 0x1936, + 0x693c, 0x1eb5, + 0x693d, 0x1944, + 0x695a, 0x05a0, + 0x695b, 0x1962, + 0x6a21, 0x1986, + 0x6a24, 0x0d1e, + 0x6a25, 0x198a, + 0x6a27, 0x1eb6, + 0x6a28, 0x198d, + 0x6a3d, 0x1eb7, + 0x6a3e, 0x19a3, + 0x6a6f, 0x1eb8, + 0x6a70, 0x19d5, + 0x6b21, 0x19e4, + 0x6b32, 0x1eb9, + 0x6b33, 0x19f6, + 0x6b5d, 0x060e, + 0x6b5e, 0x1a21, + 0x6b66, 0x1eba, + 0x6b67, 0x1a2a, + 0x6b76, 0x1ebb, + 0x6b77, 0x1a3a, + 0x6c21, 0x1a42, + 0x6c4d, 0x0aaa, + 0x6c4e, 0x1a6f, + 0x6c69, 0x1ebc, + 0x6c6a, 0x1a8b, + 0x6c74, 0x1ebd, + 0x6c75, 0x1a96, + 0x6d21, 0x1aa0, + 0x6d4e, 0x1ebe, + 0x6d4f, 0x1ace, + 0x6d6c, 0x1ebf, + 0x6d6d, 0x1aec, + 0x6d6e, 0x1ec0, + 0x6d6f, 0x1aee, + 0x6e21, 0x1afe, + 0x6e29, 0x1ec1, + 0x6e2a, 0x1b07, + 0x6e3d, 0x1ec2, + 0x6e3e, 0x1b1b, + 0x6e57, 0x1ec3, + 0x6e58, 0x1b35, + 0x6f21, 0x1b5c, + 0x6f65, 0x1ec4, + 0x6f66, 0x1ba1, + 0x7021, 0x1bba, + 0x7033, 0x1ec5, + 0x7034, 0x1bcd, + 0x7045, 0x1ec6, + 0x7046, 0x1bdf, + 0x7051, 0x1ec7, + 0x7052, 0x1beb, + 0x7057, 0x1ec8, + 0x7058, 0x1bf1, + 0x7074, 0x0731, + 0x7075, 0x1ec9, + 0x7076, 0x1c0f, + 0x7121, 0x1c18, + 0x7221, 0x1c76, + 0x722d, 0x1eca, + 0x722e, 0x1c83, + 0x723c, 0x1ecb, + 0x723d, 0x1c92, + 0x724d, 0x0477, + 0x724e, 0x1ecc, + 0x724f, 0x1ca4, + 0x7274, 0x0529, + 0x7275, 0x1cca, + 0x7321, 0x1cd4, + 0x7351, 0x1ecd, + 0x7352, 0x1d05, + 0x737d, 0x1ece, + 0x737e, 0x1d31, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12NWPHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12NWPHMap2, 761 +}; + +static Gushort japan12NWPVMap2[1618] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2169, 0x1d36, + 0x216a, 0x02c2, + 0x2221, 0x02d7, + 0x223a, 0x02e5, + 0x224a, 0x02ed, + 0x225c, 0x02f4, + 0x2272, 0x0303, + 0x227e, 0x030b, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x2921, 0x00e8, + 0x2960, 0x0186, + 0x2961, 0x0128, + 0x2a21, 0x0147, + 0x2a60, 0x0187, + 0x2b21, 0x01a6, + 0x2b72, 0x0127, + 0x2b73, 0x01f7, + 0x2c24, 0x1d37, + 0x2d21, 0x1d83, + 0x2d40, 0x1da1, + 0x2d60, 0x1db8, + 0x2d70, 0x02fa, + 0x2d71, 0x02f9, + 0x2d72, 0x0301, + 0x2d73, 0x1dc8, + 0x2d7a, 0x0300, + 0x2d7b, 0x1dcf, + 0x2e21, 0x0282, + 0x2e22, 0x02a1, + 0x2e23, 0x0305, + 0x2e24, 0x02c8, + 0x2e25, 0x02cb, + 0x2e26, 0x02cd, + 0x2e27, 0x029f, + 0x2e28, 0x02a2, + 0x2e2a, 0x02ce, + 0x2e2b, 0x02b4, + 0x2e2c, 0x027c, + 0x2e2d, 0x02b5, + 0x2e2e, 0x027d, + 0x2e2f, 0x0297, + 0x2e30, 0x030c, + 0x2e3a, 0x027f, + 0x2e3c, 0x02bb, + 0x2e3d, 0x02b9, + 0x2e3e, 0x02bc, + 0x2e3f, 0x0281, + 0x2e40, 0x02cf, + 0x2e41, 0x0316, + 0x2e5b, 0x02a6, + 0x2e5c, 0x02c7, + 0x2e5d, 0x02a7, + 0x2e5e, 0x0288, + 0x2e5f, 0x028a, + 0x2e60, 0x0286, + 0x2e61, 0x0330, + 0x2e7b, 0x02a8, + 0x2e7c, 0x029b, + 0x2e7d, 0x02a9, + 0x2e7e, 0x0289, + 0x2f21, 0x027b, + 0x2f22, 0x02ae, + 0x2f24, 0x027a, + 0x2f25, 0x027e, + 0x2f26, 0x03ee, + 0x2f27, 0x039d, + 0x2f28, 0x039f, + 0x2f29, 0x03a1, + 0x2f2a, 0x03a3, + 0x2f2b, 0x03a5, + 0x2f2c, 0x03df, + 0x2f2d, 0x03e1, + 0x2f2e, 0x03e3, + 0x2f2f, 0x03bf, + 0x2f30, 0x0294, + 0x2f31, 0x039e, + 0x2f32, 0x03a0, + 0x2f33, 0x03a2, + 0x2f34, 0x03a4, + 0x2f35, 0x03a6, + 0x2f37, 0x03a9, + 0x2f38, 0x03ab, + 0x2f39, 0x03ad, + 0x2f3a, 0x03af, + 0x2f3b, 0x03b1, + 0x2f3c, 0x03b3, + 0x2f3d, 0x03b5, + 0x2f3e, 0x03b7, + 0x2f3f, 0x03b9, + 0x2f40, 0x03bb, + 0x2f41, 0x03bd, + 0x2f42, 0x03c0, + 0x2f43, 0x03c2, + 0x2f44, 0x03c4, + 0x2f45, 0x03c6, + 0x2f4b, 0x03ce, + 0x2f4c, 0x03d1, + 0x2f4d, 0x03d4, + 0x2f4e, 0x03d7, + 0x2f4f, 0x03da, + 0x2f54, 0x03e0, + 0x2f55, 0x03e2, + 0x2f56, 0x03e4, + 0x2f5c, 0x03eb, + 0x2f5d, 0x03ef, + 0x2f5e, 0x0283, + 0x2f60, 0x03ec, + 0x2f62, 0x03ea, + 0x2f63, 0x03f1, + 0x2f65, 0x03f0, + 0x2f66, 0x03a8, + 0x2f67, 0x03aa, + 0x2f68, 0x03ac, + 0x2f69, 0x03ae, + 0x2f6a, 0x03b0, + 0x2f6b, 0x03b2, + 0x2f6c, 0x03b4, + 0x2f6d, 0x03b6, + 0x2f6e, 0x03b8, + 0x2f6f, 0x03ba, + 0x2f70, 0x03bc, + 0x2f71, 0x03be, + 0x2f72, 0x03c1, + 0x2f73, 0x03c3, + 0x2f74, 0x03c5, + 0x2f75, 0x03cc, + 0x2f77, 0x03cf, + 0x2f79, 0x03d2, + 0x2f7b, 0x03d5, + 0x2f7d, 0x03d8, + 0x3021, 0x0465, + 0x3022, 0x1dd1, + 0x3023, 0x0467, + 0x3033, 0x1ca2, + 0x3034, 0x0478, + 0x303b, 0x1dd2, + 0x303c, 0x0480, + 0x306e, 0x1dd3, + 0x306f, 0x04b3, + 0x3073, 0x1dd4, + 0x3074, 0x04b8, + 0x307c, 0x1dd5, + 0x307d, 0x04c1, + 0x3121, 0x04c3, + 0x312a, 0x1dd6, + 0x312b, 0x04cd, + 0x3135, 0x1dd7, + 0x3136, 0x04d8, + 0x3139, 0x1dd8, + 0x313a, 0x04dc, + 0x313c, 0x1dd9, + 0x313e, 0x04e0, + 0x3142, 0x1ddb, + 0x3143, 0x04e5, + 0x316b, 0x1ddc, + 0x316c, 0x050e, + 0x3221, 0x0521, + 0x3228, 0x1ddd, + 0x3229, 0x1cc9, + 0x322a, 0x1dde, + 0x322b, 0x052b, + 0x3260, 0x1ddf, + 0x3261, 0x0561, + 0x327a, 0x1de0, + 0x327b, 0x057b, + 0x327d, 0x1de1, + 0x327e, 0x057e, + 0x3321, 0x057f, + 0x3322, 0x1de2, + 0x3323, 0x0581, + 0x3342, 0x1961, + 0x3343, 0x05a1, + 0x3349, 0x139f, + 0x334a, 0x05a8, + 0x3365, 0x1de3, + 0x3366, 0x05c4, + 0x336b, 0x1de4, + 0x336c, 0x05ca, + 0x3373, 0x1de5, + 0x3374, 0x05d2, + 0x3376, 0x1731, + 0x3377, 0x05d5, + 0x337a, 0x1de6, + 0x337b, 0x05d9, + 0x3421, 0x05dd, + 0x3442, 0x1de7, + 0x3443, 0x1572, + 0x3444, 0x0600, + 0x344d, 0x1de8, + 0x344e, 0x060a, + 0x3452, 0x1a20, + 0x3453, 0x060f, + 0x3465, 0x1de9, + 0x3466, 0x0622, + 0x3521, 0x063b, + 0x352b, 0x1dea, + 0x352c, 0x0646, + 0x3540, 0x1deb, + 0x3541, 0x065b, + 0x3621, 0x0699, + 0x3622, 0x1dec, + 0x3623, 0x069b, + 0x362a, 0x1ded, + 0x362b, 0x06a3, + 0x3646, 0x1d32, + 0x3647, 0x06bf, + 0x364f, 0x1dee, + 0x3650, 0x06c8, + 0x366d, 0x1def, + 0x366e, 0x06e6, + 0x3674, 0x1df0, + 0x3675, 0x06ed, + 0x367b, 0x1df1, + 0x367c, 0x06f4, + 0x367d, 0x1df2, + 0x367e, 0x06f6, + 0x3721, 0x06f7, + 0x3724, 0x1df3, + 0x3725, 0x06fb, + 0x3737, 0x1df4, + 0x3738, 0x070e, + 0x3745, 0x1df5, + 0x3746, 0x071c, + 0x374e, 0x1df6, + 0x374f, 0x0725, + 0x3752, 0x1df7, + 0x3753, 0x0729, + 0x3755, 0x1df8, + 0x3756, 0x072c, + 0x375b, 0x1c0d, + 0x375c, 0x0732, + 0x3764, 0x1df9, + 0x3765, 0x073b, + 0x3771, 0x1dfa, + 0x3772, 0x0748, + 0x3779, 0x1dfb, + 0x377a, 0x0750, + 0x377e, 0x1dfc, + 0x3821, 0x0755, + 0x3834, 0x1dfd, + 0x3835, 0x0769, + 0x3841, 0x1dfe, + 0x3842, 0x0776, + 0x3921, 0x07b3, + 0x392b, 0x1dff, + 0x392c, 0x07be, + 0x3937, 0x1e00, + 0x3938, 0x07ca, + 0x3942, 0x1e01, + 0x3943, 0x07d5, + 0x395c, 0x16dd, + 0x395d, 0x07ef, + 0x396d, 0x1e02, + 0x396e, 0x0800, + 0x3974, 0x1e03, + 0x3975, 0x0807, + 0x3979, 0x1e04, + 0x397a, 0x080c, + 0x3a21, 0x0811, + 0x3a53, 0x1e05, + 0x3a54, 0x0844, + 0x3a67, 0x1e06, + 0x3a68, 0x0858, + 0x3a74, 0x1e07, + 0x3a75, 0x0865, + 0x3b21, 0x086f, + 0x3b27, 0x1e08, + 0x3b28, 0x0876, + 0x3b2a, 0x1e09, + 0x3b2b, 0x0879, + 0x3b2c, 0x1e0a, + 0x3b2d, 0x087b, + 0x3b39, 0x1e0b, + 0x3b3a, 0x0888, + 0x3c21, 0x08cd, + 0x3c38, 0x1e0c, + 0x3c39, 0x08e5, + 0x3c48, 0x1e0d, + 0x3c49, 0x1929, + 0x3c4a, 0x08f6, + 0x3c57, 0x1e0e, + 0x3c58, 0x0904, + 0x3c5d, 0x1e0f, + 0x3c5f, 0x090b, + 0x3d21, 0x092b, + 0x3d2b, 0x1e11, + 0x3d2c, 0x0936, + 0x3d36, 0x1e12, + 0x3d37, 0x0941, + 0x3d6c, 0x1e13, + 0x3d6e, 0x0978, + 0x3d72, 0x1e15, + 0x3d74, 0x097e, + 0x3e21, 0x0989, + 0x3e25, 0x1e17, + 0x3e26, 0x098e, + 0x3e33, 0x1e18, + 0x3e34, 0x099c, + 0x3e3f, 0x1e19, + 0x3e40, 0x09a8, + 0x3e55, 0x1e1a, + 0x3e56, 0x09be, + 0x3e5f, 0x1e1b, + 0x3e60, 0x09c8, + 0x3e64, 0x1e1c, + 0x3e65, 0x09cd, + 0x3f21, 0x09e7, + 0x3f2a, 0x1e1d, + 0x3f2b, 0x09f1, + 0x3f59, 0x1e1e, + 0x3f5a, 0x0a20, + 0x3f60, 0x1e1f, + 0x3f61, 0x0a27, + 0x3f69, 0x1e20, + 0x3f6a, 0x0a30, + 0x4021, 0x0a45, + 0x4022, 0x1e21, + 0x4023, 0x0a47, + 0x4042, 0x1e22, + 0x4043, 0x0a67, + 0x4066, 0x1e23, + 0x4067, 0x0a8b, + 0x4071, 0x1e24, + 0x4073, 0x0a97, + 0x4079, 0x1e26, + 0x407b, 0x0a9f, + 0x4121, 0x0aa3, + 0x4127, 0x1e28, + 0x4128, 0x1a6e, + 0x4129, 0x0aab, + 0x4139, 0x1e29, + 0x413a, 0x0abc, + 0x414c, 0x1e2a, + 0x414d, 0x0acf, + 0x414f, 0x1e2b, + 0x4150, 0x0ad2, + 0x415f, 0x1e2c, + 0x4160, 0x0ae2, + 0x4169, 0x1e2d, + 0x416a, 0x0aec, + 0x4221, 0x0b01, + 0x423d, 0x1e2e, + 0x423e, 0x0b1e, + 0x424d, 0x1e2f, + 0x424e, 0x0b2e, + 0x425c, 0x1e30, + 0x425d, 0x0b3d, + 0x4263, 0x1e31, + 0x4264, 0x0b44, + 0x426f, 0x1e32, + 0x4270, 0x0b50, + 0x4275, 0x1e33, + 0x4277, 0x0b57, + 0x427d, 0x1e35, + 0x427e, 0x0b5e, + 0x4321, 0x0b5f, + 0x4327, 0x1e36, + 0x4328, 0x0b66, + 0x4329, 0x1e37, + 0x432b, 0x0b69, + 0x432d, 0x1e39, + 0x432f, 0x0b6d, + 0x433d, 0x1e3b, + 0x433e, 0x0b7c, + 0x4370, 0x1e3c, + 0x4371, 0x0baf, + 0x4375, 0x1e3d, + 0x4376, 0x0bb4, + 0x437c, 0x1e3e, + 0x437d, 0x0bbb, + 0x4421, 0x0bbd, + 0x443d, 0x1e3f, + 0x443e, 0x0bda, + 0x4448, 0x1e40, + 0x4449, 0x0be5, + 0x444a, 0x1e41, + 0x444b, 0x0be7, + 0x444d, 0x1e42, + 0x444e, 0x0bea, + 0x444f, 0x1e43, + 0x4450, 0x0bec, + 0x445b, 0x11b5, + 0x445c, 0x0bf8, + 0x4521, 0x0c1b, + 0x4522, 0x1e44, + 0x4523, 0x0c1d, + 0x4527, 0x1e45, + 0x4528, 0x0c22, + 0x452e, 0x1e46, + 0x452f, 0x0c29, + 0x4536, 0x1e47, + 0x4537, 0x0c31, + 0x453f, 0x1e48, + 0x4540, 0x0c3a, + 0x4548, 0x1e49, + 0x4549, 0x0c43, + 0x454b, 0x1e4a, + 0x454c, 0x0c46, + 0x4551, 0x1e4b, + 0x4553, 0x0c4d, + 0x4557, 0x16df, + 0x4558, 0x0c52, + 0x4564, 0x1e4d, + 0x4565, 0x0c5f, + 0x456e, 0x1450, + 0x456f, 0x0c69, + 0x4573, 0x1536, + 0x4574, 0x0c6e, + 0x4578, 0x1e4e, + 0x4579, 0x0c73, + 0x4621, 0x0c79, + 0x463e, 0x1e4f, + 0x463f, 0x0c97, + 0x4642, 0x1e50, + 0x4643, 0x0c9b, + 0x4654, 0x1e51, + 0x4656, 0x0cae, + 0x465b, 0x1e53, + 0x465d, 0x0cb5, + 0x4661, 0x1e55, + 0x4662, 0x0cba, + 0x4666, 0x1e56, + 0x4668, 0x0cc0, + 0x466a, 0x1e58, + 0x466b, 0x0cc3, + 0x4676, 0x1aed, + 0x4677, 0x0ccf, + 0x4721, 0x0cd7, + 0x4729, 0x1e59, + 0x472a, 0x0ce0, + 0x4739, 0x1e5a, + 0x473a, 0x0cf0, + 0x4757, 0x1e5b, + 0x4758, 0x0d0e, + 0x4767, 0x1e5c, + 0x4768, 0x1989, + 0x4769, 0x1e5d, + 0x476a, 0x0d20, + 0x476d, 0x1e5e, + 0x476e, 0x0d24, + 0x4821, 0x0d35, + 0x4824, 0x1e5f, + 0x4825, 0x0d39, + 0x482e, 0x1e60, + 0x482f, 0x0d43, + 0x4830, 0x1e61, + 0x4831, 0x0d45, + 0x4854, 0x1e62, + 0x4855, 0x0d69, + 0x4862, 0x1e63, + 0x4863, 0x0d77, + 0x4875, 0x1e64, + 0x4876, 0x0d8a, + 0x4921, 0x0d93, + 0x4922, 0x1e65, + 0x4924, 0x0d96, + 0x492f, 0x1e67, + 0x4930, 0x143b, + 0x4931, 0x0da3, + 0x4932, 0x1e68, + 0x4933, 0x0da5, + 0x4935, 0x1e69, + 0x4936, 0x0da8, + 0x4940, 0x1e6a, + 0x4941, 0x0db3, + 0x494e, 0x1e6b, + 0x494f, 0x0dc1, + 0x4951, 0x1e6c, + 0x4952, 0x0dc4, + 0x4a21, 0x0df1, + 0x4a43, 0x1e6d, + 0x4a44, 0x0e14, + 0x4a4d, 0x1e6e, + 0x4a4e, 0x0e1e, + 0x4a5a, 0x1e6f, + 0x4a5b, 0x0e2b, + 0x4a79, 0x1e70, + 0x4a7a, 0x0e4a, + 0x4b21, 0x0e4f, + 0x4b22, 0x1e71, + 0x4b23, 0x0e51, + 0x4b29, 0x1e72, + 0x4b2a, 0x0e58, + 0x4b4b, 0x1e73, + 0x4b4c, 0x0e7a, + 0x4b6a, 0x1d33, + 0x4b6b, 0x0e99, + 0x4b70, 0x1e74, + 0x4b71, 0x0e9f, + 0x4b79, 0x102f, + 0x4b7a, 0x0ea8, + 0x4c21, 0x0ead, + 0x4c4d, 0x1e75, + 0x4c4e, 0x0eda, + 0x4c59, 0x1e76, + 0x4c5a, 0x0ee6, + 0x4c5f, 0x1e77, + 0x4c60, 0x0eec, + 0x4c62, 0x1e78, + 0x4c63, 0x0eef, + 0x4c79, 0x1935, + 0x4c7a, 0x1e79, + 0x4c7b, 0x0f07, + 0x4c7c, 0x1e7a, + 0x4c7d, 0x0f09, + 0x4c7e, 0x1e7b, + 0x4d21, 0x0f0b, + 0x4d32, 0x1e7c, + 0x4d33, 0x0f1d, + 0x4d50, 0x1e7d, + 0x4d51, 0x0f3b, + 0x4d54, 0x1e7e, + 0x4d55, 0x0f3f, + 0x4d5a, 0x1d34, + 0x4d5b, 0x0f45, + 0x4d69, 0x1e7f, + 0x4d6a, 0x0f54, + 0x4e21, 0x0f69, + 0x4e4b, 0x1e80, + 0x4e4c, 0x0f94, + 0x4e7a, 0x1e81, + 0x4e7c, 0x0fc4, + 0x4f21, 0x1e83, + 0x4f22, 0x0fc8, + 0x4f31, 0x1e84, + 0x4f32, 0x0fd8, + 0x4f36, 0x1777, + 0x4f37, 0x0fdd, + 0x4f39, 0x1e85, + 0x4f3a, 0x0fe0, + 0x5021, 0x0ffa, + 0x5056, 0x0ea7, + 0x5057, 0x1030, + 0x5121, 0x1058, + 0x513d, 0x1e86, + 0x513e, 0x1075, + 0x5147, 0x1e87, + 0x5148, 0x107f, + 0x514b, 0x1e88, + 0x514c, 0x1083, + 0x514d, 0x1e89, + 0x514e, 0x1085, + 0x5221, 0x10b6, + 0x5321, 0x1114, + 0x5330, 0x1e8a, + 0x5331, 0x1124, + 0x533a, 0x1e8b, + 0x533b, 0x112e, + 0x5350, 0x1e8c, + 0x5351, 0x1144, + 0x535e, 0x1e8d, + 0x535f, 0x1152, + 0x536b, 0x1e8e, + 0x536c, 0x115f, + 0x5421, 0x1172, + 0x5444, 0x1e8f, + 0x5445, 0x1196, + 0x5464, 0x0bf7, + 0x5465, 0x11b6, + 0x5521, 0x11d0, + 0x553d, 0x1e90, + 0x553e, 0x11ed, + 0x5563, 0x1e91, + 0x5564, 0x1213, + 0x5621, 0x122e, + 0x5622, 0x1e92, + 0x5623, 0x1230, + 0x5672, 0x1e93, + 0x5673, 0x1280, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5824, 0x1e94, + 0x5825, 0x12ee, + 0x5921, 0x1348, + 0x5960, 0x1e95, + 0x5961, 0x1388, + 0x596c, 0x1e96, + 0x596d, 0x1394, + 0x5978, 0x05a7, + 0x5979, 0x13a0, + 0x5a21, 0x13a6, + 0x5a39, 0x1e97, + 0x5a3a, 0x13bf, + 0x5a4d, 0x1e98, + 0x5a4e, 0x13d3, + 0x5b21, 0x1404, + 0x5b45, 0x1e99, + 0x5b46, 0x1429, + 0x5b4a, 0x1e9a, + 0x5b4b, 0x142e, + 0x5b58, 0x0da2, + 0x5b59, 0x143c, + 0x5b6b, 0x1e9b, + 0x5b6c, 0x144f, + 0x5b6d, 0x0c68, + 0x5b6e, 0x1451, + 0x5b74, 0x1e9c, + 0x5b75, 0x1458, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5e21, 0x151e, + 0x5e39, 0x0c6d, + 0x5e3a, 0x1537, + 0x5e50, 0x1e9d, + 0x5e51, 0x154e, + 0x5e75, 0x05ff, + 0x5e76, 0x1573, + 0x5f21, 0x157c, + 0x5f73, 0x1e9e, + 0x5f74, 0x15cf, + 0x6021, 0x15da, + 0x6026, 0x1e9f, + 0x6027, 0x15e0, + 0x605f, 0x1ea0, + 0x6060, 0x1619, + 0x6076, 0x1d35, + 0x6077, 0x1630, + 0x6121, 0x1638, + 0x612b, 0x1ea1, + 0x612c, 0x1643, + 0x6130, 0x1ea2, + 0x6132, 0x1649, + 0x6221, 0x1696, + 0x622b, 0x1ea4, + 0x622c, 0x16a1, + 0x6268, 0x07ee, + 0x6269, 0x16de, + 0x626a, 0x0c51, + 0x626b, 0x16e0, + 0x626f, 0x1ea5, + 0x6270, 0x16e5, + 0x6321, 0x16f4, + 0x634a, 0x1ea6, + 0x634b, 0x171e, + 0x6354, 0x1ea7, + 0x6355, 0x1728, + 0x635e, 0x05d4, + 0x635f, 0x1732, + 0x6421, 0x1752, + 0x6439, 0x1ea8, + 0x643a, 0x176b, + 0x6446, 0x0fdc, + 0x6447, 0x1778, + 0x6464, 0x1ea9, + 0x6465, 0x1796, + 0x646e, 0x1eaa, + 0x646f, 0x17a0, + 0x6521, 0x17b0, + 0x6539, 0x1eab, + 0x653a, 0x17c9, + 0x653b, 0x1eac, + 0x653c, 0x17cb, + 0x6546, 0x1ead, + 0x6547, 0x17d6, + 0x6621, 0x180e, + 0x6646, 0x1eae, + 0x6647, 0x1834, + 0x6721, 0x186c, + 0x6764, 0x1eaf, + 0x6765, 0x18b0, + 0x6769, 0x1eb0, + 0x676a, 0x18b5, + 0x6772, 0x1eb1, + 0x6773, 0x18be, + 0x6821, 0x18ca, + 0x6834, 0x1eb2, + 0x6835, 0x18de, + 0x683b, 0x1eb3, + 0x683c, 0x18e5, + 0x6874, 0x1eb4, + 0x6875, 0x191e, + 0x6921, 0x1928, + 0x6922, 0x08f5, + 0x6923, 0x192a, + 0x692e, 0x0f05, + 0x692f, 0x1936, + 0x693c, 0x1eb5, + 0x693d, 0x1944, + 0x695a, 0x05a0, + 0x695b, 0x1962, + 0x6a21, 0x1986, + 0x6a24, 0x0d1e, + 0x6a25, 0x198a, + 0x6a27, 0x1eb6, + 0x6a28, 0x198d, + 0x6a3d, 0x1eb7, + 0x6a3e, 0x19a3, + 0x6a6f, 0x1eb8, + 0x6a70, 0x19d5, + 0x6b21, 0x19e4, + 0x6b32, 0x1eb9, + 0x6b33, 0x19f6, + 0x6b5d, 0x060e, + 0x6b5e, 0x1a21, + 0x6b66, 0x1eba, + 0x6b67, 0x1a2a, + 0x6b76, 0x1ebb, + 0x6b77, 0x1a3a, + 0x6c21, 0x1a42, + 0x6c4d, 0x0aaa, + 0x6c4e, 0x1a6f, + 0x6c69, 0x1ebc, + 0x6c6a, 0x1a8b, + 0x6c74, 0x1ebd, + 0x6c75, 0x1a96, + 0x6d21, 0x1aa0, + 0x6d4e, 0x1ebe, + 0x6d4f, 0x1ace, + 0x6d6c, 0x1ebf, + 0x6d6d, 0x1aec, + 0x6d6e, 0x1ec0, + 0x6d6f, 0x1aee, + 0x6e21, 0x1afe, + 0x6e29, 0x1ec1, + 0x6e2a, 0x1b07, + 0x6e3d, 0x1ec2, + 0x6e3e, 0x1b1b, + 0x6e57, 0x1ec3, + 0x6e58, 0x1b35, + 0x6f21, 0x1b5c, + 0x6f65, 0x1ec4, + 0x6f66, 0x1ba1, + 0x7021, 0x1bba, + 0x7033, 0x1ec5, + 0x7034, 0x1bcd, + 0x7045, 0x1ec6, + 0x7046, 0x1bdf, + 0x7051, 0x1ec7, + 0x7052, 0x1beb, + 0x7057, 0x1ec8, + 0x7058, 0x1bf1, + 0x7074, 0x0731, + 0x7075, 0x1ec9, + 0x7076, 0x1c0f, + 0x7121, 0x1c18, + 0x7221, 0x1c76, + 0x722d, 0x1eca, + 0x722e, 0x1c83, + 0x723c, 0x1ecb, + 0x723d, 0x1c92, + 0x724d, 0x0477, + 0x724e, 0x1ecc, + 0x724f, 0x1ca4, + 0x7274, 0x0529, + 0x7275, 0x1cca, + 0x7321, 0x1cd4, + 0x7351, 0x1ecd, + 0x7352, 0x1d05, + 0x737d, 0x1ece, + 0x737e, 0x1d31, + 0x2122, 0x1ecf, + 0x2124, 0x204c, + 0x2125, 0x2052, + 0x212b, 0x2050, + 0x212c, 0x204f, + 0x213c, 0x1ed3, + 0x2141, 0x1ed6, + 0x2146, 0x2059, + 0x2147, 0x2054, + 0x2148, 0x2057, + 0x2149, 0x2056, + 0x214a, 0x1edb, + 0x216b, 0x204d, + 0x216c, 0x2051, + 0x216d, 0x205b, + 0x222e, 0x204e, + 0x2421, 0x1eee, + 0x2423, 0x1eef, + 0x2425, 0x1ef0, + 0x2427, 0x1ef1, + 0x2429, 0x1ef2, + 0x2443, 0x1ef3, + 0x2463, 0x1ef4, + 0x2465, 0x1ef5, + 0x2467, 0x1ef6, + 0x246e, 0x1ef7, + 0x2521, 0x1ef8, + 0x2523, 0x1ef9, + 0x2525, 0x1efa, + 0x2527, 0x1efb, + 0x2529, 0x1efc, + 0x2543, 0x1efd, + 0x2563, 0x1efe, + 0x2565, 0x1eff, + 0x2567, 0x1f00, + 0x256e, 0x1f01, + 0x2575, 0x1f02, + 0x2d40, 0x1f04, + 0x2d60, 0x1f14, + 0x2f21, 0x1ed0, + 0x2f22, 0x1ee7, + 0x2f24, 0x1ecf, + 0x2f27, 0x1ef8, + 0x2f2c, 0x1efe, + 0x2f2f, 0x1efd, + 0x2f30, 0x1ed3, + 0x2f5e, 0x2050, + 0x2f5f, 0x204f, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12NWPVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12NWPVMap2, 809 +}; + +static Gushort japan12RKSJHMap2[244] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x889f, 0x0465, + 0x8940, 0x04c3, + 0x8980, 0x0502, + 0x8a40, 0x057f, + 0x8a80, 0x05be, + 0x8b40, 0x063b, + 0x8b80, 0x067a, + 0x8c40, 0x06f7, + 0x8c80, 0x0736, + 0x8d40, 0x07b3, + 0x8d80, 0x07f2, + 0x8e40, 0x086f, + 0x8e80, 0x08ae, + 0x8f40, 0x092b, + 0x8f80, 0x096a, + 0x9040, 0x09e7, + 0x9080, 0x0a26, + 0x9140, 0x0aa3, + 0x9180, 0x0ae2, + 0x9240, 0x0b5f, + 0x9280, 0x0b9e, + 0x9340, 0x0c1b, + 0x9380, 0x0c5a, + 0x9440, 0x0cd7, + 0x9480, 0x0d16, + 0x9540, 0x0d93, + 0x9580, 0x0dd2, + 0x9640, 0x0e4f, + 0x9680, 0x0e8e, + 0x9740, 0x0f0b, + 0x9780, 0x0f4a, + 0x9840, 0x0fc7, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a80, 0x1153, + 0x9b40, 0x11d0, + 0x9b80, 0x120f, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9d40, 0x1348, + 0x9d80, 0x1387, + 0x9e40, 0x1404, + 0x9e80, 0x1443, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe140, 0x1638, + 0xe180, 0x1677, + 0xe240, 0x16f4, + 0xe280, 0x1733, + 0xe340, 0x17b0, + 0xe380, 0x17ef, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe640, 0x19e4, + 0xe680, 0x1a23, + 0xe740, 0x1aa0, + 0xe780, 0x1adf, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xea40, 0x1cd4, + 0xea80, 0x1d13, + 0xeaa3, 0x205c, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12RKSJHEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12RKSJHMap2, 122 +}; + +static Gushort japan12RKSJVMap2[298] = { + 0x0000, 0x0000, + 0x8140, 0x0279, + 0x8180, 0x02b8, + 0x81b8, 0x02e5, + 0x81c8, 0x02ed, + 0x81da, 0x02f4, + 0x81f0, 0x0303, + 0x81fc, 0x030b, + 0x824f, 0x030c, + 0x8260, 0x0316, + 0x8281, 0x0330, + 0x829f, 0x034a, + 0x8340, 0x039d, + 0x8380, 0x03dc, + 0x839f, 0x03f3, + 0x83bf, 0x040b, + 0x8440, 0x0423, + 0x8470, 0x0444, + 0x8480, 0x0453, + 0x849f, 0x1d37, + 0x84a0, 0x1d39, + 0x84a1, 0x1d43, + 0x84a2, 0x1d47, + 0x84a3, 0x1d4f, + 0x84a4, 0x1d4b, + 0x84a5, 0x1d53, + 0x84a6, 0x1d63, + 0x84a7, 0x1d5b, + 0x84a8, 0x1d6b, + 0x84a9, 0x1d73, + 0x84aa, 0x1d38, + 0x84ab, 0x1d3a, + 0x84ac, 0x1d46, + 0x84ad, 0x1d4a, + 0x84ae, 0x1d52, + 0x84af, 0x1d4e, + 0x84b0, 0x1d5a, + 0x84b1, 0x1d6a, + 0x84b2, 0x1d62, + 0x84b3, 0x1d72, + 0x84b4, 0x1d82, + 0x84b5, 0x1d57, + 0x84b6, 0x1d66, + 0x84b7, 0x1d5f, + 0x84b8, 0x1d6e, + 0x84b9, 0x1d76, + 0x84ba, 0x1d54, + 0x84bb, 0x1d67, + 0x84bc, 0x1d5c, + 0x84bd, 0x1d6f, + 0x84be, 0x1d79, + 0x889f, 0x0465, + 0x8940, 0x04c3, + 0x8980, 0x0502, + 0x8a40, 0x057f, + 0x8a80, 0x05be, + 0x8b40, 0x063b, + 0x8b80, 0x067a, + 0x8c40, 0x06f7, + 0x8c80, 0x0736, + 0x8d40, 0x07b3, + 0x8d80, 0x07f2, + 0x8e40, 0x086f, + 0x8e80, 0x08ae, + 0x8f40, 0x092b, + 0x8f80, 0x096a, + 0x9040, 0x09e7, + 0x9080, 0x0a26, + 0x9140, 0x0aa3, + 0x9180, 0x0ae2, + 0x9240, 0x0b5f, + 0x9280, 0x0b9e, + 0x9340, 0x0c1b, + 0x9380, 0x0c5a, + 0x9440, 0x0cd7, + 0x9480, 0x0d16, + 0x9540, 0x0d93, + 0x9580, 0x0dd2, + 0x9640, 0x0e4f, + 0x9680, 0x0e8e, + 0x9740, 0x0f0b, + 0x9780, 0x0f4a, + 0x9840, 0x0fc7, + 0x989f, 0x0ffa, + 0x9940, 0x1058, + 0x9980, 0x1097, + 0x9a40, 0x1114, + 0x9a80, 0x1153, + 0x9b40, 0x11d0, + 0x9b80, 0x120f, + 0x9c40, 0x128c, + 0x9c80, 0x12cb, + 0x9d40, 0x1348, + 0x9d80, 0x1387, + 0x9e40, 0x1404, + 0x9e80, 0x1443, + 0x9f40, 0x14c0, + 0x9f80, 0x14ff, + 0xe040, 0x157c, + 0xe080, 0x15bb, + 0xe140, 0x1638, + 0xe180, 0x1677, + 0xe240, 0x16f4, + 0xe280, 0x1733, + 0xe340, 0x17b0, + 0xe380, 0x17ef, + 0xe440, 0x186c, + 0xe480, 0x18ab, + 0xe540, 0x1928, + 0xe580, 0x1967, + 0xe640, 0x19e4, + 0xe680, 0x1a23, + 0xe740, 0x1aa0, + 0xe780, 0x1adf, + 0xe840, 0x1b5c, + 0xe880, 0x1b9b, + 0xe940, 0x1c18, + 0xe980, 0x1c57, + 0xea40, 0x1cd4, + 0xea80, 0x1d13, + 0xeaa3, 0x205c, + 0x8141, 0x1ecf, + 0x8150, 0x1ed1, + 0x815b, 0x1ed3, + 0x8160, 0x1ed6, + 0x8169, 0x1edb, + 0x8181, 0x1eed, + 0x829f, 0x1eee, + 0x82a1, 0x1eef, + 0x82a3, 0x1ef0, + 0x82a5, 0x1ef1, + 0x82a7, 0x1ef2, + 0x82c1, 0x1ef3, + 0x82e1, 0x1ef4, + 0x82e3, 0x1ef5, + 0x82e5, 0x1ef6, + 0x82ec, 0x1ef7, + 0x8340, 0x1ef8, + 0x8342, 0x1ef9, + 0x8344, 0x1efa, + 0x8346, 0x1efb, + 0x8348, 0x1efc, + 0x8362, 0x1efd, + 0x8383, 0x1efe, + 0x8385, 0x1eff, + 0x8387, 0x1f00, + 0x838e, 0x1f01, + 0x8395, 0x1f02, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12RKSJVEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0146, 0x0147, 0x0148, 0x0149, 0x014a, 0x014b, 0x014c, 0x014d, + 0x014e, 0x014f, 0x0150, 0x0151, 0x0152, 0x0153, 0x0154, 0x0155, + 0x0156, 0x0157, 0x0158, 0x0159, 0x015a, 0x015b, 0x015c, 0x015d, + 0x015e, 0x015f, 0x0160, 0x0161, 0x0162, 0x0163, 0x0164, 0x0165, + 0x0166, 0x0167, 0x0168, 0x0169, 0x016a, 0x016b, 0x016c, 0x016d, + 0x016e, 0x016f, 0x0170, 0x0171, 0x0172, 0x0173, 0x0174, 0x0175, + 0x0176, 0x0177, 0x0178, 0x0179, 0x017a, 0x017b, 0x017c, 0x017d, + 0x017e, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183, 0x0184, 0x0185, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12RKSJVMap2, 149 +}; + +static Gushort japan12RomanMap2[4] = { + 0x0000, 0x0000, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12RomanEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, + 0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, + 0x00f7, 0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, + 0x00ff, 0x0100, 0x0101, 0x0102, 0x0103, 0x0104, 0x0105, 0x0106, + 0x0107, 0x0108, 0x0109, 0x010a, 0x010b, 0x010c, 0x010d, 0x010e, + 0x010f, 0x0110, 0x0111, 0x0112, 0x0113, 0x0114, 0x0115, 0x0116, + 0x0117, 0x0118, 0x0119, 0x011a, 0x011b, 0x011c, 0x011d, 0x011e, + 0x011f, 0x0120, 0x0121, 0x0122, 0x0123, 0x0124, 0x0125, 0x0126, + 0x0127, 0x0128, 0x0129, 0x012a, 0x012b, 0x012c, 0x012d, 0x012e, + 0x012f, 0x0130, 0x0131, 0x0132, 0x0133, 0x0134, 0x0135, 0x0136, + 0x0137, 0x0138, 0x0139, 0x013a, 0x013b, 0x013c, 0x013d, 0x013e, + 0x013f, 0x0140, 0x0141, 0x0142, 0x0143, 0x0144, 0x0145, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12RomanMap2, 2 +}; + +static Gushort japan12UniJISUCS2HMap2[13926] = { + 0x0000, 0x0000, + 0x0020, 0x0001, + 0x005c, 0x0061, + 0x005d, 0x003e, + 0x00a1, 0x0065, + 0x00a4, 0x006b, + 0x00a5, 0x003d, + 0x00a6, 0x0063, + 0x00a7, 0x02d0, + 0x00a8, 0x0287, + 0x00a9, 0x0098, + 0x00aa, 0x008c, + 0x00ab, 0x006d, + 0x00ac, 0x0099, + 0x00ad, 0x0097, + 0x00ae, 0x009a, + 0x00af, 0x0081, + 0x00b0, 0x02c3, + 0x00b1, 0x02b6, + 0x00b2, 0x009d, + 0x00b4, 0x0285, + 0x00b5, 0x009f, + 0x00b6, 0x030a, + 0x00b7, 0x0075, + 0x00b8, 0x0086, + 0x00b9, 0x00a0, + 0x00ba, 0x0090, + 0x00bb, 0x007b, + 0x00bc, 0x00a1, + 0x00bf, 0x007e, + 0x00c0, 0x00a4, + 0x00c6, 0x008b, + 0x00c7, 0x00aa, + 0x00d7, 0x02b7, + 0x00d8, 0x008e, + 0x00d9, 0x00bb, + 0x00df, 0x0096, + 0x00e0, 0x00c1, + 0x00e6, 0x0091, + 0x00e7, 0x00c7, + 0x00f7, 0x02b8, + 0x00f8, 0x0094, + 0x00f9, 0x00d8, + 0x0131, 0x0092, + 0x0141, 0x008d, + 0x0142, 0x0093, + 0x0152, 0x008f, + 0x0153, 0x0095, + 0x0160, 0x00df, + 0x0161, 0x00e3, + 0x0178, 0x00e0, + 0x017d, 0x00e1, + 0x017e, 0x00e5, + 0x01c0, 0x0063, + 0x0300, 0x0041, + 0x0301, 0x007f, + 0x0303, 0x005f, + 0x0304, 0x0081, + 0x0305, 0x00e2, + 0x0306, 0x0082, + 0x030a, 0x0085, + 0x030b, 0x0087, + 0x030c, 0x0089, + 0x0327, 0x0086, + 0x0328, 0x0088, + 0x0332, 0x0040, + 0x0336, 0x008a, + 0x0361, 0x02f6, + 0x0391, 0x03f3, + 0x03a3, 0x0404, + 0x03b1, 0x040b, + 0x03c3, 0x041c, + 0x0401, 0x0429, + 0x0410, 0x0423, + 0x0416, 0x042a, + 0x0436, 0x044b, + 0x0451, 0x044a, + 0x2002, 0x00e7, + 0x2003, 0x0279, + 0x2010, 0x000e, + 0x2011, 0x000e, + 0x2012, 0x0072, + 0x2013, 0x0072, + 0x2014, 0x008a, + 0x2015, 0x0295, + 0x2016, 0x029a, + 0x2018, 0x029e, + 0x201a, 0x0078, + 0x201c, 0x02a0, + 0x201e, 0x0079, + 0x2020, 0x0308, + 0x2022, 0x0077, + 0x2025, 0x029d, + 0x2026, 0x029c, + 0x2030, 0x0304, + 0x2032, 0x02c4, + 0x2039, 0x006e, + 0x203b, 0x02de, + 0x203e, 0x0145, + 0x2044, 0x0068, + 0x20dd, 0x030b, + 0x2103, 0x02c6, + 0x2109, 0x2071, + 0x2113, 0x1f59, + 0x2116, 0x1dba, + 0x2121, 0x1f77, + 0x2122, 0x00e4, + 0x212b, 0x0303, + 0x2160, 0x1d97, + 0x216a, 0x2021, + 0x2170, 0x1f9c, + 0x217a, 0x206a, + 0x217f, 0x206f, + 0x2190, 0x02e1, + 0x2192, 0x02e0, + 0x2193, 0x02e3, + 0x21c4, 0x2076, + 0x21c6, 0x2075, + 0x21d2, 0x02f0, + 0x21d4, 0x02f1, + 0x21e6, 0x1f4d, + 0x21e7, 0x1f4c, + 0x21e8, 0x1f4e, + 0x21e9, 0x1f4b, + 0x2200, 0x02f2, + 0x2202, 0x02f7, + 0x2203, 0x02f3, + 0x2207, 0x02f8, + 0x2208, 0x02e5, + 0x220b, 0x02e6, + 0x2211, 0x1dc9, + 0x2212, 0x02b5, + 0x221a, 0x02fd, + 0x221d, 0x02ff, + 0x221e, 0x02bf, + 0x221f, 0x1dcd, + 0x2220, 0x02f4, + 0x2225, 0x029a, + 0x2227, 0x02ed, + 0x2229, 0x02ec, + 0x222a, 0x02eb, + 0x222b, 0x0301, + 0x222d, 0x2003, + 0x222e, 0x1dc8, + 0x2234, 0x02c0, + 0x2235, 0x0300, + 0x223c, 0x0299, + 0x223d, 0x02fe, + 0x2252, 0x02fa, + 0x2260, 0x02ba, + 0x2261, 0x02f9, + 0x2266, 0x02bd, + 0x226a, 0x02fb, + 0x2282, 0x02e9, + 0x2286, 0x02e7, + 0x22a5, 0x02f5, + 0x22bf, 0x1dce, + 0x22ee, 0x1ed9, + 0x22ef, 0x029c, + 0x2312, 0x02f6, + 0x2460, 0x1d83, + 0x2474, 0x1f87, + 0x2488, 0x1f7e, + 0x249c, 0x1fb0, + 0x24ea, 0x2020, + 0x2500, 0x1d37, + 0x2550, 0x203b, + 0x255e, 0x203c, + 0x2561, 0x203e, + 0x256a, 0x203d, + 0x256d, 0x2037, + 0x256f, 0x203a, + 0x2570, 0x2039, + 0x2571, 0x2045, + 0x2581, 0x2026, + 0x2589, 0x2034, + 0x258a, 0x2033, + 0x258b, 0x2032, + 0x258c, 0x2031, + 0x258d, 0x2030, + 0x258e, 0x202f, + 0x258f, 0x202e, + 0x2594, 0x2035, + 0x25a0, 0x02d9, + 0x25a1, 0x02d8, + 0x25a2, 0x1f4f, + 0x25b2, 0x02db, + 0x25b3, 0x02da, + 0x25b7, 0x1f4a, + 0x25bc, 0x02dd, + 0x25bd, 0x02dc, + 0x25c1, 0x1f49, + 0x25c6, 0x02d7, + 0x25c7, 0x02d6, + 0x25c9, 0x2012, + 0x25cb, 0x02d3, + 0x25ce, 0x02d5, + 0x25cf, 0x02d4, + 0x25e2, 0x203f, + 0x25e4, 0x2042, + 0x25e5, 0x2041, + 0x25ef, 0x030b, + 0x2600, 0x2017, + 0x2605, 0x02d2, + 0x2606, 0x02d1, + 0x260e, 0x1f78, + 0x261c, 0x201c, + 0x261e, 0x201b, + 0x261f, 0x201e, + 0x2640, 0x02c2, + 0x2642, 0x02c1, + 0x2660, 0x2013, + 0x2661, 0x1f51, + 0x2662, 0x1f53, + 0x2663, 0x2015, + 0x2664, 0x1f52, + 0x2665, 0x2014, + 0x2666, 0x2016, + 0x2667, 0x1f50, + 0x266a, 0x0307, + 0x266d, 0x0306, + 0x266f, 0x0305, + 0x2776, 0x205e, + 0x27a1, 0x200e, + 0x3000, 0x0279, + 0x3003, 0x028f, + 0x3004, 0x2074, + 0x3005, 0x0291, + 0x3008, 0x02aa, + 0x3012, 0x02df, + 0x3013, 0x02e4, + 0x3014, 0x02a4, + 0x301c, 0x0299, + 0x301d, 0x1db8, + 0x301f, 0x1db9, + 0x3020, 0x1f7a, + 0x3036, 0x1f79, + 0x3041, 0x034a, + 0x3094, 0x1f16, + 0x309b, 0x0283, + 0x309d, 0x028d, + 0x30a1, 0x039d, + 0x30f7, 0x2079, + 0x30fb, 0x027e, + 0x30fc, 0x0294, + 0x30fd, 0x028b, + 0x322a, 0x2006, + 0x3230, 0x2005, + 0x3231, 0x1dc2, + 0x3233, 0x1fcf, + 0x3234, 0x1fcd, + 0x3235, 0x1fd4, + 0x3236, 0x1fd3, + 0x3237, 0x200c, + 0x3238, 0x1fce, + 0x3239, 0x1dc4, + 0x323a, 0x1fd7, + 0x323b, 0x1fd5, + 0x323c, 0x1fd0, + 0x323d, 0x1fcb, + 0x323e, 0x1fd2, + 0x323f, 0x1fcc, + 0x3240, 0x1fd6, + 0x3241, 0x200d, + 0x3242, 0x1fd1, + 0x3243, 0x1fca, + 0x3291, 0x1fe1, + 0x3292, 0x1fe0, + 0x3293, 0x1fe2, + 0x3294, 0x1fdc, + 0x3296, 0x1fe5, + 0x3298, 0x1fde, + 0x3299, 0x201f, + 0x329d, 0x207f, + 0x329e, 0x1fff, + 0x32a4, 0x1dbd, + 0x32a9, 0x1fda, + 0x32aa, 0x1fdd, + 0x32ab, 0x1fdf, + 0x32ac, 0x1fe3, + 0x32ad, 0x1fd9, + 0x32ae, 0x1fe4, + 0x32af, 0x1fdb, + 0x32b0, 0x1fd8, + 0x3300, 0x1f70, + 0x3303, 0x1f6a, + 0x3305, 0x1ff7, + 0x330d, 0x1dab, + 0x3314, 0x1da2, + 0x3315, 0x1f69, + 0x3316, 0x1f67, + 0x3318, 0x1f68, + 0x331e, 0x1f73, + 0x3322, 0x1f66, + 0x3323, 0x1f6b, + 0x3326, 0x1dac, + 0x3327, 0x1da6, + 0x332a, 0x1f74, + 0x332b, 0x1dae, + 0x3331, 0x1f71, + 0x3333, 0x2087, + 0x3336, 0x1da8, + 0x3339, 0x1f6e, + 0x333b, 0x1f6f, + 0x3342, 0x1f6d, + 0x3347, 0x1f72, + 0x3349, 0x1da1, + 0x334a, 0x1daf, + 0x334d, 0x1da4, + 0x334e, 0x2088, + 0x3351, 0x1da9, + 0x3357, 0x1f6c, + 0x337b, 0x2083, + 0x337c, 0x1dc7, + 0x337d, 0x1dc6, + 0x337e, 0x1dc5, + 0x337f, 0x1f76, + 0x3385, 0x1f5f, + 0x3388, 0x2000, + 0x338e, 0x1db4, + 0x3390, 0x1f63, + 0x3396, 0x1f65, + 0x3397, 0x1f58, + 0x3398, 0x1f5a, + 0x339c, 0x1db1, + 0x339f, 0x1ffa, + 0x33a0, 0x1f54, + 0x33a1, 0x1db7, + 0x33a2, 0x1f55, + 0x33a3, 0x1ffb, + 0x33a4, 0x1f56, + 0x33a6, 0x1ffc, + 0x33b0, 0x1f5e, + 0x33b1, 0x1f5d, + 0x33b2, 0x1f5c, + 0x33b3, 0x1f5b, + 0x33c4, 0x1db6, + 0x33c8, 0x2002, + 0x33cb, 0x1f62, + 0x33cc, 0x1ff6, + 0x33cd, 0x1dbb, + 0x33d4, 0x1f64, + 0x4e00, 0x04b0, + 0x4e01, 0x0bb8, + 0x4e03, 0x08e3, + 0x4e07, 0x0eaa, + 0x4e08, 0x09ce, + 0x4e09, 0x087e, + 0x4e0a, 0x09cd, + 0x4e0b, 0x053c, + 0x4e0d, 0x0dc6, + 0x4e0e, 0x0f29, + 0x4e10, 0x0ffb, + 0x4e11, 0x04d1, + 0x4e14, 0x05cc, + 0x4e15, 0x0ffc, + 0x4e16, 0x0a48, + 0x4e17, 0x10d7, + 0x4e18, 0x0670, + 0x4e19, 0x0e0a, + 0x4e1e, 0x09cf, + 0x4e21, 0x0f86, + 0x4e26, 0x0e12, + 0x4e28, 0x20b3, + 0x4e2a, 0x0ffd, + 0x4e2d, 0x0ba4, + 0x4e31, 0x0ffe, + 0x4e32, 0x06f2, + 0x4e36, 0x0fff, + 0x4e38, 0x0619, + 0x4e39, 0x0b6e, + 0x4e3b, 0x0913, + 0x4e3c, 0x1000, + 0x4e3f, 0x1001, + 0x4e42, 0x1002, + 0x4e43, 0x0ceb, + 0x4e45, 0x0671, + 0x4e4b, 0x0ced, + 0x4e4d, 0x0cbb, + 0x4e4e, 0x0777, + 0x4e4f, 0x0e61, + 0x4e55, 0x1950, + 0x4e56, 0x1003, + 0x4e57, 0x09d0, + 0x4e58, 0x1004, + 0x4e59, 0x0535, + 0x4e5d, 0x06dd, + 0x4e5e, 0x07a4, + 0x4e5f, 0x0ef5, + 0x4e62, 0x1233, + 0x4e71, 0x0f5a, + 0x4e73, 0x0cd5, + 0x4e7e, 0x05e1, + 0x4e80, 0x064f, + 0x4e82, 0x1005, + 0x4e85, 0x1006, + 0x4e86, 0x0f83, + 0x4e88, 0x0f27, + 0x4e89, 0x0aea, + 0x4e8a, 0x1008, + 0x4e8b, 0x08c4, + 0x4e8c, 0x0ccb, + 0x4e8e, 0x100b, + 0x4e91, 0x04e0, + 0x4e92, 0x0793, + 0x4e94, 0x0792, + 0x4e95, 0x04aa, + 0x4e98, 0x0ff1, + 0x4e99, 0x0ff0, + 0x4e9b, 0x0823, + 0x4e9c, 0x0465, + 0x4e9e, 0x100c, + 0x4ea1, 0x0e62, + 0x4ea2, 0x100f, + 0x4ea4, 0x07a6, + 0x4ea5, 0x04ab, + 0x4ea6, 0x0ea0, + 0x4ea8, 0x0696, + 0x4eab, 0x0697, + 0x4ead, 0x0bfe, + 0x4eae, 0x0f84, + 0x4eb0, 0x1010, + 0x4eb3, 0x1011, + 0x4eb6, 0x1012, + 0x4eba, 0x0a13, + 0x4ec0, 0x0944, + 0x4ec1, 0x0a14, + 0x4ec2, 0x1017, + 0x4ec4, 0x1015, + 0x4ec6, 0x1016, + 0x4ec7, 0x0672, + 0x4eca, 0x0813, + 0x4ecb, 0x0570, + 0x4ecd, 0x1014, + 0x4ece, 0x1013, + 0x4ecf, 0x0df9, + 0x4ed4, 0x0894, + 0x4ed5, 0x0893, + 0x4ed6, 0x0b1e, + 0x4ed7, 0x1018, + 0x4ed8, 0x0dc7, + 0x4ed9, 0x0a8b, + 0x4edd, 0x0290, + 0x4ede, 0x1019, + 0x4edf, 0x101b, + 0x4ee1, 0x20b4, + 0x4ee3, 0x0b45, + 0x4ee4, 0x0fa9, + 0x4ee5, 0x048e, + 0x4eed, 0x101a, + 0x4eee, 0x053e, + 0x4ef0, 0x06bc, + 0x4ef2, 0x0ba5, + 0x4ef6, 0x0745, + 0x4ef7, 0x101c, + 0x4efb, 0x0cda, + 0x4efc, 0x20b5, + 0x4f00, 0x20b6, + 0x4f01, 0x0627, + 0x4f03, 0x20b7, + 0x4f09, 0x101d, + 0x4f0a, 0x048f, + 0x4f0d, 0x0794, + 0x4f0e, 0x0628, + 0x4f0f, 0x0dec, + 0x4f10, 0x0d46, + 0x4f11, 0x0673, + 0x4f1a, 0x0571, + 0x4f1c, 0x1040, + 0x4f1d, 0x0c3b, + 0x4f2f, 0x0d22, + 0x4f30, 0x101f, + 0x4f34, 0x0d50, + 0x4f36, 0x0faa, + 0x4f38, 0x09f3, + 0x4f39, 0x20b8, + 0x4f3a, 0x0895, + 0x4f3c, 0x08c5, + 0x4f3d, 0x0540, + 0x4f43, 0x0bed, + 0x4f46, 0x0b60, + 0x4f47, 0x1023, + 0x4f4d, 0x0490, + 0x4f4e, 0x0bff, + 0x4f4f, 0x0945, + 0x4f50, 0x0824, + 0x4f51, 0x0f0e, + 0x4f53, 0x0b2e, + 0x4f55, 0x053f, + 0x4f56, 0x20b9, + 0x4f57, 0x1022, + 0x4f59, 0x0f28, + 0x4f5a, 0x101e, + 0x4f5b, 0x1020, + 0x4f5c, 0x085e, + 0x4f5d, 0x1021, + 0x4f5e, 0x11d3, + 0x4f69, 0x1029, + 0x4f6f, 0x102c, + 0x4f70, 0x102a, + 0x4f73, 0x0542, + 0x4f75, 0x0e0b, + 0x4f76, 0x1024, + 0x4f7b, 0x1028, + 0x4f7c, 0x07a7, + 0x4f7f, 0x0896, + 0x4f83, 0x05e2, + 0x4f86, 0x102d, + 0x4f88, 0x1025, + 0x4f8a, 0x20bb, + 0x4f8b, 0x0fab, + 0x4f8d, 0x08c6, + 0x4f8f, 0x1026, + 0x4f91, 0x102b, + 0x4f92, 0x20ba, + 0x4f94, 0x20bd, + 0x4f96, 0x102e, + 0x4f98, 0x1027, + 0x4f9a, 0x20bc, + 0x4f9b, 0x0699, + 0x4f9d, 0x0491, + 0x4fa0, 0x069a, + 0x4fa1, 0x0541, + 0x4fab, 0x11d4, + 0x4fad, 0x0ea7, + 0x4fae, 0x0de0, + 0x4faf, 0x07a8, + 0x4fb5, 0x09f5, + 0x4fb6, 0x0f7f, + 0x4fbf, 0x0e28, + 0x4fc2, 0x070e, + 0x4fc3, 0x0b05, + 0x4fc4, 0x0564, + 0x4fc9, 0x20ac, + 0x4fca, 0x095d, + 0x4fcd, 0x20be, + 0x4fce, 0x1032, + 0x4fd0, 0x1037, + 0x4fd1, 0x1035, + 0x4fd4, 0x1030, + 0x4fd7, 0x0b0f, + 0x4fd8, 0x1033, + 0x4fda, 0x1036, + 0x4fdb, 0x1034, + 0x4fdd, 0x0e2d, + 0x4fdf, 0x1031, + 0x4fe0, 0x1dec, + 0x4fe1, 0x09f4, + 0x4fe3, 0x0ea1, + 0x4fe4, 0x1038, + 0x4fee, 0x092e, + 0x4fef, 0x1046, + 0x4ff3, 0x0d06, + 0x4ff5, 0x0da8, + 0x4ff6, 0x1041, + 0x4ff8, 0x0e40, + 0x4ffa, 0x0536, + 0x4ffe, 0x1045, + 0x4fff, 0x20c1, + 0x5005, 0x103f, + 0x5006, 0x1048, + 0x5009, 0x0ad4, + 0x500b, 0x0778, + 0x500d, 0x0d12, + 0x500f, 0x1600, + 0x5011, 0x1047, + 0x5012, 0x0c57, + 0x5014, 0x103c, + 0x5016, 0x07aa, + 0x5019, 0x07a9, + 0x501a, 0x103a, + 0x501e, 0x20c2, + 0x501f, 0x0906, + 0x5021, 0x1042, + 0x5022, 0x20c0, + 0x5023, 0x0e3f, + 0x5024, 0x0b8b, + 0x5025, 0x103e, + 0x5026, 0x0747, + 0x5028, 0x103b, + 0x5029, 0x1043, + 0x502a, 0x103d, + 0x502b, 0x0f99, + 0x502c, 0x1044, + 0x502d, 0x0fe7, + 0x5036, 0x06de, + 0x5039, 0x0746, + 0x5040, 0x20bf, + 0x5042, 0x20c5, + 0x5043, 0x1049, + 0x5046, 0x20c3, + 0x5047, 0x104a, + 0x5048, 0x104e, + 0x5049, 0x0492, + 0x504f, 0x0e20, + 0x5050, 0x104d, + 0x5055, 0x104c, + 0x5056, 0x1050, + 0x505a, 0x104f, + 0x505c, 0x0c00, + 0x5065, 0x0748, + 0x506c, 0x1051, + 0x5070, 0x20c4, + 0x5072, 0x08f1, + 0x5074, 0x0b06, + 0x5075, 0x0c01, + 0x5076, 0x06ee, + 0x5078, 0x1052, + 0x507d, 0x0650, + 0x5080, 0x1053, + 0x5085, 0x1055, + 0x508d, 0x0e63, + 0x5091, 0x073c, + 0x5094, 0x20c6, + 0x5098, 0x087f, + 0x5099, 0x0d8b, + 0x509a, 0x1054, + 0x50ac, 0x0835, + 0x50ad, 0x0f2d, + 0x50b2, 0x1057, + 0x50b3, 0x105a, + 0x50b4, 0x1056, + 0x50b5, 0x0834, + 0x50b7, 0x0987, + 0x50be, 0x070f, + 0x50c2, 0x105b, + 0x50c5, 0x06c7, + 0x50c9, 0x1058, + 0x50cd, 0x0c87, + 0x50cf, 0x0afe, + 0x50d1, 0x069b, + 0x50d5, 0x0e7b, + 0x50d6, 0x105c, + 0x50d8, 0x20c8, + 0x50da, 0x0f85, + 0x50de, 0x105d, + 0x50e3, 0x1060, + 0x50e5, 0x105e, + 0x50e7, 0x0ad0, + 0x50ed, 0x105f, + 0x50ee, 0x1061, + 0x50f4, 0x20c7, + 0x50f5, 0x1063, + 0x50f9, 0x1062, + 0x50fb, 0x0e18, + 0x5100, 0x0651, + 0x5101, 0x1065, + 0x5104, 0x052f, + 0x5109, 0x1064, + 0x5112, 0x0920, + 0x5114, 0x1069, + 0x5115, 0x1068, + 0x5116, 0x1067, + 0x5118, 0x102f, + 0x511a, 0x106a, + 0x511f, 0x0988, + 0x5121, 0x106b, + 0x512a, 0x0f0f, + 0x5132, 0x0ee5, + 0x5137, 0x106d, + 0x513a, 0x106c, + 0x513b, 0x106f, + 0x513c, 0x106e, + 0x513f, 0x1070, + 0x5141, 0x04b8, + 0x5143, 0x0769, + 0x5144, 0x0711, + 0x5145, 0x0946, + 0x5146, 0x0bb9, + 0x5147, 0x069c, + 0x5148, 0x0a8c, + 0x5149, 0x07ab, + 0x514a, 0x20c9, + 0x514b, 0x0800, + 0x514c, 0x1073, + 0x514d, 0x0ed4, + 0x514e, 0x0c40, + 0x5150, 0x08c7, + 0x5152, 0x1072, + 0x5154, 0x1074, + 0x515a, 0x0c58, + 0x515c, 0x05d3, + 0x5162, 0x1075, + 0x5164, 0x20ca, + 0x5165, 0x0cd6, + 0x5168, 0x0ab6, + 0x5169, 0x1077, + 0x516b, 0x0d40, + 0x516c, 0x07ac, + 0x516d, 0x0fe1, + 0x516e, 0x1079, + 0x5171, 0x069e, + 0x5175, 0x0e0c, + 0x5176, 0x0b16, + 0x5177, 0x06e9, + 0x5178, 0x0c2f, + 0x517c, 0x0749, + 0x5180, 0x107a, + 0x5182, 0x107b, + 0x5185, 0x0cba, + 0x5186, 0x0501, + 0x5189, 0x107e, + 0x518a, 0x086d, + 0x518c, 0x107d, + 0x518d, 0x0836, + 0x518f, 0x107f, + 0x5190, 0x185b, + 0x5191, 0x1080, + 0x5192, 0x0e6f, + 0x5193, 0x1081, + 0x5195, 0x1082, + 0x5197, 0x09d1, + 0x5199, 0x08f8, + 0x519d, 0x20cb, + 0x51a0, 0x05e3, + 0x51a2, 0x1086, + 0x51a4, 0x1084, + 0x51a5, 0x0ec9, + 0x51a6, 0x1085, + 0x51a8, 0x0dcc, + 0x51a9, 0x1087, + 0x51ac, 0x0c59, + 0x51b0, 0x108d, + 0x51b1, 0x108b, + 0x51b3, 0x108a, + 0x51b4, 0x0853, + 0x51b5, 0x108e, + 0x51b6, 0x0ef6, + 0x51b7, 0x0fac, + 0x51bd, 0x108f, + 0x51be, 0x20cc, + 0x51c4, 0x0a4c, + 0x51c5, 0x1090, + 0x51c6, 0x0964, + 0x51c9, 0x1091, + 0x51cb, 0x0bba, + 0x51cc, 0x0f87, + 0x51cd, 0x0c5a, + 0x51d6, 0x10da, + 0x51db, 0x1092, + 0x51dc, 0x205c, + 0x51dd, 0x06bd, + 0x51e0, 0x1093, + 0x51e1, 0x0e8c, + 0x51e6, 0x0972, + 0x51e7, 0x0b5c, + 0x51e9, 0x1095, + 0x51ea, 0x0cbc, + 0x51ec, 0x20cd, + 0x51ed, 0x1096, + 0x51f0, 0x1097, + 0x51f1, 0x058c, + 0x51f5, 0x1098, + 0x51f6, 0x069f, + 0x51f8, 0x0ca4, + 0x51f9, 0x051c, + 0x51fa, 0x095a, + 0x51fd, 0x0d35, + 0x51fe, 0x1099, + 0x5200, 0x0c5b, + 0x5203, 0x0a15, + 0x5204, 0x109a, + 0x5206, 0x0dfc, + 0x5207, 0x0a7e, + 0x5208, 0x05de, + 0x520a, 0x05e5, + 0x520b, 0x109b, + 0x520e, 0x109d, + 0x5211, 0x0710, + 0x5214, 0x109c, + 0x5215, 0x20ce, + 0x5217, 0x0fbb, + 0x521d, 0x0973, + 0x5224, 0x0d51, + 0x5225, 0x0e1c, + 0x5227, 0x109e, + 0x5229, 0x0f62, + 0x522a, 0x109f, + 0x522e, 0x10a0, + 0x5230, 0x0c78, + 0x5233, 0x10a1, + 0x5236, 0x0a4d, + 0x5237, 0x086e, + 0x5238, 0x074a, + 0x5239, 0x10a2, + 0x523a, 0x0897, + 0x523b, 0x0801, + 0x5243, 0x0c02, + 0x5244, 0x10a4, + 0x5247, 0x0b07, + 0x524a, 0x085f, + 0x524b, 0x10a5, + 0x524d, 0x0ab2, + 0x524f, 0x10a3, + 0x5254, 0x10a8, + 0x5256, 0x0e64, + 0x525b, 0x07f6, + 0x525d, 0x1e5e, + 0x525e, 0x10a7, + 0x5263, 0x074b, + 0x5264, 0x084e, + 0x5265, 0x0d23, + 0x5269, 0x10ab, + 0x526a, 0x10a9, + 0x526f, 0x0ded, + 0x5270, 0x09d2, + 0x5271, 0x10b2, + 0x5272, 0x05c2, + 0x5273, 0x10ac, + 0x5274, 0x10aa, + 0x5275, 0x0ad1, + 0x527d, 0x10ae, + 0x527f, 0x10ad, + 0x5283, 0x05a2, + 0x5287, 0x0736, + 0x5288, 0x10b3, + 0x5289, 0x0f75, + 0x528d, 0x10af, + 0x5291, 0x10b4, + 0x5292, 0x10b1, + 0x5294, 0x10b0, + 0x529b, 0x0f97, + 0x529c, 0x20cf, + 0x529f, 0x07ad, + 0x52a0, 0x0543, + 0x52a3, 0x0fbc, + 0x52a6, 0x20d0, + 0x52a9, 0x097f, + 0x52aa, 0x0c52, + 0x52ab, 0x07f7, + 0x52ac, 0x10b7, + 0x52af, 0x217d, + 0x52b1, 0x0fad, + 0x52b4, 0x0fd1, + 0x52b5, 0x10ba, + 0x52b9, 0x07ae, + 0x52bc, 0x10b9, + 0x52be, 0x058d, + 0x52c0, 0x20d1, + 0x52c1, 0x10bb, + 0x52c3, 0x0e84, + 0x52c5, 0x0bd8, + 0x52c7, 0x0f10, + 0x52c9, 0x0e29, + 0x52cd, 0x10bc, + 0x52d2, 0x1bee, + 0x52d5, 0x0c88, + 0x52d7, 0x10bd, + 0x52d8, 0x05e6, + 0x52d9, 0x0ebf, + 0x52db, 0x20d2, + 0x52dd, 0x0989, + 0x52de, 0x10be, + 0x52df, 0x0e37, + 0x52e0, 0x10c2, + 0x52e2, 0x0a4e, + 0x52e3, 0x10bf, + 0x52e4, 0x06c8, + 0x52e6, 0x10c0, + 0x52e7, 0x05e7, + 0x52f2, 0x0704, + 0x52f3, 0x10c3, + 0x52f5, 0x10c4, + 0x52f8, 0x10c5, + 0x52fa, 0x0907, + 0x52fe, 0x07af, + 0x52ff, 0x0eea, + 0x5300, 0x20d3, + 0x5301, 0x0ef4, + 0x5302, 0x0ccf, + 0x5305, 0x0e41, + 0x5306, 0x10c7, + 0x5307, 0x20d4, + 0x5308, 0x10c8, + 0x530d, 0x10ca, + 0x530f, 0x10cc, + 0x5310, 0x10cb, + 0x5315, 0x10cd, + 0x5316, 0x053d, + 0x5317, 0x0e7a, + 0x5319, 0x086c, + 0x531a, 0x10ce, + 0x531d, 0x0adb, + 0x5320, 0x098a, + 0x5321, 0x06a1, + 0x5323, 0x10cf, + 0x5324, 0x20d5, + 0x532a, 0x0d6f, + 0x532f, 0x10d0, + 0x5331, 0x10d1, + 0x5333, 0x10d2, + 0x5338, 0x10d3, + 0x5339, 0x0d96, + 0x533a, 0x06e0, + 0x533b, 0x04a9, + 0x533f, 0x0c97, + 0x5340, 0x10d4, + 0x5341, 0x0947, + 0x5343, 0x0a8d, + 0x5345, 0x10d6, + 0x5346, 0x10d5, + 0x5347, 0x098b, + 0x5348, 0x0795, + 0x5349, 0x10d8, + 0x534a, 0x0d52, + 0x534d, 0x10d9, + 0x5351, 0x0d70, + 0x5352, 0x0b14, + 0x5353, 0x0b4e, + 0x5354, 0x06a0, + 0x5357, 0x0cc6, + 0x5358, 0x0b6f, + 0x535a, 0x0d24, + 0x535c, 0x0e7c, + 0x535e, 0x10db, + 0x5360, 0x0a8e, + 0x5366, 0x070b, + 0x5369, 0x10dc, + 0x536e, 0x10dd, + 0x536f, 0x04ce, + 0x5370, 0x04b9, + 0x5371, 0x0629, + 0x5372, 0x20d6, + 0x5373, 0x0b08, + 0x5374, 0x066b, + 0x5375, 0x0f5b, + 0x5377, 0x10e0, + 0x5378, 0x0537, + 0x537b, 0x10df, + 0x537f, 0x06a2, + 0x5382, 0x10e1, + 0x5384, 0x0efd, + 0x5393, 0x20d7, + 0x5396, 0x10e2, + 0x5398, 0x0f9a, + 0x539a, 0x07b0, + 0x539f, 0x076a, + 0x53a0, 0x10e3, + 0x53a5, 0x10e5, + 0x53a6, 0x10e4, + 0x53a8, 0x0a25, + 0x53a9, 0x04db, + 0x53ad, 0x0500, + 0x53ae, 0x10e6, + 0x53b0, 0x10e7, + 0x53b2, 0x20d8, + 0x53b3, 0x076b, + 0x53b6, 0x10e8, + 0x53bb, 0x0688, + 0x53c2, 0x0880, + 0x53c3, 0x10e9, + 0x53c8, 0x0ea2, + 0x53c9, 0x0825, + 0x53ca, 0x0674, + 0x53cb, 0x0f11, + 0x53cc, 0x0ad2, + 0x53cd, 0x0d53, + 0x53ce, 0x0929, + 0x53d4, 0x0951, + 0x53d6, 0x0914, + 0x53d7, 0x0921, + 0x53d9, 0x0980, + 0x53db, 0x0d54, + 0x53dd, 0x20d9, + 0x53df, 0x10ec, + 0x53e1, 0x04e5, + 0x53e2, 0x0ad3, + 0x53e3, 0x07b1, + 0x53e4, 0x0779, + 0x53e5, 0x06df, + 0x53e8, 0x10f0, + 0x53e9, 0x0b5f, + 0x53ea, 0x0b5e, + 0x53eb, 0x06a3, + 0x53ec, 0x098c, + 0x53ed, 0x10f1, + 0x53ee, 0x10ef, + 0x53ef, 0x0544, + 0x53f0, 0x0b46, + 0x53f1, 0x08e4, + 0x53f2, 0x0899, + 0x53f3, 0x04c8, + 0x53f6, 0x05ce, + 0x53f7, 0x07f8, + 0x53f8, 0x0898, + 0x53fa, 0x10f2, + 0x5401, 0x10f3, + 0x5403, 0x0663, + 0x5404, 0x05a4, + 0x5408, 0x07f9, + 0x5409, 0x0662, + 0x540a, 0x0bfb, + 0x540b, 0x04c7, + 0x540c, 0x0c89, + 0x540d, 0x0eca, + 0x540e, 0x07b3, + 0x540f, 0x0f63, + 0x5410, 0x0c41, + 0x5411, 0x07b2, + 0x541b, 0x0705, + 0x541d, 0x10fc, + 0x541f, 0x06db, + 0x5420, 0x0e78, + 0x5426, 0x0d71, + 0x5429, 0x10fb, + 0x542b, 0x061a, + 0x542c, 0x10f6, + 0x542e, 0x10f9, + 0x5436, 0x10fa, + 0x5438, 0x0675, + 0x5439, 0x0a27, + 0x543b, 0x0dfd, + 0x543c, 0x10f8, + 0x543d, 0x10f4, + 0x543e, 0x0797, + 0x5440, 0x10f5, + 0x5442, 0x0fca, + 0x5446, 0x0e42, + 0x5448, 0x0c04, + 0x5449, 0x0796, + 0x544a, 0x0802, + 0x544e, 0x10fd, + 0x5451, 0x0cb5, + 0x545f, 0x1101, + 0x5468, 0x092a, + 0x546a, 0x0922, + 0x5470, 0x1104, + 0x5471, 0x1102, + 0x5473, 0x0eaf, + 0x5475, 0x10ff, + 0x5476, 0x1108, + 0x5477, 0x1103, + 0x547b, 0x1106, + 0x547c, 0x077a, + 0x547d, 0x0ecb, + 0x5480, 0x1107, + 0x5484, 0x1109, + 0x5486, 0x110b, + 0x548a, 0x20dc, + 0x548b, 0x0860, + 0x548c, 0x0fe8, + 0x548e, 0x1100, + 0x548f, 0x10fe, + 0x5490, 0x110a, + 0x5492, 0x1105, + 0x549c, 0x20db, + 0x54a2, 0x110d, + 0x54a4, 0x1116, + 0x54a5, 0x110f, + 0x54a8, 0x1113, + 0x54a9, 0x20dd, + 0x54ab, 0x1114, + 0x54ac, 0x1110, + 0x54af, 0x1131, + 0x54b2, 0x0859, + 0x54b3, 0x058f, + 0x54b8, 0x110e, + 0x54bc, 0x1118, + 0x54bd, 0x04ba, + 0x54be, 0x1117, + 0x54c0, 0x0469, + 0x54c1, 0x0dbc, + 0x54c2, 0x1115, + 0x54c4, 0x1111, + 0x54c7, 0x110c, + 0x54c8, 0x1112, + 0x54c9, 0x0838, + 0x54d8, 0x1119, + 0x54e1, 0x04bb, + 0x54e2, 0x1122, + 0x54e5, 0x111a, + 0x54e8, 0x098d, + 0x54e9, 0x0e97, + 0x54ed, 0x1120, + 0x54ee, 0x111f, + 0x54f2, 0x0c29, + 0x54fa, 0x1121, + 0x54fd, 0x111e, + 0x54ff, 0x20de, + 0x5504, 0x04d6, + 0x5506, 0x0826, + 0x5507, 0x09f6, + 0x550f, 0x111c, + 0x5510, 0x0c5c, + 0x5514, 0x111d, + 0x5516, 0x0466, + 0x552e, 0x1127, + 0x552f, 0x0f0d, + 0x5531, 0x098f, + 0x5533, 0x112d, + 0x5538, 0x112c, + 0x5539, 0x1123, + 0x553e, 0x0b23, + 0x5540, 0x1124, + 0x5544, 0x0b4f, + 0x5545, 0x1129, + 0x5546, 0x098e, + 0x554c, 0x1126, + 0x554f, 0x0ef0, + 0x5553, 0x0712, + 0x5556, 0x112a, + 0x555c, 0x1128, + 0x555d, 0x112e, + 0x555e, 0x1dd1, + 0x5563, 0x1125, + 0x557b, 0x1134, + 0x557c, 0x1139, + 0x557e, 0x1135, + 0x5580, 0x1130, + 0x5583, 0x113a, + 0x5584, 0x0ab3, + 0x5586, 0x20df, + 0x5587, 0x113c, + 0x5589, 0x07b4, + 0x558a, 0x1132, + 0x558b, 0x0bbb, + 0x5598, 0x1136, + 0x5599, 0x112f, + 0x559a, 0x05e9, + 0x559c, 0x062a, + 0x559d, 0x05c3, + 0x559e, 0x1137, + 0x559f, 0x1133, + 0x55a7, 0x074c, + 0x55a8, 0x113d, + 0x55a9, 0x113b, + 0x55aa, 0x0ad5, + 0x55ab, 0x0664, + 0x55ac, 0x06a4, + 0x55ae, 0x1138, + 0x55b0, 0x06ec, + 0x55b6, 0x04e6, + 0x55c4, 0x1141, + 0x55c5, 0x113f, + 0x55c7, 0x1178, + 0x55d4, 0x1144, + 0x55da, 0x113e, + 0x55dc, 0x1142, + 0x55df, 0x1140, + 0x55e3, 0x089a, + 0x55e4, 0x1143, + 0x55f7, 0x1146, + 0x55f9, 0x114b, + 0x55fd, 0x1149, + 0x55fe, 0x1148, + 0x5606, 0x0b70, + 0x5609, 0x0545, + 0x5614, 0x1145, + 0x5616, 0x1147, + 0x5617, 0x0990, + 0x5618, 0x04d5, + 0x561b, 0x114a, + 0x5629, 0x055e, + 0x562f, 0x1155, + 0x5631, 0x09e4, + 0x5632, 0x1151, + 0x5634, 0x114f, + 0x5636, 0x1150, + 0x5638, 0x1152, + 0x5642, 0x04df, + 0x564c, 0x0abb, + 0x564e, 0x114c, + 0x5650, 0x114d, + 0x5653, 0x1f1b, + 0x565b, 0x05d8, + 0x5664, 0x1154, + 0x5668, 0x062b, + 0x566a, 0x1157, + 0x566b, 0x1153, + 0x566c, 0x1156, + 0x5674, 0x0dfe, + 0x5678, 0x0cad, + 0x567a, 0x0d4c, + 0x5680, 0x1159, + 0x5686, 0x1158, + 0x5687, 0x05a3, + 0x568a, 0x115a, + 0x568f, 0x115d, + 0x5694, 0x115c, + 0x5699, 0x1de6, + 0x56a0, 0x115b, + 0x56a2, 0x0cef, + 0x56a5, 0x115e, + 0x56ae, 0x115f, + 0x56b4, 0x1161, + 0x56b6, 0x1160, + 0x56bc, 0x1163, + 0x56c0, 0x1166, + 0x56c1, 0x1164, + 0x56c2, 0x1162, + 0x56c3, 0x1165, + 0x56c8, 0x1167, + 0x56ca, 0x1e5a, + 0x56ce, 0x1168, + 0x56d1, 0x1169, + 0x56d3, 0x116a, + 0x56d7, 0x116b, + 0x56d8, 0x107c, + 0x56da, 0x0928, + 0x56db, 0x089b, + 0x56de, 0x0573, + 0x56e0, 0x04bc, + 0x56e3, 0x0b82, + 0x56ee, 0x116c, + 0x56f0, 0x0814, + 0x56f2, 0x0493, + 0x56f3, 0x0a24, + 0x56f9, 0x116d, + 0x56fa, 0x077b, + 0x56fd, 0x0803, + 0x56ff, 0x116f, + 0x5700, 0x116e, + 0x5703, 0x0e30, + 0x5704, 0x1170, + 0x5708, 0x1172, + 0x5709, 0x1171, + 0x570b, 0x1173, + 0x570d, 0x1174, + 0x570f, 0x074d, + 0x5712, 0x0502, + 0x5713, 0x1175, + 0x5716, 0x1177, + 0x5718, 0x1176, + 0x571c, 0x1179, + 0x571f, 0x0c54, + 0x5726, 0x117a, + 0x5727, 0x0479, + 0x5728, 0x084f, + 0x572d, 0x0713, + 0x5730, 0x0b8d, + 0x5737, 0x117b, + 0x573b, 0x117e, + 0x5740, 0x117f, + 0x5742, 0x0854, + 0x5747, 0x06c9, + 0x574a, 0x0e65, + 0x574e, 0x117d, + 0x574f, 0x1180, + 0x5750, 0x0831, + 0x5751, 0x07b5, + 0x5759, 0x20e0, + 0x5761, 0x1184, + 0x5764, 0x0815, + 0x5765, 0x20e1, + 0x5766, 0x0b71, + 0x5769, 0x1181, + 0x576a, 0x0bf6, + 0x577f, 0x1185, + 0x5782, 0x0a28, + 0x5788, 0x1183, + 0x5789, 0x1186, + 0x578b, 0x0715, + 0x5793, 0x1187, + 0x57a0, 0x1188, + 0x57a2, 0x07b6, + 0x57a3, 0x059e, + 0x57a4, 0x118a, + 0x57aa, 0x118b, + 0x57ac, 0x20e2, + 0x57b0, 0x118c, + 0x57b3, 0x1189, + 0x57c0, 0x1182, + 0x57c3, 0x118d, + 0x57c6, 0x118e, + 0x57c7, 0x20e4, + 0x57c8, 0x20e3, + 0x57cb, 0x0e92, + 0x57ce, 0x09d3, + 0x57d2, 0x1190, + 0x57d4, 0x118f, + 0x57d6, 0x1193, + 0x57dc, 0x0cee, + 0x57df, 0x04ac, + 0x57e0, 0x0dc8, + 0x57e3, 0x1194, + 0x57f4, 0x09e5, + 0x57f7, 0x08e5, + 0x57f9, 0x0d13, + 0x57fa, 0x062c, + 0x57fc, 0x085b, + 0x5800, 0x0e87, + 0x5802, 0x0c8a, + 0x5805, 0x074e, + 0x5806, 0x0b2f, + 0x580a, 0x1192, + 0x580b, 0x1195, + 0x5815, 0x0b24, + 0x5819, 0x1196, + 0x581d, 0x1197, + 0x5821, 0x1199, + 0x5824, 0x0c05, + 0x582a, 0x05ea, + 0x582f, 0x1d32, + 0x5830, 0x0503, + 0x5831, 0x0e43, + 0x5834, 0x09d4, + 0x5835, 0x0c42, + 0x583a, 0x0856, + 0x583d, 0x119f, + 0x5840, 0x0e0d, + 0x5841, 0x0fa5, + 0x584a, 0x0574, + 0x584b, 0x119b, + 0x5851, 0x0abc, + 0x5852, 0x119e, + 0x5854, 0x0c5d, + 0x5857, 0x0c43, + 0x5858, 0x0c5e, + 0x5859, 0x0d4d, + 0x585a, 0x0be9, + 0x585e, 0x0839, + 0x5861, 0x1e47, + 0x5862, 0x119a, + 0x5869, 0x0518, + 0x586b, 0x0c30, + 0x5870, 0x119c, + 0x5872, 0x1198, + 0x5875, 0x0a16, + 0x5879, 0x11a0, + 0x587e, 0x0958, + 0x5883, 0x06a5, + 0x5885, 0x11a1, + 0x5893, 0x0e38, + 0x5897, 0x0aff, + 0x589c, 0x0be2, + 0x589e, 0x20e7, + 0x589f, 0x11a3, + 0x58a8, 0x0e7d, + 0x58ab, 0x11a4, + 0x58ae, 0x11a9, + 0x58b2, 0x20e8, + 0x58b3, 0x0dff, + 0x58b8, 0x11a8, + 0x58b9, 0x11a2, + 0x58ba, 0x11a5, + 0x58bb, 0x11a7, + 0x58be, 0x0816, + 0x58c1, 0x0e19, + 0x58c5, 0x11aa, + 0x58c7, 0x0b83, + 0x58ca, 0x0575, + 0x58cc, 0x09d5, + 0x58d1, 0x11ac, + 0x58d3, 0x11ab, + 0x58d5, 0x07fa, + 0x58d7, 0x11ad, + 0x58d8, 0x11af, + 0x58d9, 0x11ae, + 0x58dc, 0x11b1, + 0x58de, 0x11a6, + 0x58df, 0x11b3, + 0x58e4, 0x11b2, + 0x58e5, 0x11b0, + 0x58eb, 0x089c, + 0x58ec, 0x0a17, + 0x58ee, 0x0ad6, + 0x58ef, 0x11b4, + 0x58f0, 0x0a60, + 0x58f1, 0x04b1, + 0x58f2, 0x0d1a, + 0x58f7, 0x0bf7, + 0x58f9, 0x11b6, + 0x58fa, 0x11b5, + 0x58fb, 0x11b7, + 0x5902, 0x11ba, + 0x5909, 0x0e21, + 0x590a, 0x11bb, + 0x590b, 0x20e9, + 0x590f, 0x0546, + 0x5910, 0x11bc, + 0x5915, 0x0f26, + 0x5916, 0x058e, + 0x5918, 0x10de, + 0x5919, 0x0952, + 0x591a, 0x0b1f, + 0x591b, 0x11bd, + 0x591c, 0x0ef7, + 0x5922, 0x0ec0, + 0x5925, 0x11bf, + 0x5927, 0x0b47, + 0x5929, 0x0c31, + 0x592a, 0x0b20, + 0x592b, 0x0dc9, + 0x592c, 0x11c0, + 0x592e, 0x051d, + 0x5931, 0x08e6, + 0x5932, 0x11c2, + 0x5937, 0x0494, + 0x5938, 0x11c3, + 0x593e, 0x11c4, + 0x5944, 0x0504, + 0x5947, 0x062d, + 0x5948, 0x0cb8, + 0x5949, 0x0e44, + 0x594e, 0x11c8, + 0x594f, 0x0ad7, + 0x5950, 0x11c7, + 0x5951, 0x0716, + 0x5953, 0x20ea, + 0x5954, 0x0e89, + 0x5955, 0x11c6, + 0x5957, 0x0c5f, + 0x5958, 0x11ca, + 0x595a, 0x11c9, + 0x595b, 0x20eb, + 0x595d, 0x20ec, + 0x5960, 0x11cc, + 0x5962, 0x11cb, + 0x5963, 0x20ed, + 0x5965, 0x051e, + 0x5967, 0x11cd, + 0x5968, 0x0991, + 0x5969, 0x11cf, + 0x596a, 0x0b63, + 0x596c, 0x11ce, + 0x596e, 0x0e03, + 0x5973, 0x0981, + 0x5974, 0x0c55, + 0x5978, 0x11d0, + 0x597d, 0x07b7, + 0x5981, 0x11d1, + 0x5982, 0x0cd7, + 0x5983, 0x0d72, + 0x5984, 0x0edd, + 0x598a, 0x0cdb, + 0x598d, 0x11da, + 0x5993, 0x0652, + 0x5996, 0x0f2f, + 0x5999, 0x0ebb, + 0x599b, 0x1239, + 0x599d, 0x11d2, + 0x59a3, 0x11d5, + 0x59a4, 0x20ee, + 0x59a5, 0x0b25, + 0x59a8, 0x0e66, + 0x59ac, 0x0c44, + 0x59b2, 0x11d6, + 0x59b9, 0x0e93, + 0x59ba, 0x20ef, + 0x59bb, 0x083a, + 0x59be, 0x0992, + 0x59c6, 0x11d7, + 0x59c9, 0x089e, + 0x59cb, 0x089d, + 0x59d0, 0x047d, + 0x59d1, 0x077c, + 0x59d3, 0x0a4f, + 0x59d4, 0x0495, + 0x59d9, 0x11db, + 0x59dc, 0x11d9, + 0x59e5, 0x04da, + 0x59e6, 0x05eb, + 0x59e8, 0x11d8, + 0x59ea, 0x0ed1, + 0x59eb, 0x0da3, + 0x59f6, 0x046c, + 0x59fb, 0x04bd, + 0x59ff, 0x089f, + 0x5a01, 0x0496, + 0x5a03, 0x0467, + 0x5a09, 0x11e1, + 0x5a11, 0x11df, + 0x5a18, 0x0ec8, + 0x5a1a, 0x11e2, + 0x5a1c, 0x11e0, + 0x5a1f, 0x11de, + 0x5a20, 0x09f7, + 0x5a25, 0x11dd, + 0x5a29, 0x0e2a, + 0x5a2f, 0x0798, + 0x5a35, 0x11e6, + 0x5a3c, 0x0993, + 0x5a40, 0x11e3, + 0x5a41, 0x0fd2, + 0x5a46, 0x0d02, + 0x5a49, 0x11e5, + 0x5a5a, 0x0817, + 0x5a62, 0x11e8, + 0x5a66, 0x0dca, + 0x5a6a, 0x11e9, + 0x5a6c, 0x11e4, + 0x5a7f, 0x0ec7, + 0x5a92, 0x0d14, + 0x5a9a, 0x11ea, + 0x5a9b, 0x0da4, + 0x5abc, 0x11eb, + 0x5abd, 0x11ef, + 0x5abe, 0x11ec, + 0x5ac1, 0x0547, + 0x5ac2, 0x11ee, + 0x5ac9, 0x08e7, + 0x5acb, 0x11ed, + 0x5acc, 0x074f, + 0x5ad0, 0x11fb, + 0x5ad6, 0x11f4, + 0x5ad7, 0x11f1, + 0x5ae1, 0x0ba2, + 0x5ae3, 0x11f0, + 0x5ae6, 0x11f2, + 0x5ae9, 0x11f3, + 0x5afa, 0x11f5, + 0x5b09, 0x062e, + 0x5b0b, 0x11f8, + 0x5b0c, 0x11f7, + 0x5b16, 0x11f9, + 0x5b22, 0x09d6, + 0x5b2a, 0x11fc, + 0x5b2c, 0x0bf8, + 0x5b30, 0x04e7, + 0x5b32, 0x11fa, + 0x5b36, 0x11fd, + 0x5b3e, 0x11fe, + 0x5b40, 0x1201, + 0x5b43, 0x11ff, + 0x5b45, 0x1200, + 0x5b50, 0x08a0, + 0x5b51, 0x1202, + 0x5b54, 0x07b8, + 0x5b55, 0x1203, + 0x5b56, 0x20f0, + 0x5b57, 0x08c8, + 0x5b58, 0x0b18, + 0x5b5a, 0x1204, + 0x5b5c, 0x08a8, + 0x5b5d, 0x07b9, + 0x5b5f, 0x0ede, + 0x5b63, 0x0642, + 0x5b64, 0x077d, + 0x5b65, 0x1206, + 0x5b66, 0x05b6, + 0x5b69, 0x1207, + 0x5b6b, 0x0b19, + 0x5b70, 0x1208, + 0x5b71, 0x1230, + 0x5b73, 0x1209, + 0x5b75, 0x120a, + 0x5b78, 0x120b, + 0x5b7a, 0x120d, + 0x5b80, 0x120e, + 0x5b83, 0x120f, + 0x5b85, 0x0b50, + 0x5b87, 0x04c9, + 0x5b88, 0x0915, + 0x5b89, 0x0486, + 0x5b8b, 0x0ad9, + 0x5b8c, 0x05ec, + 0x5b8d, 0x08e1, + 0x5b8f, 0x07ba, + 0x5b95, 0x0c60, + 0x5b97, 0x092b, + 0x5b98, 0x05ed, + 0x5b99, 0x0ba6, + 0x5b9a, 0x0c06, + 0x5b9b, 0x047c, + 0x5b9c, 0x0653, + 0x5b9d, 0x0e45, + 0x5b9f, 0x08ee, + 0x5ba2, 0x066c, + 0x5ba3, 0x0a8f, + 0x5ba4, 0x08e8, + 0x5ba5, 0x0f12, + 0x5ba6, 0x1210, + 0x5bae, 0x0676, + 0x5bb0, 0x083b, + 0x5bb3, 0x0590, + 0x5bb4, 0x0505, + 0x5bb5, 0x0994, + 0x5bb6, 0x0548, + 0x5bb8, 0x1211, + 0x5bb9, 0x0f30, + 0x5bbf, 0x0953, + 0x5bc0, 0x20f1, + 0x5bc2, 0x0910, + 0x5bc3, 0x1212, + 0x5bc4, 0x062f, + 0x5bc5, 0x0caa, + 0x5bc6, 0x0eb5, + 0x5bc7, 0x1213, + 0x5bc9, 0x1214, + 0x5bcc, 0x0dcb, + 0x5bd0, 0x1216, + 0x5bd2, 0x05e4, + 0x5bd3, 0x06ef, + 0x5bd4, 0x1215, + 0x5bd8, 0x20f3, + 0x5bdb, 0x05ee, + 0x5bdd, 0x09f8, + 0x5bde, 0x121a, + 0x5bdf, 0x086f, + 0x5be1, 0x0549, + 0x5be2, 0x1219, + 0x5be4, 0x1217, + 0x5be5, 0x121b, + 0x5be6, 0x1218, + 0x5be7, 0x0ce1, + 0x5be8, 0x148e, + 0x5be9, 0x09f9, + 0x5beb, 0x121c, + 0x5bec, 0x20f4, + 0x5bee, 0x0f88, + 0x5bf0, 0x121d, + 0x5bf3, 0x121f, + 0x5bf5, 0x0bbc, + 0x5bf6, 0x121e, + 0x5bf8, 0x0a47, + 0x5bfa, 0x08c9, + 0x5bfe, 0x0b30, + 0x5bff, 0x0923, + 0x5c01, 0x0de7, + 0x5c02, 0x0a90, + 0x5c04, 0x08f9, + 0x5c05, 0x1220, + 0x5c06, 0x0995, + 0x5c07, 0x1221, + 0x5c09, 0x0497, + 0x5c0a, 0x0b1a, + 0x5c0b, 0x0a18, + 0x5c0d, 0x1223, + 0x5c0e, 0x0c8b, + 0x5c0f, 0x0996, + 0x5c11, 0x0997, + 0x5c13, 0x1224, + 0x5c16, 0x0a91, + 0x5c1a, 0x0998, + 0x5c1e, 0x20f5, + 0x5c20, 0x1225, + 0x5c22, 0x1226, + 0x5c24, 0x0eec, + 0x5c28, 0x1227, + 0x5c2d, 0x06be, + 0x5c31, 0x092c, + 0x5c38, 0x1228, + 0x5c3a, 0x0908, + 0x5c3b, 0x09f2, + 0x5c3c, 0x0ccc, + 0x5c3d, 0x0a1a, + 0x5c3e, 0x0d8c, + 0x5c3f, 0x0cd8, + 0x5c40, 0x06c1, + 0x5c41, 0x122a, + 0x5c45, 0x0689, + 0x5c46, 0x122b, + 0x5c48, 0x06f6, + 0x5c4a, 0x0ca7, + 0x5c4b, 0x0530, + 0x5c4d, 0x08a1, + 0x5c4e, 0x122c, + 0x5c4f, 0x122f, + 0x5c50, 0x122e, + 0x5c51, 0x06f5, + 0x5c53, 0x122d, + 0x5c55, 0x0c32, + 0x5c5b, 0x1e92, + 0x5c5e, 0x0b10, + 0x5c60, 0x0c45, + 0x5c61, 0x08f4, + 0x5c62, 0x1e0d, + 0x5c64, 0x0ada, + 0x5c65, 0x0f64, + 0x5c6c, 0x1231, + 0x5c6e, 0x1232, + 0x5c6f, 0x0cae, + 0x5c71, 0x0881, + 0x5c76, 0x1234, + 0x5c79, 0x1235, + 0x5c8c, 0x1236, + 0x5c90, 0x0630, + 0x5c91, 0x1237, + 0x5c94, 0x1238, + 0x5ca1, 0x052c, + 0x5ca6, 0x20f6, + 0x5ca8, 0x0abd, + 0x5ca9, 0x0620, + 0x5cab, 0x123a, + 0x5cac, 0x0eb4, + 0x5cb1, 0x0b32, + 0x5cb3, 0x05b7, + 0x5cb6, 0x123c, + 0x5cb7, 0x123e, + 0x5cb8, 0x061b, + 0x5cba, 0x20f7, + 0x5cbb, 0x123b, + 0x5cbc, 0x123d, + 0x5cbe, 0x1240, + 0x5cc5, 0x123f, + 0x5cc7, 0x1241, + 0x5cd9, 0x1242, + 0x5ce0, 0x0c95, + 0x5ce1, 0x06a6, + 0x5ce8, 0x0565, + 0x5ce9, 0x1243, + 0x5cea, 0x1248, + 0x5ced, 0x1246, + 0x5cef, 0x0e47, + 0x5cf0, 0x0e46, + 0x5cf5, 0x20f8, + 0x5cf6, 0x0c61, + 0x5cfa, 0x1245, + 0x5cfb, 0x095e, + 0x5cfd, 0x1244, + 0x5d07, 0x0a38, + 0x5d0b, 0x1249, + 0x5d0e, 0x085a, + 0x5d11, 0x124f, + 0x5d14, 0x1250, + 0x5d15, 0x124a, + 0x5d16, 0x0591, + 0x5d17, 0x124b, + 0x5d18, 0x1254, + 0x5d19, 0x1253, + 0x5d1a, 0x1252, + 0x5d1b, 0x124e, + 0x5d1f, 0x124d, + 0x5d22, 0x1251, + 0x5d27, 0x20f9, + 0x5d29, 0x0e48, + 0x5d42, 0x20fc, + 0x5d4b, 0x1258, + 0x5d4c, 0x1255, + 0x5d4e, 0x1257, + 0x5d50, 0x0f5c, + 0x5d52, 0x1256, + 0x5d53, 0x20fa, + 0x5d5c, 0x124c, + 0x5d69, 0x0a39, + 0x5d6c, 0x1259, + 0x5d6d, 0x20fd, + 0x5d6f, 0x0827, + 0x5d73, 0x125a, + 0x5d76, 0x125b, + 0x5d82, 0x125e, + 0x5d84, 0x125d, + 0x5d87, 0x125c, + 0x5d8b, 0x0c62, + 0x5d8c, 0x1247, + 0x5d90, 0x1264, + 0x5d9d, 0x1260, + 0x5da2, 0x125f, + 0x5dac, 0x1261, + 0x5dae, 0x1262, + 0x5db7, 0x1265, + 0x5db8, 0x20fe, + 0x5dba, 0x0fae, + 0x5dbc, 0x1266, + 0x5dbd, 0x1263, + 0x5dc9, 0x1267, + 0x5dcc, 0x061c, + 0x5dcd, 0x1268, + 0x5dd0, 0x2100, + 0x5dd2, 0x126a, + 0x5dd3, 0x1269, + 0x5dd6, 0x126b, + 0x5ddb, 0x126c, + 0x5ddd, 0x0a92, + 0x5dde, 0x092d, + 0x5de1, 0x096e, + 0x5de3, 0x0ae5, + 0x5de5, 0x07bb, + 0x5de6, 0x0828, + 0x5de7, 0x07bc, + 0x5de8, 0x068a, + 0x5deb, 0x126d, + 0x5dee, 0x0829, + 0x5df1, 0x077e, + 0x5df2, 0x126e, + 0x5df3, 0x0eb2, + 0x5df4, 0x0cf9, + 0x5df5, 0x126f, + 0x5df7, 0x07bd, + 0x5dfb, 0x05e8, + 0x5dfd, 0x0b65, + 0x5dfe, 0x06ca, + 0x5e02, 0x08a2, + 0x5e03, 0x0dcd, + 0x5e06, 0x0d55, + 0x5e0b, 0x1270, + 0x5e0c, 0x0631, + 0x5e11, 0x1273, + 0x5e16, 0x0bbd, + 0x5e19, 0x1272, + 0x5e1a, 0x1271, + 0x5e1b, 0x1274, + 0x5e1d, 0x0c07, + 0x5e25, 0x0a29, + 0x5e2b, 0x08a3, + 0x5e2d, 0x0a6e, + 0x5e2f, 0x0b33, + 0x5e30, 0x063c, + 0x5e33, 0x0bbe, + 0x5e36, 0x1275, + 0x5e38, 0x09d7, + 0x5e3d, 0x0e67, + 0x5e40, 0x1279, + 0x5e43, 0x1278, + 0x5e44, 0x1277, + 0x5e45, 0x0def, + 0x5e47, 0x1280, + 0x5e4c, 0x0e88, + 0x5e4e, 0x127a, + 0x5e54, 0x127c, + 0x5e55, 0x0e99, + 0x5e57, 0x127b, + 0x5e5f, 0x127d, + 0x5e61, 0x0d3c, + 0x5e62, 0x127e, + 0x5e63, 0x0e0e, + 0x5e64, 0x127f, + 0x5e72, 0x05ef, + 0x5e73, 0x0e0f, + 0x5e74, 0x0ce5, + 0x5e75, 0x1281, + 0x5e78, 0x07be, + 0x5e79, 0x05f0, + 0x5e7a, 0x1283, + 0x5e7b, 0x076c, + 0x5e7c, 0x0f2e, + 0x5e7d, 0x0f13, + 0x5e7e, 0x0632, + 0x5e7f, 0x1285, + 0x5e81, 0x0bbf, + 0x5e83, 0x07bf, + 0x5e84, 0x0999, + 0x5e87, 0x0d73, + 0x5e8a, 0x099a, + 0x5e8f, 0x0982, + 0x5e95, 0x0c08, + 0x5e96, 0x0e49, + 0x5e97, 0x0c33, + 0x5e9a, 0x07c0, + 0x5e9c, 0x0dce, + 0x5ea0, 0x1286, + 0x5ea6, 0x0c53, + 0x5ea7, 0x0832, + 0x5eab, 0x077f, + 0x5ead, 0x0c09, + 0x5eb5, 0x0487, + 0x5eb6, 0x0978, + 0x5eb7, 0x07c1, + 0x5eb8, 0x0f31, + 0x5ec1, 0x1287, + 0x5ec3, 0x0d07, + 0x5ec8, 0x1289, + 0x5ec9, 0x0fbf, + 0x5eca, 0x0fd3, + 0x5ecf, 0x128b, + 0x5ed0, 0x128a, + 0x5ed3, 0x05a5, + 0x5ed6, 0x128c, + 0x5eda, 0x128f, + 0x5edd, 0x128e, + 0x5edf, 0x0db2, + 0x5ee0, 0x099b, + 0x5ee1, 0x1292, + 0x5ee2, 0x1291, + 0x5ee3, 0x128d, + 0x5ee8, 0x1293, + 0x5eec, 0x1295, + 0x5ef0, 0x1298, + 0x5ef1, 0x1296, + 0x5ef3, 0x1297, + 0x5ef4, 0x1299, + 0x5ef6, 0x0506, + 0x5ef7, 0x0c0a, + 0x5ef8, 0x129a, + 0x5efa, 0x0750, + 0x5efb, 0x0576, + 0x5efc, 0x0cec, + 0x5efe, 0x129b, + 0x5eff, 0x0cd3, + 0x5f01, 0x0e2b, + 0x5f03, 0x129c, + 0x5f04, 0x0fd4, + 0x5f09, 0x129d, + 0x5f0a, 0x0e10, + 0x5f0b, 0x12a0, + 0x5f0c, 0x0ffa, + 0x5f0d, 0x100a, + 0x5f0f, 0x08dc, + 0x5f10, 0x0ccd, + 0x5f11, 0x12a1, + 0x5f13, 0x0677, + 0x5f14, 0x0bc0, + 0x5f15, 0x04be, + 0x5f16, 0x12a2, + 0x5f17, 0x0df6, + 0x5f18, 0x07c2, + 0x5f1b, 0x0b8e, + 0x5f1f, 0x0c0b, + 0x5f21, 0x2101, + 0x5f25, 0x0efb, + 0x5f26, 0x076d, + 0x5f27, 0x0780, + 0x5f29, 0x12a3, + 0x5f2d, 0x12a4, + 0x5f2f, 0x12aa, + 0x5f31, 0x0911, + 0x5f34, 0x2102, + 0x5f35, 0x0bc1, + 0x5f37, 0x06a7, + 0x5f38, 0x12a5, + 0x5f3c, 0x0d9d, + 0x5f3e, 0x0b84, + 0x5f41, 0x12a6, + 0x5f45, 0x20b2, + 0x5f48, 0x12a7, + 0x5f4a, 0x06a8, + 0x5f4c, 0x12a8, + 0x5f4e, 0x12a9, + 0x5f51, 0x12ab, + 0x5f53, 0x0c70, + 0x5f56, 0x12ac, + 0x5f59, 0x12ae, + 0x5f5c, 0x129f, + 0x5f5d, 0x129e, + 0x5f61, 0x12af, + 0x5f62, 0x0717, + 0x5f66, 0x0d99, + 0x5f67, 0x2103, + 0x5f69, 0x083c, + 0x5f6a, 0x0da9, + 0x5f6b, 0x0bc2, + 0x5f6c, 0x0dbd, + 0x5f6d, 0x12b0, + 0x5f70, 0x099c, + 0x5f71, 0x04e8, + 0x5f73, 0x12b1, + 0x5f77, 0x12b2, + 0x5f79, 0x0efe, + 0x5f7c, 0x0d74, + 0x5f7f, 0x12b5, + 0x5f80, 0x051f, + 0x5f81, 0x0a50, + 0x5f82, 0x12b4, + 0x5f83, 0x12b3, + 0x5f84, 0x0718, + 0x5f85, 0x0b34, + 0x5f87, 0x12b9, + 0x5f88, 0x12b7, + 0x5f8a, 0x12b6, + 0x5f8b, 0x0f6f, + 0x5f8c, 0x0799, + 0x5f90, 0x0983, + 0x5f91, 0x12b8, + 0x5f92, 0x0c46, + 0x5f93, 0x0948, + 0x5f97, 0x0c98, + 0x5f98, 0x12bc, + 0x5f99, 0x12bb, + 0x5f9e, 0x12ba, + 0x5fa0, 0x12bd, + 0x5fa1, 0x079a, + 0x5fa8, 0x12be, + 0x5fa9, 0x0dee, + 0x5faa, 0x0965, + 0x5fad, 0x12bf, + 0x5fae, 0x0d8d, + 0x5fb3, 0x0c99, + 0x5fb4, 0x0bc3, + 0x5fb7, 0x2104, + 0x5fb9, 0x0c2a, + 0x5fbc, 0x12c0, + 0x5fbd, 0x0645, + 0x5fc3, 0x09fa, + 0x5fc5, 0x0d9e, + 0x5fcc, 0x0633, + 0x5fcd, 0x0cdc, + 0x5fd6, 0x12c1, + 0x5fd7, 0x08a4, + 0x5fd8, 0x0e68, + 0x5fdc, 0x0520, + 0x5fdd, 0x12c6, + 0x5fde, 0x2105, + 0x5fe0, 0x0ba7, + 0x5fe4, 0x12c3, + 0x5feb, 0x0577, + 0x5ff0, 0x12f6, + 0x5ff1, 0x12c5, + 0x5ff5, 0x0ce6, + 0x5ff8, 0x12c4, + 0x5ffb, 0x12c2, + 0x5ffd, 0x080c, + 0x5fff, 0x12c8, + 0x600e, 0x12ce, + 0x600f, 0x12d4, + 0x6010, 0x12cc, + 0x6012, 0x0c56, + 0x6015, 0x12d1, + 0x6016, 0x0dcf, + 0x6019, 0x12cb, + 0x601b, 0x12d0, + 0x601c, 0x0faf, + 0x601d, 0x08a5, + 0x6020, 0x0b35, + 0x6021, 0x12c9, + 0x6025, 0x0678, + 0x6026, 0x12d3, + 0x6027, 0x0a51, + 0x6028, 0x0507, + 0x6029, 0x12cd, + 0x602a, 0x0578, + 0x602b, 0x12d2, + 0x602f, 0x06a9, + 0x6031, 0x12cf, + 0x603a, 0x12d5, + 0x6041, 0x12d7, + 0x6042, 0x12e1, + 0x6043, 0x12df, + 0x6046, 0x12dc, + 0x604a, 0x12db, + 0x604b, 0x0fc0, + 0x604d, 0x12dd, + 0x6050, 0x06aa, + 0x6052, 0x07c3, + 0x6055, 0x0984, + 0x6059, 0x12e4, + 0x605a, 0x12d6, + 0x605d, 0x2106, + 0x605f, 0x12da, + 0x6060, 0x12ca, + 0x6062, 0x057a, + 0x6063, 0x12de, + 0x6064, 0x12e0, + 0x6065, 0x0b8f, + 0x6068, 0x0818, + 0x6069, 0x0538, + 0x606a, 0x12d8, + 0x606b, 0x12e3, + 0x606c, 0x12e2, + 0x606d, 0x06ab, + 0x606f, 0x0b09, + 0x6070, 0x05c4, + 0x6075, 0x0719, + 0x6077, 0x12d9, + 0x6081, 0x12e5, + 0x6083, 0x12e8, + 0x6084, 0x12ea, + 0x6085, 0x2107, + 0x6089, 0x08e9, + 0x608a, 0x2108, + 0x608b, 0x12f0, + 0x608c, 0x0c0c, + 0x608d, 0x12e6, + 0x6092, 0x12ee, + 0x6094, 0x0579, + 0x6096, 0x12ec, + 0x609a, 0x12e9, + 0x609b, 0x12eb, + 0x609f, 0x079b, + 0x60a0, 0x0f14, + 0x60a3, 0x05f1, + 0x60a6, 0x04fb, + 0x60a7, 0x12ef, + 0x60a9, 0x0cf0, + 0x60aa, 0x0471, + 0x60b2, 0x0d75, + 0x60b3, 0x12c7, + 0x60b4, 0x12f5, + 0x60b5, 0x12f9, + 0x60b6, 0x0ef1, + 0x60b8, 0x12f2, + 0x60bc, 0x0c63, + 0x60bd, 0x12f7, + 0x60c5, 0x09d8, + 0x60c6, 0x12f8, + 0x60c7, 0x0caf, + 0x60d1, 0x0fed, + 0x60d3, 0x12f4, + 0x60d5, 0x210a, + 0x60d8, 0x12fa, + 0x60da, 0x080d, + 0x60dc, 0x0a6f, + 0x60de, 0x2109, + 0x60df, 0x0498, + 0x60e0, 0x12f3, + 0x60e1, 0x12f1, + 0x60e3, 0x0adc, + 0x60e7, 0x12e7, + 0x60e8, 0x0882, + 0x60f0, 0x0b26, + 0x60f1, 0x1306, + 0x60f2, 0x210c, + 0x60f3, 0x0add, + 0x60f4, 0x1301, + 0x60f6, 0x12fe, + 0x60f9, 0x0912, + 0x60fa, 0x1302, + 0x60fb, 0x1305, + 0x6100, 0x1300, + 0x6101, 0x092f, + 0x6103, 0x1303, + 0x6106, 0x12fd, + 0x6108, 0x0f08, + 0x6109, 0x0f07, + 0x610d, 0x1307, + 0x610f, 0x0499, + 0x6111, 0x210d, + 0x6115, 0x12fc, + 0x611a, 0x06ea, + 0x611b, 0x046a, + 0x611f, 0x05f2, + 0x6120, 0x210b, + 0x6121, 0x1304, + 0x6127, 0x130c, + 0x6128, 0x130b, + 0x612c, 0x1310, + 0x6130, 0x210f, + 0x6134, 0x1311, + 0x6137, 0x210e, + 0x613c, 0x130f, + 0x613d, 0x1312, + 0x613e, 0x130a, + 0x613f, 0x130e, + 0x6142, 0x1313, + 0x6144, 0x1314, + 0x6147, 0x1309, + 0x6148, 0x08ca, + 0x614a, 0x130d, + 0x614b, 0x0b36, + 0x614c, 0x07c4, + 0x614d, 0x12fb, + 0x614e, 0x09fb, + 0x6153, 0x1321, + 0x6155, 0x0e39, + 0x6158, 0x1317, + 0x615d, 0x1320, + 0x615f, 0x131f, + 0x6162, 0x0eab, + 0x6163, 0x05f3, + 0x6165, 0x131d, + 0x6167, 0x071b, + 0x6168, 0x0592, + 0x616b, 0x131a, + 0x616e, 0x0f80, + 0x616f, 0x131c, + 0x6170, 0x049a, + 0x6171, 0x131e, + 0x6173, 0x1315, + 0x6174, 0x131b, + 0x6175, 0x1322, + 0x6176, 0x071a, + 0x6177, 0x1316, + 0x617e, 0x0f47, + 0x6182, 0x0f15, + 0x6187, 0x1325, + 0x618a, 0x1329, + 0x618e, 0x0b00, + 0x6190, 0x0fc1, + 0x6191, 0x132a, + 0x6194, 0x1327, + 0x6196, 0x1324, + 0x6198, 0x2110, + 0x6199, 0x1323, + 0x619a, 0x1328, + 0x61a4, 0x0e00, + 0x61a7, 0x0c8c, + 0x61a9, 0x071c, + 0x61ab, 0x132b, + 0x61ac, 0x1326, + 0x61ae, 0x132c, + 0x61b2, 0x0751, + 0x61b6, 0x0531, + 0x61ba, 0x1334, + 0x61be, 0x05f4, + 0x61c3, 0x1332, + 0x61c6, 0x1333, + 0x61c7, 0x0819, + 0x61c8, 0x1331, + 0x61c9, 0x132f, + 0x61ca, 0x132e, + 0x61cb, 0x1335, + 0x61cc, 0x132d, + 0x61cd, 0x1337, + 0x61d0, 0x057b, + 0x61e3, 0x1339, + 0x61e6, 0x1338, + 0x61f2, 0x0bc4, + 0x61f4, 0x133c, + 0x61f6, 0x133a, + 0x61f7, 0x1330, + 0x61f8, 0x0752, + 0x61fa, 0x133b, + 0x61fc, 0x133f, + 0x61fd, 0x133e, + 0x61fe, 0x1340, + 0x61ff, 0x133d, + 0x6200, 0x1341, + 0x6208, 0x1342, + 0x620a, 0x0e3a, + 0x620c, 0x1345, + 0x620d, 0x1344, + 0x620e, 0x0949, + 0x6210, 0x0a52, + 0x6211, 0x0566, + 0x6212, 0x057c, + 0x6213, 0x2111, + 0x6214, 0x1346, + 0x6216, 0x0483, + 0x621a, 0x0a70, + 0x621b, 0x1347, + 0x621d, 0x1a64, + 0x621e, 0x1348, + 0x621f, 0x0737, + 0x6221, 0x1349, + 0x6226, 0x0a93, + 0x622a, 0x134a, + 0x622e, 0x134b, + 0x622f, 0x0654, + 0x6230, 0x134c, + 0x6232, 0x134d, + 0x6234, 0x0b37, + 0x6238, 0x0781, + 0x623b, 0x0eed, + 0x623f, 0x0e6a, + 0x6240, 0x0974, + 0x6241, 0x134f, + 0x6247, 0x0a94, + 0x6248, 0x1b1a, + 0x6249, 0x0d76, + 0x624b, 0x0916, + 0x624d, 0x083d, + 0x624e, 0x1350, + 0x6253, 0x0b27, + 0x6255, 0x0df7, + 0x6258, 0x0b51, + 0x625b, 0x1353, + 0x625e, 0x1351, + 0x6260, 0x1354, + 0x6263, 0x1352, + 0x6268, 0x1355, + 0x626e, 0x0e01, + 0x6271, 0x047b, + 0x6276, 0x0dd0, + 0x6279, 0x0d77, + 0x627c, 0x1356, + 0x627e, 0x1359, + 0x627f, 0x099d, + 0x6280, 0x0655, + 0x6282, 0x1357, + 0x6283, 0x135e, + 0x6284, 0x099e, + 0x6289, 0x1358, + 0x628a, 0x0cfa, + 0x6291, 0x0f48, + 0x6292, 0x135a, + 0x6294, 0x135f, + 0x6295, 0x0c64, + 0x6296, 0x135c, + 0x6297, 0x07c5, + 0x6298, 0x0a82, + 0x629b, 0x136d, + 0x629c, 0x0d48, + 0x629e, 0x0b52, + 0x62a6, 0x2112, + 0x62ab, 0x0d78, + 0x62ac, 0x13b2, + 0x62b1, 0x0e4a, + 0x62b5, 0x0c0d, + 0x62b9, 0x0ea3, + 0x62bb, 0x1362, + 0x62bc, 0x0521, + 0x62bd, 0x0ba8, + 0x62c2, 0x136b, + 0x62c5, 0x0b72, + 0x62c6, 0x1365, + 0x62c7, 0x136c, + 0x62c8, 0x1367, + 0x62c9, 0x136e, + 0x62ca, 0x136a, + 0x62cc, 0x1369, + 0x62cd, 0x0d25, + 0x62cf, 0x1363, + 0x62d0, 0x057d, + 0x62d1, 0x1361, + 0x62d2, 0x068b, + 0x62d3, 0x0b53, + 0x62d4, 0x135d, + 0x62d7, 0x1360, + 0x62d8, 0x07c6, + 0x62d9, 0x0a7f, + 0x62db, 0x099f, + 0x62dc, 0x1368, + 0x62dd, 0x0d08, + 0x62e0, 0x068c, + 0x62e1, 0x05a6, + 0x62ec, 0x05c5, + 0x62ed, 0x09e7, + 0x62ee, 0x1370, + 0x62ef, 0x1375, + 0x62f1, 0x1371, + 0x62f3, 0x0753, + 0x62f5, 0x1376, + 0x62f6, 0x0870, + 0x62f7, 0x07fb, + 0x62fe, 0x0930, + 0x62ff, 0x1364, + 0x6301, 0x08cb, + 0x6302, 0x1373, + 0x6307, 0x08a6, + 0x6308, 0x1374, + 0x6309, 0x0488, + 0x630c, 0x136f, + 0x6311, 0x0bc5, + 0x6319, 0x068d, + 0x631f, 0x06ac, + 0x6327, 0x1372, + 0x6328, 0x046b, + 0x632b, 0x0833, + 0x632f, 0x09fc, + 0x633a, 0x0c0e, + 0x633d, 0x0d68, + 0x633e, 0x1378, + 0x633f, 0x0ae0, + 0x6349, 0x0b0a, + 0x634c, 0x0879, + 0x634d, 0x1379, + 0x634f, 0x137b, + 0x6350, 0x1377, + 0x6355, 0x0e31, + 0x6357, 0x0bd9, + 0x635c, 0x0ade, + 0x6367, 0x0e4b, + 0x6368, 0x08fa, + 0x6369, 0x1387, + 0x636b, 0x1386, + 0x636e, 0x0a3e, + 0x6372, 0x0754, + 0x6376, 0x1380, + 0x6377, 0x09a1, + 0x637a, 0x0cc0, + 0x637b, 0x0ce7, + 0x6380, 0x137e, + 0x6383, 0x0adf, + 0x6388, 0x0924, + 0x6389, 0x1383, + 0x638c, 0x09a0, + 0x638e, 0x137d, + 0x638f, 0x1382, + 0x6392, 0x0d09, + 0x6396, 0x137c, + 0x6398, 0x06f7, + 0x639b, 0x05bb, + 0x639f, 0x1384, + 0x63a0, 0x0f73, + 0x63a1, 0x083e, + 0x63a2, 0x0b73, + 0x63a3, 0x1381, + 0x63a5, 0x0a80, + 0x63a7, 0x07c7, + 0x63a8, 0x0a2a, + 0x63a9, 0x0508, + 0x63aa, 0x0abe, + 0x63ab, 0x137f, + 0x63ac, 0x065f, + 0x63b2, 0x071d, + 0x63b4, 0x0beb, + 0x63b5, 0x1385, + 0x63bb, 0x0ae1, + 0x63be, 0x1388, + 0x63c0, 0x138a, + 0x63c3, 0x0b17, + 0x63c4, 0x1390, + 0x63c6, 0x138b, + 0x63c9, 0x138d, + 0x63cf, 0x0db3, + 0x63d0, 0x0c0f, + 0x63d2, 0x138e, + 0x63d6, 0x0f16, + 0x63da, 0x0f32, + 0x63db, 0x05f5, + 0x63e1, 0x0472, + 0x63e3, 0x138c, + 0x63e9, 0x1389, + 0x63ee, 0x0634, + 0x63f4, 0x0509, + 0x63f5, 0x2113, + 0x63f6, 0x138f, + 0x63fa, 0x0f33, + 0x6406, 0x1393, + 0x640d, 0x0b1b, + 0x640f, 0x139a, + 0x6413, 0x1394, + 0x6414, 0x1e2c, + 0x6416, 0x1391, + 0x6417, 0x1398, + 0x641c, 0x137a, + 0x6426, 0x1395, + 0x6428, 0x1399, + 0x642c, 0x0d56, + 0x642d, 0x0c65, + 0x6434, 0x1392, + 0x6436, 0x1396, + 0x643a, 0x071e, + 0x643e, 0x0861, + 0x6442, 0x0a81, + 0x644e, 0x139e, + 0x6451, 0x1e43, + 0x6458, 0x0c20, + 0x6460, 0x2114, + 0x6467, 0x139b, + 0x6469, 0x0e8e, + 0x646f, 0x139c, + 0x6476, 0x139d, + 0x6478, 0x0eda, + 0x647a, 0x0a46, + 0x6483, 0x0738, + 0x6488, 0x13a4, + 0x6492, 0x0883, + 0x6493, 0x13a1, + 0x6495, 0x13a0, + 0x649a, 0x0ce8, + 0x649d, 0x2115, + 0x649e, 0x0c8d, + 0x64a4, 0x0c2b, + 0x64a5, 0x13a2, + 0x64a9, 0x13a3, + 0x64ab, 0x0de1, + 0x64ad, 0x0cfb, + 0x64ae, 0x0871, + 0x64b0, 0x0a95, + 0x64b2, 0x0e7e, + 0x64b9, 0x05a7, + 0x64bb, 0x13aa, + 0x64bc, 0x13a5, + 0x64c1, 0x0f34, + 0x64c2, 0x13ac, + 0x64c5, 0x13a8, + 0x64c7, 0x13a9, + 0x64cd, 0x0ae2, + 0x64ce, 0x2116, + 0x64d2, 0x13a7, + 0x64d4, 0x1366, + 0x64d8, 0x13ab, + 0x64da, 0x13a6, + 0x64e0, 0x13b0, + 0x64e2, 0x0c21, + 0x64e3, 0x13b3, + 0x64e6, 0x0872, + 0x64e7, 0x13ae, + 0x64ec, 0x0656, + 0x64ef, 0x13b4, + 0x64f1, 0x13ad, + 0x64f2, 0x13b8, + 0x64f4, 0x13b7, + 0x64f6, 0x13b6, + 0x64fa, 0x13b9, + 0x64fd, 0x13bb, + 0x64fe, 0x09d9, + 0x6500, 0x13ba, + 0x6505, 0x13be, + 0x6518, 0x13bc, + 0x651c, 0x13bd, + 0x651d, 0x1397, + 0x6522, 0x1e97, + 0x6523, 0x13c0, + 0x6524, 0x13bf, + 0x652a, 0x139f, + 0x652b, 0x13c1, + 0x652c, 0x13b5, + 0x652f, 0x08a7, + 0x6534, 0x13c2, + 0x6536, 0x13c5, + 0x6537, 0x13c4, + 0x6538, 0x13c6, + 0x6539, 0x057e, + 0x653b, 0x07c8, + 0x653e, 0x0e4c, + 0x653f, 0x0a53, + 0x6545, 0x0782, + 0x6548, 0x13c8, + 0x654d, 0x13cb, + 0x654e, 0x2117, + 0x654f, 0x0dc4, + 0x6551, 0x0679, + 0x6555, 0x13ca, + 0x6556, 0x13c9, + 0x6557, 0x0d0a, + 0x6558, 0x13cc, + 0x6559, 0x06ad, + 0x655d, 0x13ce, + 0x655e, 0x13cd, + 0x6562, 0x05f6, + 0x6563, 0x0884, + 0x6566, 0x0cb0, + 0x656c, 0x071f, + 0x6570, 0x0a3a, + 0x6572, 0x13cf, + 0x6574, 0x0a54, + 0x6575, 0x0c22, + 0x6577, 0x0dd1, + 0x6578, 0x13d0, + 0x6582, 0x13d1, + 0x6587, 0x0e08, + 0x6588, 0x120c, + 0x6589, 0x0a6a, + 0x658c, 0x0dbe, + 0x658e, 0x0848, + 0x6590, 0x0d79, + 0x6591, 0x0d57, + 0x6597, 0x0c47, + 0x6599, 0x0f89, + 0x659b, 0x13d4, + 0x659c, 0x08fc, + 0x659f, 0x13d5, + 0x65a1, 0x047a, + 0x65a4, 0x06cc, + 0x65a5, 0x0a71, + 0x65a7, 0x0dd2, + 0x65ab, 0x13d6, + 0x65ac, 0x0890, + 0x65ad, 0x0b85, + 0x65af, 0x08a9, + 0x65b0, 0x09fd, + 0x65b7, 0x13d7, + 0x65b9, 0x0e4d, + 0x65bc, 0x0519, + 0x65bd, 0x08aa, + 0x65c1, 0x13da, + 0x65c3, 0x13d8, + 0x65c4, 0x13db, + 0x65c5, 0x0f81, + 0x65c6, 0x13d9, + 0x65cb, 0x0a9f, + 0x65cc, 0x13dc, + 0x65cf, 0x0b12, + 0x65d2, 0x13dd, + 0x65d7, 0x0636, + 0x65d9, 0x13df, + 0x65db, 0x13de, + 0x65e0, 0x13e0, + 0x65e2, 0x0637, + 0x65e5, 0x0cd4, + 0x65e6, 0x0b74, + 0x65e7, 0x0686, + 0x65e8, 0x08ab, + 0x65e9, 0x0ae3, + 0x65ec, 0x0966, + 0x65ed, 0x0474, + 0x65f1, 0x13e2, + 0x65fa, 0x0522, + 0x65fb, 0x13e6, + 0x6600, 0x2118, + 0x6602, 0x07c9, + 0x6603, 0x13e5, + 0x6606, 0x081b, + 0x6607, 0x09a2, + 0x6609, 0x211a, + 0x660a, 0x13e4, + 0x660c, 0x09a3, + 0x660e, 0x0ecc, + 0x660f, 0x081a, + 0x6613, 0x049b, + 0x6614, 0x0a72, + 0x6615, 0x2119, + 0x661c, 0x13eb, + 0x661e, 0x211c, + 0x661f, 0x0a55, + 0x6620, 0x04e9, + 0x6624, 0x211d, + 0x6625, 0x095f, + 0x6627, 0x0e94, + 0x6628, 0x0862, + 0x662d, 0x09a4, + 0x662e, 0x211b, + 0x662f, 0x0a4b, + 0x6631, 0x20ae, + 0x6634, 0x13ea, + 0x6635, 0x13e8, + 0x663b, 0x1e00, + 0x663c, 0x0ba9, + 0x663f, 0x1409, + 0x6641, 0x13ef, + 0x6642, 0x08cc, + 0x6643, 0x07ca, + 0x6644, 0x13ed, + 0x6649, 0x13ee, + 0x664b, 0x09fe, + 0x664f, 0x13ec, + 0x6652, 0x087d, + 0x6657, 0x211f, + 0x6659, 0x2120, + 0x665d, 0x13f1, + 0x665e, 0x13f0, + 0x665f, 0x13f5, + 0x6662, 0x13f6, + 0x6664, 0x13f2, + 0x6665, 0x211e, + 0x6666, 0x0580, + 0x6667, 0x13f3, + 0x6669, 0x0d69, + 0x666e, 0x0dd3, + 0x666f, 0x0720, + 0x6670, 0x13f7, + 0x6673, 0x2122, + 0x6674, 0x0a56, + 0x6676, 0x09a5, + 0x667a, 0x0b90, + 0x6681, 0x06bf, + 0x6683, 0x13f8, + 0x6684, 0x13fc, + 0x6687, 0x054b, + 0x6688, 0x13f9, + 0x6689, 0x13fb, + 0x668e, 0x13fa, + 0x6691, 0x0975, + 0x6696, 0x0b86, + 0x6697, 0x0489, + 0x6698, 0x13fd, + 0x6699, 0x2123, + 0x669d, 0x13fe, + 0x66a0, 0x2124, + 0x66a2, 0x0bc6, + 0x66a6, 0x0fb9, + 0x66ab, 0x0891, + 0x66ae, 0x0e3b, + 0x66b2, 0x2125, + 0x66b4, 0x0e6b, + 0x66b8, 0x1405, + 0x66b9, 0x1400, + 0x66bc, 0x1403, + 0x66be, 0x1402, + 0x66bf, 0x2126, + 0x66c1, 0x13ff, + 0x66c4, 0x1404, + 0x66c7, 0x0cb6, + 0x66c9, 0x1401, + 0x66d6, 0x1406, + 0x66d9, 0x0976, + 0x66da, 0x1407, + 0x66dc, 0x0f35, + 0x66dd, 0x0d2e, + 0x66e0, 0x1408, + 0x66e6, 0x140a, + 0x66e9, 0x140b, + 0x66f0, 0x140c, + 0x66f2, 0x06c2, + 0x66f3, 0x04ea, + 0x66f4, 0x07cb, + 0x66f5, 0x140d, + 0x66f7, 0x140e, + 0x66f8, 0x097b, + 0x66f9, 0x0ae4, + 0x66fa, 0x2127, + 0x66fb, 0x20b1, + 0x66fc, 0x10ed, + 0x66fd, 0x0ac0, + 0x66fe, 0x0abf, + 0x66ff, 0x0b38, + 0x6700, 0x0837, + 0x6703, 0x104b, + 0x6708, 0x0744, + 0x6709, 0x0f17, + 0x670b, 0x0e4e, + 0x670d, 0x0df0, + 0x670e, 0x2128, + 0x670f, 0x140f, + 0x6714, 0x0863, + 0x6715, 0x0bdb, + 0x6716, 0x1410, + 0x6717, 0x0fd5, + 0x671b, 0x0e6c, + 0x671d, 0x0bc7, + 0x671e, 0x1411, + 0x671f, 0x0638, + 0x6726, 0x1412, + 0x6728, 0x0ee6, + 0x672a, 0x0eb0, + 0x672b, 0x0ea4, + 0x672c, 0x0e8a, + 0x672d, 0x0873, + 0x672e, 0x1415, + 0x6731, 0x0917, + 0x6734, 0x0e7f, + 0x6736, 0x1417, + 0x6737, 0x141a, + 0x6738, 0x1419, + 0x673a, 0x0635, + 0x673d, 0x067a, + 0x673f, 0x1416, + 0x6741, 0x1418, + 0x6746, 0x141b, + 0x6749, 0x0a3f, + 0x674e, 0x0f65, + 0x674f, 0x048d, + 0x6750, 0x0850, + 0x6751, 0x0b1c, + 0x6753, 0x0909, + 0x6756, 0x09db, + 0x6759, 0x141e, + 0x675c, 0x0c48, + 0x675e, 0x141c, + 0x675f, 0x0b0b, + 0x6760, 0x141d, + 0x6761, 0x09da, + 0x6762, 0x0ee9, + 0x6763, 0x141f, + 0x6765, 0x0f52, + 0x6766, 0x212a, + 0x676a, 0x1425, + 0x676d, 0x07cc, + 0x676f, 0x0d0b, + 0x6770, 0x1422, + 0x6771, 0x0c66, + 0x6772, 0x13e3, + 0x6773, 0x13e7, + 0x6775, 0x0669, + 0x6777, 0x0cfd, + 0x677c, 0x1424, + 0x677e, 0x09a6, + 0x677f, 0x0d58, + 0x6785, 0x142a, + 0x6787, 0x0d8e, + 0x6789, 0x1421, + 0x678b, 0x1427, + 0x678c, 0x1426, + 0x6790, 0x0a73, + 0x6795, 0x0e9b, + 0x6797, 0x0f9b, + 0x679a, 0x0e95, + 0x679c, 0x054c, + 0x679d, 0x08ac, + 0x67a0, 0x0fee, + 0x67a1, 0x1429, + 0x67a2, 0x0a3b, + 0x67a6, 0x1428, + 0x67a9, 0x1423, + 0x67af, 0x0783, + 0x67b3, 0x142f, + 0x67b4, 0x142d, + 0x67b6, 0x054d, + 0x67b7, 0x142b, + 0x67b8, 0x1431, + 0x67b9, 0x1437, + 0x67bb, 0x212b, + 0x67c0, 0x212d, + 0x67c1, 0x0b28, + 0x67c4, 0x0e11, + 0x67c6, 0x1439, + 0x67ca, 0x0d94, + 0x67ce, 0x1438, + 0x67cf, 0x0d26, + 0x67d0, 0x0e6d, + 0x67d1, 0x05f7, + 0x67d3, 0x0a9b, + 0x67d4, 0x094a, + 0x67d8, 0x0bef, + 0x67da, 0x0f18, + 0x67dd, 0x1434, + 0x67de, 0x1433, + 0x67e2, 0x1435, + 0x67e4, 0x1432, + 0x67e7, 0x143a, + 0x67e9, 0x1430, + 0x67ec, 0x142e, + 0x67ee, 0x1436, + 0x67ef, 0x142c, + 0x67f1, 0x0baa, + 0x67f3, 0x0f04, + 0x67f4, 0x08f2, + 0x67f5, 0x0864, + 0x67fb, 0x082a, + 0x67fe, 0x0e9d, + 0x67ff, 0x059f, + 0x6801, 0x212e, + 0x6802, 0x0bea, + 0x6803, 0x0ca2, + 0x6804, 0x04eb, + 0x6805, 0x1e07, + 0x6813, 0x0a96, + 0x6816, 0x0a58, + 0x6817, 0x0700, + 0x681e, 0x143c, + 0x6821, 0x07cd, + 0x6822, 0x05da, + 0x6829, 0x143e, + 0x682a, 0x05d2, + 0x682b, 0x1444, + 0x6832, 0x1441, + 0x6834, 0x0a97, + 0x6838, 0x05a9, + 0x6839, 0x081c, + 0x683c, 0x05a8, + 0x683d, 0x083f, + 0x6840, 0x143f, + 0x6841, 0x073b, + 0x6842, 0x0721, + 0x6843, 0x0c67, + 0x6844, 0x212f, + 0x6846, 0x143d, + 0x6848, 0x048a, + 0x684d, 0x1440, + 0x684e, 0x1442, + 0x6850, 0x06c5, + 0x6851, 0x0702, + 0x6852, 0x212c, + 0x6853, 0x05f8, + 0x6854, 0x0665, + 0x6859, 0x1445, + 0x685c, 0x0869, + 0x685d, 0x0e9f, + 0x685f, 0x0885, + 0x6863, 0x1446, + 0x6867, 0x0da2, + 0x6874, 0x1452, + 0x6876, 0x0533, + 0x6877, 0x1447, + 0x687e, 0x1458, + 0x687f, 0x1448, + 0x6881, 0x0f8a, + 0x6883, 0x144f, + 0x6885, 0x0d15, + 0x688d, 0x1457, + 0x688e, 0x1e9c, + 0x688f, 0x144a, + 0x6893, 0x0478, + 0x6894, 0x144c, + 0x6897, 0x07ce, + 0x689b, 0x144e, + 0x689d, 0x144d, + 0x689f, 0x1449, + 0x68a0, 0x1454, + 0x68a2, 0x09a7, + 0x68a6, 0x11be, + 0x68a7, 0x079c, + 0x68a8, 0x0f66, + 0x68ad, 0x144b, + 0x68af, 0x0c10, + 0x68b0, 0x0581, + 0x68b1, 0x081d, + 0x68b3, 0x1443, + 0x68b5, 0x1453, + 0x68b6, 0x05bf, + 0x68b9, 0x1451, + 0x68ba, 0x1455, + 0x68bc, 0x0c68, + 0x68c4, 0x063a, + 0x68c6, 0x1473, + 0x68c8, 0x20af, + 0x68c9, 0x0ed5, + 0x68ca, 0x145a, + 0x68cb, 0x0639, + 0x68cd, 0x1461, + 0x68cf, 0x2130, + 0x68d2, 0x0e6e, + 0x68d4, 0x1462, + 0x68d5, 0x1464, + 0x68d7, 0x1468, + 0x68d8, 0x145c, + 0x68da, 0x0b68, + 0x68df, 0x0c69, + 0x68e0, 0x146c, + 0x68e1, 0x145f, + 0x68e3, 0x1469, + 0x68e7, 0x1463, + 0x68ee, 0x09ff, + 0x68ef, 0x146d, + 0x68f2, 0x0a57, + 0x68f9, 0x146b, + 0x68fa, 0x05f9, + 0x6900, 0x0ff6, + 0x6901, 0x1459, + 0x6904, 0x1467, + 0x6905, 0x049c, + 0x6908, 0x145b, + 0x690b, 0x0ec6, + 0x690c, 0x1460, + 0x690d, 0x09e8, + 0x690e, 0x0be3, + 0x690f, 0x1456, + 0x6912, 0x1466, + 0x6919, 0x0a40, + 0x691a, 0x1470, + 0x691b, 0x05cf, + 0x691c, 0x0755, + 0x6921, 0x1472, + 0x6922, 0x145d, + 0x6923, 0x1471, + 0x6925, 0x146a, + 0x6926, 0x145e, + 0x6928, 0x146e, + 0x692a, 0x146f, + 0x6930, 0x1480, + 0x6934, 0x0ca6, + 0x6936, 0x1465, + 0x6939, 0x147c, + 0x693d, 0x147e, + 0x693f, 0x0bf4, + 0x694a, 0x0f36, + 0x6953, 0x0de8, + 0x6954, 0x1479, + 0x6955, 0x0b2a, + 0x6959, 0x147f, + 0x695a, 0x0ac1, + 0x695c, 0x1476, + 0x695d, 0x1483, + 0x695e, 0x1482, + 0x6960, 0x0cc7, + 0x6961, 0x1481, + 0x6962, 0x0cc2, + 0x6968, 0x2132, + 0x696a, 0x1485, + 0x696b, 0x1478, + 0x696d, 0x06c0, + 0x696e, 0x147b, + 0x696f, 0x0967, + 0x6973, 0x0d16, + 0x6974, 0x147d, + 0x6975, 0x06c3, + 0x6977, 0x1475, + 0x6978, 0x1477, + 0x6979, 0x1474, + 0x697c, 0x0fd6, + 0x697d, 0x05b8, + 0x697e, 0x147a, + 0x6981, 0x1484, + 0x6982, 0x0593, + 0x698a, 0x0857, + 0x698e, 0x04ff, + 0x6991, 0x1495, + 0x6994, 0x0fd7, + 0x6995, 0x1498, + 0x6998, 0x2134, + 0x699b, 0x0a00, + 0x699c, 0x1497, + 0x69a0, 0x1496, + 0x69a7, 0x1493, + 0x69ae, 0x1487, + 0x69b1, 0x14a4, + 0x69b2, 0x1486, + 0x69b4, 0x1499, + 0x69bb, 0x1491, + 0x69be, 0x148c, + 0x69bf, 0x1489, + 0x69c1, 0x148a, + 0x69c3, 0x1492, + 0x69c7, 0x1d33, + 0x69ca, 0x148f, + 0x69cb, 0x07cf, + 0x69cc, 0x0be4, + 0x69cd, 0x0ae6, + 0x69ce, 0x148d, + 0x69d0, 0x1488, + 0x69d3, 0x148b, + 0x69d8, 0x0f37, + 0x69d9, 0x0e98, + 0x69dd, 0x1490, + 0x69de, 0x149a, + 0x69e2, 0x2135, + 0x69e7, 0x14a2, + 0x69e8, 0x149b, + 0x69eb, 0x14a8, + 0x69ed, 0x14a6, + 0x69f2, 0x14a1, + 0x69f9, 0x14a0, + 0x69fb, 0x0bec, + 0x69fd, 0x0ae7, + 0x69ff, 0x149e, + 0x6a02, 0x149c, + 0x6a05, 0x14a3, + 0x6a0a, 0x14a9, + 0x6a0b, 0x0d89, + 0x6a0c, 0x14af, + 0x6a12, 0x14aa, + 0x6a13, 0x14ad, + 0x6a14, 0x14a7, + 0x6a17, 0x0bb2, + 0x6a19, 0x0daa, + 0x6a1b, 0x149d, + 0x6a1e, 0x14a5, + 0x6a1f, 0x09a8, + 0x6a21, 0x0edb, + 0x6a22, 0x14b9, + 0x6a23, 0x14ac, + 0x6a29, 0x0756, + 0x6a2a, 0x0523, + 0x6a2b, 0x05bd, + 0x6a2e, 0x1494, + 0x6a30, 0x2136, + 0x6a35, 0x09a9, + 0x6a36, 0x14b1, + 0x6a38, 0x14b8, + 0x6a39, 0x0925, + 0x6a3a, 0x05d0, + 0x6a3d, 0x0b6c, + 0x6a44, 0x14ae, + 0x6a46, 0x2138, + 0x6a47, 0x14b3, + 0x6a48, 0x14b7, + 0x6a4b, 0x06ae, + 0x6a58, 0x0666, + 0x6a59, 0x14b5, + 0x6a5f, 0x063b, + 0x6a61, 0x0ca3, + 0x6a62, 0x14b4, + 0x6a66, 0x14b6, + 0x6a6b, 0x2137, + 0x6a72, 0x14b0, + 0x6a73, 0x2139, + 0x6a78, 0x14b2, + 0x6a7e, 0x213a, + 0x6a7f, 0x05be, + 0x6a80, 0x0b87, + 0x6a84, 0x14bd, + 0x6a8d, 0x14bb, + 0x6a8e, 0x079d, + 0x6a90, 0x14ba, + 0x6a97, 0x14c0, + 0x6a9c, 0x143b, + 0x6aa0, 0x14bc, + 0x6aa2, 0x14be, + 0x6aaa, 0x14cb, + 0x6aac, 0x14c7, + 0x6aae, 0x1450, + 0x6ab3, 0x14c6, + 0x6ab8, 0x14c5, + 0x6abb, 0x14c2, + 0x6ac1, 0x14ab, + 0x6ac2, 0x14c4, + 0x6ac3, 0x14c3, + 0x6ad1, 0x14c9, + 0x6ad3, 0x0fcc, + 0x6ada, 0x14cc, + 0x6adb, 0x06f3, + 0x6ade, 0x14c8, + 0x6adf, 0x14ca, + 0x6ae2, 0x213b, + 0x6ae4, 0x213c, + 0x6ae8, 0x0d3b, + 0x6aea, 0x14cd, + 0x6afa, 0x14d1, + 0x6afb, 0x14ce, + 0x6b04, 0x0f5d, + 0x6b05, 0x14cf, + 0x6b0a, 0x149f, + 0x6b12, 0x14d2, + 0x6b16, 0x14d3, + 0x6b1d, 0x04d7, + 0x6b1f, 0x14d5, + 0x6b20, 0x073d, + 0x6b21, 0x08cd, + 0x6b23, 0x06cd, + 0x6b27, 0x0524, + 0x6b32, 0x0f49, + 0x6b37, 0x14d7, + 0x6b38, 0x14d6, + 0x6b39, 0x14d9, + 0x6b3a, 0x0657, + 0x6b3d, 0x06ce, + 0x6b3e, 0x05fa, + 0x6b43, 0x14dc, + 0x6b47, 0x14db, + 0x6b49, 0x14dd, + 0x6b4c, 0x054e, + 0x6b4e, 0x0b75, + 0x6b50, 0x14de, + 0x6b53, 0x05fb, + 0x6b54, 0x14e0, + 0x6b59, 0x14df, + 0x6b5b, 0x14e1, + 0x6b5f, 0x14e2, + 0x6b61, 0x14e3, + 0x6b62, 0x08ad, + 0x6b63, 0x0a59, + 0x6b64, 0x0811, + 0x6b66, 0x0de2, + 0x6b69, 0x0e32, + 0x6b6a, 0x0fea, + 0x6b6f, 0x08c3, + 0x6b73, 0x0840, + 0x6b74, 0x0fba, + 0x6b78, 0x14e4, + 0x6b7b, 0x08ae, + 0x6b7f, 0x14e6, + 0x6b83, 0x14e9, + 0x6b84, 0x14e8, + 0x6b86, 0x0e86, + 0x6b89, 0x0968, + 0x6b8a, 0x0918, + 0x6b8b, 0x0892, + 0x6b8d, 0x14ea, + 0x6b95, 0x14ec, + 0x6b96, 0x09e9, + 0x6b98, 0x14eb, + 0x6b9e, 0x14ed, + 0x6ba4, 0x14ee, + 0x6baa, 0x14ef, + 0x6baf, 0x14f1, + 0x6bb1, 0x14f3, + 0x6bb2, 0x14f2, + 0x6bb3, 0x14f4, + 0x6bb4, 0x0525, + 0x6bb5, 0x0b88, + 0x6bb7, 0x14f5, + 0x6bba, 0x0874, + 0x6bbb, 0x05aa, + 0x6bbc, 0x14f6, + 0x6bbf, 0x0c3c, + 0x6bc0, 0x119d, + 0x6bc5, 0x063d, + 0x6bc6, 0x14f7, + 0x6bcb, 0x14f8, + 0x6bcd, 0x0e3c, + 0x6bce, 0x0e96, + 0x6bd2, 0x0c9f, + 0x6bd3, 0x14f9, + 0x6bd4, 0x0d7a, + 0x6bd6, 0x213d, + 0x6bd8, 0x0d8f, + 0x6bdb, 0x0edf, + 0x6bdf, 0x14fa, + 0x6beb, 0x14fc, + 0x6bec, 0x14fb, + 0x6bef, 0x14fe, + 0x6bf3, 0x14fd, + 0x6c08, 0x1500, + 0x6c0f, 0x08af, + 0x6c11, 0x0ebd, + 0x6c13, 0x1501, + 0x6c17, 0x063e, + 0x6c1b, 0x1503, + 0x6c23, 0x1505, + 0x6c24, 0x1504, + 0x6c34, 0x0a2b, + 0x6c37, 0x0dab, + 0x6c38, 0x04ec, + 0x6c3e, 0x0d59, + 0x6c3f, 0x213e, + 0x6c40, 0x0c11, + 0x6c41, 0x094b, + 0x6c42, 0x067b, + 0x6c4e, 0x0d5a, + 0x6c50, 0x08da, + 0x6c55, 0x1507, + 0x6c57, 0x05fc, + 0x6c5a, 0x051a, + 0x6c5c, 0x213f, + 0x6c5d, 0x0cca, + 0x6c5e, 0x1506, + 0x6c5f, 0x07d0, + 0x6c60, 0x0b91, + 0x6c62, 0x1508, + 0x6c68, 0x1510, + 0x6c6a, 0x1509, + 0x6c6f, 0x2141, + 0x6c70, 0x0b21, + 0x6c72, 0x067c, + 0x6c73, 0x1511, + 0x6c7a, 0x073e, + 0x6c7d, 0x063f, + 0x6c7e, 0x150f, + 0x6c81, 0x150d, + 0x6c82, 0x150a, + 0x6c83, 0x0f4a, + 0x6c86, 0x2140, + 0x6c88, 0x0bdc, + 0x6c8c, 0x0cb1, + 0x6c8d, 0x150b, + 0x6c90, 0x1513, + 0x6c92, 0x1512, + 0x6c93, 0x06f9, + 0x6c96, 0x052d, + 0x6c99, 0x082b, + 0x6c9a, 0x150c, + 0x6c9b, 0x150e, + 0x6ca1, 0x0e85, + 0x6ca2, 0x0b54, + 0x6cab, 0x0ea5, + 0x6cae, 0x151b, + 0x6cb1, 0x151c, + 0x6cb3, 0x054f, + 0x6cb8, 0x0df8, + 0x6cb9, 0x0f09, + 0x6cba, 0x151e, + 0x6cbb, 0x08cf, + 0x6cbc, 0x09aa, + 0x6cbd, 0x1517, + 0x6cbe, 0x151d, + 0x6cbf, 0x050a, + 0x6cc1, 0x06af, + 0x6cc4, 0x1514, + 0x6cc5, 0x1519, + 0x6cc9, 0x0a98, + 0x6cca, 0x0d27, + 0x6ccc, 0x0d7b, + 0x6cd3, 0x1516, + 0x6cd5, 0x0e4f, + 0x6cd7, 0x1518, + 0x6cd9, 0x1521, + 0x6cda, 0x2142, + 0x6cdb, 0x151f, + 0x6cdd, 0x151a, + 0x6ce1, 0x0e50, + 0x6ce2, 0x0cfe, + 0x6ce3, 0x067d, + 0x6ce5, 0x0c1f, + 0x6ce8, 0x0bab, + 0x6cea, 0x1522, + 0x6cef, 0x1520, + 0x6cf0, 0x0b39, + 0x6cf1, 0x1515, + 0x6cf3, 0x04ed, + 0x6d04, 0x2143, + 0x6d0b, 0x0f38, + 0x6d0c, 0x152d, + 0x6d12, 0x152c, + 0x6d17, 0x0a9a, + 0x6d19, 0x1529, + 0x6d1b, 0x0f56, + 0x6d1e, 0x0c8e, + 0x6d1f, 0x1523, + 0x6d25, 0x0be1, + 0x6d29, 0x04ee, + 0x6d2a, 0x07d1, + 0x6d2b, 0x1526, + 0x6d32, 0x0931, + 0x6d33, 0x152b, + 0x6d35, 0x152a, + 0x6d36, 0x1525, + 0x6d38, 0x1528, + 0x6d3b, 0x05c6, + 0x6d3d, 0x1527, + 0x6d3e, 0x0cff, + 0x6d41, 0x0f76, + 0x6d44, 0x09dc, + 0x6d45, 0x0a99, + 0x6d59, 0x1533, + 0x6d5a, 0x1531, + 0x6d5c, 0x0dbf, + 0x6d63, 0x152e, + 0x6d64, 0x1530, + 0x6d66, 0x04dc, + 0x6d69, 0x07d2, + 0x6d6a, 0x0fd8, + 0x6d6c, 0x059b, + 0x6d6e, 0x0dd4, + 0x6d6f, 0x2145, + 0x6d74, 0x0f4b, + 0x6d77, 0x0582, + 0x6d78, 0x0a01, + 0x6d79, 0x1532, + 0x6d85, 0x1537, + 0x6d87, 0x2144, + 0x6d88, 0x09ab, + 0x6d8c, 0x0f1a, + 0x6d8e, 0x1534, + 0x6d93, 0x152f, + 0x6d95, 0x1535, + 0x6d96, 0x2146, + 0x6d99, 0x0fa6, + 0x6d9b, 0x0c6d, + 0x6d9c, 0x0c9a, + 0x6dac, 0x2147, + 0x6daf, 0x0594, + 0x6db2, 0x04f7, + 0x6db5, 0x153b, + 0x6db8, 0x153e, + 0x6dbc, 0x0f8b, + 0x6dc0, 0x0f4e, + 0x6dc5, 0x1545, + 0x6dc6, 0x153f, + 0x6dc7, 0x153c, + 0x6dcb, 0x0f9c, + 0x6dcc, 0x1542, + 0x6dcf, 0x2148, + 0x6dd1, 0x0954, + 0x6dd2, 0x1544, + 0x6dd5, 0x1549, + 0x6dd8, 0x0c6b, + 0x6dd9, 0x1547, + 0x6dde, 0x1541, + 0x6de1, 0x0b76, + 0x6de4, 0x1548, + 0x6de6, 0x153d, + 0x6de8, 0x1543, + 0x6dea, 0x154a, + 0x6deb, 0x04c0, + 0x6dec, 0x1540, + 0x6dee, 0x154b, + 0x6df1, 0x0a02, + 0x6df2, 0x214a, + 0x6df3, 0x0969, + 0x6df5, 0x0df5, + 0x6df7, 0x081e, + 0x6df8, 0x2149, + 0x6df9, 0x1538, + 0x6dfa, 0x1546, + 0x6dfb, 0x0c34, + 0x6dfc, 0x214b, + 0x6e05, 0x0a5a, + 0x6e07, 0x05c7, + 0x6e08, 0x0841, + 0x6e09, 0x09ac, + 0x6e0a, 0x153a, + 0x6e0b, 0x094c, + 0x6e13, 0x0722, + 0x6e15, 0x1539, + 0x6e19, 0x154f, + 0x6e1a, 0x0977, + 0x6e1b, 0x076e, + 0x6e1d, 0x155e, + 0x6e1f, 0x1558, + 0x6e20, 0x068e, + 0x6e21, 0x0c49, + 0x6e23, 0x1553, + 0x6e24, 0x155c, + 0x6e25, 0x0473, + 0x6e26, 0x04d4, + 0x6e27, 0x214e, + 0x6e29, 0x0539, + 0x6e2b, 0x1555, + 0x6e2c, 0x0b0c, + 0x6e2d, 0x154c, + 0x6e2e, 0x154e, + 0x6e2f, 0x07d3, + 0x6e38, 0x155f, + 0x6e39, 0x214c, + 0x6e3a, 0x155a, + 0x6e3c, 0x214f, + 0x6e3e, 0x1552, + 0x6e43, 0x1559, + 0x6e4a, 0x0eb7, + 0x6e4d, 0x1557, + 0x6e4e, 0x155b, + 0x6e56, 0x0784, + 0x6e58, 0x09ad, + 0x6e5b, 0x0b77, + 0x6e5c, 0x214d, + 0x6e5f, 0x1551, + 0x6e67, 0x0f19, + 0x6e6b, 0x1554, + 0x6e6e, 0x154d, + 0x6e6f, 0x0c6c, + 0x6e72, 0x1550, + 0x6e76, 0x1556, + 0x6e7e, 0x0ff7, + 0x6e7f, 0x08ea, + 0x6e80, 0x0eac, + 0x6e82, 0x1560, + 0x6e8c, 0x0d42, + 0x6e8f, 0x156c, + 0x6e90, 0x076f, + 0x6e96, 0x096a, + 0x6e98, 0x1562, + 0x6e9c, 0x0f77, + 0x6e9d, 0x07d4, + 0x6e9f, 0x156f, + 0x6ea2, 0x04b2, + 0x6ea5, 0x156d, + 0x6eaa, 0x1561, + 0x6eaf, 0x1567, + 0x6eb2, 0x1569, + 0x6eb6, 0x0f39, + 0x6eb7, 0x1564, + 0x6eba, 0x0c28, + 0x6ebd, 0x1566, + 0x6ebf, 0x2150, + 0x6ec2, 0x156e, + 0x6ec4, 0x1568, + 0x6ec5, 0x0ed3, + 0x6ec9, 0x1563, + 0x6ecb, 0x08ce, + 0x6ecc, 0x157b, + 0x6ed1, 0x05c8, + 0x6ed3, 0x1565, + 0x6ed4, 0x156a, + 0x6edd, 0x0b4c, + 0x6ede, 0x0b3a, + 0x6eec, 0x1573, + 0x6eef, 0x1579, + 0x6ef2, 0x1577, + 0x6ef4, 0x0c23, + 0x6ef7, 0x157e, + 0x6ef8, 0x1574, + 0x6efe, 0x1575, + 0x6eff, 0x155d, + 0x6f01, 0x0693, + 0x6f02, 0x0dac, + 0x6f06, 0x08eb, + 0x6f09, 0x0809, + 0x6f0f, 0x0fd9, + 0x6f11, 0x1571, + 0x6f13, 0x157d, + 0x6f14, 0x050b, + 0x6f15, 0x0ae8, + 0x6f20, 0x0d2f, + 0x6f22, 0x05fd, + 0x6f23, 0x0fc2, + 0x6f2b, 0x0ead, + 0x6f2c, 0x0bee, + 0x6f31, 0x1578, + 0x6f32, 0x157a, + 0x6f38, 0x0ab4, + 0x6f3e, 0x157c, + 0x6f3f, 0x1576, + 0x6f41, 0x1570, + 0x6f45, 0x05ff, + 0x6f51, 0x1e60, + 0x6f54, 0x073f, + 0x6f58, 0x158a, + 0x6f5b, 0x1585, + 0x6f5c, 0x0a9c, + 0x6f5f, 0x05c1, + 0x6f64, 0x096b, + 0x6f66, 0x158e, + 0x6f6d, 0x1587, + 0x6f6e, 0x0bc8, + 0x6f6f, 0x1584, + 0x6f70, 0x0bf5, + 0x6f74, 0x15a7, + 0x6f78, 0x1581, + 0x6f7a, 0x1580, + 0x6f7c, 0x1589, + 0x6f80, 0x1583, + 0x6f81, 0x1582, + 0x6f82, 0x1588, + 0x6f84, 0x0a45, + 0x6f86, 0x157f, + 0x6f88, 0x2151, + 0x6f8e, 0x158b, + 0x6f91, 0x158c, + 0x6f97, 0x05fe, + 0x6fa1, 0x1591, + 0x6fa3, 0x1590, + 0x6fa4, 0x1592, + 0x6faa, 0x1595, + 0x6fb1, 0x0c3d, + 0x6fb3, 0x158f, + 0x6fb5, 0x2152, + 0x6fb9, 0x1593, + 0x6fc0, 0x0739, + 0x6fc1, 0x0b59, + 0x6fc2, 0x158d, + 0x6fc3, 0x0cf1, + 0x6fc6, 0x1594, + 0x6fd4, 0x1599, + 0x6fd5, 0x1597, + 0x6fd8, 0x159a, + 0x6fdb, 0x159d, + 0x6fdf, 0x1596, + 0x6fe0, 0x07fc, + 0x6fe1, 0x0cde, + 0x6fe4, 0x1536, + 0x6feb, 0x0f5e, + 0x6fec, 0x1598, + 0x6fee, 0x159c, + 0x6fef, 0x0b55, + 0x6ff1, 0x159b, + 0x6ff3, 0x1586, + 0x6ff5, 0x2153, + 0x6ff6, 0x1ba4, + 0x6ffa, 0x15a0, + 0x6ffe, 0x15a4, + 0x7001, 0x15a2, + 0x7005, 0x2154, + 0x7006, 0x1e50, + 0x7007, 0x2155, + 0x7009, 0x159e, + 0x700b, 0x159f, + 0x700f, 0x15a3, + 0x7011, 0x15a1, + 0x7015, 0x0dc0, + 0x7018, 0x15a9, + 0x701a, 0x15a6, + 0x701b, 0x15a5, + 0x701d, 0x15a8, + 0x701e, 0x0cac, + 0x701f, 0x15aa, + 0x7026, 0x0bb3, + 0x7027, 0x0b4d, + 0x7028, 0x2156, + 0x702c, 0x0a49, + 0x7030, 0x15ab, + 0x7032, 0x15ad, + 0x703e, 0x15ac, + 0x704c, 0x1572, + 0x7051, 0x15ae, + 0x7058, 0x0cbf, + 0x7063, 0x15af, + 0x706b, 0x0550, + 0x706f, 0x0c6e, + 0x7070, 0x0583, + 0x7078, 0x067e, + 0x707c, 0x090a, + 0x707d, 0x0842, + 0x7085, 0x2157, + 0x7089, 0x0fcd, + 0x708a, 0x0a2c, + 0x708e, 0x050c, + 0x7092, 0x15b1, + 0x7099, 0x15b0, + 0x70ab, 0x2158, + 0x70ac, 0x15b4, + 0x70ad, 0x0b78, + 0x70ae, 0x15b7, + 0x70af, 0x15b2, + 0x70b3, 0x15b6, + 0x70b8, 0x15b5, + 0x70b9, 0x0c3a, + 0x70ba, 0x049d, + 0x70bb, 0x20ad, + 0x70c8, 0x0fbd, + 0x70cb, 0x15b9, + 0x70cf, 0x04ca, + 0x70d9, 0x15bb, + 0x70dd, 0x15ba, + 0x70df, 0x15b8, + 0x70f1, 0x15b3, + 0x70f9, 0x0e51, + 0x70fd, 0x15bd, + 0x7104, 0x215a, + 0x7109, 0x15bc, + 0x710f, 0x2159, + 0x7114, 0x050d, + 0x7119, 0x15bf, + 0x711a, 0x0e02, + 0x711c, 0x15be, + 0x7121, 0x0ec1, + 0x7126, 0x09af, + 0x7130, 0x1ddc, + 0x7136, 0x0ab5, + 0x713c, 0x09ae, + 0x7146, 0x215c, + 0x7149, 0x0fc3, + 0x714c, 0x15c5, + 0x714e, 0x0a9d, + 0x7155, 0x15c1, + 0x7156, 0x15c6, + 0x7159, 0x050e, + 0x715c, 0x215b, + 0x7162, 0x15c4, + 0x7164, 0x0d17, + 0x7165, 0x15c0, + 0x7166, 0x15c3, + 0x7167, 0x09b0, + 0x7169, 0x0d65, + 0x716c, 0x15c7, + 0x716e, 0x08fd, + 0x717d, 0x0a9e, + 0x7184, 0x15ca, + 0x7188, 0x15c2, + 0x718a, 0x06fd, + 0x718f, 0x15c8, + 0x7194, 0x0f3a, + 0x7195, 0x15cb, + 0x7199, 0x205d, + 0x719f, 0x0959, + 0x71a8, 0x15cc, + 0x71ac, 0x15cd, + 0x71b1, 0x0ce4, + 0x71b9, 0x15cf, + 0x71be, 0x15d0, + 0x71c1, 0x215f, + 0x71c3, 0x0ce9, + 0x71c8, 0x0c6f, + 0x71c9, 0x15d2, + 0x71ce, 0x15d4, + 0x71d0, 0x0f9d, + 0x71d2, 0x15d1, + 0x71d4, 0x15d3, + 0x71d5, 0x050f, + 0x71d7, 0x15ce, + 0x71df, 0x114e, + 0x71e0, 0x15d5, + 0x71e5, 0x0ae9, + 0x71e6, 0x0886, + 0x71e7, 0x15d7, + 0x71ec, 0x15d6, + 0x71ed, 0x09ea, + 0x71ee, 0x10ee, + 0x71f5, 0x15d8, + 0x71f9, 0x15da, + 0x71fb, 0x15c9, + 0x71fc, 0x15d9, + 0x71fe, 0x2160, + 0x71ff, 0x15db, + 0x7206, 0x0d30, + 0x720d, 0x15dc, + 0x7210, 0x15dd, + 0x721b, 0x15de, + 0x7228, 0x15df, + 0x722a, 0x0bfa, + 0x722c, 0x15e1, + 0x722d, 0x15e0, + 0x7230, 0x15e2, + 0x7232, 0x15e3, + 0x7235, 0x090b, + 0x7236, 0x0dd5, + 0x723a, 0x0ef8, + 0x723b, 0x15e4, + 0x723d, 0x0ad8, + 0x723e, 0x08d0, + 0x723f, 0x15e6, + 0x7246, 0x15e8, + 0x7247, 0x0e22, + 0x7248, 0x0d5b, + 0x724b, 0x15e9, + 0x724c, 0x0d0d, + 0x7252, 0x0bc9, + 0x7258, 0x15ea, + 0x7259, 0x0567, + 0x725b, 0x0687, + 0x725d, 0x0ed2, + 0x725f, 0x0ec2, + 0x7261, 0x0534, + 0x7262, 0x0fda, + 0x7267, 0x0e80, + 0x7269, 0x0dfa, + 0x7272, 0x0a5b, + 0x7274, 0x15eb, + 0x7279, 0x0c9b, + 0x727d, 0x0757, + 0x727e, 0x15ec, + 0x7280, 0x0844, + 0x7281, 0x15ee, + 0x7282, 0x15ed, + 0x7287, 0x15ef, + 0x7292, 0x15f0, + 0x7296, 0x15f1, + 0x72a0, 0x0658, + 0x72a2, 0x15f2, + 0x72a7, 0x15f3, + 0x72ac, 0x0758, + 0x72af, 0x0d5c, + 0x72b1, 0x2161, + 0x72b2, 0x15f5, + 0x72b6, 0x09dd, + 0x72b9, 0x15f4, + 0x72be, 0x2162, + 0x72c2, 0x06b0, + 0x72c3, 0x15f6, + 0x72c4, 0x15f8, + 0x72c6, 0x15f7, + 0x72ce, 0x15f9, + 0x72d0, 0x0785, + 0x72d2, 0x15fa, + 0x72d7, 0x06e1, + 0x72d9, 0x0ac2, + 0x72db, 0x080f, + 0x72e0, 0x15fc, + 0x72e2, 0x15fb, + 0x72e9, 0x0919, + 0x72ec, 0x0ca0, + 0x72ed, 0x06b1, + 0x72f7, 0x15ff, + 0x72f8, 0x0b6a, + 0x72f9, 0x15fe, + 0x72fc, 0x0fdb, + 0x72fd, 0x0d18, + 0x730a, 0x1602, + 0x7316, 0x1604, + 0x7317, 0x1601, + 0x731b, 0x0ee0, + 0x731c, 0x1603, + 0x731d, 0x1605, + 0x731f, 0x0f8c, + 0x7324, 0x2163, + 0x7325, 0x1609, + 0x7329, 0x1608, + 0x732a, 0x0bb4, + 0x732b, 0x0ce3, + 0x732e, 0x0759, + 0x732f, 0x1607, + 0x7334, 0x1606, + 0x7336, 0x0f1b, + 0x733e, 0x160a, + 0x733f, 0x0510, + 0x7344, 0x0808, + 0x7345, 0x08b0, + 0x734e, 0x160b, + 0x7357, 0x160e, + 0x7363, 0x094d, + 0x7368, 0x1610, + 0x736a, 0x160f, + 0x7370, 0x1611, + 0x7372, 0x05ab, + 0x7375, 0x1613, + 0x7377, 0x2165, + 0x7378, 0x1612, + 0x737a, 0x1615, + 0x737b, 0x1614, + 0x7384, 0x0770, + 0x7387, 0x0f70, + 0x7389, 0x06c4, + 0x738b, 0x0526, + 0x7396, 0x06e2, + 0x73a9, 0x061d, + 0x73b2, 0x0fb0, + 0x73b3, 0x1617, + 0x73bb, 0x1619, + 0x73bd, 0x2166, + 0x73c0, 0x161a, + 0x73c2, 0x0551, + 0x73c8, 0x1616, + 0x73c9, 0x2167, + 0x73ca, 0x0887, + 0x73cd, 0x0bdd, + 0x73ce, 0x1618, + 0x73d2, 0x216a, + 0x73d6, 0x2168, + 0x73de, 0x161d, + 0x73e0, 0x091a, + 0x73e3, 0x2169, + 0x73e5, 0x161b, + 0x73ea, 0x0714, + 0x73ed, 0x0d5d, + 0x73ee, 0x161c, + 0x73f1, 0x1637, + 0x73f5, 0x216c, + 0x73f8, 0x1622, + 0x73fe, 0x0771, + 0x7403, 0x067f, + 0x7405, 0x161f, + 0x7406, 0x0f67, + 0x7407, 0x216b, + 0x7409, 0x0f78, + 0x7422, 0x0b56, + 0x7425, 0x1621, + 0x7426, 0x216d, + 0x7429, 0x216f, + 0x742a, 0x216e, + 0x742e, 0x2170, + 0x7432, 0x1623, + 0x7433, 0x0f9e, + 0x7434, 0x06cf, + 0x7435, 0x0d90, + 0x7436, 0x0d00, + 0x743a, 0x1624, + 0x743f, 0x1626, + 0x7441, 0x1629, + 0x7455, 0x1625, + 0x7459, 0x1628, + 0x745a, 0x079e, + 0x745b, 0x04ef, + 0x745c, 0x162a, + 0x745e, 0x0a36, + 0x745f, 0x1627, + 0x7460, 0x0fa4, + 0x7462, 0x2171, + 0x7463, 0x162d, + 0x7464, 0x1d35, + 0x7469, 0x162b, + 0x746a, 0x162e, + 0x746f, 0x1620, + 0x7470, 0x162c, + 0x7473, 0x082c, + 0x7476, 0x162f, + 0x747e, 0x1630, + 0x7483, 0x0f68, + 0x7489, 0x2172, + 0x748b, 0x1631, + 0x749e, 0x1632, + 0x749f, 0x2173, + 0x74a2, 0x161e, + 0x74a7, 0x1633, + 0x74b0, 0x0600, + 0x74bd, 0x08d1, + 0x74ca, 0x1634, + 0x74cf, 0x1635, + 0x74d4, 0x1636, + 0x74dc, 0x04dd, + 0x74e0, 0x1638, + 0x74e2, 0x0dad, + 0x74e3, 0x1639, + 0x74e6, 0x05e0, + 0x74e7, 0x163a, + 0x74e9, 0x163b, + 0x74ee, 0x163c, + 0x74f0, 0x163e, + 0x74f2, 0x163d, + 0x74f6, 0x0dc5, + 0x74f7, 0x1641, + 0x74f8, 0x1640, + 0x7501, 0x2174, + 0x7503, 0x1643, + 0x7504, 0x1642, + 0x7505, 0x1644, + 0x750c, 0x1645, + 0x750d, 0x1647, + 0x750e, 0x1646, + 0x7511, 0x080b, + 0x7513, 0x1649, + 0x7515, 0x1648, + 0x7518, 0x0601, + 0x751a, 0x0a19, + 0x751c, 0x0c36, + 0x751e, 0x164a, + 0x751f, 0x0a5c, + 0x7523, 0x0888, + 0x7525, 0x051b, + 0x7526, 0x164b, + 0x7528, 0x0f3b, + 0x752b, 0x0e33, + 0x752c, 0x164c, + 0x752f, 0x20f2, + 0x7530, 0x0c3e, + 0x7531, 0x0f1d, + 0x7532, 0x07d5, + 0x7533, 0x0a03, + 0x7537, 0x0b89, + 0x7538, 0x10c9, + 0x753a, 0x0bca, + 0x753b, 0x0568, + 0x753c, 0x164d, + 0x7544, 0x164e, + 0x7546, 0x1653, + 0x7549, 0x1651, + 0x754a, 0x1650, + 0x754b, 0x13c7, + 0x754c, 0x0584, + 0x754d, 0x164f, + 0x754f, 0x049e, + 0x7551, 0x0d3e, + 0x7554, 0x0d5e, + 0x7559, 0x0f79, + 0x755a, 0x1654, + 0x755b, 0x1652, + 0x755c, 0x0b9a, + 0x755d, 0x0a4a, + 0x7560, 0x0d3f, + 0x7562, 0x0d9f, + 0x7564, 0x1656, + 0x7565, 0x0f74, + 0x7566, 0x0723, + 0x7567, 0x1657, + 0x7569, 0x1655, + 0x756a, 0x0d6a, + 0x756b, 0x1658, + 0x756d, 0x1659, + 0x756f, 0x2175, + 0x7570, 0x049f, + 0x7573, 0x09de, + 0x7574, 0x165e, + 0x7576, 0x165b, + 0x7577, 0x0cc5, + 0x7578, 0x165a, + 0x757f, 0x0640, + 0x7582, 0x1661, + 0x7586, 0x165c, + 0x7589, 0x1660, + 0x758a, 0x165f, + 0x758b, 0x0d97, + 0x758e, 0x0ac4, + 0x758f, 0x0ac3, + 0x7591, 0x0659, + 0x7594, 0x1662, + 0x759a, 0x1663, + 0x759d, 0x1664, + 0x75a3, 0x1666, + 0x75a5, 0x1665, + 0x75ab, 0x04f8, + 0x75b1, 0x166e, + 0x75b2, 0x0d7c, + 0x75b3, 0x1668, + 0x75b5, 0x166a, + 0x75b8, 0x166c, + 0x75b9, 0x0a04, + 0x75bc, 0x166d, + 0x75bd, 0x166b, + 0x75be, 0x08ec, + 0x75c2, 0x1667, + 0x75c3, 0x1669, + 0x75c5, 0x0db4, + 0x75c7, 0x09b1, + 0x75ca, 0x1670, + 0x75cd, 0x166f, + 0x75d2, 0x1671, + 0x75d4, 0x08d2, + 0x75d5, 0x081f, + 0x75d8, 0x0c71, + 0x75d9, 0x1672, + 0x75db, 0x0be7, + 0x75de, 0x1674, + 0x75e2, 0x0f69, + 0x75e3, 0x1673, + 0x75e9, 0x0aeb, + 0x75f0, 0x1679, + 0x75f2, 0x167b, + 0x75f4, 0x0b92, + 0x75fa, 0x167a, + 0x75fc, 0x1677, + 0x75fe, 0x1675, + 0x7601, 0x1678, + 0x7609, 0x167f, + 0x760b, 0x167d, + 0x760d, 0x167e, + 0x761f, 0x1680, + 0x7620, 0x1682, + 0x7624, 0x1685, + 0x7626, 0x1e2d, + 0x7627, 0x1681, + 0x7630, 0x1687, + 0x7634, 0x1686, + 0x763b, 0x1688, + 0x7642, 0x0f8d, + 0x7646, 0x168b, + 0x7647, 0x1689, + 0x764c, 0x061e, + 0x7652, 0x0f0a, + 0x7656, 0x0e1a, + 0x7658, 0x168d, + 0x765c, 0x168c, + 0x7661, 0x168e, + 0x7667, 0x1693, + 0x7668, 0x1690, + 0x766c, 0x1694, + 0x7670, 0x1695, + 0x7672, 0x1696, + 0x7676, 0x1697, + 0x7678, 0x1698, + 0x767a, 0x0d43, + 0x767b, 0x0c4a, + 0x767c, 0x1699, + 0x767d, 0x0d28, + 0x767e, 0x0da6, + 0x7680, 0x169a, + 0x7682, 0x2176, + 0x7683, 0x169b, + 0x7684, 0x0c24, + 0x7686, 0x0585, + 0x7687, 0x07d6, + 0x7688, 0x169c, + 0x768b, 0x169d, + 0x768e, 0x169e, + 0x7690, 0x0877, + 0x7693, 0x16a0, + 0x7696, 0x169f, + 0x7699, 0x16a1, + 0x769b, 0x2179, + 0x769c, 0x2177, + 0x769e, 0x2178, + 0x76a6, 0x217a, + 0x76ae, 0x0d7d, + 0x76b0, 0x16a3, + 0x76b4, 0x16a4, + 0x76b7, 0x1d1c, + 0x76b8, 0x16a5, + 0x76bf, 0x087c, + 0x76c2, 0x16a8, + 0x76c3, 0x0d0c, + 0x76c6, 0x0e8d, + 0x76c8, 0x04f0, + 0x76ca, 0x04f9, + 0x76cd, 0x16a9, + 0x76d2, 0x16ab, + 0x76d6, 0x16aa, + 0x76d7, 0x0c6a, + 0x76db, 0x0a5d, + 0x76dc, 0x14d8, + 0x76de, 0x16ac, + 0x76df, 0x0ecd, + 0x76e1, 0x16ad, + 0x76e3, 0x0602, + 0x76e4, 0x0d6b, + 0x76e5, 0x16ae, + 0x76e7, 0x16af, + 0x76ea, 0x16b0, + 0x76ee, 0x0ee8, + 0x76f2, 0x0ee1, + 0x76f4, 0x0bda, + 0x76f8, 0x0aec, + 0x76fb, 0x16b2, + 0x76fe, 0x096c, + 0x7701, 0x09b2, + 0x7704, 0x16b5, + 0x7707, 0x16b4, + 0x7708, 0x16b3, + 0x7709, 0x0d91, + 0x770b, 0x0603, + 0x770c, 0x075d, + 0x771b, 0x16bb, + 0x771e, 0x16b8, + 0x771f, 0x0a05, + 0x7720, 0x0ebe, + 0x7724, 0x16b7, + 0x7725, 0x16b9, + 0x7729, 0x16b6, + 0x7737, 0x16bc, + 0x773a, 0x0bcb, + 0x773c, 0x061f, + 0x7740, 0x0ba3, + 0x7746, 0x217c, + 0x7747, 0x16be, + 0x775a, 0x16bf, + 0x775b, 0x16c2, + 0x7761, 0x0a2d, + 0x7762, 0x1ec5, + 0x7763, 0x0c9c, + 0x7765, 0x16c3, + 0x7766, 0x0e81, + 0x7768, 0x16c0, + 0x776b, 0x16c1, + 0x7779, 0x16c6, + 0x777e, 0x16c5, + 0x777f, 0x16c4, + 0x778b, 0x16c8, + 0x778e, 0x16c7, + 0x7791, 0x16c9, + 0x779e, 0x16cb, + 0x77a0, 0x16ca, + 0x77a5, 0x0e1d, + 0x77ac, 0x0960, + 0x77ad, 0x0f8e, + 0x77b0, 0x16cc, + 0x77b3, 0x0c8f, + 0x77b6, 0x16cd, + 0x77b9, 0x16ce, + 0x77bb, 0x16d2, + 0x77bc, 0x16d0, + 0x77bf, 0x16cf, + 0x77c7, 0x16d3, + 0x77cd, 0x16d4, + 0x77d7, 0x16d5, + 0x77da, 0x16d6, + 0x77db, 0x0ec3, + 0x77dc, 0x16d7, + 0x77e2, 0x0efc, + 0x77e3, 0x16d8, + 0x77e5, 0x0b8c, + 0x77e7, 0x0d20, + 0x77e9, 0x06e3, + 0x77ed, 0x0b79, + 0x77ee, 0x16d9, + 0x77ef, 0x06b2, + 0x77f3, 0x0a74, + 0x77fc, 0x16da, + 0x7802, 0x082d, + 0x780c, 0x16db, + 0x7812, 0x16dc, + 0x7814, 0x075a, + 0x7815, 0x0845, + 0x7820, 0x16de, + 0x7821, 0x217e, + 0x7825, 0x0c50, + 0x7826, 0x0846, + 0x7827, 0x0668, + 0x7832, 0x0e52, + 0x7834, 0x0d01, + 0x783a, 0x0c51, + 0x783f, 0x07ee, + 0x7845, 0x16e0, + 0x784e, 0x217f, + 0x785d, 0x09b3, + 0x7864, 0x2180, + 0x786b, 0x0f7a, + 0x786c, 0x07d7, + 0x786f, 0x075b, + 0x7872, 0x0d37, + 0x7874, 0x16e2, + 0x787a, 0x2181, + 0x787c, 0x16e4, + 0x7881, 0x079f, + 0x7886, 0x16e3, + 0x7887, 0x0c12, + 0x788c, 0x16e6, + 0x788d, 0x0595, + 0x788e, 0x16e1, + 0x7891, 0x0d7e, + 0x7893, 0x04d2, + 0x7895, 0x085c, + 0x7897, 0x0ff8, + 0x789a, 0x16e5, + 0x78a3, 0x16e7, + 0x78a7, 0x0e1b, + 0x78a9, 0x0a7d, + 0x78aa, 0x16e9, + 0x78af, 0x16ea, + 0x78b5, 0x16e8, + 0x78ba, 0x05ac, + 0x78bc, 0x16f0, + 0x78be, 0x16ef, + 0x78c1, 0x08d3, + 0x78c5, 0x16f1, + 0x78c6, 0x16ec, + 0x78ca, 0x16f2, + 0x78cb, 0x16ed, + 0x78d0, 0x0d6c, + 0x78d1, 0x16eb, + 0x78d4, 0x16ee, + 0x78da, 0x16f5, + 0x78e7, 0x16f4, + 0x78e8, 0x0e8f, + 0x78ec, 0x16f3, + 0x78ef, 0x04af, + 0x78f4, 0x16f7, + 0x78fd, 0x16f6, + 0x7901, 0x09b4, + 0x7907, 0x16f8, + 0x790e, 0x0ac5, + 0x7911, 0x16fa, + 0x7912, 0x16f9, + 0x7919, 0x16fb, + 0x7926, 0x16dd, + 0x792a, 0x16df, + 0x792b, 0x16fd, + 0x792c, 0x16fc, + 0x7930, 0x2182, + 0x793a, 0x08d4, + 0x793c, 0x0fb1, + 0x793e, 0x08fe, + 0x7940, 0x16fe, + 0x7941, 0x070d, + 0x7947, 0x065a, + 0x7948, 0x0641, + 0x7949, 0x08b1, + 0x7950, 0x0f1e, + 0x7953, 0x1704, + 0x7955, 0x1703, + 0x7956, 0x0ac6, + 0x7957, 0x1700, + 0x795a, 0x1702, + 0x795d, 0x0955, + 0x795e, 0x0a06, + 0x795f, 0x1701, + 0x7960, 0x16ff, + 0x7962, 0x0ce0, + 0x7965, 0x09b5, + 0x7968, 0x0dae, + 0x796d, 0x0847, + 0x7977, 0x0c72, + 0x797a, 0x1705, + 0x797f, 0x1706, + 0x7980, 0x171c, + 0x7981, 0x06d0, + 0x7984, 0x0fe3, + 0x7985, 0x0ab7, + 0x798a, 0x1707, + 0x798d, 0x0552, + 0x798e, 0x0c13, + 0x798f, 0x0df1, + 0x7994, 0x2186, + 0x799b, 0x2188, + 0x799d, 0x1708, + 0x79a6, 0x0694, + 0x79a7, 0x1709, + 0x79aa, 0x170b, + 0x79ae, 0x170c, + 0x79b0, 0x0cdf, + 0x79b1, 0x1e4e, + 0x79b3, 0x170d, + 0x79b9, 0x170e, + 0x79bd, 0x06d1, + 0x79be, 0x0553, + 0x79bf, 0x0c9d, + 0x79c0, 0x0932, + 0x79c1, 0x08b2, + 0x79c9, 0x1710, + 0x79cb, 0x0933, + 0x79d1, 0x054a, + 0x79d2, 0x0db5, + 0x79d5, 0x1711, + 0x79d8, 0x0d7f, + 0x79df, 0x0ac7, + 0x79e1, 0x1714, + 0x79e3, 0x1715, + 0x79e4, 0x0d1f, + 0x79e6, 0x0a07, + 0x79e7, 0x1712, + 0x79e9, 0x0b9f, + 0x79ec, 0x1713, + 0x79f0, 0x09b6, + 0x79fb, 0x04a0, + 0x7a00, 0x0643, + 0x7a08, 0x1716, + 0x7a0b, 0x0c14, + 0x7a0d, 0x1717, + 0x7a0e, 0x0a6b, + 0x7a14, 0x0eb9, + 0x7a17, 0x0d95, + 0x7a18, 0x1718, + 0x7a1a, 0x0b93, + 0x7a1c, 0x0f8f, + 0x7a1f, 0x171b, + 0x7a20, 0x171a, + 0x7a2e, 0x091b, + 0x7a31, 0x171d, + 0x7a32, 0x04b4, + 0x7a37, 0x1720, + 0x7a3b, 0x171e, + 0x7a3c, 0x0554, + 0x7a3d, 0x0724, + 0x7a3e, 0x171f, + 0x7a3f, 0x07d8, + 0x7a40, 0x0804, + 0x7a42, 0x0e36, + 0x7a43, 0x1721, + 0x7a46, 0x0e82, + 0x7a49, 0x1723, + 0x7a4d, 0x0a75, + 0x7a4e, 0x04f1, + 0x7a4f, 0x053a, + 0x7a50, 0x0470, + 0x7a57, 0x1722, + 0x7a61, 0x1724, + 0x7a63, 0x09df, + 0x7a69, 0x1726, + 0x7a6b, 0x05ad, + 0x7a70, 0x1728, + 0x7a74, 0x0740, + 0x7a76, 0x0680, + 0x7a79, 0x1729, + 0x7a7a, 0x06ed, + 0x7a7d, 0x172a, + 0x7a7f, 0x0aa0, + 0x7a81, 0x0ca5, + 0x7a83, 0x0a84, + 0x7a84, 0x0865, + 0x7a88, 0x172b, + 0x7a92, 0x0ba0, + 0x7a93, 0x0aed, + 0x7a95, 0x172d, + 0x7a96, 0x172f, + 0x7a97, 0x172c, + 0x7a98, 0x172e, + 0x7a9f, 0x06f8, + 0x7aa9, 0x1730, + 0x7aaa, 0x06fc, + 0x7aae, 0x0681, + 0x7aaf, 0x0f3c, + 0x7ab0, 0x1732, + 0x7ab6, 0x1733, + 0x7aba, 0x04d0, + 0x7abf, 0x1736, + 0x7ac3, 0x05d4, + 0x7ac4, 0x1735, + 0x7ac5, 0x1734, + 0x7ac7, 0x1738, + 0x7ac8, 0x1731, + 0x7aca, 0x1739, + 0x7acb, 0x0f71, + 0x7acd, 0x173a, + 0x7acf, 0x173b, + 0x7ad1, 0x2189, + 0x7ad2, 0x11c5, + 0x7ad3, 0x173d, + 0x7ad5, 0x173c, + 0x7ad9, 0x173e, + 0x7adc, 0x0f7d, + 0x7add, 0x1740, + 0x7adf, 0x1c08, + 0x7ae0, 0x09b7, + 0x7ae1, 0x1741, + 0x7ae3, 0x0961, + 0x7ae5, 0x0c90, + 0x7ae6, 0x1743, + 0x7ae7, 0x218a, + 0x7aea, 0x0b66, + 0x7aeb, 0x218c, + 0x7aed, 0x1744, + 0x7aef, 0x0b7a, + 0x7af0, 0x1745, + 0x7af6, 0x069d, + 0x7af8, 0x1076, + 0x7af9, 0x0b9b, + 0x7afa, 0x08df, + 0x7aff, 0x0604, + 0x7b02, 0x1746, + 0x7b04, 0x1753, + 0x7b06, 0x1749, + 0x7b08, 0x0682, + 0x7b0a, 0x1748, + 0x7b0b, 0x1755, + 0x7b0f, 0x1747, + 0x7b11, 0x09b8, + 0x7b18, 0x174b, + 0x7b1b, 0x0c25, + 0x7b1e, 0x174d, + 0x7b20, 0x05bc, + 0x7b25, 0x0a20, + 0x7b26, 0x0dd6, + 0x7b28, 0x174f, + 0x7b2c, 0x0b48, + 0x7b33, 0x174a, + 0x7b35, 0x174e, + 0x7b36, 0x1750, + 0x7b39, 0x086b, + 0x7b45, 0x1757, + 0x7b46, 0x0da0, + 0x7b48, 0x0d3a, + 0x7b49, 0x0c73, + 0x7b4b, 0x06d2, + 0x7b4c, 0x1756, + 0x7b4d, 0x1754, + 0x7b4f, 0x0d49, + 0x7b50, 0x1751, + 0x7b51, 0x0b9c, + 0x7b52, 0x0c75, + 0x7b54, 0x0c74, + 0x7b56, 0x0866, + 0x7b5d, 0x1769, + 0x7b65, 0x1759, + 0x7b67, 0x175b, + 0x7b6c, 0x175e, + 0x7b6e, 0x175f, + 0x7b70, 0x175c, + 0x7b74, 0x175a, + 0x7b75, 0x1758, + 0x7b7a, 0x1752, + 0x7b86, 0x0e1f, + 0x7b87, 0x0555, + 0x7b8b, 0x1766, + 0x7b8d, 0x1763, + 0x7b8f, 0x1768, + 0x7b92, 0x1767, + 0x7b94, 0x0d29, + 0x7b95, 0x0eb3, + 0x7b97, 0x0889, + 0x7b98, 0x1761, + 0x7b99, 0x176a, + 0x7b9a, 0x1765, + 0x7b9c, 0x1764, + 0x7b9d, 0x1760, + 0x7b9e, 0x218d, + 0x7b9f, 0x1762, + 0x7ba1, 0x0605, + 0x7baa, 0x0b7b, + 0x7bad, 0x0aa1, + 0x7bb1, 0x0d36, + 0x7bb4, 0x176f, + 0x7bb8, 0x0d38, + 0x7bc0, 0x0a85, + 0x7bc1, 0x176c, + 0x7bc4, 0x0d63, + 0x7bc6, 0x1770, + 0x7bc7, 0x0e23, + 0x7bc9, 0x0b99, + 0x7bcb, 0x176b, + 0x7bcc, 0x176d, + 0x7bcf, 0x176e, + 0x7bdd, 0x1771, + 0x7be0, 0x08f0, + 0x7be4, 0x0c9e, + 0x7be5, 0x1776, + 0x7be6, 0x1775, + 0x7be9, 0x1772, + 0x7bed, 0x0fdc, + 0x7bf3, 0x177b, + 0x7bf6, 0x177f, + 0x7bf7, 0x177c, + 0x7c00, 0x1778, + 0x7c07, 0x1779, + 0x7c0d, 0x177e, + 0x7c11, 0x1773, + 0x7c12, 0x10ea, + 0x7c13, 0x177a, + 0x7c14, 0x1774, + 0x7c17, 0x177d, + 0x7c1e, 0x1e3b, + 0x7c1f, 0x1783, + 0x7c21, 0x0606, + 0x7c23, 0x1780, + 0x7c27, 0x1781, + 0x7c2a, 0x1782, + 0x7c2b, 0x1785, + 0x7c37, 0x1784, + 0x7c38, 0x0d8a, + 0x7c3d, 0x1786, + 0x7c3e, 0x0fc4, + 0x7c3f, 0x0e3d, + 0x7c40, 0x178b, + 0x7c43, 0x1788, + 0x7c4c, 0x1787, + 0x7c4d, 0x0a76, + 0x7c4f, 0x178a, + 0x7c50, 0x178c, + 0x7c54, 0x1789, + 0x7c56, 0x1790, + 0x7c58, 0x178d, + 0x7c5f, 0x178e, + 0x7c60, 0x1777, + 0x7c64, 0x178f, + 0x7c65, 0x1791, + 0x7c6c, 0x1792, + 0x7c73, 0x0e16, + 0x7c75, 0x1793, + 0x7c7e, 0x0eee, + 0x7c81, 0x06c6, + 0x7c82, 0x06ff, + 0x7c83, 0x1794, + 0x7c89, 0x0e04, + 0x7c8b, 0x0a2e, + 0x7c8d, 0x0ebc, + 0x7c90, 0x1795, + 0x7c92, 0x0f7b, + 0x7c95, 0x0d2a, + 0x7c97, 0x0ac8, + 0x7c98, 0x0cea, + 0x7c9b, 0x0957, + 0x7c9f, 0x0484, + 0x7ca1, 0x179a, + 0x7ca2, 0x1798, + 0x7ca4, 0x1796, + 0x7ca5, 0x05dd, + 0x7ca7, 0x09b9, + 0x7ca8, 0x179b, + 0x7cab, 0x1799, + 0x7cad, 0x1797, + 0x7cae, 0x179f, + 0x7cb1, 0x179e, + 0x7cb2, 0x179d, + 0x7cb3, 0x179c, + 0x7cb9, 0x17a0, + 0x7cbd, 0x17a1, + 0x7cbe, 0x0a5e, + 0x7cc0, 0x17a2, + 0x7cc2, 0x17a4, + 0x7cc5, 0x17a3, + 0x7cca, 0x0786, + 0x7cce, 0x0aba, + 0x7cd2, 0x17a6, + 0x7cd6, 0x0c76, + 0x7cd8, 0x17a5, + 0x7cdc, 0x17a7, + 0x7cde, 0x0e05, + 0x7cdf, 0x0aee, + 0x7ce0, 0x07d9, + 0x7ce2, 0x17a8, + 0x7ce7, 0x0f90, + 0x7cef, 0x17aa, + 0x7cf2, 0x17ab, + 0x7cf4, 0x17ac, + 0x7cf6, 0x17ad, + 0x7cf8, 0x08b3, + 0x7cfa, 0x17ae, + 0x7cfb, 0x0725, + 0x7cfe, 0x0684, + 0x7d00, 0x0644, + 0x7d02, 0x17b0, + 0x7d04, 0x0eff, + 0x7d05, 0x07da, + 0x7d06, 0x17af, + 0x7d0a, 0x17b3, + 0x7d0b, 0x0ef2, + 0x7d0d, 0x0cf2, + 0x7d10, 0x0da5, + 0x7d14, 0x096d, + 0x7d15, 0x17b2, + 0x7d17, 0x08ff, + 0x7d18, 0x07db, + 0x7d19, 0x08b4, + 0x7d1a, 0x0683, + 0x7d1b, 0x0e06, + 0x7d1c, 0x17b1, + 0x7d20, 0x0ac9, + 0x7d21, 0x0e70, + 0x7d22, 0x0867, + 0x7d2b, 0x08b5, + 0x7d2c, 0x0bf9, + 0x7d2e, 0x17b6, + 0x7d2f, 0x0fa7, + 0x7d30, 0x0849, + 0x7d32, 0x17b7, + 0x7d33, 0x0a08, + 0x7d35, 0x17b9, + 0x7d39, 0x09ba, + 0x7d3a, 0x0820, + 0x7d3f, 0x17b8, + 0x7d42, 0x0934, + 0x7d43, 0x0772, + 0x7d44, 0x0aca, + 0x7d45, 0x17b4, + 0x7d46, 0x17ba, + 0x7d48, 0x218f, + 0x7d4b, 0x17b5, + 0x7d4c, 0x0726, + 0x7d4e, 0x17bd, + 0x7d4f, 0x17c1, + 0x7d50, 0x0741, + 0x7d56, 0x17bc, + 0x7d5b, 0x17c5, + 0x7d5c, 0x2190, + 0x7d5e, 0x07dc, + 0x7d61, 0x0f57, + 0x7d62, 0x0480, + 0x7d63, 0x17c2, + 0x7d66, 0x0685, + 0x7d68, 0x17bf, + 0x7d6e, 0x17c0, + 0x7d71, 0x0c77, + 0x7d72, 0x17be, + 0x7d73, 0x17bb, + 0x7d75, 0x0586, + 0x7d76, 0x0a88, + 0x7d79, 0x075c, + 0x7d7d, 0x17c7, + 0x7d89, 0x17c4, + 0x7d8f, 0x17c6, + 0x7d93, 0x17c3, + 0x7d99, 0x0727, + 0x7d9a, 0x0b13, + 0x7d9b, 0x17c8, + 0x7d9c, 0x0af0, + 0x7d9f, 0x17d5, + 0x7da0, 0x2192, + 0x7da2, 0x17d1, + 0x7da3, 0x17cb, + 0x7dab, 0x17cf, + 0x7dac, 0x0926, + 0x7dad, 0x04a1, + 0x7dae, 0x17ca, + 0x7daf, 0x17d2, + 0x7db0, 0x17d6, + 0x7db1, 0x07dd, + 0x7db2, 0x0ee2, + 0x7db4, 0x0bf2, + 0x7db5, 0x17cc, + 0x7db7, 0x2191, + 0x7db8, 0x17d4, + 0x7dba, 0x17c9, + 0x7dbb, 0x0b7c, + 0x7dbd, 0x17ce, + 0x7dbe, 0x0481, + 0x7dbf, 0x0ed6, + 0x7dc7, 0x17cd, + 0x7dca, 0x06d3, + 0x7dcb, 0x0d80, + 0x7dcf, 0x0aef, + 0x7dd1, 0x0f98, + 0x7dd2, 0x0979, + 0x7dd5, 0x17fd, + 0x7dd6, 0x2193, + 0x7dd8, 0x17d7, + 0x7dda, 0x0aa2, + 0x7ddc, 0x17d3, + 0x7ddd, 0x17d8, + 0x7dde, 0x17da, + 0x7de0, 0x0c15, + 0x7de1, 0x17dd, + 0x7de4, 0x17d9, + 0x7de8, 0x0e24, + 0x7de9, 0x0607, + 0x7dec, 0x0ed7, + 0x7def, 0x04a2, + 0x7df2, 0x17dc, + 0x7df4, 0x0fc5, + 0x7dfb, 0x17db, + 0x7e01, 0x0511, + 0x7e04, 0x0cc4, + 0x7e05, 0x17de, + 0x7e09, 0x17e5, + 0x7e0a, 0x17df, + 0x7e0b, 0x17e6, + 0x7e12, 0x17e2, + 0x7e1b, 0x0d31, + 0x7e1e, 0x08f6, + 0x7e1f, 0x17e4, + 0x7e21, 0x17e1, + 0x7e22, 0x17e7, + 0x7e23, 0x17e0, + 0x7e26, 0x094e, + 0x7e2b, 0x0e53, + 0x7e2e, 0x0956, + 0x7e31, 0x17e3, + 0x7e32, 0x17ef, + 0x7e35, 0x17eb, + 0x7e37, 0x17ee, + 0x7e39, 0x17ec, + 0x7e3a, 0x17f0, + 0x7e3b, 0x17ea, + 0x7e3d, 0x17d0, + 0x7e3e, 0x0a77, + 0x7e41, 0x0d5f, + 0x7e43, 0x17ed, + 0x7e46, 0x17e8, + 0x7e4a, 0x0aa3, + 0x7e4b, 0x0728, + 0x7e4d, 0x0935, + 0x7e52, 0x2194, + 0x7e54, 0x09eb, + 0x7e55, 0x0ab8, + 0x7e56, 0x17f3, + 0x7e59, 0x17f5, + 0x7e5d, 0x17f2, + 0x7e5e, 0x17f4, + 0x7e61, 0x1e11, + 0x7e66, 0x17e9, + 0x7e67, 0x17f1, + 0x7e69, 0x17f9, + 0x7e6a, 0x17f8, + 0x7e6b, 0x1df7, + 0x7e6d, 0x0ea8, + 0x7e70, 0x0701, + 0x7e79, 0x17f7, + 0x7e7b, 0x17fb, + 0x7e7c, 0x17fa, + 0x7e7d, 0x17fe, + 0x7e7f, 0x1800, + 0x7e82, 0x088a, + 0x7e83, 0x17fc, + 0x7e88, 0x1801, + 0x7e8a, 0x20a7, + 0x7e8c, 0x1803, + 0x7e8e, 0x1809, + 0x7e8f, 0x0c35, + 0x7e90, 0x1805, + 0x7e92, 0x1804, + 0x7e93, 0x1806, + 0x7e96, 0x1808, + 0x7e9b, 0x180a, + 0x7f36, 0x0608, + 0x7f38, 0x180c, + 0x7f3a, 0x180d, + 0x7f45, 0x180e, + 0x7f47, 0x2195, + 0x7f4c, 0x180f, + 0x7f50, 0x1812, + 0x7f54, 0x1815, + 0x7f55, 0x1814, + 0x7f58, 0x1816, + 0x7f5f, 0x1817, + 0x7f67, 0x181b, + 0x7f68, 0x1819, + 0x7f6a, 0x0851, + 0x7f6b, 0x0729, + 0x7f6e, 0x0b94, + 0x7f70, 0x0d47, + 0x7f72, 0x097a, + 0x7f75, 0x0d03, + 0x7f77, 0x0d81, + 0x7f78, 0x181c, + 0x7f79, 0x1336, + 0x7f82, 0x181d, + 0x7f83, 0x181f, + 0x7f85, 0x0f4f, + 0x7f86, 0x181e, + 0x7f87, 0x1821, + 0x7f88, 0x1820, + 0x7f8a, 0x0f3d, + 0x7f8c, 0x1822, + 0x7f8e, 0x0d92, + 0x7f94, 0x1823, + 0x7f9a, 0x1826, + 0x7f9d, 0x1825, + 0x7f9e, 0x1824, + 0x7fa1, 0x2196, + 0x7fa3, 0x1827, + 0x7fa4, 0x0708, + 0x7fa8, 0x0aa4, + 0x7fa9, 0x065b, + 0x7fae, 0x182b, + 0x7faf, 0x1828, + 0x7fb2, 0x1829, + 0x7fb6, 0x182c, + 0x7fb8, 0x182d, + 0x7fb9, 0x182a, + 0x7fbd, 0x04cb, + 0x7fc1, 0x0527, + 0x7fc5, 0x182f, + 0x7fca, 0x1831, + 0x7fcc, 0x0f4c, + 0x7fd2, 0x0936, + 0x7fd4, 0x1833, + 0x7fd5, 0x1832, + 0x7fe0, 0x0a2f, + 0x7fe1, 0x1834, + 0x7fe6, 0x1835, + 0x7fe9, 0x1836, + 0x7feb, 0x0621, + 0x7ff0, 0x0609, + 0x7ff3, 0x1837, + 0x7ff9, 0x1838, + 0x7ffb, 0x0e8b, + 0x7ffc, 0x0f4d, + 0x8000, 0x0f3e, + 0x8001, 0x0fdd, + 0x8003, 0x07df, + 0x8004, 0x183b, + 0x8005, 0x0900, + 0x8006, 0x183a, + 0x800b, 0x183c, + 0x800c, 0x08d5, + 0x8010, 0x0b31, + 0x8012, 0x183d, + 0x8015, 0x07de, + 0x8017, 0x0ee3, + 0x8018, 0x183e, + 0x801c, 0x1840, + 0x8021, 0x1841, + 0x8028, 0x1842, + 0x8033, 0x08d6, + 0x8036, 0x0ef9, + 0x803b, 0x1844, + 0x803d, 0x0b7d, + 0x803f, 0x1843, + 0x8046, 0x1846, + 0x804a, 0x1845, + 0x8052, 0x1847, + 0x8056, 0x0a5f, + 0x8058, 0x1848, + 0x805a, 0x1849, + 0x805e, 0x0e09, + 0x805f, 0x184a, + 0x8061, 0x0af1, + 0x8062, 0x184b, + 0x8068, 0x184c, + 0x806f, 0x0fc6, + 0x8070, 0x184f, + 0x8072, 0x184e, + 0x8073, 0x184d, + 0x8074, 0x0bcc, + 0x8076, 0x1850, + 0x8077, 0x09ec, + 0x8079, 0x1851, + 0x807d, 0x1852, + 0x807e, 0x0fde, + 0x807f, 0x1853, + 0x8084, 0x1854, + 0x8085, 0x1856, + 0x8086, 0x1855, + 0x8087, 0x0d39, + 0x8089, 0x0cd1, + 0x808b, 0x0fe4, + 0x808c, 0x0d3d, + 0x8093, 0x1858, + 0x8096, 0x09bb, + 0x8098, 0x0d9c, + 0x809a, 0x1859, + 0x809b, 0x1857, + 0x809d, 0x060a, + 0x80a1, 0x0788, + 0x80a2, 0x08b6, + 0x80a5, 0x0d82, + 0x80a9, 0x075e, + 0x80aa, 0x0e71, + 0x80ac, 0x185c, + 0x80ad, 0x185a, + 0x80af, 0x07e0, + 0x80b1, 0x07e1, + 0x80b2, 0x04ad, + 0x80b4, 0x0858, + 0x80ba, 0x0d0f, + 0x80c3, 0x04a3, + 0x80c4, 0x1861, + 0x80c6, 0x0b7e, + 0x80cc, 0x0d0e, + 0x80ce, 0x0b3b, + 0x80d6, 0x1863, + 0x80d9, 0x185f, + 0x80da, 0x1862, + 0x80db, 0x185d, + 0x80dd, 0x1860, + 0x80de, 0x0e54, + 0x80e1, 0x0789, + 0x80e4, 0x04c1, + 0x80e5, 0x185e, + 0x80ef, 0x1865, + 0x80f1, 0x1866, + 0x80f4, 0x0c91, + 0x80f8, 0x06b3, + 0x80fc, 0x1871, + 0x80fd, 0x0cf3, + 0x8102, 0x08b7, + 0x8105, 0x06b4, + 0x8106, 0x0a6c, + 0x8107, 0x0fec, + 0x8108, 0x0eba, + 0x8109, 0x1864, + 0x810a, 0x0a78, + 0x811a, 0x066d, + 0x811b, 0x1867, + 0x8123, 0x1869, + 0x8129, 0x1868, + 0x812f, 0x186a, + 0x8131, 0x0b64, + 0x8133, 0x0cf4, + 0x8139, 0x0bcd, + 0x813e, 0x186e, + 0x8146, 0x186d, + 0x814b, 0x186b, + 0x814e, 0x0a1b, + 0x8150, 0x0dd7, + 0x8151, 0x1870, + 0x8153, 0x186f, + 0x8154, 0x07e2, + 0x8155, 0x0ff9, + 0x815f, 0x1880, + 0x8165, 0x1874, + 0x816b, 0x091c, + 0x816e, 0x1873, + 0x8170, 0x080a, + 0x8171, 0x1872, + 0x8174, 0x1876, + 0x8178, 0x0bce, + 0x8179, 0x0df2, + 0x817a, 0x0aa5, + 0x817f, 0x0b3c, + 0x8180, 0x187a, + 0x8182, 0x187b, + 0x8183, 0x1877, + 0x8188, 0x1878, + 0x818a, 0x1879, + 0x818f, 0x07e3, + 0x8193, 0x1881, + 0x8195, 0x187d, + 0x819a, 0x0dd8, + 0x819c, 0x0e9a, + 0x819d, 0x0d9a, + 0x81a0, 0x187c, + 0x81a3, 0x187f, + 0x81a4, 0x187e, + 0x81a8, 0x0e72, + 0x81a9, 0x1882, + 0x81b0, 0x1883, + 0x81b3, 0x0ab9, + 0x81b5, 0x1884, + 0x81b8, 0x1886, + 0x81ba, 0x188a, + 0x81bd, 0x1887, + 0x81be, 0x1885, + 0x81bf, 0x0cf5, + 0x81c0, 0x1888, + 0x81c2, 0x1889, + 0x81c6, 0x0532, + 0x81c8, 0x1890, + 0x81c9, 0x188b, + 0x81cd, 0x188c, + 0x81d1, 0x188d, + 0x81d3, 0x0b01, + 0x81d8, 0x188f, + 0x81d9, 0x188e, + 0x81da, 0x1891, + 0x81df, 0x1892, + 0x81e3, 0x0a09, + 0x81e5, 0x0569, + 0x81e7, 0x1894, + 0x81e8, 0x0f9f, + 0x81ea, 0x08d7, + 0x81ed, 0x0937, + 0x81f3, 0x08b8, + 0x81f4, 0x0b95, + 0x81fa, 0x1895, + 0x81fc, 0x04d3, + 0x81fe, 0x1897, + 0x8201, 0x1898, + 0x8205, 0x189a, + 0x8207, 0x189b, + 0x8208, 0x06b5, + 0x8209, 0x13af, + 0x820a, 0x189c, + 0x820c, 0x0a89, + 0x820d, 0x189d, + 0x820e, 0x08f7, + 0x8210, 0x189e, + 0x8212, 0x1009, + 0x8216, 0x189f, + 0x8217, 0x0e2e, + 0x8218, 0x0618, + 0x821b, 0x0aa6, + 0x821c, 0x0962, + 0x821e, 0x0de3, + 0x821f, 0x0938, + 0x8229, 0x18a0, + 0x822a, 0x07e4, + 0x822b, 0x18a1, + 0x822c, 0x0d60, + 0x822e, 0x18af, + 0x8233, 0x18a3, + 0x8235, 0x0b29, + 0x8236, 0x0d2b, + 0x8237, 0x0773, + 0x8238, 0x18a2, + 0x8239, 0x0aa7, + 0x8240, 0x18a4, + 0x8247, 0x0c16, + 0x8258, 0x18a6, + 0x8259, 0x18a5, + 0x825a, 0x18a8, + 0x825d, 0x18a7, + 0x825f, 0x18a9, + 0x8262, 0x18ab, + 0x8264, 0x18aa, + 0x8266, 0x060b, + 0x8268, 0x18ac, + 0x826a, 0x18ad, + 0x826e, 0x0821, + 0x826f, 0x0f91, + 0x8271, 0x18b0, + 0x8272, 0x09ed, + 0x8276, 0x0512, + 0x8277, 0x18b1, + 0x827e, 0x18b3, + 0x828b, 0x04b6, + 0x828d, 0x18b4, + 0x8292, 0x18b5, + 0x8299, 0x0dd9, + 0x829d, 0x08f3, + 0x829f, 0x18b7, + 0x82a5, 0x0587, + 0x82a6, 0x0476, + 0x82ab, 0x18b6, + 0x82ac, 0x18b9, + 0x82ad, 0x0d04, + 0x82af, 0x0a0a, + 0x82b1, 0x0556, + 0x82b3, 0x0e55, + 0x82b8, 0x0733, + 0x82b9, 0x06d4, + 0x82bb, 0x18b8, + 0x82bd, 0x056a, + 0x82c5, 0x05df, + 0x82d1, 0x0513, + 0x82d2, 0x18bd, + 0x82d3, 0x0fb2, + 0x82d4, 0x0b3d, + 0x82d7, 0x0db6, + 0x82d9, 0x18c9, + 0x82db, 0x0557, + 0x82dc, 0x18c7, + 0x82de, 0x18c5, + 0x82df, 0x18bc, + 0x82e1, 0x18ba, + 0x82e3, 0x18bb, + 0x82e5, 0x090f, + 0x82e6, 0x06e4, + 0x82e7, 0x0bb5, + 0x82eb, 0x0ca9, + 0x82f1, 0x04f3, + 0x82f3, 0x18bf, + 0x82f4, 0x18be, + 0x82f9, 0x18c4, + 0x82fa, 0x18c0, + 0x82fb, 0x18c3, + 0x8301, 0x2198, + 0x8302, 0x0edc, + 0x8303, 0x18c2, + 0x8304, 0x0558, + 0x8305, 0x05db, + 0x8306, 0x18c6, + 0x8309, 0x18c8, + 0x830e, 0x072a, + 0x8316, 0x18cc, + 0x8317, 0x18d5, + 0x831c, 0x046f, + 0x8323, 0x18dd, + 0x8328, 0x04b5, + 0x832b, 0x18d4, + 0x832f, 0x18d3, + 0x8331, 0x18ce, + 0x8332, 0x18cd, + 0x8334, 0x18cb, + 0x8335, 0x18ca, + 0x8336, 0x0ba1, + 0x8338, 0x0b5b, + 0x8339, 0x18d0, + 0x8340, 0x18cf, + 0x8345, 0x18d2, + 0x8349, 0x0af2, + 0x834a, 0x072b, + 0x834f, 0x04e3, + 0x8350, 0x18d1, + 0x8352, 0x07e5, + 0x8358, 0x0af3, + 0x8362, 0x2199, + 0x8373, 0x18e3, + 0x8375, 0x18e4, + 0x8377, 0x0559, + 0x837b, 0x052e, + 0x837c, 0x18e1, + 0x837f, 0x219a, + 0x8385, 0x18d7, + 0x8387, 0x18df, + 0x8389, 0x18e6, + 0x838a, 0x18e0, + 0x838e, 0x18de, + 0x8393, 0x18c1, + 0x8396, 0x18dc, + 0x839a, 0x18d8, + 0x839e, 0x060c, + 0x839f, 0x18da, + 0x83a0, 0x18e5, + 0x83a2, 0x18db, + 0x83a8, 0x18e7, + 0x83aa, 0x18d9, + 0x83ab, 0x0d32, + 0x83b1, 0x0f53, + 0x83b5, 0x18e2, + 0x83bd, 0x18f8, + 0x83c1, 0x18f0, + 0x83c5, 0x0a41, + 0x83c7, 0x219b, + 0x83ca, 0x0660, + 0x83cc, 0x06d5, + 0x83ce, 0x18eb, + 0x83d3, 0x055b, + 0x83d6, 0x09bc, + 0x83d8, 0x18ee, + 0x83dc, 0x084a, + 0x83df, 0x0c4b, + 0x83e0, 0x18f3, + 0x83e9, 0x0e3e, + 0x83eb, 0x18ea, + 0x83ef, 0x055a, + 0x83f0, 0x078a, + 0x83f1, 0x0d9b, + 0x83f2, 0x18f4, + 0x83f4, 0x18e8, + 0x83f6, 0x219c, + 0x83f7, 0x18f1, + 0x83fb, 0x18fb, + 0x83fd, 0x18ec, + 0x8403, 0x18ed, + 0x8404, 0x0c92, + 0x8407, 0x18f2, + 0x840a, 0x1e7f, + 0x840b, 0x18ef, + 0x840c, 0x0e56, + 0x840d, 0x18f5, + 0x840e, 0x04a4, + 0x8413, 0x18e9, + 0x8420, 0x18f7, + 0x8422, 0x18f6, + 0x8429, 0x0d21, + 0x842a, 0x18fd, + 0x842c, 0x1908, + 0x8431, 0x05dc, + 0x8435, 0x190b, + 0x8438, 0x18f9, + 0x843c, 0x18fe, + 0x843d, 0x0f58, + 0x8446, 0x1907, + 0x8448, 0x219d, + 0x8449, 0x0f3f, + 0x844e, 0x0f72, + 0x8457, 0x0bb6, + 0x845b, 0x05c9, + 0x8461, 0x0de4, + 0x8462, 0x190d, + 0x8463, 0x0c79, + 0x8466, 0x0475, + 0x8469, 0x1906, + 0x846b, 0x1902, + 0x846c, 0x0af4, + 0x846d, 0x18fc, + 0x846e, 0x1904, + 0x846f, 0x1909, + 0x8471, 0x0ce2, + 0x8475, 0x046e, + 0x8477, 0x1901, + 0x8479, 0x190a, + 0x847a, 0x0dea, + 0x8482, 0x1905, + 0x8484, 0x1900, + 0x848b, 0x09bd, + 0x8490, 0x0939, + 0x8494, 0x08d8, + 0x8499, 0x0ee4, + 0x849c, 0x0db9, + 0x849f, 0x1910, + 0x84a1, 0x1919, + 0x84ad, 0x1903, + 0x84b2, 0x05d5, + 0x84b4, 0x219e, + 0x84b8, 0x09e0, + 0x84b9, 0x190e, + 0x84bb, 0x1913, + 0x84bc, 0x0af5, + 0x84bf, 0x190f, + 0x84c1, 0x1916, + 0x84c4, 0x0b9d, + 0x84c6, 0x1917, + 0x84c9, 0x0f40, + 0x84ca, 0x190c, + 0x84cb, 0x0596, + 0x84cd, 0x1912, + 0x84d0, 0x1915, + 0x84d1, 0x0eb8, + 0x84d6, 0x1918, + 0x84d9, 0x1911, + 0x84da, 0x1914, + 0x84dc, 0x20ab, + 0x84ec, 0x0e57, + 0x84ee, 0x0fc7, + 0x84f4, 0x191c, + 0x84fc, 0x1923, + 0x84ff, 0x191b, + 0x8500, 0x08ef, + 0x8506, 0x18fa, + 0x8511, 0x0e1e, + 0x8513, 0x0eae, + 0x8514, 0x1922, + 0x8515, 0x1921, + 0x8517, 0x191d, + 0x851a, 0x04d8, + 0x851f, 0x1920, + 0x8521, 0x191a, + 0x8523, 0x1e1a, + 0x8526, 0x0bf1, + 0x852c, 0x191f, + 0x852d, 0x04c2, + 0x8535, 0x0b02, + 0x853d, 0x0e13, + 0x853e, 0x1eb5, + 0x8540, 0x1924, + 0x8541, 0x1928, + 0x8543, 0x0d6d, + 0x8548, 0x1927, + 0x8549, 0x09be, + 0x854a, 0x08f5, + 0x854b, 0x192a, + 0x854e, 0x06b6, + 0x8553, 0x219f, + 0x8555, 0x192b, + 0x8557, 0x0deb, + 0x8558, 0x1926, + 0x8559, 0x21a0, + 0x855a, 0x18ff, + 0x8563, 0x1925, + 0x8568, 0x0ff5, + 0x8569, 0x0c7a, + 0x856a, 0x0de5, + 0x856b, 0x21a1, + 0x856d, 0x1932, + 0x8577, 0x1938, + 0x857e, 0x1939, + 0x8580, 0x192c, + 0x8584, 0x0d2c, + 0x8587, 0x1936, + 0x8588, 0x192e, + 0x858a, 0x1930, + 0x8590, 0x193a, + 0x8591, 0x192f, + 0x8594, 0x1933, + 0x8597, 0x0514, + 0x8599, 0x0cbd, + 0x859b, 0x1934, + 0x859c, 0x1937, + 0x85a4, 0x192d, + 0x85a6, 0x0aa8, + 0x85a8, 0x1931, + 0x85a9, 0x0875, + 0x85aa, 0x0a0b, + 0x85ab, 0x0706, + 0x85ac, 0x0f00, + 0x85ae, 0x0f05, + 0x85af, 0x097c, + 0x85b0, 0x21a3, + 0x85b9, 0x193e, + 0x85ba, 0x193c, + 0x85c1, 0x0ff4, + 0x85c9, 0x193b, + 0x85cd, 0x0f5f, + 0x85cf, 0x193d, + 0x85d0, 0x193f, + 0x85d5, 0x1940, + 0x85dc, 0x1943, + 0x85dd, 0x1941, + 0x85e4, 0x0c7b, + 0x85e5, 0x1942, + 0x85e9, 0x0d61, + 0x85ea, 0x1935, + 0x85f7, 0x097d, + 0x85f9, 0x1944, + 0x85fa, 0x1949, + 0x85fb, 0x0af6, + 0x85fe, 0x1948, + 0x8602, 0x1929, + 0x8606, 0x194a, + 0x8607, 0x0acb, + 0x860a, 0x1945, + 0x860b, 0x1947, + 0x8613, 0x1946, + 0x8616, 0x14d0, + 0x8617, 0x14c1, + 0x861a, 0x194c, + 0x8622, 0x194b, + 0x862d, 0x0f60, + 0x862f, 0x16b1, + 0x8630, 0x194d, + 0x863f, 0x194e, + 0x864d, 0x194f, + 0x864e, 0x078b, + 0x8650, 0x066e, + 0x8654, 0x1951, + 0x8655, 0x1094, + 0x865a, 0x068f, + 0x865c, 0x0f82, + 0x865e, 0x06eb, + 0x865f, 0x1952, + 0x8667, 0x1953, + 0x866b, 0x0bac, + 0x8671, 0x1954, + 0x8679, 0x0cd2, + 0x867b, 0x047e, + 0x868a, 0x0563, + 0x868b, 0x1959, + 0x8693, 0x1955, + 0x8695, 0x088b, + 0x86a3, 0x1956, + 0x86a4, 0x0cf8, + 0x86a9, 0x1957, + 0x86ab, 0x1962, + 0x86af, 0x195c, + 0x86b0, 0x195f, + 0x86b6, 0x195b, + 0x86c4, 0x195d, + 0x86c6, 0x195e, + 0x86c7, 0x0904, + 0x86c9, 0x1960, + 0x86cb, 0x0b7f, + 0x86cd, 0x072c, + 0x86ce, 0x05a0, + 0x86d4, 0x1963, + 0x86d9, 0x059d, + 0x86db, 0x1968, + 0x86de, 0x1964, + 0x86df, 0x1967, + 0x86e4, 0x0d4e, + 0x86e9, 0x1965, + 0x86ec, 0x1966, + 0x86ed, 0x0dba, + 0x86ee, 0x0d6e, + 0x86ef, 0x1969, + 0x86f8, 0x0b5d, + 0x86f9, 0x1973, + 0x86fb, 0x196f, + 0x86fe, 0x056b, + 0x8700, 0x196d, + 0x8702, 0x0e58, + 0x8703, 0x196e, + 0x8706, 0x196b, + 0x8708, 0x196c, + 0x8709, 0x1971, + 0x870a, 0x1974, + 0x870d, 0x1972, + 0x8711, 0x1970, + 0x8712, 0x196a, + 0x8718, 0x0b96, + 0x871a, 0x197b, + 0x871c, 0x0eb6, + 0x8725, 0x1979, + 0x8729, 0x197a, + 0x8734, 0x1975, + 0x8737, 0x1977, + 0x873b, 0x1978, + 0x873f, 0x1976, + 0x8749, 0x0a8a, + 0x874b, 0x0fdf, + 0x874c, 0x197f, + 0x874e, 0x1980, + 0x8753, 0x1986, + 0x8755, 0x09f0, + 0x8757, 0x1982, + 0x8759, 0x1985, + 0x875f, 0x197d, + 0x8760, 0x197c, + 0x8763, 0x1987, + 0x8766, 0x055c, + 0x8768, 0x1983, + 0x876a, 0x1988, + 0x876e, 0x1984, + 0x8774, 0x1981, + 0x8776, 0x0bcf, + 0x8778, 0x197e, + 0x877f, 0x0d1e, + 0x8782, 0x198c, + 0x878d, 0x0f25, + 0x879f, 0x198b, + 0x87a2, 0x198a, + 0x87ab, 0x1993, + 0x87af, 0x198d, + 0x87b3, 0x1995, + 0x87ba, 0x0f50, + 0x87bb, 0x1998, + 0x87bd, 0x198f, + 0x87c0, 0x1990, + 0x87c4, 0x1994, + 0x87c6, 0x1997, + 0x87c7, 0x1996, + 0x87cb, 0x198e, + 0x87d0, 0x1991, + 0x87d2, 0x19a2, + 0x87e0, 0x199b, + 0x87ec, 0x1e23, + 0x87ef, 0x1999, + 0x87f2, 0x199a, + 0x87f6, 0x199f, + 0x87f9, 0x0588, + 0x87fb, 0x065c, + 0x87fe, 0x199e, + 0x8805, 0x1989, + 0x8807, 0x21a6, + 0x880d, 0x199d, + 0x880e, 0x19a1, + 0x880f, 0x199c, + 0x8811, 0x19a3, + 0x8815, 0x19a5, + 0x8816, 0x19a4, + 0x881f, 0x1e85, + 0x8821, 0x19a7, + 0x8822, 0x19a6, + 0x8823, 0x1961, + 0x8827, 0x19ab, + 0x8831, 0x19a8, + 0x8836, 0x19a9, + 0x8839, 0x19aa, + 0x883b, 0x19ac, + 0x8840, 0x0742, + 0x8842, 0x19ae, + 0x8844, 0x19ad, + 0x8846, 0x093a, + 0x884c, 0x07e6, + 0x884d, 0x1524, + 0x8852, 0x19af, + 0x8853, 0x095b, + 0x8857, 0x0597, + 0x8859, 0x19b0, + 0x885b, 0x04f4, + 0x885d, 0x09bf, + 0x885e, 0x19b1, + 0x8861, 0x07e7, + 0x8862, 0x19b2, + 0x8863, 0x04a5, + 0x8868, 0x0daf, + 0x886b, 0x19b3, + 0x8870, 0x0a30, + 0x8872, 0x19ba, + 0x8875, 0x19b7, + 0x8877, 0x0bad, + 0x887d, 0x19b8, + 0x887e, 0x19b5, + 0x887f, 0x06d6, + 0x8881, 0x19b4, + 0x8882, 0x19bb, + 0x8888, 0x070c, + 0x888b, 0x0b3e, + 0x888d, 0x19c1, + 0x8892, 0x19bd, + 0x8896, 0x0b15, + 0x8897, 0x19bc, + 0x8899, 0x19bf, + 0x889e, 0x19b6, + 0x88a2, 0x19c0, + 0x88a4, 0x19c2, + 0x88ab, 0x0d83, + 0x88ae, 0x19be, + 0x88b0, 0x19c3, + 0x88b1, 0x19c5, + 0x88b4, 0x0787, + 0x88b5, 0x19b9, + 0x88b7, 0x0485, + 0x88bf, 0x19c4, + 0x88c1, 0x084b, + 0x88c2, 0x0fbe, + 0x88c3, 0x19c6, + 0x88c5, 0x0af7, + 0x88cf, 0x0f6a, + 0x88d4, 0x19c8, + 0x88d5, 0x0f1f, + 0x88d8, 0x19c9, + 0x88dc, 0x0e34, + 0x88dd, 0x19cb, + 0x88df, 0x0830, + 0x88e1, 0x0f6b, + 0x88e8, 0x19d0, + 0x88f2, 0x19d1, + 0x88f3, 0x09c0, + 0x88f4, 0x19cf, + 0x88f5, 0x21a7, + 0x88f8, 0x0f51, + 0x88f9, 0x19cc, + 0x88fc, 0x19ce, + 0x88fd, 0x0a61, + 0x88fe, 0x0a44, + 0x8902, 0x19cd, + 0x8904, 0x19d2, + 0x8907, 0x0df3, + 0x890a, 0x19d4, + 0x890c, 0x19d3, + 0x8910, 0x05ca, + 0x8912, 0x0e59, + 0x8913, 0x19d5, + 0x891c, 0x20a8, + 0x891d, 0x19e1, + 0x891e, 0x19d7, + 0x8925, 0x19d8, + 0x892a, 0x19d9, + 0x8936, 0x19de, + 0x8938, 0x19df, + 0x893b, 0x19dd, + 0x8941, 0x19db, + 0x8943, 0x19d6, + 0x8944, 0x19dc, + 0x894c, 0x19e0, + 0x894d, 0x1bd0, + 0x8956, 0x0528, + 0x895e, 0x19e3, + 0x895f, 0x06d7, + 0x8960, 0x19e2, + 0x8964, 0x19e5, + 0x8966, 0x19e4, + 0x896a, 0x19e7, + 0x896d, 0x19e6, + 0x896f, 0x19e8, + 0x8972, 0x093b, + 0x8974, 0x19e9, + 0x8977, 0x19ea, + 0x897e, 0x19eb, + 0x897f, 0x0a62, + 0x8981, 0x0f41, + 0x8983, 0x19ec, + 0x8986, 0x0df4, + 0x8987, 0x0cfc, + 0x8988, 0x19ed, + 0x898a, 0x19ee, + 0x898b, 0x075f, + 0x898f, 0x0646, + 0x8993, 0x19ef, + 0x8996, 0x08b9, + 0x8997, 0x0cf7, + 0x8998, 0x19f0, + 0x899a, 0x05ae, + 0x89a1, 0x19f1, + 0x89a6, 0x19f3, + 0x89a7, 0x0f61, + 0x89a9, 0x19f2, + 0x89aa, 0x0a0c, + 0x89ac, 0x19f4, + 0x89af, 0x19f5, + 0x89b2, 0x19f6, + 0x89b3, 0x060d, + 0x89ba, 0x19f7, + 0x89bd, 0x19f8, + 0x89bf, 0x19f9, + 0x89d2, 0x05af, + 0x89da, 0x19fb, + 0x89dc, 0x19fc, + 0x89e3, 0x0572, + 0x89e6, 0x09ee, + 0x89e7, 0x19fe, + 0x89f4, 0x19ff, + 0x89f8, 0x1a00, + 0x8a00, 0x0774, + 0x8a02, 0x0c17, + 0x8a03, 0x1a01, + 0x8a08, 0x072d, + 0x8a0a, 0x0a1c, + 0x8a0c, 0x1a04, + 0x8a0e, 0x0c7c, + 0x8a10, 0x1a03, + 0x8a12, 0x21a8, + 0x8a13, 0x0707, + 0x8a16, 0x1a02, + 0x8a17, 0x0b57, + 0x8a18, 0x0647, + 0x8a1b, 0x1a05, + 0x8a1d, 0x1a06, + 0x8a1f, 0x09c1, + 0x8a23, 0x0743, + 0x8a25, 0x1a07, + 0x8a2a, 0x0e5a, + 0x8a2d, 0x0a83, + 0x8a31, 0x0690, + 0x8a33, 0x0f01, + 0x8a34, 0x0acc, + 0x8a36, 0x1a08, + 0x8a37, 0x21a9, + 0x8a3a, 0x0a0d, + 0x8a3b, 0x0bae, + 0x8a3c, 0x09c2, + 0x8a41, 0x1a09, + 0x8a46, 0x1a0c, + 0x8a48, 0x1a0d, + 0x8a50, 0x082e, + 0x8a51, 0x0b22, + 0x8a52, 0x1a0b, + 0x8a54, 0x09c3, + 0x8a55, 0x0db0, + 0x8a5b, 0x1a0a, + 0x8a5e, 0x08ba, + 0x8a60, 0x04f5, + 0x8a62, 0x1a11, + 0x8a63, 0x072e, + 0x8a66, 0x08bc, + 0x8a69, 0x08bb, + 0x8a6b, 0x0ff3, + 0x8a6c, 0x1a10, + 0x8a6d, 0x1a0f, + 0x8a6e, 0x0aa9, + 0x8a70, 0x0667, + 0x8a71, 0x0fe9, + 0x8a72, 0x0598, + 0x8a73, 0x09c4, + 0x8a79, 0x21aa, + 0x8a7c, 0x1a0e, + 0x8a82, 0x1a13, + 0x8a84, 0x1a14, + 0x8a85, 0x1a12, + 0x8a87, 0x078c, + 0x8a89, 0x0f2a, + 0x8a8c, 0x08bd, + 0x8a8d, 0x0cdd, + 0x8a91, 0x1a17, + 0x8a93, 0x0a64, + 0x8a95, 0x0b80, + 0x8a98, 0x0f20, + 0x8a9a, 0x1a1a, + 0x8a9e, 0x07a0, + 0x8aa0, 0x0a63, + 0x8aa1, 0x1a16, + 0x8aa3, 0x1a1b, + 0x8aa4, 0x07a1, + 0x8aa5, 0x1a18, + 0x8aa7, 0x21ab, + 0x8aa8, 0x1a15, + 0x8aac, 0x0a86, + 0x8aad, 0x0ca1, + 0x8ab0, 0x0b6d, + 0x8ab2, 0x055d, + 0x8ab9, 0x0d84, + 0x8abc, 0x065d, + 0x8abe, 0x21ac, + 0x8abf, 0x0bd0, + 0x8ac2, 0x1a1e, + 0x8ac4, 0x1a1c, + 0x8ac7, 0x0b8a, + 0x8acb, 0x0a65, + 0x8acc, 0x060e, + 0x8acd, 0x1a1d, + 0x8acf, 0x0a21, + 0x8ad2, 0x0f92, + 0x8ad6, 0x0fe6, + 0x8ada, 0x1a1f, + 0x8adb, 0x1a2a, + 0x8adc, 0x0bd1, + 0x8ade, 0x1a29, + 0x8adf, 0x21ad, + 0x8ae0, 0x1a26, + 0x8ae1, 0x1a2e, + 0x8ae2, 0x1a27, + 0x8ae4, 0x1a23, + 0x8ae6, 0x0c18, + 0x8ae7, 0x1a22, + 0x8aeb, 0x1a20, + 0x8aed, 0x0f0b, + 0x8aee, 0x08be, + 0x8af1, 0x1a24, + 0x8af3, 0x1a21, + 0x8af6, 0x21af, + 0x8af7, 0x1a28, + 0x8af8, 0x097e, + 0x8afa, 0x0775, + 0x8afe, 0x0b5a, + 0x8b00, 0x0e73, + 0x8b01, 0x04fc, + 0x8b02, 0x04a6, + 0x8b04, 0x0c7d, + 0x8b07, 0x1a2c, + 0x8b0c, 0x1a2b, + 0x8b0e, 0x0cbe, + 0x8b10, 0x1a30, + 0x8b14, 0x1a25, + 0x8b16, 0x1a2f, + 0x8b17, 0x1a31, + 0x8b19, 0x0760, + 0x8b1a, 0x1a2d, + 0x8b1b, 0x07e8, + 0x8b1d, 0x0901, + 0x8b20, 0x1a32, + 0x8b21, 0x0f42, + 0x8b26, 0x1a35, + 0x8b28, 0x1a38, + 0x8b2b, 0x1a36, + 0x8b2c, 0x0da7, + 0x8b33, 0x1a33, + 0x8b39, 0x06d8, + 0x8b3e, 0x1a37, + 0x8b41, 0x1a39, + 0x8b49, 0x1a3d, + 0x8b4c, 0x1a3a, + 0x8b4e, 0x1a3c, + 0x8b4f, 0x1a3b, + 0x8b53, 0x21b0, + 0x8b56, 0x1a3e, + 0x8b58, 0x08dd, + 0x8b5a, 0x1a40, + 0x8b5b, 0x1a3f, + 0x8b5c, 0x0dda, + 0x8b5f, 0x1a42, + 0x8b66, 0x072f, + 0x8b6b, 0x1a41, + 0x8b6c, 0x1a43, + 0x8b6f, 0x1a44, + 0x8b70, 0x065e, + 0x8b71, 0x182e, + 0x8b72, 0x09e1, + 0x8b74, 0x1a45, + 0x8b77, 0x07a2, + 0x8b7d, 0x1a46, + 0x8b7f, 0x21b1, + 0x8b80, 0x1a47, + 0x8b83, 0x088c, + 0x8b8a, 0x13d3, + 0x8b8c, 0x1a48, + 0x8b8e, 0x1a49, + 0x8b90, 0x093c, + 0x8b92, 0x1a4a, + 0x8b96, 0x1a4c, + 0x8b99, 0x1a4d, + 0x8c37, 0x0b69, + 0x8c3a, 0x1a4f, + 0x8c3f, 0x1a51, + 0x8c41, 0x1a50, + 0x8c46, 0x0c7e, + 0x8c48, 0x1a52, + 0x8c4a, 0x0e5b, + 0x8c4c, 0x1a53, + 0x8c4e, 0x1a54, + 0x8c50, 0x1a55, + 0x8c55, 0x1a56, + 0x8c5a, 0x0cb2, + 0x8c61, 0x09c5, + 0x8c62, 0x1a57, + 0x8c6a, 0x07fd, + 0x8c6b, 0x1007, + 0x8c6c, 0x1a58, + 0x8c78, 0x1a59, + 0x8c79, 0x0db1, + 0x8c7a, 0x1a5a, + 0x8c7c, 0x1a62, + 0x8c82, 0x1a5b, + 0x8c85, 0x1a5d, + 0x8c89, 0x1a5c, + 0x8c8a, 0x1a5e, + 0x8c8c, 0x0e74, + 0x8c8d, 0x1a5f, + 0x8c94, 0x1a61, + 0x8c98, 0x1a63, + 0x8c9d, 0x058b, + 0x8c9e, 0x0c03, + 0x8ca0, 0x0ddb, + 0x8ca1, 0x0852, + 0x8ca2, 0x07e9, + 0x8ca7, 0x0dc1, + 0x8ca8, 0x055f, + 0x8ca9, 0x0d62, + 0x8caa, 0x1a66, + 0x8cab, 0x060f, + 0x8cac, 0x0a79, + 0x8cad, 0x1a65, + 0x8cae, 0x1a6a, + 0x8caf, 0x0bb7, + 0x8cb0, 0x0eef, + 0x8cb2, 0x1a68, + 0x8cb4, 0x0648, + 0x8cb6, 0x1a6b, + 0x8cb7, 0x0d19, + 0x8cb8, 0x0b3f, + 0x8cbb, 0x0d85, + 0x8cbc, 0x0c37, + 0x8cbd, 0x1a67, + 0x8cbf, 0x0e75, + 0x8cc0, 0x056c, + 0x8cc1, 0x1a6d, + 0x8cc2, 0x0fce, + 0x8cc3, 0x0bde, + 0x8cc4, 0x0feb, + 0x8cc7, 0x08bf, + 0x8cc8, 0x1a6c, + 0x8cca, 0x0b11, + 0x8ccd, 0x1a7d, + 0x8cce, 0x0aaa, + 0x8cd1, 0x0cd0, + 0x8cd3, 0x0dc2, + 0x8cda, 0x1a70, + 0x8cdb, 0x088d, + 0x8cdc, 0x08c0, + 0x8cde, 0x09c6, + 0x8ce0, 0x0d1b, + 0x8ce2, 0x0761, + 0x8ce3, 0x1a6f, + 0x8ce4, 0x1a6e, + 0x8ce6, 0x0ddc, + 0x8cea, 0x08ed, + 0x8ced, 0x0c4c, + 0x8cf0, 0x21b2, + 0x8cf4, 0x21b3, + 0x8cfa, 0x1a72, + 0x8cfc, 0x07ea, + 0x8cfd, 0x1a71, + 0x8d04, 0x1a74, + 0x8d07, 0x1a77, + 0x8d08, 0x0b03, + 0x8d0a, 0x1a76, + 0x8d0b, 0x0622, + 0x8d0d, 0x1a79, + 0x8d0f, 0x1a78, + 0x8d10, 0x1a7a, + 0x8d12, 0x21b4, + 0x8d13, 0x1a7c, + 0x8d14, 0x1a7e, + 0x8d16, 0x1a7f, + 0x8d64, 0x0a7a, + 0x8d66, 0x08fb, + 0x8d67, 0x1a80, + 0x8d6b, 0x05b0, + 0x8d6d, 0x1a81, + 0x8d70, 0x0af8, + 0x8d71, 0x1a82, + 0x8d73, 0x1a83, + 0x8d74, 0x0ddd, + 0x8d76, 0x21b5, + 0x8d77, 0x0649, + 0x8d81, 0x1a84, + 0x8d85, 0x0bd2, + 0x8d8a, 0x04fd, + 0x8d99, 0x1a85, + 0x8da3, 0x091d, + 0x8da8, 0x0a3c, + 0x8db3, 0x0b0d, + 0x8dba, 0x1a88, + 0x8dbe, 0x1a87, + 0x8dc2, 0x1a86, + 0x8dcb, 0x1a8e, + 0x8dcc, 0x1a8c, + 0x8dcf, 0x1a89, + 0x8dd6, 0x1a8b, + 0x8dda, 0x1a8a, + 0x8ddb, 0x1a8d, + 0x8ddd, 0x0691, + 0x8ddf, 0x1a91, + 0x8de1, 0x0a7b, + 0x8de3, 0x1a92, + 0x8de8, 0x078d, + 0x8dea, 0x1a8f, + 0x8def, 0x0fcf, + 0x8df3, 0x0bd3, + 0x8df5, 0x0aab, + 0x8dfc, 0x1a93, + 0x8dff, 0x1a96, + 0x8e08, 0x1a94, + 0x8e0a, 0x0f43, + 0x8e0f, 0x0c7f, + 0x8e10, 0x1a99, + 0x8e1d, 0x1a97, + 0x8e1f, 0x1a9a, + 0x8e2a, 0x1aa8, + 0x8e30, 0x1a9d, + 0x8e34, 0x1a9e, + 0x8e35, 0x1a9c, + 0x8e42, 0x1a9b, + 0x8e44, 0x0c19, + 0x8e47, 0x1aa0, + 0x8e48, 0x1aa4, + 0x8e49, 0x1aa1, + 0x8e4a, 0x1a9f, + 0x8e4c, 0x1aa2, + 0x8e50, 0x1aa3, + 0x8e55, 0x1aaa, + 0x8e59, 0x1aa5, + 0x8e5f, 0x0a7c, + 0x8e60, 0x1aa7, + 0x8e63, 0x1aa9, + 0x8e64, 0x1aa6, + 0x8e72, 0x1aac, + 0x8e74, 0x093d, + 0x8e76, 0x1aab, + 0x8e7c, 0x1aad, + 0x8e81, 0x1aae, + 0x8e84, 0x1ab1, + 0x8e85, 0x1ab0, + 0x8e87, 0x1aaf, + 0x8e8a, 0x1ab3, + 0x8e8b, 0x1ab2, + 0x8e8d, 0x0f02, + 0x8e91, 0x1ab5, + 0x8e93, 0x1ab4, + 0x8e94, 0x1ab6, + 0x8e99, 0x1ab7, + 0x8ea1, 0x1ab9, + 0x8eaa, 0x1ab8, + 0x8eab, 0x0a0e, + 0x8eac, 0x1aba, + 0x8eaf, 0x06e5, + 0x8eb0, 0x1abb, + 0x8eb1, 0x1abd, + 0x8ebe, 0x1abe, + 0x8ec0, 0x1def, + 0x8ec5, 0x1abf, + 0x8ec6, 0x1abc, + 0x8ec8, 0x1ac0, + 0x8eca, 0x0902, + 0x8ecb, 0x1ac1, + 0x8ecc, 0x064a, + 0x8ecd, 0x0709, + 0x8ecf, 0x21b7, + 0x8ed2, 0x0762, + 0x8edb, 0x1ac2, + 0x8edf, 0x0cc8, + 0x8ee2, 0x0c38, + 0x8ee3, 0x1ac3, + 0x8eeb, 0x1ac6, + 0x8ef8, 0x08e0, + 0x8efb, 0x1ac5, + 0x8efc, 0x1ac4, + 0x8efd, 0x0730, + 0x8efe, 0x1ac7, + 0x8f03, 0x05b1, + 0x8f05, 0x1ac9, + 0x8f09, 0x084c, + 0x8f0a, 0x1ac8, + 0x8f0c, 0x1ad1, + 0x8f12, 0x1acb, + 0x8f13, 0x1acd, + 0x8f14, 0x0e35, + 0x8f15, 0x1aca, + 0x8f19, 0x1acc, + 0x8f1b, 0x1ad0, + 0x8f1c, 0x1ace, + 0x8f1d, 0x064b, + 0x8f1f, 0x1acf, + 0x8f26, 0x1ad2, + 0x8f29, 0x0d10, + 0x8f2a, 0x0fa0, + 0x8f2f, 0x093e, + 0x8f33, 0x1ad3, + 0x8f38, 0x0f0c, + 0x8f39, 0x1ad5, + 0x8f3b, 0x1ad4, + 0x8f3e, 0x1ad8, + 0x8f3f, 0x0f2b, + 0x8f42, 0x1ad7, + 0x8f44, 0x05cb, + 0x8f45, 0x1ad6, + 0x8f46, 0x1adb, + 0x8f49, 0x1ada, + 0x8f4c, 0x1ad9, + 0x8f4d, 0x0c2c, + 0x8f4e, 0x1adc, + 0x8f57, 0x1add, + 0x8f5c, 0x1ade, + 0x8f5f, 0x07fe, + 0x8f61, 0x06fb, + 0x8f62, 0x1adf, + 0x8f9b, 0x0a0f, + 0x8f9c, 0x1ae2, + 0x8f9e, 0x08d9, + 0x8f9f, 0x1ae3, + 0x8fa3, 0x1ae4, + 0x8fa7, 0x10b6, + 0x8fa8, 0x10b5, + 0x8fad, 0x1ae5, + 0x8fae, 0x17ff, + 0x8faf, 0x1ae6, + 0x8fb0, 0x0b62, + 0x8fb1, 0x09f1, + 0x8fb2, 0x0cf6, + 0x8fb7, 0x1ae7, + 0x8fba, 0x0e25, + 0x8fbb, 0x0bf0, + 0x8fbc, 0x0810, + 0x8fbf, 0x0b67, + 0x8fc2, 0x04cc, + 0x8fc4, 0x0ea6, + 0x8fc5, 0x0a1d, + 0x8fce, 0x0734, + 0x8fd1, 0x06d9, + 0x8fd4, 0x0e26, + 0x8fda, 0x1ae8, + 0x8fe2, 0x1aea, + 0x8fe5, 0x1ae9, + 0x8fe6, 0x0560, + 0x8fe9, 0x0cce, + 0x8fea, 0x1aeb, + 0x8feb, 0x0d2d, + 0x8fed, 0x0c2d, + 0x8fef, 0x1aec, + 0x8ff0, 0x095c, + 0x8ff4, 0x1aee, + 0x8ff7, 0x0ece, + 0x8ff8, 0x1afd, + 0x8ff9, 0x1af0, + 0x8ffd, 0x0be5, + 0x9000, 0x0b40, + 0x9001, 0x0af9, + 0x9003, 0x0c80, + 0x9005, 0x1aef, + 0x9006, 0x066f, + 0x900b, 0x1af8, + 0x900d, 0x1af5, + 0x900e, 0x1b02, + 0x900f, 0x0c81, + 0x9010, 0x0b9e, + 0x9011, 0x1af2, + 0x9013, 0x0c1a, + 0x9014, 0x0c4d, + 0x9015, 0x1af3, + 0x9016, 0x1af7, + 0x9017, 0x0a26, + 0x9019, 0x0d1d, + 0x901a, 0x0be8, + 0x901d, 0x0a66, + 0x901e, 0x1af6, + 0x901f, 0x0b0e, + 0x9020, 0x0b04, + 0x9021, 0x1af4, + 0x9022, 0x046d, + 0x9023, 0x0fc8, + 0x9027, 0x1af9, + 0x902e, 0x0b41, + 0x9031, 0x093f, + 0x9032, 0x0a10, + 0x9035, 0x1afb, + 0x9036, 0x1afa, + 0x9038, 0x04b3, + 0x9039, 0x1afc, + 0x903c, 0x0da1, + 0x903e, 0x1b04, + 0x9041, 0x0cb3, + 0x9042, 0x0a31, + 0x9045, 0x0b97, + 0x9047, 0x06f0, + 0x9049, 0x1b03, + 0x904a, 0x0f21, + 0x904b, 0x04e1, + 0x904d, 0x0e27, + 0x904e, 0x0561, + 0x904f, 0x1afe, + 0x9053, 0x0c93, + 0x9054, 0x0b61, + 0x9055, 0x04a7, + 0x9056, 0x1b05, + 0x9058, 0x1b06, + 0x9059, 0x1d34, + 0x905c, 0x0b1d, + 0x905e, 0x1b07, + 0x9060, 0x0515, + 0x9061, 0x0ace, + 0x9063, 0x0763, + 0x9065, 0x0f44, + 0x9067, 0x21ba, + 0x9068, 0x1b08, + 0x9069, 0x0c26, + 0x906d, 0x0afa, + 0x906e, 0x0903, + 0x906f, 0x1b09, + 0x9072, 0x1b0c, + 0x9075, 0x096f, + 0x9076, 0x1b0a, + 0x9077, 0x0aad, + 0x9078, 0x0aac, + 0x907a, 0x04a8, + 0x907c, 0x0f93, + 0x907d, 0x1b0e, + 0x907f, 0x0d86, + 0x9080, 0x1b10, + 0x9081, 0x1b0f, + 0x9082, 0x1b0d, + 0x9083, 0x1737, + 0x9084, 0x0610, + 0x9087, 0x1aed, + 0x9089, 0x1b12, + 0x908a, 0x1b11, + 0x908f, 0x1b13, + 0x9091, 0x0f22, + 0x90a3, 0x0cb9, + 0x90a6, 0x0e5c, + 0x90a8, 0x1b14, + 0x90aa, 0x0905, + 0x90af, 0x1b15, + 0x90b1, 0x1b16, + 0x90b5, 0x1b17, + 0x90b8, 0x0c1b, + 0x90c1, 0x04ae, + 0x90ca, 0x07eb, + 0x90ce, 0x0fe0, + 0x90db, 0x1b1b, + 0x90de, 0x21bb, + 0x90e1, 0x070a, + 0x90e2, 0x1b18, + 0x90e4, 0x1b19, + 0x90e8, 0x0de6, + 0x90ed, 0x05b2, + 0x90f5, 0x0f23, + 0x90f7, 0x06b7, + 0x90fd, 0x0c4e, + 0x9102, 0x1b1c, + 0x9112, 0x1b1d, + 0x9115, 0x21bd, + 0x9119, 0x1b1e, + 0x9127, 0x21be, + 0x912d, 0x0c1c, + 0x9130, 0x1b20, + 0x9132, 0x1b1f, + 0x9149, 0x0cab, + 0x914a, 0x1b21, + 0x914b, 0x0940, + 0x914c, 0x090c, + 0x914d, 0x0d11, + 0x914e, 0x0baf, + 0x9152, 0x091e, + 0x9154, 0x0a32, + 0x9156, 0x1b22, + 0x9158, 0x1b23, + 0x9162, 0x0a23, + 0x9163, 0x1b24, + 0x9165, 0x1b25, + 0x9169, 0x1b26, + 0x916a, 0x0f59, + 0x916c, 0x0941, + 0x9172, 0x1b28, + 0x9173, 0x1b27, + 0x9175, 0x07ec, + 0x9177, 0x0805, + 0x9178, 0x088e, + 0x9182, 0x1b2b, + 0x9187, 0x0970, + 0x9189, 0x1b2a, + 0x918b, 0x1b29, + 0x918d, 0x0b49, + 0x9190, 0x07a3, + 0x9192, 0x0a67, + 0x9197, 0x0d44, + 0x919c, 0x0943, + 0x91a2, 0x1b2c, + 0x91a4, 0x09c7, + 0x91aa, 0x1b2f, + 0x91ab, 0x1b2d, + 0x91ac, 0x1e1b, + 0x91af, 0x1b2e, + 0x91b1, 0x1e61, + 0x91b4, 0x1b31, + 0x91b5, 0x1b30, + 0x91b8, 0x09e2, + 0x91ba, 0x1b32, + 0x91c0, 0x1b33, + 0x91c6, 0x0d64, + 0x91c7, 0x0843, + 0x91c8, 0x090d, + 0x91c9, 0x1b35, + 0x91cb, 0x1b36, + 0x91cc, 0x0f6c, + 0x91cd, 0x094f, + 0x91ce, 0x0efa, + 0x91cf, 0x0f94, + 0x91d0, 0x1b37, + 0x91d1, 0x06da, + 0x91d6, 0x1b38, + 0x91d7, 0x21c0, + 0x91d8, 0x0c1d, + 0x91da, 0x21bf, + 0x91db, 0x1b3b, + 0x91dc, 0x05d6, + 0x91dd, 0x0a11, + 0x91de, 0x21c1, + 0x91df, 0x1b39, + 0x91e1, 0x1b3a, + 0x91e3, 0x0bfc, + 0x91e4, 0x21c4, + 0x91e6, 0x0e83, + 0x91e7, 0x06f4, + 0x91ed, 0x21c2, + 0x91f5, 0x1b3d, + 0x91fc, 0x1b3c, + 0x91ff, 0x1b40, + 0x9206, 0x21c6, + 0x920a, 0x21c8, + 0x920d, 0x0cb7, + 0x920e, 0x05a1, + 0x9210, 0x21c7, + 0x9211, 0x1b44, + 0x9214, 0x1b41, + 0x9215, 0x1b43, + 0x921e, 0x1b3f, + 0x9229, 0x1b8a, + 0x922c, 0x1b42, + 0x9234, 0x0fb3, + 0x9237, 0x078e, + 0x9239, 0x21cf, + 0x923a, 0x21c9, + 0x923c, 0x21cb, + 0x923f, 0x1b4c, + 0x9240, 0x21ca, + 0x9244, 0x0c2e, + 0x9245, 0x1b47, + 0x9248, 0x1b4a, + 0x9249, 0x1b48, + 0x924b, 0x1b4d, + 0x924e, 0x21cc, + 0x9250, 0x1b4e, + 0x9251, 0x21ce, + 0x9257, 0x1b46, + 0x9259, 0x21cd, + 0x925a, 0x1b53, + 0x925b, 0x0516, + 0x925e, 0x1b45, + 0x9262, 0x0d41, + 0x9264, 0x1b49, + 0x9266, 0x09c8, + 0x9267, 0x21d0, + 0x9271, 0x07ed, + 0x9277, 0x21d2, + 0x927e, 0x0e76, + 0x9280, 0x06dc, + 0x9283, 0x0950, + 0x9285, 0x0c94, + 0x9288, 0x20aa, + 0x9291, 0x0aaf, + 0x9293, 0x1b51, + 0x9295, 0x1b4b, + 0x9296, 0x1b50, + 0x9298, 0x0ecf, + 0x929a, 0x0bd4, + 0x929b, 0x1b52, + 0x929c, 0x1b4f, + 0x92a7, 0x21d1, + 0x92ad, 0x0aae, + 0x92b7, 0x1b56, + 0x92b9, 0x1b55, + 0x92cf, 0x1b54, + 0x92d0, 0x21d7, + 0x92d2, 0x0e5d, + 0x92d3, 0x21db, + 0x92d5, 0x21d9, + 0x92d7, 0x21d5, + 0x92d9, 0x21d6, + 0x92e0, 0x21da, + 0x92e4, 0x0985, + 0x92e7, 0x21d4, + 0x92e9, 0x1b57, + 0x92ea, 0x0e2f, + 0x92ed, 0x04f6, + 0x92f2, 0x0db8, + 0x92f3, 0x0bb0, + 0x92f8, 0x0692, + 0x92f9, 0x20b0, + 0x92fa, 0x1b59, + 0x92fb, 0x21de, + 0x92fc, 0x07ef, + 0x92ff, 0x21e1, + 0x9302, 0x21e3, + 0x9306, 0x087a, + 0x930f, 0x1b58, + 0x9310, 0x0a33, + 0x9318, 0x0a34, + 0x9319, 0x1b5c, + 0x931a, 0x1b5e, + 0x931d, 0x21e2, + 0x931e, 0x21e0, + 0x9320, 0x09e3, + 0x9321, 0x21dd, + 0x9322, 0x1b5d, + 0x9323, 0x1b5f, + 0x9325, 0x21dc, + 0x9326, 0x06cb, + 0x9328, 0x0db7, + 0x932b, 0x090e, + 0x932c, 0x0fc9, + 0x932e, 0x1b5b, + 0x932f, 0x0868, + 0x9332, 0x0fe5, + 0x9335, 0x1b61, + 0x933a, 0x1b60, + 0x933b, 0x1b62, + 0x9344, 0x1b5a, + 0x9348, 0x20a9, + 0x934b, 0x0cc1, + 0x934d, 0x0c4f, + 0x9354, 0x0bf3, + 0x9356, 0x1b67, + 0x9357, 0x21e5, + 0x935b, 0x0b81, + 0x935c, 0x1b63, + 0x9360, 0x1b64, + 0x936c, 0x0703, + 0x936e, 0x1b66, + 0x9370, 0x21e4, + 0x9375, 0x0764, + 0x937c, 0x1b65, + 0x937e, 0x09c9, + 0x938c, 0x05d7, + 0x9394, 0x1b6b, + 0x9396, 0x082f, + 0x9397, 0x0afb, + 0x939a, 0x0be6, + 0x93a4, 0x21e6, + 0x93a7, 0x0599, + 0x93ac, 0x1b69, + 0x93ae, 0x0bdf, + 0x93b0, 0x1b68, + 0x93b9, 0x1b6c, + 0x93c3, 0x1b72, + 0x93c6, 0x21e7, + 0x93c8, 0x1b75, + 0x93d0, 0x1b74, + 0x93d1, 0x0c27, + 0x93d6, 0x1b6d, + 0x93d8, 0x1b71, + 0x93dd, 0x1b73, + 0x93de, 0x21e8, + 0x93e1, 0x06b8, + 0x93e4, 0x1b76, + 0x93e5, 0x1b70, + 0x93e8, 0x1b6f, + 0x93f8, 0x21e9, + 0x9403, 0x1b7a, + 0x9407, 0x1b7b, + 0x9410, 0x1b7c, + 0x9413, 0x1b79, + 0x9414, 0x1b78, + 0x9418, 0x09ca, + 0x9419, 0x0c82, + 0x941a, 0x1b77, + 0x9421, 0x1b80, + 0x942b, 0x1b7e, + 0x9431, 0x21ea, + 0x9435, 0x1b7f, + 0x9436, 0x1b7d, + 0x9438, 0x0b58, + 0x943a, 0x1b81, + 0x9441, 0x1b82, + 0x9444, 0x1b84, + 0x9445, 0x21eb, + 0x9448, 0x21ec, + 0x9451, 0x0611, + 0x9452, 0x1b83, + 0x9453, 0x0f06, + 0x945a, 0x1b8f, + 0x945b, 0x1b85, + 0x945e, 0x1b88, + 0x9460, 0x1b86, + 0x9462, 0x1b87, + 0x946a, 0x1b89, + 0x9470, 0x1b8b, + 0x9475, 0x1b8c, + 0x9477, 0x1b8d, + 0x947c, 0x1b90, + 0x947d, 0x1b8e, + 0x947e, 0x1b91, + 0x947f, 0x1b93, + 0x9481, 0x1b92, + 0x9577, 0x0bd5, + 0x9580, 0x0ef3, + 0x9582, 0x1b94, + 0x9583, 0x0ab0, + 0x9587, 0x1b95, + 0x9589, 0x0e14, + 0x958a, 0x1b96, + 0x958b, 0x0589, + 0x958f, 0x04de, + 0x9591, 0x0613, + 0x9592, 0x21ed, + 0x9593, 0x0612, + 0x9594, 0x1b97, + 0x9596, 0x1b98, + 0x9598, 0x1b99, + 0x95a0, 0x1b9b, + 0x95a2, 0x0614, + 0x95a3, 0x05b3, + 0x95a4, 0x07f0, + 0x95a5, 0x0d4a, + 0x95a7, 0x1b9d, + 0x95a8, 0x1b9c, + 0x95ad, 0x1b9e, + 0x95b2, 0x04fe, + 0x95b9, 0x1ba1, + 0x95bb, 0x1ba0, + 0x95bc, 0x1b9f, + 0x95be, 0x1ba2, + 0x95c3, 0x1ba5, + 0x95c7, 0x048b, + 0x95ca, 0x1ba3, + 0x95cc, 0x1ba7, + 0x95cd, 0x1ba6, + 0x95d4, 0x1ba9, + 0x95d5, 0x1ba8, + 0x95d6, 0x1baa, + 0x95d8, 0x0c86, + 0x95dc, 0x1bab, + 0x95e1, 0x1bac, + 0x95e2, 0x1bae, + 0x95e5, 0x1bad, + 0x961c, 0x0dde, + 0x9621, 0x1baf, + 0x9628, 0x1bb0, + 0x962a, 0x0855, + 0x962e, 0x1bb1, + 0x9632, 0x0e77, + 0x963b, 0x0acd, + 0x963f, 0x0468, + 0x9640, 0x0b2b, + 0x9642, 0x1bb3, + 0x9644, 0x0ddf, + 0x964b, 0x1bb6, + 0x964c, 0x1bb4, + 0x964d, 0x07f1, + 0x964f, 0x1bb5, + 0x9650, 0x0776, + 0x965b, 0x0e15, + 0x965c, 0x1bb8, + 0x965d, 0x1bba, + 0x965e, 0x1bb9, + 0x965f, 0x1bbb, + 0x9662, 0x04c3, + 0x9663, 0x0a1e, + 0x9664, 0x0986, + 0x9665, 0x0615, + 0x9666, 0x1bbc, + 0x966a, 0x0d1c, + 0x966c, 0x1bbe, + 0x9670, 0x04c4, + 0x9672, 0x1bbd, + 0x9673, 0x0be0, + 0x9675, 0x0f95, + 0x9676, 0x0c83, + 0x9677, 0x1bb7, + 0x9678, 0x0f6e, + 0x967a, 0x0765, + 0x967d, 0x0f45, + 0x9685, 0x06f1, + 0x9686, 0x0f7c, + 0x9688, 0x06fe, + 0x968a, 0x0b42, + 0x968b, 0x186c, + 0x968d, 0x1bbf, + 0x968e, 0x058a, + 0x968f, 0x0a35, + 0x9694, 0x05b4, + 0x9695, 0x1bc1, + 0x9697, 0x1bc2, + 0x9698, 0x1bc0, + 0x9699, 0x073a, + 0x969b, 0x084d, + 0x969c, 0x09cb, + 0x969d, 0x21f0, + 0x96a0, 0x04c5, + 0x96a3, 0x0fa1, + 0x96a7, 0x1bc4, + 0x96a8, 0x1b0b, + 0x96aa, 0x1bc3, + 0x96af, 0x21f1, + 0x96b0, 0x1bc7, + 0x96b1, 0x1bc5, + 0x96b4, 0x1bc8, + 0x96b6, 0x1bc9, + 0x96b7, 0x0fb4, + 0x96b8, 0x1bca, + 0x96bb, 0x0a6d, + 0x96bc, 0x0d4f, + 0x96c0, 0x0a43, + 0x96c1, 0x0623, + 0x96c4, 0x0f24, + 0x96c5, 0x056d, + 0x96c6, 0x0942, + 0x96c7, 0x078f, + 0x96c9, 0x1bce, + 0x96cb, 0x1bcd, + 0x96cc, 0x08c1, + 0x96cd, 0x1bcf, + 0x96ce, 0x1bcc, + 0x96d1, 0x0876, + 0x96d5, 0x1bd3, + 0x96d6, 0x1992, + 0x96d9, 0x10eb, + 0x96db, 0x0a3d, + 0x96dc, 0x1bd1, + 0x96e2, 0x0f6d, + 0x96e3, 0x0cc9, + 0x96e8, 0x04cd, + 0x96ea, 0x0a87, + 0x96eb, 0x08e2, + 0x96f0, 0x0e07, + 0x96f2, 0x04e2, + 0x96f6, 0x0fb5, + 0x96f7, 0x0f55, + 0x96f9, 0x1bd4, + 0x96fb, 0x0c3f, + 0x9700, 0x0927, + 0x9704, 0x1bd5, + 0x9706, 0x1bd6, + 0x9707, 0x0a12, + 0x9708, 0x1bd7, + 0x970a, 0x0fb6, + 0x970d, 0x1bd2, + 0x970e, 0x1bd9, + 0x970f, 0x1bdb, + 0x9711, 0x1bda, + 0x9713, 0x1bd8, + 0x9716, 0x1bdc, + 0x9719, 0x1bdd, + 0x971c, 0x0afc, + 0x971e, 0x0562, + 0x9724, 0x1bde, + 0x9727, 0x0ec4, + 0x972a, 0x1bdf, + 0x9730, 0x1be0, + 0x9732, 0x0fd0, + 0x9733, 0x21f2, + 0x9738, 0x1414, + 0x9739, 0x1be1, + 0x973b, 0x21f3, + 0x973d, 0x1be2, + 0x9742, 0x1be7, + 0x9743, 0x21f4, + 0x9744, 0x1be4, + 0x9746, 0x1be5, + 0x9748, 0x1be6, + 0x9749, 0x1be8, + 0x974d, 0x21f5, + 0x974f, 0x21f6, + 0x9751, 0x21f7, + 0x9752, 0x0a68, + 0x9755, 0x21f8, + 0x9756, 0x0f03, + 0x9759, 0x0a69, + 0x975c, 0x1be9, + 0x975e, 0x0d87, + 0x9760, 0x1bea, + 0x9761, 0x1d06, + 0x9762, 0x0ed8, + 0x9764, 0x1beb, + 0x9766, 0x1bec, + 0x9768, 0x1bed, + 0x9769, 0x05b5, + 0x976b, 0x1bef, + 0x976d, 0x0a1f, + 0x9771, 0x1bf0, + 0x9774, 0x06fa, + 0x9779, 0x1bf1, + 0x977a, 0x1bf5, + 0x977c, 0x1bf3, + 0x9781, 0x1bf4, + 0x9784, 0x05d1, + 0x9785, 0x1bf2, + 0x9786, 0x1bf6, + 0x978b, 0x1bf7, + 0x978d, 0x048c, + 0x978f, 0x1bf8, + 0x9798, 0x09cc, + 0x979c, 0x1bfa, + 0x97a0, 0x0661, + 0x97a3, 0x1bfd, + 0x97a6, 0x1bfc, + 0x97a8, 0x1bfb, + 0x97ab, 0x1a34, + 0x97ad, 0x0e2c, + 0x97b3, 0x1bfe, + 0x97c3, 0x1c00, + 0x97c6, 0x1c01, + 0x97c8, 0x1c02, + 0x97cb, 0x1c03, + 0x97d3, 0x0616, + 0x97dc, 0x1c04, + 0x97ed, 0x1c05, + 0x97ee, 0x0cd9, + 0x97f2, 0x1c07, + 0x97f3, 0x053b, + 0x97f5, 0x1c0a, + 0x97f6, 0x1c09, + 0x97fb, 0x04c6, + 0x97ff, 0x06b9, + 0x9801, 0x0e17, + 0x9802, 0x0bd6, + 0x9803, 0x0812, + 0x9805, 0x07f2, + 0x9806, 0x0971, + 0x9808, 0x0a22, + 0x980c, 0x1c0c, + 0x980f, 0x1c0b, + 0x9810, 0x0f2c, + 0x9811, 0x0624, + 0x9812, 0x0d66, + 0x9813, 0x0cb4, + 0x9817, 0x0a42, + 0x9818, 0x0f96, + 0x981a, 0x0731, + 0x9821, 0x1c0f, + 0x9824, 0x1c0e, + 0x982c, 0x0e79, + 0x982d, 0x0c84, + 0x9830, 0x1e73, + 0x9834, 0x04f2, + 0x9837, 0x1c10, + 0x9838, 0x1c0d, + 0x983b, 0x0dc3, + 0x983c, 0x0f54, + 0x983d, 0x1c11, + 0x9846, 0x1c12, + 0x984b, 0x1c14, + 0x984c, 0x0b4a, + 0x984d, 0x05b9, + 0x984f, 0x1c13, + 0x9854, 0x0625, + 0x9855, 0x0766, + 0x9857, 0x21f9, + 0x9858, 0x0626, + 0x985a, 0x1e48, + 0x985b, 0x0c39, + 0x985e, 0x0fa8, + 0x9865, 0x21fa, + 0x9867, 0x0790, + 0x986b, 0x1c15, + 0x986f, 0x1c16, + 0x9873, 0x1c1a, + 0x9874, 0x1c19, + 0x98a8, 0x0de9, + 0x98aa, 0x1c1b, + 0x98af, 0x1c1c, + 0x98b1, 0x1c1d, + 0x98b6, 0x1c1e, + 0x98c3, 0x1c20, + 0x98c4, 0x1c1f, + 0x98c6, 0x1c21, + 0x98db, 0x0d88, + 0x98dc, 0x1839, + 0x98df, 0x09ef, + 0x98e2, 0x064c, + 0x98e9, 0x1c22, + 0x98eb, 0x1c23, + 0x98ed, 0x10c1, + 0x98ee, 0x14da, + 0x98ef, 0x0d67, + 0x98f2, 0x04bf, + 0x98f4, 0x047f, + 0x98fc, 0x08c2, + 0x98fd, 0x0e5e, + 0x98fe, 0x09e6, + 0x9903, 0x1c24, + 0x9905, 0x0eeb, + 0x9909, 0x1c25, + 0x990a, 0x0f46, + 0x990c, 0x04e4, + 0x9910, 0x088f, + 0x9912, 0x1c26, + 0x9913, 0x056e, + 0x9914, 0x1c27, + 0x9918, 0x1c28, + 0x991d, 0x1c2a, + 0x9920, 0x1c2d, + 0x9921, 0x1c29, + 0x9924, 0x1c2c, + 0x9927, 0x21fd, + 0x9928, 0x0617, + 0x992c, 0x1c2e, + 0x992e, 0x1c2f, + 0x993d, 0x1c30, + 0x9942, 0x1c32, + 0x9945, 0x1c34, + 0x9949, 0x1c33, + 0x994b, 0x1c36, + 0x994c, 0x1c39, + 0x9950, 0x1c35, + 0x9951, 0x1c37, + 0x9955, 0x1c3a, + 0x9957, 0x06ba, + 0x9996, 0x091f, + 0x9997, 0x1c3b, + 0x9999, 0x07f3, + 0x999e, 0x21ff, + 0x99a5, 0x1c3d, + 0x99a8, 0x059c, + 0x99ac, 0x0d05, + 0x99ad, 0x1c3e, + 0x99b3, 0x0b98, + 0x99b4, 0x0cc3, + 0x99bc, 0x1c40, + 0x99c1, 0x0d33, + 0x99c4, 0x0b2c, + 0x99c5, 0x04fa, + 0x99c6, 0x06e6, + 0x99c8, 0x06e7, + 0x99d0, 0x0bb1, + 0x99d1, 0x1c45, + 0x99d2, 0x06e8, + 0x99d5, 0x056f, + 0x99d8, 0x1c44, + 0x99db, 0x1c42, + 0x99dd, 0x1c43, + 0x99df, 0x1c41, + 0x99e2, 0x1c4f, + 0x99ed, 0x1c46, + 0x99f1, 0x1c48, + 0x99f8, 0x1c4b, + 0x99fb, 0x1c4a, + 0x99ff, 0x0963, + 0x9a01, 0x1c4c, + 0x9a05, 0x1c4e, + 0x9a0e, 0x064d, + 0x9a0f, 0x1c4d, + 0x9a12, 0x0afd, + 0x9a13, 0x0767, + 0x9a19, 0x1c50, + 0x9a28, 0x0b2d, + 0x9a2b, 0x1c51, + 0x9a30, 0x0c85, + 0x9a37, 0x1c52, + 0x9a3e, 0x1c57, + 0x9a40, 0x1c55, + 0x9a42, 0x1c54, + 0x9a43, 0x1c56, + 0x9a45, 0x1c53, + 0x9a4d, 0x1c59, + 0x9a4e, 0x2200, + 0x9a52, 0x1e2f, + 0x9a55, 0x1c58, + 0x9a57, 0x1c5b, + 0x9a5a, 0x06bb, + 0x9a5b, 0x1c5a, + 0x9a5f, 0x1c5c, + 0x9a62, 0x1c5d, + 0x9a64, 0x1c5f, + 0x9a65, 0x1c5e, + 0x9a69, 0x1c60, + 0x9a6a, 0x1c62, + 0x9a6b, 0x1c61, + 0x9aa8, 0x080e, + 0x9aad, 0x1c63, + 0x9ab0, 0x1c64, + 0x9ab8, 0x059a, + 0x9abc, 0x1c65, + 0x9ac0, 0x1c66, + 0x9ac4, 0x0a37, + 0x9acf, 0x1c67, + 0x9ad1, 0x1c68, + 0x9ad3, 0x1c69, + 0x9ad8, 0x07f4, + 0x9ad9, 0x2201, + 0x9adc, 0x2202, + 0x9ade, 0x1c6b, + 0x9ae2, 0x1c6d, + 0x9ae6, 0x1c6f, + 0x9aea, 0x0d45, + 0x9aeb, 0x1c71, + 0x9aed, 0x0d98, + 0x9aee, 0x1c72, + 0x9aef, 0x1c70, + 0x9af1, 0x1c74, + 0x9af4, 0x1c73, + 0x9af7, 0x1c75, + 0x9afb, 0x1c76, + 0x9b06, 0x1c77, + 0x9b18, 0x1c78, + 0x9b1a, 0x1c79, + 0x9b1f, 0x1c7a, + 0x9b22, 0x1c7b, + 0x9b25, 0x1c7d, + 0x9b27, 0x1c7e, + 0x9b2e, 0x1c82, + 0x9b31, 0x14d4, + 0x9b32, 0x1c84, + 0x9b3b, 0x17a9, + 0x9b3c, 0x064e, + 0x9b41, 0x057f, + 0x9b42, 0x0822, + 0x9b43, 0x1c86, + 0x9b44, 0x1c85, + 0x9b45, 0x0eb1, + 0x9b4d, 0x1c88, + 0x9b4f, 0x1c87, + 0x9b51, 0x1c8a, + 0x9b54, 0x0e90, + 0x9b58, 0x1c8b, + 0x9b5a, 0x0695, + 0x9b6f, 0x0fcb, + 0x9b72, 0x2204, + 0x9b74, 0x1c8c, + 0x9b75, 0x2203, + 0x9b83, 0x1c8e, + 0x9b8e, 0x0482, + 0x9b8f, 0x2205, + 0x9b91, 0x1c8f, + 0x9b92, 0x0dfb, + 0x9b93, 0x1c8d, + 0x9b96, 0x1c90, + 0x9b9f, 0x1c92, + 0x9ba8, 0x1c94, + 0x9baa, 0x0e9c, + 0x9bab, 0x087b, + 0x9bad, 0x086a, + 0x9bae, 0x0ab1, + 0x9bb1, 0x2206, + 0x9bb4, 0x1c95, + 0x9bb9, 0x1c98, + 0x9bbb, 0x2207, + 0x9bc0, 0x1c96, + 0x9bc6, 0x1c99, + 0x9bc9, 0x07a5, + 0x9bca, 0x1c97, + 0x9bcf, 0x1c9a, + 0x9bd1, 0x1c9b, + 0x9bd4, 0x1ca0, + 0x9bd6, 0x0878, + 0x9bdb, 0x0b44, + 0x9be1, 0x1ca1, + 0x9be2, 0x1c9e, + 0x9be3, 0x1c9d, + 0x9be4, 0x1c9f, + 0x9be8, 0x0735, + 0x9bf0, 0x1ca5, + 0x9bf1, 0x1ca4, + 0x9bf2, 0x1ca3, + 0x9bf5, 0x0477, + 0x9c00, 0x2208, + 0x9c04, 0x1caf, + 0x9c06, 0x1cab, + 0x9c08, 0x1cac, + 0x9c09, 0x1ca8, + 0x9c0a, 0x1cae, + 0x9c0c, 0x1caa, + 0x9c0d, 0x05c0, + 0x9c10, 0x0ff2, + 0x9c12, 0x1cad, + 0x9c13, 0x1ca9, + 0x9c14, 0x1ca7, + 0x9c15, 0x1ca6, + 0x9c1b, 0x1cb1, + 0x9c21, 0x1cb4, + 0x9c24, 0x1cb3, + 0x9c25, 0x1cb2, + 0x9c2d, 0x0dbb, + 0x9c2e, 0x1cb0, + 0x9c2f, 0x04b7, + 0x9c30, 0x1cb5, + 0x9c32, 0x1cb7, + 0x9c39, 0x05cd, + 0x9c3a, 0x1ca2, + 0x9c3b, 0x04d9, + 0x9c3e, 0x1cb9, + 0x9c46, 0x1cb8, + 0x9c47, 0x1cb6, + 0x9c48, 0x0b6b, + 0x9c52, 0x0e9e, + 0x9c57, 0x0fa2, + 0x9c5a, 0x1cba, + 0x9c60, 0x1cbb, + 0x9c67, 0x1cbc, + 0x9c76, 0x1cbd, + 0x9c78, 0x1cbe, + 0x9ce5, 0x0bd7, + 0x9ce7, 0x1cbf, + 0x9ce9, 0x0d4b, + 0x9ceb, 0x1cc4, + 0x9cec, 0x1cc0, + 0x9cf0, 0x1cc1, + 0x9cf3, 0x0e5f, + 0x9cf4, 0x0ed0, + 0x9cf6, 0x0ca8, + 0x9d03, 0x1cc5, + 0x9d06, 0x1cc6, + 0x9d07, 0x0c96, + 0x9d08, 0x1cc3, + 0x9d09, 0x1cc2, + 0x9d0e, 0x052a, + 0x9d12, 0x1cce, + 0x9d15, 0x1ccd, + 0x9d1b, 0x0517, + 0x9d1f, 0x1ccb, + 0x9d23, 0x1cca, + 0x9d26, 0x1cc8, + 0x9d28, 0x05d9, + 0x9d2a, 0x1cc7, + 0x9d2b, 0x08de, + 0x9d2c, 0x0529, + 0x9d3b, 0x07f5, + 0x9d3e, 0x1cd1, + 0x9d3f, 0x1cd0, + 0x9d41, 0x1ccf, + 0x9d44, 0x1ccc, + 0x9d46, 0x1cd2, + 0x9d48, 0x1cd3, + 0x9d50, 0x1cd8, + 0x9d51, 0x1cd7, + 0x9d59, 0x1cd9, + 0x9d5c, 0x04cf, + 0x9d5d, 0x1cd4, + 0x9d60, 0x0806, + 0x9d61, 0x0ec5, + 0x9d64, 0x1cd6, + 0x9d6b, 0x220a, + 0x9d6c, 0x0e60, + 0x9d6f, 0x1cde, + 0x9d70, 0x2209, + 0x9d72, 0x1cda, + 0x9d7a, 0x1cdf, + 0x9d87, 0x1cdc, + 0x9d89, 0x1cdb, + 0x9d8f, 0x0732, + 0x9d9a, 0x1ce0, + 0x9da4, 0x1ce1, + 0x9da9, 0x1ce2, + 0x9dab, 0x1cdd, + 0x9daf, 0x1cc9, + 0x9db2, 0x1ce3, + 0x9db4, 0x0bfd, + 0x9db8, 0x1ce7, + 0x9dba, 0x1ce8, + 0x9dbb, 0x1ce6, + 0x9dc1, 0x1ce5, + 0x9dc2, 0x1ceb, + 0x9dc4, 0x1ce4, + 0x9dc6, 0x1ce9, + 0x9dcf, 0x1cea, + 0x9dd3, 0x1ced, + 0x9dd7, 0x1dde, + 0x9dd9, 0x1cec, + 0x9de6, 0x1cef, + 0x9ded, 0x1cf0, + 0x9def, 0x1cf1, + 0x9df2, 0x0fef, + 0x9df8, 0x1cee, + 0x9df9, 0x0b4b, + 0x9dfa, 0x085d, + 0x9dfd, 0x1cf2, + 0x9e19, 0x220c, + 0x9e1a, 0x1cf3, + 0x9e1e, 0x1cf5, + 0x9e75, 0x1cf6, + 0x9e78, 0x0768, + 0x9e79, 0x1cf7, + 0x9e7c, 0x1dfd, + 0x9e7d, 0x1cf8, + 0x9e7f, 0x08db, + 0x9e81, 0x1cf9, + 0x9e88, 0x1cfa, + 0x9e8b, 0x1cfb, + 0x9e91, 0x1cff, + 0x9e92, 0x1cfd, + 0x9e93, 0x0fe2, + 0x9e95, 0x1cfe, + 0x9e97, 0x0fb7, + 0x9e9d, 0x1d00, + 0x9e9f, 0x0fa3, + 0x9ea5, 0x1d01, + 0x9ea6, 0x0d34, + 0x9ea9, 0x1d02, + 0x9eaa, 0x1d04, + 0x9ead, 0x1d05, + 0x9eb4, 0x1e02, + 0x9eb5, 0x1e75, + 0x9eb8, 0x1d03, + 0x9eb9, 0x07ff, + 0x9eba, 0x0ed9, + 0x9ebb, 0x0e91, + 0x9ebc, 0x1284, + 0x9ebe, 0x14ff, + 0x9ebf, 0x0ea9, + 0x9ec4, 0x052b, + 0x9ecc, 0x1d07, + 0x9ecd, 0x066a, + 0x9ece, 0x1d08, + 0x9ed1, 0x220d, + 0x9ed2, 0x0807, + 0x9ed4, 0x1d0b, + 0x9ed8, 0x160d, + 0x9ed9, 0x0ee7, + 0x9edb, 0x0b43, + 0x9edc, 0x1d0c, + 0x9edd, 0x1d0e, + 0x9ede, 0x1d0d, + 0x9ee0, 0x1d0f, + 0x9ee5, 0x1d10, + 0x9ee8, 0x1d11, + 0x9eef, 0x1d12, + 0x9ef4, 0x1d13, + 0x9ef6, 0x1d14, + 0x9ef9, 0x1d16, + 0x9efb, 0x1d17, + 0x9f07, 0x1d1a, + 0x9f0e, 0x0c1e, + 0x9f13, 0x0791, + 0x9f15, 0x1d1d, + 0x9f20, 0x0acf, + 0x9f21, 0x1d1e, + 0x9f2c, 0x1d1f, + 0x9f3b, 0x0d93, + 0x9f3e, 0x1d20, + 0x9f4a, 0x1d21, + 0x9f4b, 0x170a, + 0x9f4e, 0x1a7b, + 0x9f4f, 0x1c06, + 0x9f52, 0x1d22, + 0x9f54, 0x1d23, + 0x9f5f, 0x1d25, + 0x9f62, 0x0fb8, + 0x9f63, 0x1d24, + 0x9f66, 0x1d28, + 0x9f6a, 0x1d2b, + 0x9f6c, 0x1d2a, + 0x9f72, 0x1d2d, + 0x9f76, 0x1d2e, + 0x9f77, 0x1d2c, + 0x9f8d, 0x0f7e, + 0x9f95, 0x1d2f, + 0x9f9c, 0x1d30, + 0x9f9d, 0x1727, + 0x9fa0, 0x1d31, + 0xf929, 0x2129, + 0xf9dc, 0x21ee, + 0xfa0e, 0x20da, + 0xfa0f, 0x20e5, + 0xfa11, 0x20fb, + 0xfa12, 0x2121, + 0xfa13, 0x2131, + 0xfa14, 0x2133, + 0xfa15, 0x215e, + 0xfa16, 0x2164, + 0xfa17, 0x217b, + 0xfa18, 0x2183, + 0xfa1b, 0x2187, + 0xfa1c, 0x218b, + 0xfa1d, 0x218e, + 0xfa1e, 0x2197, + 0xfa1f, 0x21a2, + 0xfa20, 0x21a4, + 0xfa22, 0x21ae, + 0xfa23, 0x21b6, + 0xfa24, 0x21b8, + 0xfa26, 0x21bc, + 0xfa27, 0x21d8, + 0xfa28, 0x21df, + 0xfa29, 0x21ef, + 0xfa2a, 0x21fb, + 0xfa2c, 0x21fe, + 0xfa2d, 0x220b, + 0xfb01, 0x0070, + 0xfe30, 0x1eda, + 0xfe31, 0x1ed4, + 0xfe33, 0x1ed2, + 0xfe35, 0x1edb, + 0xfe37, 0x1ee1, + 0xfe39, 0x1edd, + 0xfe3b, 0x1eeb, + 0xfe3d, 0x1ee5, + 0xfe3f, 0x1ee3, + 0xfe41, 0x1ee7, + 0xff01, 0x0282, + 0xff02, 0x1f47, + 0xff03, 0x02cc, + 0xff04, 0x02c8, + 0xff05, 0x02cb, + 0xff06, 0x02cd, + 0xff07, 0x1f46, + 0xff08, 0x02a2, + 0xff0a, 0x02ce, + 0xff0b, 0x02b4, + 0xff0c, 0x027c, + 0xff0d, 0x0296, + 0xff0e, 0x027d, + 0xff0f, 0x0297, + 0xff10, 0x030c, + 0xff1a, 0x027f, + 0xff1c, 0x02bb, + 0xff1d, 0x02b9, + 0xff1e, 0x02bc, + 0xff1f, 0x0281, + 0xff20, 0x02cf, + 0xff21, 0x0316, + 0xff3b, 0x02a6, + 0xff3c, 0x0298, + 0xff3d, 0x02a7, + 0xff3e, 0x0288, + 0xff3f, 0x028a, + 0xff40, 0x0286, + 0xff41, 0x0330, + 0xff5b, 0x02a8, + 0xff5c, 0x029b, + 0xff5d, 0x02a9, + 0xff5e, 0x0299, + 0xff61, 0x0147, + 0xffe0, 0x02c9, + 0xffe2, 0x02ef, + 0xffe3, 0x0289, + 0xffe4, 0x1f45, + 0xffe5, 0x02c7, + 0xffe8, 0x0143, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12UniJISUCS2HEnc16 = { + 0, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12UniJISUCS2HMap2, 6963 +}; + +static Gushort japan12UniJISUCS2VMap2[14216] = { + 0x0000, 0x0000, + 0x0020, 0x0001, + 0x005c, 0x0061, + 0x005d, 0x003e, + 0x00a1, 0x0065, + 0x00a4, 0x006b, + 0x00a5, 0x003d, + 0x00a6, 0x0063, + 0x00a7, 0x02d0, + 0x00a8, 0x0287, + 0x00a9, 0x0098, + 0x00aa, 0x008c, + 0x00ab, 0x006d, + 0x00ac, 0x0099, + 0x00ad, 0x0097, + 0x00ae, 0x009a, + 0x00af, 0x0081, + 0x00b0, 0x02c3, + 0x00b1, 0x02b6, + 0x00b2, 0x009d, + 0x00b4, 0x0285, + 0x00b5, 0x009f, + 0x00b6, 0x030a, + 0x00b7, 0x0075, + 0x00b8, 0x0086, + 0x00b9, 0x00a0, + 0x00ba, 0x0090, + 0x00bb, 0x007b, + 0x00bc, 0x00a1, + 0x00bf, 0x007e, + 0x00c0, 0x00a4, + 0x00c6, 0x008b, + 0x00c7, 0x00aa, + 0x00d7, 0x02b7, + 0x00d8, 0x008e, + 0x00d9, 0x00bb, + 0x00df, 0x0096, + 0x00e0, 0x00c1, + 0x00e6, 0x0091, + 0x00e7, 0x00c7, + 0x00f7, 0x02b8, + 0x00f8, 0x0094, + 0x00f9, 0x00d8, + 0x0131, 0x0092, + 0x0141, 0x008d, + 0x0142, 0x0093, + 0x0152, 0x008f, + 0x0153, 0x0095, + 0x0160, 0x00df, + 0x0161, 0x00e3, + 0x0178, 0x00e0, + 0x017d, 0x00e1, + 0x017e, 0x00e5, + 0x01c0, 0x0063, + 0x0300, 0x0041, + 0x0301, 0x007f, + 0x0303, 0x005f, + 0x0304, 0x0081, + 0x0305, 0x00e2, + 0x0306, 0x0082, + 0x030a, 0x0085, + 0x030b, 0x0087, + 0x030c, 0x0089, + 0x0327, 0x0086, + 0x0328, 0x0088, + 0x0332, 0x0040, + 0x0336, 0x008a, + 0x0361, 0x02f6, + 0x0391, 0x03f3, + 0x03a3, 0x0404, + 0x03b1, 0x040b, + 0x03c3, 0x041c, + 0x0401, 0x0429, + 0x0410, 0x0423, + 0x0416, 0x042a, + 0x0436, 0x044b, + 0x0451, 0x044a, + 0x2002, 0x00e7, + 0x2003, 0x0279, + 0x2010, 0x000e, + 0x2011, 0x000e, + 0x2012, 0x0072, + 0x2013, 0x0072, + 0x2014, 0x008a, + 0x2015, 0x0295, + 0x2016, 0x029a, + 0x2018, 0x029e, + 0x201a, 0x0078, + 0x201c, 0x02a0, + 0x201e, 0x0079, + 0x2020, 0x0308, + 0x2022, 0x0077, + 0x2025, 0x029d, + 0x2026, 0x029c, + 0x2030, 0x0304, + 0x2032, 0x02c4, + 0x2039, 0x006e, + 0x203b, 0x02de, + 0x203e, 0x0145, + 0x2044, 0x0068, + 0x20dd, 0x030b, + 0x2103, 0x02c6, + 0x2109, 0x2071, + 0x2113, 0x1f59, + 0x2116, 0x1dba, + 0x2121, 0x1f77, + 0x2122, 0x00e4, + 0x212b, 0x0303, + 0x2160, 0x1d97, + 0x216a, 0x2021, + 0x2170, 0x1f9c, + 0x217a, 0x206a, + 0x217f, 0x206f, + 0x2190, 0x02e1, + 0x2192, 0x02e0, + 0x2193, 0x02e3, + 0x21c4, 0x2076, + 0x21c6, 0x2075, + 0x21d2, 0x02f0, + 0x21d4, 0x02f1, + 0x21e6, 0x1f4d, + 0x21e7, 0x1f4c, + 0x21e8, 0x1f4e, + 0x21e9, 0x1f4b, + 0x2200, 0x02f2, + 0x2202, 0x02f7, + 0x2203, 0x02f3, + 0x2207, 0x02f8, + 0x2208, 0x02e5, + 0x220b, 0x02e6, + 0x2211, 0x1dc9, + 0x2212, 0x02b5, + 0x221a, 0x02fd, + 0x221d, 0x02ff, + 0x221e, 0x02bf, + 0x221f, 0x1dcd, + 0x2220, 0x02f4, + 0x2225, 0x029a, + 0x2227, 0x02ed, + 0x2229, 0x02ec, + 0x222a, 0x02eb, + 0x222b, 0x0301, + 0x222d, 0x2003, + 0x222e, 0x1dc8, + 0x2234, 0x02c0, + 0x2235, 0x0300, + 0x223c, 0x0299, + 0x223d, 0x02fe, + 0x2252, 0x02fa, + 0x2260, 0x02ba, + 0x2261, 0x02f9, + 0x2266, 0x02bd, + 0x226a, 0x02fb, + 0x2282, 0x02e9, + 0x2286, 0x02e7, + 0x22a5, 0x02f5, + 0x22bf, 0x1dce, + 0x22ee, 0x1ed9, + 0x22ef, 0x029c, + 0x2312, 0x02f6, + 0x2460, 0x1d83, + 0x2474, 0x1f87, + 0x2488, 0x1f7e, + 0x249c, 0x1fb0, + 0x24ea, 0x2020, + 0x2500, 0x1d37, + 0x2550, 0x203b, + 0x255e, 0x203c, + 0x2561, 0x203e, + 0x256a, 0x203d, + 0x256d, 0x2037, + 0x256f, 0x203a, + 0x2570, 0x2039, + 0x2571, 0x2045, + 0x2581, 0x2026, + 0x2589, 0x2034, + 0x258a, 0x2033, + 0x258b, 0x2032, + 0x258c, 0x2031, + 0x258d, 0x2030, + 0x258e, 0x202f, + 0x258f, 0x202e, + 0x2594, 0x2035, + 0x25a0, 0x02d9, + 0x25a1, 0x02d8, + 0x25a2, 0x1f4f, + 0x25b2, 0x02db, + 0x25b3, 0x02da, + 0x25b7, 0x1f4a, + 0x25bc, 0x02dd, + 0x25bd, 0x02dc, + 0x25c1, 0x1f49, + 0x25c6, 0x02d7, + 0x25c7, 0x02d6, + 0x25c9, 0x2012, + 0x25cb, 0x02d3, + 0x25ce, 0x02d5, + 0x25cf, 0x02d4, + 0x25e2, 0x203f, + 0x25e4, 0x2042, + 0x25e5, 0x2041, + 0x25ef, 0x030b, + 0x2600, 0x2017, + 0x2605, 0x02d2, + 0x2606, 0x02d1, + 0x260e, 0x1f78, + 0x261c, 0x201c, + 0x261e, 0x201b, + 0x261f, 0x201e, + 0x2640, 0x02c2, + 0x2642, 0x02c1, + 0x2660, 0x2013, + 0x2661, 0x1f51, + 0x2662, 0x1f53, + 0x2663, 0x2015, + 0x2664, 0x1f52, + 0x2665, 0x2014, + 0x2666, 0x2016, + 0x2667, 0x1f50, + 0x266a, 0x0307, + 0x266d, 0x0306, + 0x266f, 0x0305, + 0x2776, 0x205e, + 0x27a1, 0x200e, + 0x3000, 0x0279, + 0x3003, 0x028f, + 0x3004, 0x2074, + 0x3005, 0x0291, + 0x3008, 0x02aa, + 0x3012, 0x02df, + 0x3013, 0x02e4, + 0x3014, 0x02a4, + 0x301c, 0x0299, + 0x301d, 0x1db8, + 0x301f, 0x1db9, + 0x3020, 0x1f7a, + 0x3036, 0x1f79, + 0x3041, 0x034a, + 0x3094, 0x1f16, + 0x309b, 0x0283, + 0x309d, 0x028d, + 0x30a1, 0x039d, + 0x30f7, 0x2079, + 0x30fb, 0x027e, + 0x30fc, 0x0294, + 0x30fd, 0x028b, + 0x322a, 0x2006, + 0x3230, 0x2005, + 0x3231, 0x1dc2, + 0x3233, 0x1fcf, + 0x3234, 0x1fcd, + 0x3235, 0x1fd4, + 0x3236, 0x1fd3, + 0x3237, 0x200c, + 0x3238, 0x1fce, + 0x3239, 0x1dc4, + 0x323a, 0x1fd7, + 0x323b, 0x1fd5, + 0x323c, 0x1fd0, + 0x323d, 0x1fcb, + 0x323e, 0x1fd2, + 0x323f, 0x1fcc, + 0x3240, 0x1fd6, + 0x3241, 0x200d, + 0x3242, 0x1fd1, + 0x3243, 0x1fca, + 0x3291, 0x1fe1, + 0x3292, 0x1fe0, + 0x3293, 0x1fe2, + 0x3294, 0x1fdc, + 0x3296, 0x1fe5, + 0x3298, 0x1fde, + 0x3299, 0x201f, + 0x329d, 0x207f, + 0x329e, 0x1fff, + 0x32a4, 0x1dbd, + 0x32a9, 0x1fda, + 0x32aa, 0x1fdd, + 0x32ab, 0x1fdf, + 0x32ac, 0x1fe3, + 0x32ad, 0x1fd9, + 0x32ae, 0x1fe4, + 0x32af, 0x1fdb, + 0x32b0, 0x1fd8, + 0x3300, 0x1f70, + 0x3303, 0x1f6a, + 0x3305, 0x1ff7, + 0x330d, 0x1dab, + 0x3314, 0x1da2, + 0x3315, 0x1f69, + 0x3316, 0x1f67, + 0x3318, 0x1f68, + 0x331e, 0x1f73, + 0x3322, 0x1f66, + 0x3323, 0x1f6b, + 0x3326, 0x1dac, + 0x3327, 0x1da6, + 0x332a, 0x1f74, + 0x332b, 0x1dae, + 0x3331, 0x1f71, + 0x3333, 0x2087, + 0x3336, 0x1da8, + 0x3339, 0x1f6e, + 0x333b, 0x1f6f, + 0x3342, 0x1f6d, + 0x3347, 0x1f72, + 0x3349, 0x1da1, + 0x334a, 0x1daf, + 0x334d, 0x1da4, + 0x334e, 0x2088, + 0x3351, 0x1da9, + 0x3357, 0x1f6c, + 0x337b, 0x2083, + 0x337c, 0x1dc7, + 0x337d, 0x1dc6, + 0x337e, 0x1dc5, + 0x337f, 0x1f76, + 0x3385, 0x1f5f, + 0x3388, 0x2000, + 0x338e, 0x1db4, + 0x3390, 0x1f63, + 0x3396, 0x1f65, + 0x3397, 0x1f58, + 0x3398, 0x1f5a, + 0x339c, 0x1db1, + 0x339f, 0x1ffa, + 0x33a0, 0x1f54, + 0x33a1, 0x1db7, + 0x33a2, 0x1f55, + 0x33a3, 0x1ffb, + 0x33a4, 0x1f56, + 0x33a6, 0x1ffc, + 0x33b0, 0x1f5e, + 0x33b1, 0x1f5d, + 0x33b2, 0x1f5c, + 0x33b3, 0x1f5b, + 0x33c4, 0x1db6, + 0x33c8, 0x2002, + 0x33cb, 0x1f62, + 0x33cc, 0x1ff6, + 0x33cd, 0x1dbb, + 0x33d4, 0x1f64, + 0x4e00, 0x04b0, + 0x4e01, 0x0bb8, + 0x4e03, 0x08e3, + 0x4e07, 0x0eaa, + 0x4e08, 0x09ce, + 0x4e09, 0x087e, + 0x4e0a, 0x09cd, + 0x4e0b, 0x053c, + 0x4e0d, 0x0dc6, + 0x4e0e, 0x0f29, + 0x4e10, 0x0ffb, + 0x4e11, 0x04d1, + 0x4e14, 0x05cc, + 0x4e15, 0x0ffc, + 0x4e16, 0x0a48, + 0x4e17, 0x10d7, + 0x4e18, 0x0670, + 0x4e19, 0x0e0a, + 0x4e1e, 0x09cf, + 0x4e21, 0x0f86, + 0x4e26, 0x0e12, + 0x4e28, 0x20b3, + 0x4e2a, 0x0ffd, + 0x4e2d, 0x0ba4, + 0x4e31, 0x0ffe, + 0x4e32, 0x06f2, + 0x4e36, 0x0fff, + 0x4e38, 0x0619, + 0x4e39, 0x0b6e, + 0x4e3b, 0x0913, + 0x4e3c, 0x1000, + 0x4e3f, 0x1001, + 0x4e42, 0x1002, + 0x4e43, 0x0ceb, + 0x4e45, 0x0671, + 0x4e4b, 0x0ced, + 0x4e4d, 0x0cbb, + 0x4e4e, 0x0777, + 0x4e4f, 0x0e61, + 0x4e55, 0x1950, + 0x4e56, 0x1003, + 0x4e57, 0x09d0, + 0x4e58, 0x1004, + 0x4e59, 0x0535, + 0x4e5d, 0x06dd, + 0x4e5e, 0x07a4, + 0x4e5f, 0x0ef5, + 0x4e62, 0x1233, + 0x4e71, 0x0f5a, + 0x4e73, 0x0cd5, + 0x4e7e, 0x05e1, + 0x4e80, 0x064f, + 0x4e82, 0x1005, + 0x4e85, 0x1006, + 0x4e86, 0x0f83, + 0x4e88, 0x0f27, + 0x4e89, 0x0aea, + 0x4e8a, 0x1008, + 0x4e8b, 0x08c4, + 0x4e8c, 0x0ccb, + 0x4e8e, 0x100b, + 0x4e91, 0x04e0, + 0x4e92, 0x0793, + 0x4e94, 0x0792, + 0x4e95, 0x04aa, + 0x4e98, 0x0ff1, + 0x4e99, 0x0ff0, + 0x4e9b, 0x0823, + 0x4e9c, 0x0465, + 0x4e9e, 0x100c, + 0x4ea1, 0x0e62, + 0x4ea2, 0x100f, + 0x4ea4, 0x07a6, + 0x4ea5, 0x04ab, + 0x4ea6, 0x0ea0, + 0x4ea8, 0x0696, + 0x4eab, 0x0697, + 0x4ead, 0x0bfe, + 0x4eae, 0x0f84, + 0x4eb0, 0x1010, + 0x4eb3, 0x1011, + 0x4eb6, 0x1012, + 0x4eba, 0x0a13, + 0x4ec0, 0x0944, + 0x4ec1, 0x0a14, + 0x4ec2, 0x1017, + 0x4ec4, 0x1015, + 0x4ec6, 0x1016, + 0x4ec7, 0x0672, + 0x4eca, 0x0813, + 0x4ecb, 0x0570, + 0x4ecd, 0x1014, + 0x4ece, 0x1013, + 0x4ecf, 0x0df9, + 0x4ed4, 0x0894, + 0x4ed5, 0x0893, + 0x4ed6, 0x0b1e, + 0x4ed7, 0x1018, + 0x4ed8, 0x0dc7, + 0x4ed9, 0x0a8b, + 0x4edd, 0x0290, + 0x4ede, 0x1019, + 0x4edf, 0x101b, + 0x4ee1, 0x20b4, + 0x4ee3, 0x0b45, + 0x4ee4, 0x0fa9, + 0x4ee5, 0x048e, + 0x4eed, 0x101a, + 0x4eee, 0x053e, + 0x4ef0, 0x06bc, + 0x4ef2, 0x0ba5, + 0x4ef6, 0x0745, + 0x4ef7, 0x101c, + 0x4efb, 0x0cda, + 0x4efc, 0x20b5, + 0x4f00, 0x20b6, + 0x4f01, 0x0627, + 0x4f03, 0x20b7, + 0x4f09, 0x101d, + 0x4f0a, 0x048f, + 0x4f0d, 0x0794, + 0x4f0e, 0x0628, + 0x4f0f, 0x0dec, + 0x4f10, 0x0d46, + 0x4f11, 0x0673, + 0x4f1a, 0x0571, + 0x4f1c, 0x1040, + 0x4f1d, 0x0c3b, + 0x4f2f, 0x0d22, + 0x4f30, 0x101f, + 0x4f34, 0x0d50, + 0x4f36, 0x0faa, + 0x4f38, 0x09f3, + 0x4f39, 0x20b8, + 0x4f3a, 0x0895, + 0x4f3c, 0x08c5, + 0x4f3d, 0x0540, + 0x4f43, 0x0bed, + 0x4f46, 0x0b60, + 0x4f47, 0x1023, + 0x4f4d, 0x0490, + 0x4f4e, 0x0bff, + 0x4f4f, 0x0945, + 0x4f50, 0x0824, + 0x4f51, 0x0f0e, + 0x4f53, 0x0b2e, + 0x4f55, 0x053f, + 0x4f56, 0x20b9, + 0x4f57, 0x1022, + 0x4f59, 0x0f28, + 0x4f5a, 0x101e, + 0x4f5b, 0x1020, + 0x4f5c, 0x085e, + 0x4f5d, 0x1021, + 0x4f5e, 0x11d3, + 0x4f69, 0x1029, + 0x4f6f, 0x102c, + 0x4f70, 0x102a, + 0x4f73, 0x0542, + 0x4f75, 0x0e0b, + 0x4f76, 0x1024, + 0x4f7b, 0x1028, + 0x4f7c, 0x07a7, + 0x4f7f, 0x0896, + 0x4f83, 0x05e2, + 0x4f86, 0x102d, + 0x4f88, 0x1025, + 0x4f8a, 0x20bb, + 0x4f8b, 0x0fab, + 0x4f8d, 0x08c6, + 0x4f8f, 0x1026, + 0x4f91, 0x102b, + 0x4f92, 0x20ba, + 0x4f94, 0x20bd, + 0x4f96, 0x102e, + 0x4f98, 0x1027, + 0x4f9a, 0x20bc, + 0x4f9b, 0x0699, + 0x4f9d, 0x0491, + 0x4fa0, 0x069a, + 0x4fa1, 0x0541, + 0x4fab, 0x11d4, + 0x4fad, 0x0ea7, + 0x4fae, 0x0de0, + 0x4faf, 0x07a8, + 0x4fb5, 0x09f5, + 0x4fb6, 0x0f7f, + 0x4fbf, 0x0e28, + 0x4fc2, 0x070e, + 0x4fc3, 0x0b05, + 0x4fc4, 0x0564, + 0x4fc9, 0x20ac, + 0x4fca, 0x095d, + 0x4fcd, 0x20be, + 0x4fce, 0x1032, + 0x4fd0, 0x1037, + 0x4fd1, 0x1035, + 0x4fd4, 0x1030, + 0x4fd7, 0x0b0f, + 0x4fd8, 0x1033, + 0x4fda, 0x1036, + 0x4fdb, 0x1034, + 0x4fdd, 0x0e2d, + 0x4fdf, 0x1031, + 0x4fe0, 0x1dec, + 0x4fe1, 0x09f4, + 0x4fe3, 0x0ea1, + 0x4fe4, 0x1038, + 0x4fee, 0x092e, + 0x4fef, 0x1046, + 0x4ff3, 0x0d06, + 0x4ff5, 0x0da8, + 0x4ff6, 0x1041, + 0x4ff8, 0x0e40, + 0x4ffa, 0x0536, + 0x4ffe, 0x1045, + 0x4fff, 0x20c1, + 0x5005, 0x103f, + 0x5006, 0x1048, + 0x5009, 0x0ad4, + 0x500b, 0x0778, + 0x500d, 0x0d12, + 0x500f, 0x1600, + 0x5011, 0x1047, + 0x5012, 0x0c57, + 0x5014, 0x103c, + 0x5016, 0x07aa, + 0x5019, 0x07a9, + 0x501a, 0x103a, + 0x501e, 0x20c2, + 0x501f, 0x0906, + 0x5021, 0x1042, + 0x5022, 0x20c0, + 0x5023, 0x0e3f, + 0x5024, 0x0b8b, + 0x5025, 0x103e, + 0x5026, 0x0747, + 0x5028, 0x103b, + 0x5029, 0x1043, + 0x502a, 0x103d, + 0x502b, 0x0f99, + 0x502c, 0x1044, + 0x502d, 0x0fe7, + 0x5036, 0x06de, + 0x5039, 0x0746, + 0x5040, 0x20bf, + 0x5042, 0x20c5, + 0x5043, 0x1049, + 0x5046, 0x20c3, + 0x5047, 0x104a, + 0x5048, 0x104e, + 0x5049, 0x0492, + 0x504f, 0x0e20, + 0x5050, 0x104d, + 0x5055, 0x104c, + 0x5056, 0x1050, + 0x505a, 0x104f, + 0x505c, 0x0c00, + 0x5065, 0x0748, + 0x506c, 0x1051, + 0x5070, 0x20c4, + 0x5072, 0x08f1, + 0x5074, 0x0b06, + 0x5075, 0x0c01, + 0x5076, 0x06ee, + 0x5078, 0x1052, + 0x507d, 0x0650, + 0x5080, 0x1053, + 0x5085, 0x1055, + 0x508d, 0x0e63, + 0x5091, 0x073c, + 0x5094, 0x20c6, + 0x5098, 0x087f, + 0x5099, 0x0d8b, + 0x509a, 0x1054, + 0x50ac, 0x0835, + 0x50ad, 0x0f2d, + 0x50b2, 0x1057, + 0x50b3, 0x105a, + 0x50b4, 0x1056, + 0x50b5, 0x0834, + 0x50b7, 0x0987, + 0x50be, 0x070f, + 0x50c2, 0x105b, + 0x50c5, 0x06c7, + 0x50c9, 0x1058, + 0x50cd, 0x0c87, + 0x50cf, 0x0afe, + 0x50d1, 0x069b, + 0x50d5, 0x0e7b, + 0x50d6, 0x105c, + 0x50d8, 0x20c8, + 0x50da, 0x0f85, + 0x50de, 0x105d, + 0x50e3, 0x1060, + 0x50e5, 0x105e, + 0x50e7, 0x0ad0, + 0x50ed, 0x105f, + 0x50ee, 0x1061, + 0x50f4, 0x20c7, + 0x50f5, 0x1063, + 0x50f9, 0x1062, + 0x50fb, 0x0e18, + 0x5100, 0x0651, + 0x5101, 0x1065, + 0x5104, 0x052f, + 0x5109, 0x1064, + 0x5112, 0x0920, + 0x5114, 0x1069, + 0x5115, 0x1068, + 0x5116, 0x1067, + 0x5118, 0x102f, + 0x511a, 0x106a, + 0x511f, 0x0988, + 0x5121, 0x106b, + 0x512a, 0x0f0f, + 0x5132, 0x0ee5, + 0x5137, 0x106d, + 0x513a, 0x106c, + 0x513b, 0x106f, + 0x513c, 0x106e, + 0x513f, 0x1070, + 0x5141, 0x04b8, + 0x5143, 0x0769, + 0x5144, 0x0711, + 0x5145, 0x0946, + 0x5146, 0x0bb9, + 0x5147, 0x069c, + 0x5148, 0x0a8c, + 0x5149, 0x07ab, + 0x514a, 0x20c9, + 0x514b, 0x0800, + 0x514c, 0x1073, + 0x514d, 0x0ed4, + 0x514e, 0x0c40, + 0x5150, 0x08c7, + 0x5152, 0x1072, + 0x5154, 0x1074, + 0x515a, 0x0c58, + 0x515c, 0x05d3, + 0x5162, 0x1075, + 0x5164, 0x20ca, + 0x5165, 0x0cd6, + 0x5168, 0x0ab6, + 0x5169, 0x1077, + 0x516b, 0x0d40, + 0x516c, 0x07ac, + 0x516d, 0x0fe1, + 0x516e, 0x1079, + 0x5171, 0x069e, + 0x5175, 0x0e0c, + 0x5176, 0x0b16, + 0x5177, 0x06e9, + 0x5178, 0x0c2f, + 0x517c, 0x0749, + 0x5180, 0x107a, + 0x5182, 0x107b, + 0x5185, 0x0cba, + 0x5186, 0x0501, + 0x5189, 0x107e, + 0x518a, 0x086d, + 0x518c, 0x107d, + 0x518d, 0x0836, + 0x518f, 0x107f, + 0x5190, 0x185b, + 0x5191, 0x1080, + 0x5192, 0x0e6f, + 0x5193, 0x1081, + 0x5195, 0x1082, + 0x5197, 0x09d1, + 0x5199, 0x08f8, + 0x519d, 0x20cb, + 0x51a0, 0x05e3, + 0x51a2, 0x1086, + 0x51a4, 0x1084, + 0x51a5, 0x0ec9, + 0x51a6, 0x1085, + 0x51a8, 0x0dcc, + 0x51a9, 0x1087, + 0x51ac, 0x0c59, + 0x51b0, 0x108d, + 0x51b1, 0x108b, + 0x51b3, 0x108a, + 0x51b4, 0x0853, + 0x51b5, 0x108e, + 0x51b6, 0x0ef6, + 0x51b7, 0x0fac, + 0x51bd, 0x108f, + 0x51be, 0x20cc, + 0x51c4, 0x0a4c, + 0x51c5, 0x1090, + 0x51c6, 0x0964, + 0x51c9, 0x1091, + 0x51cb, 0x0bba, + 0x51cc, 0x0f87, + 0x51cd, 0x0c5a, + 0x51d6, 0x10da, + 0x51db, 0x1092, + 0x51dc, 0x205c, + 0x51dd, 0x06bd, + 0x51e0, 0x1093, + 0x51e1, 0x0e8c, + 0x51e6, 0x0972, + 0x51e7, 0x0b5c, + 0x51e9, 0x1095, + 0x51ea, 0x0cbc, + 0x51ec, 0x20cd, + 0x51ed, 0x1096, + 0x51f0, 0x1097, + 0x51f1, 0x058c, + 0x51f5, 0x1098, + 0x51f6, 0x069f, + 0x51f8, 0x0ca4, + 0x51f9, 0x051c, + 0x51fa, 0x095a, + 0x51fd, 0x0d35, + 0x51fe, 0x1099, + 0x5200, 0x0c5b, + 0x5203, 0x0a15, + 0x5204, 0x109a, + 0x5206, 0x0dfc, + 0x5207, 0x0a7e, + 0x5208, 0x05de, + 0x520a, 0x05e5, + 0x520b, 0x109b, + 0x520e, 0x109d, + 0x5211, 0x0710, + 0x5214, 0x109c, + 0x5215, 0x20ce, + 0x5217, 0x0fbb, + 0x521d, 0x0973, + 0x5224, 0x0d51, + 0x5225, 0x0e1c, + 0x5227, 0x109e, + 0x5229, 0x0f62, + 0x522a, 0x109f, + 0x522e, 0x10a0, + 0x5230, 0x0c78, + 0x5233, 0x10a1, + 0x5236, 0x0a4d, + 0x5237, 0x086e, + 0x5238, 0x074a, + 0x5239, 0x10a2, + 0x523a, 0x0897, + 0x523b, 0x0801, + 0x5243, 0x0c02, + 0x5244, 0x10a4, + 0x5247, 0x0b07, + 0x524a, 0x085f, + 0x524b, 0x10a5, + 0x524d, 0x0ab2, + 0x524f, 0x10a3, + 0x5254, 0x10a8, + 0x5256, 0x0e64, + 0x525b, 0x07f6, + 0x525d, 0x1e5e, + 0x525e, 0x10a7, + 0x5263, 0x074b, + 0x5264, 0x084e, + 0x5265, 0x0d23, + 0x5269, 0x10ab, + 0x526a, 0x10a9, + 0x526f, 0x0ded, + 0x5270, 0x09d2, + 0x5271, 0x10b2, + 0x5272, 0x05c2, + 0x5273, 0x10ac, + 0x5274, 0x10aa, + 0x5275, 0x0ad1, + 0x527d, 0x10ae, + 0x527f, 0x10ad, + 0x5283, 0x05a2, + 0x5287, 0x0736, + 0x5288, 0x10b3, + 0x5289, 0x0f75, + 0x528d, 0x10af, + 0x5291, 0x10b4, + 0x5292, 0x10b1, + 0x5294, 0x10b0, + 0x529b, 0x0f97, + 0x529c, 0x20cf, + 0x529f, 0x07ad, + 0x52a0, 0x0543, + 0x52a3, 0x0fbc, + 0x52a6, 0x20d0, + 0x52a9, 0x097f, + 0x52aa, 0x0c52, + 0x52ab, 0x07f7, + 0x52ac, 0x10b7, + 0x52af, 0x217d, + 0x52b1, 0x0fad, + 0x52b4, 0x0fd1, + 0x52b5, 0x10ba, + 0x52b9, 0x07ae, + 0x52bc, 0x10b9, + 0x52be, 0x058d, + 0x52c0, 0x20d1, + 0x52c1, 0x10bb, + 0x52c3, 0x0e84, + 0x52c5, 0x0bd8, + 0x52c7, 0x0f10, + 0x52c9, 0x0e29, + 0x52cd, 0x10bc, + 0x52d2, 0x1bee, + 0x52d5, 0x0c88, + 0x52d7, 0x10bd, + 0x52d8, 0x05e6, + 0x52d9, 0x0ebf, + 0x52db, 0x20d2, + 0x52dd, 0x0989, + 0x52de, 0x10be, + 0x52df, 0x0e37, + 0x52e0, 0x10c2, + 0x52e2, 0x0a4e, + 0x52e3, 0x10bf, + 0x52e4, 0x06c8, + 0x52e6, 0x10c0, + 0x52e7, 0x05e7, + 0x52f2, 0x0704, + 0x52f3, 0x10c3, + 0x52f5, 0x10c4, + 0x52f8, 0x10c5, + 0x52fa, 0x0907, + 0x52fe, 0x07af, + 0x52ff, 0x0eea, + 0x5300, 0x20d3, + 0x5301, 0x0ef4, + 0x5302, 0x0ccf, + 0x5305, 0x0e41, + 0x5306, 0x10c7, + 0x5307, 0x20d4, + 0x5308, 0x10c8, + 0x530d, 0x10ca, + 0x530f, 0x10cc, + 0x5310, 0x10cb, + 0x5315, 0x10cd, + 0x5316, 0x053d, + 0x5317, 0x0e7a, + 0x5319, 0x086c, + 0x531a, 0x10ce, + 0x531d, 0x0adb, + 0x5320, 0x098a, + 0x5321, 0x06a1, + 0x5323, 0x10cf, + 0x5324, 0x20d5, + 0x532a, 0x0d6f, + 0x532f, 0x10d0, + 0x5331, 0x10d1, + 0x5333, 0x10d2, + 0x5338, 0x10d3, + 0x5339, 0x0d96, + 0x533a, 0x06e0, + 0x533b, 0x04a9, + 0x533f, 0x0c97, + 0x5340, 0x10d4, + 0x5341, 0x0947, + 0x5343, 0x0a8d, + 0x5345, 0x10d6, + 0x5346, 0x10d5, + 0x5347, 0x098b, + 0x5348, 0x0795, + 0x5349, 0x10d8, + 0x534a, 0x0d52, + 0x534d, 0x10d9, + 0x5351, 0x0d70, + 0x5352, 0x0b14, + 0x5353, 0x0b4e, + 0x5354, 0x06a0, + 0x5357, 0x0cc6, + 0x5358, 0x0b6f, + 0x535a, 0x0d24, + 0x535c, 0x0e7c, + 0x535e, 0x10db, + 0x5360, 0x0a8e, + 0x5366, 0x070b, + 0x5369, 0x10dc, + 0x536e, 0x10dd, + 0x536f, 0x04ce, + 0x5370, 0x04b9, + 0x5371, 0x0629, + 0x5372, 0x20d6, + 0x5373, 0x0b08, + 0x5374, 0x066b, + 0x5375, 0x0f5b, + 0x5377, 0x10e0, + 0x5378, 0x0537, + 0x537b, 0x10df, + 0x537f, 0x06a2, + 0x5382, 0x10e1, + 0x5384, 0x0efd, + 0x5393, 0x20d7, + 0x5396, 0x10e2, + 0x5398, 0x0f9a, + 0x539a, 0x07b0, + 0x539f, 0x076a, + 0x53a0, 0x10e3, + 0x53a5, 0x10e5, + 0x53a6, 0x10e4, + 0x53a8, 0x0a25, + 0x53a9, 0x04db, + 0x53ad, 0x0500, + 0x53ae, 0x10e6, + 0x53b0, 0x10e7, + 0x53b2, 0x20d8, + 0x53b3, 0x076b, + 0x53b6, 0x10e8, + 0x53bb, 0x0688, + 0x53c2, 0x0880, + 0x53c3, 0x10e9, + 0x53c8, 0x0ea2, + 0x53c9, 0x0825, + 0x53ca, 0x0674, + 0x53cb, 0x0f11, + 0x53cc, 0x0ad2, + 0x53cd, 0x0d53, + 0x53ce, 0x0929, + 0x53d4, 0x0951, + 0x53d6, 0x0914, + 0x53d7, 0x0921, + 0x53d9, 0x0980, + 0x53db, 0x0d54, + 0x53dd, 0x20d9, + 0x53df, 0x10ec, + 0x53e1, 0x04e5, + 0x53e2, 0x0ad3, + 0x53e3, 0x07b1, + 0x53e4, 0x0779, + 0x53e5, 0x06df, + 0x53e8, 0x10f0, + 0x53e9, 0x0b5f, + 0x53ea, 0x0b5e, + 0x53eb, 0x06a3, + 0x53ec, 0x098c, + 0x53ed, 0x10f1, + 0x53ee, 0x10ef, + 0x53ef, 0x0544, + 0x53f0, 0x0b46, + 0x53f1, 0x08e4, + 0x53f2, 0x0899, + 0x53f3, 0x04c8, + 0x53f6, 0x05ce, + 0x53f7, 0x07f8, + 0x53f8, 0x0898, + 0x53fa, 0x10f2, + 0x5401, 0x10f3, + 0x5403, 0x0663, + 0x5404, 0x05a4, + 0x5408, 0x07f9, + 0x5409, 0x0662, + 0x540a, 0x0bfb, + 0x540b, 0x04c7, + 0x540c, 0x0c89, + 0x540d, 0x0eca, + 0x540e, 0x07b3, + 0x540f, 0x0f63, + 0x5410, 0x0c41, + 0x5411, 0x07b2, + 0x541b, 0x0705, + 0x541d, 0x10fc, + 0x541f, 0x06db, + 0x5420, 0x0e78, + 0x5426, 0x0d71, + 0x5429, 0x10fb, + 0x542b, 0x061a, + 0x542c, 0x10f6, + 0x542e, 0x10f9, + 0x5436, 0x10fa, + 0x5438, 0x0675, + 0x5439, 0x0a27, + 0x543b, 0x0dfd, + 0x543c, 0x10f8, + 0x543d, 0x10f4, + 0x543e, 0x0797, + 0x5440, 0x10f5, + 0x5442, 0x0fca, + 0x5446, 0x0e42, + 0x5448, 0x0c04, + 0x5449, 0x0796, + 0x544a, 0x0802, + 0x544e, 0x10fd, + 0x5451, 0x0cb5, + 0x545f, 0x1101, + 0x5468, 0x092a, + 0x546a, 0x0922, + 0x5470, 0x1104, + 0x5471, 0x1102, + 0x5473, 0x0eaf, + 0x5475, 0x10ff, + 0x5476, 0x1108, + 0x5477, 0x1103, + 0x547b, 0x1106, + 0x547c, 0x077a, + 0x547d, 0x0ecb, + 0x5480, 0x1107, + 0x5484, 0x1109, + 0x5486, 0x110b, + 0x548a, 0x20dc, + 0x548b, 0x0860, + 0x548c, 0x0fe8, + 0x548e, 0x1100, + 0x548f, 0x10fe, + 0x5490, 0x110a, + 0x5492, 0x1105, + 0x549c, 0x20db, + 0x54a2, 0x110d, + 0x54a4, 0x1116, + 0x54a5, 0x110f, + 0x54a8, 0x1113, + 0x54a9, 0x20dd, + 0x54ab, 0x1114, + 0x54ac, 0x1110, + 0x54af, 0x1131, + 0x54b2, 0x0859, + 0x54b3, 0x058f, + 0x54b8, 0x110e, + 0x54bc, 0x1118, + 0x54bd, 0x04ba, + 0x54be, 0x1117, + 0x54c0, 0x0469, + 0x54c1, 0x0dbc, + 0x54c2, 0x1115, + 0x54c4, 0x1111, + 0x54c7, 0x110c, + 0x54c8, 0x1112, + 0x54c9, 0x0838, + 0x54d8, 0x1119, + 0x54e1, 0x04bb, + 0x54e2, 0x1122, + 0x54e5, 0x111a, + 0x54e8, 0x098d, + 0x54e9, 0x0e97, + 0x54ed, 0x1120, + 0x54ee, 0x111f, + 0x54f2, 0x0c29, + 0x54fa, 0x1121, + 0x54fd, 0x111e, + 0x54ff, 0x20de, + 0x5504, 0x04d6, + 0x5506, 0x0826, + 0x5507, 0x09f6, + 0x550f, 0x111c, + 0x5510, 0x0c5c, + 0x5514, 0x111d, + 0x5516, 0x0466, + 0x552e, 0x1127, + 0x552f, 0x0f0d, + 0x5531, 0x098f, + 0x5533, 0x112d, + 0x5538, 0x112c, + 0x5539, 0x1123, + 0x553e, 0x0b23, + 0x5540, 0x1124, + 0x5544, 0x0b4f, + 0x5545, 0x1129, + 0x5546, 0x098e, + 0x554c, 0x1126, + 0x554f, 0x0ef0, + 0x5553, 0x0712, + 0x5556, 0x112a, + 0x555c, 0x1128, + 0x555d, 0x112e, + 0x555e, 0x1dd1, + 0x5563, 0x1125, + 0x557b, 0x1134, + 0x557c, 0x1139, + 0x557e, 0x1135, + 0x5580, 0x1130, + 0x5583, 0x113a, + 0x5584, 0x0ab3, + 0x5586, 0x20df, + 0x5587, 0x113c, + 0x5589, 0x07b4, + 0x558a, 0x1132, + 0x558b, 0x0bbb, + 0x5598, 0x1136, + 0x5599, 0x112f, + 0x559a, 0x05e9, + 0x559c, 0x062a, + 0x559d, 0x05c3, + 0x559e, 0x1137, + 0x559f, 0x1133, + 0x55a7, 0x074c, + 0x55a8, 0x113d, + 0x55a9, 0x113b, + 0x55aa, 0x0ad5, + 0x55ab, 0x0664, + 0x55ac, 0x06a4, + 0x55ae, 0x1138, + 0x55b0, 0x06ec, + 0x55b6, 0x04e6, + 0x55c4, 0x1141, + 0x55c5, 0x113f, + 0x55c7, 0x1178, + 0x55d4, 0x1144, + 0x55da, 0x113e, + 0x55dc, 0x1142, + 0x55df, 0x1140, + 0x55e3, 0x089a, + 0x55e4, 0x1143, + 0x55f7, 0x1146, + 0x55f9, 0x114b, + 0x55fd, 0x1149, + 0x55fe, 0x1148, + 0x5606, 0x0b70, + 0x5609, 0x0545, + 0x5614, 0x1145, + 0x5616, 0x1147, + 0x5617, 0x0990, + 0x5618, 0x04d5, + 0x561b, 0x114a, + 0x5629, 0x055e, + 0x562f, 0x1155, + 0x5631, 0x09e4, + 0x5632, 0x1151, + 0x5634, 0x114f, + 0x5636, 0x1150, + 0x5638, 0x1152, + 0x5642, 0x04df, + 0x564c, 0x0abb, + 0x564e, 0x114c, + 0x5650, 0x114d, + 0x5653, 0x1f1b, + 0x565b, 0x05d8, + 0x5664, 0x1154, + 0x5668, 0x062b, + 0x566a, 0x1157, + 0x566b, 0x1153, + 0x566c, 0x1156, + 0x5674, 0x0dfe, + 0x5678, 0x0cad, + 0x567a, 0x0d4c, + 0x5680, 0x1159, + 0x5686, 0x1158, + 0x5687, 0x05a3, + 0x568a, 0x115a, + 0x568f, 0x115d, + 0x5694, 0x115c, + 0x5699, 0x1de6, + 0x56a0, 0x115b, + 0x56a2, 0x0cef, + 0x56a5, 0x115e, + 0x56ae, 0x115f, + 0x56b4, 0x1161, + 0x56b6, 0x1160, + 0x56bc, 0x1163, + 0x56c0, 0x1166, + 0x56c1, 0x1164, + 0x56c2, 0x1162, + 0x56c3, 0x1165, + 0x56c8, 0x1167, + 0x56ca, 0x1e5a, + 0x56ce, 0x1168, + 0x56d1, 0x1169, + 0x56d3, 0x116a, + 0x56d7, 0x116b, + 0x56d8, 0x107c, + 0x56da, 0x0928, + 0x56db, 0x089b, + 0x56de, 0x0573, + 0x56e0, 0x04bc, + 0x56e3, 0x0b82, + 0x56ee, 0x116c, + 0x56f0, 0x0814, + 0x56f2, 0x0493, + 0x56f3, 0x0a24, + 0x56f9, 0x116d, + 0x56fa, 0x077b, + 0x56fd, 0x0803, + 0x56ff, 0x116f, + 0x5700, 0x116e, + 0x5703, 0x0e30, + 0x5704, 0x1170, + 0x5708, 0x1172, + 0x5709, 0x1171, + 0x570b, 0x1173, + 0x570d, 0x1174, + 0x570f, 0x074d, + 0x5712, 0x0502, + 0x5713, 0x1175, + 0x5716, 0x1177, + 0x5718, 0x1176, + 0x571c, 0x1179, + 0x571f, 0x0c54, + 0x5726, 0x117a, + 0x5727, 0x0479, + 0x5728, 0x084f, + 0x572d, 0x0713, + 0x5730, 0x0b8d, + 0x5737, 0x117b, + 0x573b, 0x117e, + 0x5740, 0x117f, + 0x5742, 0x0854, + 0x5747, 0x06c9, + 0x574a, 0x0e65, + 0x574e, 0x117d, + 0x574f, 0x1180, + 0x5750, 0x0831, + 0x5751, 0x07b5, + 0x5759, 0x20e0, + 0x5761, 0x1184, + 0x5764, 0x0815, + 0x5765, 0x20e1, + 0x5766, 0x0b71, + 0x5769, 0x1181, + 0x576a, 0x0bf6, + 0x577f, 0x1185, + 0x5782, 0x0a28, + 0x5788, 0x1183, + 0x5789, 0x1186, + 0x578b, 0x0715, + 0x5793, 0x1187, + 0x57a0, 0x1188, + 0x57a2, 0x07b6, + 0x57a3, 0x059e, + 0x57a4, 0x118a, + 0x57aa, 0x118b, + 0x57ac, 0x20e2, + 0x57b0, 0x118c, + 0x57b3, 0x1189, + 0x57c0, 0x1182, + 0x57c3, 0x118d, + 0x57c6, 0x118e, + 0x57c7, 0x20e4, + 0x57c8, 0x20e3, + 0x57cb, 0x0e92, + 0x57ce, 0x09d3, + 0x57d2, 0x1190, + 0x57d4, 0x118f, + 0x57d6, 0x1193, + 0x57dc, 0x0cee, + 0x57df, 0x04ac, + 0x57e0, 0x0dc8, + 0x57e3, 0x1194, + 0x57f4, 0x09e5, + 0x57f7, 0x08e5, + 0x57f9, 0x0d13, + 0x57fa, 0x062c, + 0x57fc, 0x085b, + 0x5800, 0x0e87, + 0x5802, 0x0c8a, + 0x5805, 0x074e, + 0x5806, 0x0b2f, + 0x580a, 0x1192, + 0x580b, 0x1195, + 0x5815, 0x0b24, + 0x5819, 0x1196, + 0x581d, 0x1197, + 0x5821, 0x1199, + 0x5824, 0x0c05, + 0x582a, 0x05ea, + 0x582f, 0x1d32, + 0x5830, 0x0503, + 0x5831, 0x0e43, + 0x5834, 0x09d4, + 0x5835, 0x0c42, + 0x583a, 0x0856, + 0x583d, 0x119f, + 0x5840, 0x0e0d, + 0x5841, 0x0fa5, + 0x584a, 0x0574, + 0x584b, 0x119b, + 0x5851, 0x0abc, + 0x5852, 0x119e, + 0x5854, 0x0c5d, + 0x5857, 0x0c43, + 0x5858, 0x0c5e, + 0x5859, 0x0d4d, + 0x585a, 0x0be9, + 0x585e, 0x0839, + 0x5861, 0x1e47, + 0x5862, 0x119a, + 0x5869, 0x0518, + 0x586b, 0x0c30, + 0x5870, 0x119c, + 0x5872, 0x1198, + 0x5875, 0x0a16, + 0x5879, 0x11a0, + 0x587e, 0x0958, + 0x5883, 0x06a5, + 0x5885, 0x11a1, + 0x5893, 0x0e38, + 0x5897, 0x0aff, + 0x589c, 0x0be2, + 0x589e, 0x20e7, + 0x589f, 0x11a3, + 0x58a8, 0x0e7d, + 0x58ab, 0x11a4, + 0x58ae, 0x11a9, + 0x58b2, 0x20e8, + 0x58b3, 0x0dff, + 0x58b8, 0x11a8, + 0x58b9, 0x11a2, + 0x58ba, 0x11a5, + 0x58bb, 0x11a7, + 0x58be, 0x0816, + 0x58c1, 0x0e19, + 0x58c5, 0x11aa, + 0x58c7, 0x0b83, + 0x58ca, 0x0575, + 0x58cc, 0x09d5, + 0x58d1, 0x11ac, + 0x58d3, 0x11ab, + 0x58d5, 0x07fa, + 0x58d7, 0x11ad, + 0x58d8, 0x11af, + 0x58d9, 0x11ae, + 0x58dc, 0x11b1, + 0x58de, 0x11a6, + 0x58df, 0x11b3, + 0x58e4, 0x11b2, + 0x58e5, 0x11b0, + 0x58eb, 0x089c, + 0x58ec, 0x0a17, + 0x58ee, 0x0ad6, + 0x58ef, 0x11b4, + 0x58f0, 0x0a60, + 0x58f1, 0x04b1, + 0x58f2, 0x0d1a, + 0x58f7, 0x0bf7, + 0x58f9, 0x11b6, + 0x58fa, 0x11b5, + 0x58fb, 0x11b7, + 0x5902, 0x11ba, + 0x5909, 0x0e21, + 0x590a, 0x11bb, + 0x590b, 0x20e9, + 0x590f, 0x0546, + 0x5910, 0x11bc, + 0x5915, 0x0f26, + 0x5916, 0x058e, + 0x5918, 0x10de, + 0x5919, 0x0952, + 0x591a, 0x0b1f, + 0x591b, 0x11bd, + 0x591c, 0x0ef7, + 0x5922, 0x0ec0, + 0x5925, 0x11bf, + 0x5927, 0x0b47, + 0x5929, 0x0c31, + 0x592a, 0x0b20, + 0x592b, 0x0dc9, + 0x592c, 0x11c0, + 0x592e, 0x051d, + 0x5931, 0x08e6, + 0x5932, 0x11c2, + 0x5937, 0x0494, + 0x5938, 0x11c3, + 0x593e, 0x11c4, + 0x5944, 0x0504, + 0x5947, 0x062d, + 0x5948, 0x0cb8, + 0x5949, 0x0e44, + 0x594e, 0x11c8, + 0x594f, 0x0ad7, + 0x5950, 0x11c7, + 0x5951, 0x0716, + 0x5953, 0x20ea, + 0x5954, 0x0e89, + 0x5955, 0x11c6, + 0x5957, 0x0c5f, + 0x5958, 0x11ca, + 0x595a, 0x11c9, + 0x595b, 0x20eb, + 0x595d, 0x20ec, + 0x5960, 0x11cc, + 0x5962, 0x11cb, + 0x5963, 0x20ed, + 0x5965, 0x051e, + 0x5967, 0x11cd, + 0x5968, 0x0991, + 0x5969, 0x11cf, + 0x596a, 0x0b63, + 0x596c, 0x11ce, + 0x596e, 0x0e03, + 0x5973, 0x0981, + 0x5974, 0x0c55, + 0x5978, 0x11d0, + 0x597d, 0x07b7, + 0x5981, 0x11d1, + 0x5982, 0x0cd7, + 0x5983, 0x0d72, + 0x5984, 0x0edd, + 0x598a, 0x0cdb, + 0x598d, 0x11da, + 0x5993, 0x0652, + 0x5996, 0x0f2f, + 0x5999, 0x0ebb, + 0x599b, 0x1239, + 0x599d, 0x11d2, + 0x59a3, 0x11d5, + 0x59a4, 0x20ee, + 0x59a5, 0x0b25, + 0x59a8, 0x0e66, + 0x59ac, 0x0c44, + 0x59b2, 0x11d6, + 0x59b9, 0x0e93, + 0x59ba, 0x20ef, + 0x59bb, 0x083a, + 0x59be, 0x0992, + 0x59c6, 0x11d7, + 0x59c9, 0x089e, + 0x59cb, 0x089d, + 0x59d0, 0x047d, + 0x59d1, 0x077c, + 0x59d3, 0x0a4f, + 0x59d4, 0x0495, + 0x59d9, 0x11db, + 0x59dc, 0x11d9, + 0x59e5, 0x04da, + 0x59e6, 0x05eb, + 0x59e8, 0x11d8, + 0x59ea, 0x0ed1, + 0x59eb, 0x0da3, + 0x59f6, 0x046c, + 0x59fb, 0x04bd, + 0x59ff, 0x089f, + 0x5a01, 0x0496, + 0x5a03, 0x0467, + 0x5a09, 0x11e1, + 0x5a11, 0x11df, + 0x5a18, 0x0ec8, + 0x5a1a, 0x11e2, + 0x5a1c, 0x11e0, + 0x5a1f, 0x11de, + 0x5a20, 0x09f7, + 0x5a25, 0x11dd, + 0x5a29, 0x0e2a, + 0x5a2f, 0x0798, + 0x5a35, 0x11e6, + 0x5a3c, 0x0993, + 0x5a40, 0x11e3, + 0x5a41, 0x0fd2, + 0x5a46, 0x0d02, + 0x5a49, 0x11e5, + 0x5a5a, 0x0817, + 0x5a62, 0x11e8, + 0x5a66, 0x0dca, + 0x5a6a, 0x11e9, + 0x5a6c, 0x11e4, + 0x5a7f, 0x0ec7, + 0x5a92, 0x0d14, + 0x5a9a, 0x11ea, + 0x5a9b, 0x0da4, + 0x5abc, 0x11eb, + 0x5abd, 0x11ef, + 0x5abe, 0x11ec, + 0x5ac1, 0x0547, + 0x5ac2, 0x11ee, + 0x5ac9, 0x08e7, + 0x5acb, 0x11ed, + 0x5acc, 0x074f, + 0x5ad0, 0x11fb, + 0x5ad6, 0x11f4, + 0x5ad7, 0x11f1, + 0x5ae1, 0x0ba2, + 0x5ae3, 0x11f0, + 0x5ae6, 0x11f2, + 0x5ae9, 0x11f3, + 0x5afa, 0x11f5, + 0x5b09, 0x062e, + 0x5b0b, 0x11f8, + 0x5b0c, 0x11f7, + 0x5b16, 0x11f9, + 0x5b22, 0x09d6, + 0x5b2a, 0x11fc, + 0x5b2c, 0x0bf8, + 0x5b30, 0x04e7, + 0x5b32, 0x11fa, + 0x5b36, 0x11fd, + 0x5b3e, 0x11fe, + 0x5b40, 0x1201, + 0x5b43, 0x11ff, + 0x5b45, 0x1200, + 0x5b50, 0x08a0, + 0x5b51, 0x1202, + 0x5b54, 0x07b8, + 0x5b55, 0x1203, + 0x5b56, 0x20f0, + 0x5b57, 0x08c8, + 0x5b58, 0x0b18, + 0x5b5a, 0x1204, + 0x5b5c, 0x08a8, + 0x5b5d, 0x07b9, + 0x5b5f, 0x0ede, + 0x5b63, 0x0642, + 0x5b64, 0x077d, + 0x5b65, 0x1206, + 0x5b66, 0x05b6, + 0x5b69, 0x1207, + 0x5b6b, 0x0b19, + 0x5b70, 0x1208, + 0x5b71, 0x1230, + 0x5b73, 0x1209, + 0x5b75, 0x120a, + 0x5b78, 0x120b, + 0x5b7a, 0x120d, + 0x5b80, 0x120e, + 0x5b83, 0x120f, + 0x5b85, 0x0b50, + 0x5b87, 0x04c9, + 0x5b88, 0x0915, + 0x5b89, 0x0486, + 0x5b8b, 0x0ad9, + 0x5b8c, 0x05ec, + 0x5b8d, 0x08e1, + 0x5b8f, 0x07ba, + 0x5b95, 0x0c60, + 0x5b97, 0x092b, + 0x5b98, 0x05ed, + 0x5b99, 0x0ba6, + 0x5b9a, 0x0c06, + 0x5b9b, 0x047c, + 0x5b9c, 0x0653, + 0x5b9d, 0x0e45, + 0x5b9f, 0x08ee, + 0x5ba2, 0x066c, + 0x5ba3, 0x0a8f, + 0x5ba4, 0x08e8, + 0x5ba5, 0x0f12, + 0x5ba6, 0x1210, + 0x5bae, 0x0676, + 0x5bb0, 0x083b, + 0x5bb3, 0x0590, + 0x5bb4, 0x0505, + 0x5bb5, 0x0994, + 0x5bb6, 0x0548, + 0x5bb8, 0x1211, + 0x5bb9, 0x0f30, + 0x5bbf, 0x0953, + 0x5bc0, 0x20f1, + 0x5bc2, 0x0910, + 0x5bc3, 0x1212, + 0x5bc4, 0x062f, + 0x5bc5, 0x0caa, + 0x5bc6, 0x0eb5, + 0x5bc7, 0x1213, + 0x5bc9, 0x1214, + 0x5bcc, 0x0dcb, + 0x5bd0, 0x1216, + 0x5bd2, 0x05e4, + 0x5bd3, 0x06ef, + 0x5bd4, 0x1215, + 0x5bd8, 0x20f3, + 0x5bdb, 0x05ee, + 0x5bdd, 0x09f8, + 0x5bde, 0x121a, + 0x5bdf, 0x086f, + 0x5be1, 0x0549, + 0x5be2, 0x1219, + 0x5be4, 0x1217, + 0x5be5, 0x121b, + 0x5be6, 0x1218, + 0x5be7, 0x0ce1, + 0x5be8, 0x148e, + 0x5be9, 0x09f9, + 0x5beb, 0x121c, + 0x5bec, 0x20f4, + 0x5bee, 0x0f88, + 0x5bf0, 0x121d, + 0x5bf3, 0x121f, + 0x5bf5, 0x0bbc, + 0x5bf6, 0x121e, + 0x5bf8, 0x0a47, + 0x5bfa, 0x08c9, + 0x5bfe, 0x0b30, + 0x5bff, 0x0923, + 0x5c01, 0x0de7, + 0x5c02, 0x0a90, + 0x5c04, 0x08f9, + 0x5c05, 0x1220, + 0x5c06, 0x0995, + 0x5c07, 0x1221, + 0x5c09, 0x0497, + 0x5c0a, 0x0b1a, + 0x5c0b, 0x0a18, + 0x5c0d, 0x1223, + 0x5c0e, 0x0c8b, + 0x5c0f, 0x0996, + 0x5c11, 0x0997, + 0x5c13, 0x1224, + 0x5c16, 0x0a91, + 0x5c1a, 0x0998, + 0x5c1e, 0x20f5, + 0x5c20, 0x1225, + 0x5c22, 0x1226, + 0x5c24, 0x0eec, + 0x5c28, 0x1227, + 0x5c2d, 0x06be, + 0x5c31, 0x092c, + 0x5c38, 0x1228, + 0x5c3a, 0x0908, + 0x5c3b, 0x09f2, + 0x5c3c, 0x0ccc, + 0x5c3d, 0x0a1a, + 0x5c3e, 0x0d8c, + 0x5c3f, 0x0cd8, + 0x5c40, 0x06c1, + 0x5c41, 0x122a, + 0x5c45, 0x0689, + 0x5c46, 0x122b, + 0x5c48, 0x06f6, + 0x5c4a, 0x0ca7, + 0x5c4b, 0x0530, + 0x5c4d, 0x08a1, + 0x5c4e, 0x122c, + 0x5c4f, 0x122f, + 0x5c50, 0x122e, + 0x5c51, 0x06f5, + 0x5c53, 0x122d, + 0x5c55, 0x0c32, + 0x5c5b, 0x1e92, + 0x5c5e, 0x0b10, + 0x5c60, 0x0c45, + 0x5c61, 0x08f4, + 0x5c62, 0x1e0d, + 0x5c64, 0x0ada, + 0x5c65, 0x0f64, + 0x5c6c, 0x1231, + 0x5c6e, 0x1232, + 0x5c6f, 0x0cae, + 0x5c71, 0x0881, + 0x5c76, 0x1234, + 0x5c79, 0x1235, + 0x5c8c, 0x1236, + 0x5c90, 0x0630, + 0x5c91, 0x1237, + 0x5c94, 0x1238, + 0x5ca1, 0x052c, + 0x5ca6, 0x20f6, + 0x5ca8, 0x0abd, + 0x5ca9, 0x0620, + 0x5cab, 0x123a, + 0x5cac, 0x0eb4, + 0x5cb1, 0x0b32, + 0x5cb3, 0x05b7, + 0x5cb6, 0x123c, + 0x5cb7, 0x123e, + 0x5cb8, 0x061b, + 0x5cba, 0x20f7, + 0x5cbb, 0x123b, + 0x5cbc, 0x123d, + 0x5cbe, 0x1240, + 0x5cc5, 0x123f, + 0x5cc7, 0x1241, + 0x5cd9, 0x1242, + 0x5ce0, 0x0c95, + 0x5ce1, 0x06a6, + 0x5ce8, 0x0565, + 0x5ce9, 0x1243, + 0x5cea, 0x1248, + 0x5ced, 0x1246, + 0x5cef, 0x0e47, + 0x5cf0, 0x0e46, + 0x5cf5, 0x20f8, + 0x5cf6, 0x0c61, + 0x5cfa, 0x1245, + 0x5cfb, 0x095e, + 0x5cfd, 0x1244, + 0x5d07, 0x0a38, + 0x5d0b, 0x1249, + 0x5d0e, 0x085a, + 0x5d11, 0x124f, + 0x5d14, 0x1250, + 0x5d15, 0x124a, + 0x5d16, 0x0591, + 0x5d17, 0x124b, + 0x5d18, 0x1254, + 0x5d19, 0x1253, + 0x5d1a, 0x1252, + 0x5d1b, 0x124e, + 0x5d1f, 0x124d, + 0x5d22, 0x1251, + 0x5d27, 0x20f9, + 0x5d29, 0x0e48, + 0x5d42, 0x20fc, + 0x5d4b, 0x1258, + 0x5d4c, 0x1255, + 0x5d4e, 0x1257, + 0x5d50, 0x0f5c, + 0x5d52, 0x1256, + 0x5d53, 0x20fa, + 0x5d5c, 0x124c, + 0x5d69, 0x0a39, + 0x5d6c, 0x1259, + 0x5d6d, 0x20fd, + 0x5d6f, 0x0827, + 0x5d73, 0x125a, + 0x5d76, 0x125b, + 0x5d82, 0x125e, + 0x5d84, 0x125d, + 0x5d87, 0x125c, + 0x5d8b, 0x0c62, + 0x5d8c, 0x1247, + 0x5d90, 0x1264, + 0x5d9d, 0x1260, + 0x5da2, 0x125f, + 0x5dac, 0x1261, + 0x5dae, 0x1262, + 0x5db7, 0x1265, + 0x5db8, 0x20fe, + 0x5dba, 0x0fae, + 0x5dbc, 0x1266, + 0x5dbd, 0x1263, + 0x5dc9, 0x1267, + 0x5dcc, 0x061c, + 0x5dcd, 0x1268, + 0x5dd0, 0x2100, + 0x5dd2, 0x126a, + 0x5dd3, 0x1269, + 0x5dd6, 0x126b, + 0x5ddb, 0x126c, + 0x5ddd, 0x0a92, + 0x5dde, 0x092d, + 0x5de1, 0x096e, + 0x5de3, 0x0ae5, + 0x5de5, 0x07bb, + 0x5de6, 0x0828, + 0x5de7, 0x07bc, + 0x5de8, 0x068a, + 0x5deb, 0x126d, + 0x5dee, 0x0829, + 0x5df1, 0x077e, + 0x5df2, 0x126e, + 0x5df3, 0x0eb2, + 0x5df4, 0x0cf9, + 0x5df5, 0x126f, + 0x5df7, 0x07bd, + 0x5dfb, 0x05e8, + 0x5dfd, 0x0b65, + 0x5dfe, 0x06ca, + 0x5e02, 0x08a2, + 0x5e03, 0x0dcd, + 0x5e06, 0x0d55, + 0x5e0b, 0x1270, + 0x5e0c, 0x0631, + 0x5e11, 0x1273, + 0x5e16, 0x0bbd, + 0x5e19, 0x1272, + 0x5e1a, 0x1271, + 0x5e1b, 0x1274, + 0x5e1d, 0x0c07, + 0x5e25, 0x0a29, + 0x5e2b, 0x08a3, + 0x5e2d, 0x0a6e, + 0x5e2f, 0x0b33, + 0x5e30, 0x063c, + 0x5e33, 0x0bbe, + 0x5e36, 0x1275, + 0x5e38, 0x09d7, + 0x5e3d, 0x0e67, + 0x5e40, 0x1279, + 0x5e43, 0x1278, + 0x5e44, 0x1277, + 0x5e45, 0x0def, + 0x5e47, 0x1280, + 0x5e4c, 0x0e88, + 0x5e4e, 0x127a, + 0x5e54, 0x127c, + 0x5e55, 0x0e99, + 0x5e57, 0x127b, + 0x5e5f, 0x127d, + 0x5e61, 0x0d3c, + 0x5e62, 0x127e, + 0x5e63, 0x0e0e, + 0x5e64, 0x127f, + 0x5e72, 0x05ef, + 0x5e73, 0x0e0f, + 0x5e74, 0x0ce5, + 0x5e75, 0x1281, + 0x5e78, 0x07be, + 0x5e79, 0x05f0, + 0x5e7a, 0x1283, + 0x5e7b, 0x076c, + 0x5e7c, 0x0f2e, + 0x5e7d, 0x0f13, + 0x5e7e, 0x0632, + 0x5e7f, 0x1285, + 0x5e81, 0x0bbf, + 0x5e83, 0x07bf, + 0x5e84, 0x0999, + 0x5e87, 0x0d73, + 0x5e8a, 0x099a, + 0x5e8f, 0x0982, + 0x5e95, 0x0c08, + 0x5e96, 0x0e49, + 0x5e97, 0x0c33, + 0x5e9a, 0x07c0, + 0x5e9c, 0x0dce, + 0x5ea0, 0x1286, + 0x5ea6, 0x0c53, + 0x5ea7, 0x0832, + 0x5eab, 0x077f, + 0x5ead, 0x0c09, + 0x5eb5, 0x0487, + 0x5eb6, 0x0978, + 0x5eb7, 0x07c1, + 0x5eb8, 0x0f31, + 0x5ec1, 0x1287, + 0x5ec3, 0x0d07, + 0x5ec8, 0x1289, + 0x5ec9, 0x0fbf, + 0x5eca, 0x0fd3, + 0x5ecf, 0x128b, + 0x5ed0, 0x128a, + 0x5ed3, 0x05a5, + 0x5ed6, 0x128c, + 0x5eda, 0x128f, + 0x5edd, 0x128e, + 0x5edf, 0x0db2, + 0x5ee0, 0x099b, + 0x5ee1, 0x1292, + 0x5ee2, 0x1291, + 0x5ee3, 0x128d, + 0x5ee8, 0x1293, + 0x5eec, 0x1295, + 0x5ef0, 0x1298, + 0x5ef1, 0x1296, + 0x5ef3, 0x1297, + 0x5ef4, 0x1299, + 0x5ef6, 0x0506, + 0x5ef7, 0x0c0a, + 0x5ef8, 0x129a, + 0x5efa, 0x0750, + 0x5efb, 0x0576, + 0x5efc, 0x0cec, + 0x5efe, 0x129b, + 0x5eff, 0x0cd3, + 0x5f01, 0x0e2b, + 0x5f03, 0x129c, + 0x5f04, 0x0fd4, + 0x5f09, 0x129d, + 0x5f0a, 0x0e10, + 0x5f0b, 0x12a0, + 0x5f0c, 0x0ffa, + 0x5f0d, 0x100a, + 0x5f0f, 0x08dc, + 0x5f10, 0x0ccd, + 0x5f11, 0x12a1, + 0x5f13, 0x0677, + 0x5f14, 0x0bc0, + 0x5f15, 0x04be, + 0x5f16, 0x12a2, + 0x5f17, 0x0df6, + 0x5f18, 0x07c2, + 0x5f1b, 0x0b8e, + 0x5f1f, 0x0c0b, + 0x5f21, 0x2101, + 0x5f25, 0x0efb, + 0x5f26, 0x076d, + 0x5f27, 0x0780, + 0x5f29, 0x12a3, + 0x5f2d, 0x12a4, + 0x5f2f, 0x12aa, + 0x5f31, 0x0911, + 0x5f34, 0x2102, + 0x5f35, 0x0bc1, + 0x5f37, 0x06a7, + 0x5f38, 0x12a5, + 0x5f3c, 0x0d9d, + 0x5f3e, 0x0b84, + 0x5f41, 0x12a6, + 0x5f45, 0x20b2, + 0x5f48, 0x12a7, + 0x5f4a, 0x06a8, + 0x5f4c, 0x12a8, + 0x5f4e, 0x12a9, + 0x5f51, 0x12ab, + 0x5f53, 0x0c70, + 0x5f56, 0x12ac, + 0x5f59, 0x12ae, + 0x5f5c, 0x129f, + 0x5f5d, 0x129e, + 0x5f61, 0x12af, + 0x5f62, 0x0717, + 0x5f66, 0x0d99, + 0x5f67, 0x2103, + 0x5f69, 0x083c, + 0x5f6a, 0x0da9, + 0x5f6b, 0x0bc2, + 0x5f6c, 0x0dbd, + 0x5f6d, 0x12b0, + 0x5f70, 0x099c, + 0x5f71, 0x04e8, + 0x5f73, 0x12b1, + 0x5f77, 0x12b2, + 0x5f79, 0x0efe, + 0x5f7c, 0x0d74, + 0x5f7f, 0x12b5, + 0x5f80, 0x051f, + 0x5f81, 0x0a50, + 0x5f82, 0x12b4, + 0x5f83, 0x12b3, + 0x5f84, 0x0718, + 0x5f85, 0x0b34, + 0x5f87, 0x12b9, + 0x5f88, 0x12b7, + 0x5f8a, 0x12b6, + 0x5f8b, 0x0f6f, + 0x5f8c, 0x0799, + 0x5f90, 0x0983, + 0x5f91, 0x12b8, + 0x5f92, 0x0c46, + 0x5f93, 0x0948, + 0x5f97, 0x0c98, + 0x5f98, 0x12bc, + 0x5f99, 0x12bb, + 0x5f9e, 0x12ba, + 0x5fa0, 0x12bd, + 0x5fa1, 0x079a, + 0x5fa8, 0x12be, + 0x5fa9, 0x0dee, + 0x5faa, 0x0965, + 0x5fad, 0x12bf, + 0x5fae, 0x0d8d, + 0x5fb3, 0x0c99, + 0x5fb4, 0x0bc3, + 0x5fb7, 0x2104, + 0x5fb9, 0x0c2a, + 0x5fbc, 0x12c0, + 0x5fbd, 0x0645, + 0x5fc3, 0x09fa, + 0x5fc5, 0x0d9e, + 0x5fcc, 0x0633, + 0x5fcd, 0x0cdc, + 0x5fd6, 0x12c1, + 0x5fd7, 0x08a4, + 0x5fd8, 0x0e68, + 0x5fdc, 0x0520, + 0x5fdd, 0x12c6, + 0x5fde, 0x2105, + 0x5fe0, 0x0ba7, + 0x5fe4, 0x12c3, + 0x5feb, 0x0577, + 0x5ff0, 0x12f6, + 0x5ff1, 0x12c5, + 0x5ff5, 0x0ce6, + 0x5ff8, 0x12c4, + 0x5ffb, 0x12c2, + 0x5ffd, 0x080c, + 0x5fff, 0x12c8, + 0x600e, 0x12ce, + 0x600f, 0x12d4, + 0x6010, 0x12cc, + 0x6012, 0x0c56, + 0x6015, 0x12d1, + 0x6016, 0x0dcf, + 0x6019, 0x12cb, + 0x601b, 0x12d0, + 0x601c, 0x0faf, + 0x601d, 0x08a5, + 0x6020, 0x0b35, + 0x6021, 0x12c9, + 0x6025, 0x0678, + 0x6026, 0x12d3, + 0x6027, 0x0a51, + 0x6028, 0x0507, + 0x6029, 0x12cd, + 0x602a, 0x0578, + 0x602b, 0x12d2, + 0x602f, 0x06a9, + 0x6031, 0x12cf, + 0x603a, 0x12d5, + 0x6041, 0x12d7, + 0x6042, 0x12e1, + 0x6043, 0x12df, + 0x6046, 0x12dc, + 0x604a, 0x12db, + 0x604b, 0x0fc0, + 0x604d, 0x12dd, + 0x6050, 0x06aa, + 0x6052, 0x07c3, + 0x6055, 0x0984, + 0x6059, 0x12e4, + 0x605a, 0x12d6, + 0x605d, 0x2106, + 0x605f, 0x12da, + 0x6060, 0x12ca, + 0x6062, 0x057a, + 0x6063, 0x12de, + 0x6064, 0x12e0, + 0x6065, 0x0b8f, + 0x6068, 0x0818, + 0x6069, 0x0538, + 0x606a, 0x12d8, + 0x606b, 0x12e3, + 0x606c, 0x12e2, + 0x606d, 0x06ab, + 0x606f, 0x0b09, + 0x6070, 0x05c4, + 0x6075, 0x0719, + 0x6077, 0x12d9, + 0x6081, 0x12e5, + 0x6083, 0x12e8, + 0x6084, 0x12ea, + 0x6085, 0x2107, + 0x6089, 0x08e9, + 0x608a, 0x2108, + 0x608b, 0x12f0, + 0x608c, 0x0c0c, + 0x608d, 0x12e6, + 0x6092, 0x12ee, + 0x6094, 0x0579, + 0x6096, 0x12ec, + 0x609a, 0x12e9, + 0x609b, 0x12eb, + 0x609f, 0x079b, + 0x60a0, 0x0f14, + 0x60a3, 0x05f1, + 0x60a6, 0x04fb, + 0x60a7, 0x12ef, + 0x60a9, 0x0cf0, + 0x60aa, 0x0471, + 0x60b2, 0x0d75, + 0x60b3, 0x12c7, + 0x60b4, 0x12f5, + 0x60b5, 0x12f9, + 0x60b6, 0x0ef1, + 0x60b8, 0x12f2, + 0x60bc, 0x0c63, + 0x60bd, 0x12f7, + 0x60c5, 0x09d8, + 0x60c6, 0x12f8, + 0x60c7, 0x0caf, + 0x60d1, 0x0fed, + 0x60d3, 0x12f4, + 0x60d5, 0x210a, + 0x60d8, 0x12fa, + 0x60da, 0x080d, + 0x60dc, 0x0a6f, + 0x60de, 0x2109, + 0x60df, 0x0498, + 0x60e0, 0x12f3, + 0x60e1, 0x12f1, + 0x60e3, 0x0adc, + 0x60e7, 0x12e7, + 0x60e8, 0x0882, + 0x60f0, 0x0b26, + 0x60f1, 0x1306, + 0x60f2, 0x210c, + 0x60f3, 0x0add, + 0x60f4, 0x1301, + 0x60f6, 0x12fe, + 0x60f9, 0x0912, + 0x60fa, 0x1302, + 0x60fb, 0x1305, + 0x6100, 0x1300, + 0x6101, 0x092f, + 0x6103, 0x1303, + 0x6106, 0x12fd, + 0x6108, 0x0f08, + 0x6109, 0x0f07, + 0x610d, 0x1307, + 0x610f, 0x0499, + 0x6111, 0x210d, + 0x6115, 0x12fc, + 0x611a, 0x06ea, + 0x611b, 0x046a, + 0x611f, 0x05f2, + 0x6120, 0x210b, + 0x6121, 0x1304, + 0x6127, 0x130c, + 0x6128, 0x130b, + 0x612c, 0x1310, + 0x6130, 0x210f, + 0x6134, 0x1311, + 0x6137, 0x210e, + 0x613c, 0x130f, + 0x613d, 0x1312, + 0x613e, 0x130a, + 0x613f, 0x130e, + 0x6142, 0x1313, + 0x6144, 0x1314, + 0x6147, 0x1309, + 0x6148, 0x08ca, + 0x614a, 0x130d, + 0x614b, 0x0b36, + 0x614c, 0x07c4, + 0x614d, 0x12fb, + 0x614e, 0x09fb, + 0x6153, 0x1321, + 0x6155, 0x0e39, + 0x6158, 0x1317, + 0x615d, 0x1320, + 0x615f, 0x131f, + 0x6162, 0x0eab, + 0x6163, 0x05f3, + 0x6165, 0x131d, + 0x6167, 0x071b, + 0x6168, 0x0592, + 0x616b, 0x131a, + 0x616e, 0x0f80, + 0x616f, 0x131c, + 0x6170, 0x049a, + 0x6171, 0x131e, + 0x6173, 0x1315, + 0x6174, 0x131b, + 0x6175, 0x1322, + 0x6176, 0x071a, + 0x6177, 0x1316, + 0x617e, 0x0f47, + 0x6182, 0x0f15, + 0x6187, 0x1325, + 0x618a, 0x1329, + 0x618e, 0x0b00, + 0x6190, 0x0fc1, + 0x6191, 0x132a, + 0x6194, 0x1327, + 0x6196, 0x1324, + 0x6198, 0x2110, + 0x6199, 0x1323, + 0x619a, 0x1328, + 0x61a4, 0x0e00, + 0x61a7, 0x0c8c, + 0x61a9, 0x071c, + 0x61ab, 0x132b, + 0x61ac, 0x1326, + 0x61ae, 0x132c, + 0x61b2, 0x0751, + 0x61b6, 0x0531, + 0x61ba, 0x1334, + 0x61be, 0x05f4, + 0x61c3, 0x1332, + 0x61c6, 0x1333, + 0x61c7, 0x0819, + 0x61c8, 0x1331, + 0x61c9, 0x132f, + 0x61ca, 0x132e, + 0x61cb, 0x1335, + 0x61cc, 0x132d, + 0x61cd, 0x1337, + 0x61d0, 0x057b, + 0x61e3, 0x1339, + 0x61e6, 0x1338, + 0x61f2, 0x0bc4, + 0x61f4, 0x133c, + 0x61f6, 0x133a, + 0x61f7, 0x1330, + 0x61f8, 0x0752, + 0x61fa, 0x133b, + 0x61fc, 0x133f, + 0x61fd, 0x133e, + 0x61fe, 0x1340, + 0x61ff, 0x133d, + 0x6200, 0x1341, + 0x6208, 0x1342, + 0x620a, 0x0e3a, + 0x620c, 0x1345, + 0x620d, 0x1344, + 0x620e, 0x0949, + 0x6210, 0x0a52, + 0x6211, 0x0566, + 0x6212, 0x057c, + 0x6213, 0x2111, + 0x6214, 0x1346, + 0x6216, 0x0483, + 0x621a, 0x0a70, + 0x621b, 0x1347, + 0x621d, 0x1a64, + 0x621e, 0x1348, + 0x621f, 0x0737, + 0x6221, 0x1349, + 0x6226, 0x0a93, + 0x622a, 0x134a, + 0x622e, 0x134b, + 0x622f, 0x0654, + 0x6230, 0x134c, + 0x6232, 0x134d, + 0x6234, 0x0b37, + 0x6238, 0x0781, + 0x623b, 0x0eed, + 0x623f, 0x0e6a, + 0x6240, 0x0974, + 0x6241, 0x134f, + 0x6247, 0x0a94, + 0x6248, 0x1b1a, + 0x6249, 0x0d76, + 0x624b, 0x0916, + 0x624d, 0x083d, + 0x624e, 0x1350, + 0x6253, 0x0b27, + 0x6255, 0x0df7, + 0x6258, 0x0b51, + 0x625b, 0x1353, + 0x625e, 0x1351, + 0x6260, 0x1354, + 0x6263, 0x1352, + 0x6268, 0x1355, + 0x626e, 0x0e01, + 0x6271, 0x047b, + 0x6276, 0x0dd0, + 0x6279, 0x0d77, + 0x627c, 0x1356, + 0x627e, 0x1359, + 0x627f, 0x099d, + 0x6280, 0x0655, + 0x6282, 0x1357, + 0x6283, 0x135e, + 0x6284, 0x099e, + 0x6289, 0x1358, + 0x628a, 0x0cfa, + 0x6291, 0x0f48, + 0x6292, 0x135a, + 0x6294, 0x135f, + 0x6295, 0x0c64, + 0x6296, 0x135c, + 0x6297, 0x07c5, + 0x6298, 0x0a82, + 0x629b, 0x136d, + 0x629c, 0x0d48, + 0x629e, 0x0b52, + 0x62a6, 0x2112, + 0x62ab, 0x0d78, + 0x62ac, 0x13b2, + 0x62b1, 0x0e4a, + 0x62b5, 0x0c0d, + 0x62b9, 0x0ea3, + 0x62bb, 0x1362, + 0x62bc, 0x0521, + 0x62bd, 0x0ba8, + 0x62c2, 0x136b, + 0x62c5, 0x0b72, + 0x62c6, 0x1365, + 0x62c7, 0x136c, + 0x62c8, 0x1367, + 0x62c9, 0x136e, + 0x62ca, 0x136a, + 0x62cc, 0x1369, + 0x62cd, 0x0d25, + 0x62cf, 0x1363, + 0x62d0, 0x057d, + 0x62d1, 0x1361, + 0x62d2, 0x068b, + 0x62d3, 0x0b53, + 0x62d4, 0x135d, + 0x62d7, 0x1360, + 0x62d8, 0x07c6, + 0x62d9, 0x0a7f, + 0x62db, 0x099f, + 0x62dc, 0x1368, + 0x62dd, 0x0d08, + 0x62e0, 0x068c, + 0x62e1, 0x05a6, + 0x62ec, 0x05c5, + 0x62ed, 0x09e7, + 0x62ee, 0x1370, + 0x62ef, 0x1375, + 0x62f1, 0x1371, + 0x62f3, 0x0753, + 0x62f5, 0x1376, + 0x62f6, 0x0870, + 0x62f7, 0x07fb, + 0x62fe, 0x0930, + 0x62ff, 0x1364, + 0x6301, 0x08cb, + 0x6302, 0x1373, + 0x6307, 0x08a6, + 0x6308, 0x1374, + 0x6309, 0x0488, + 0x630c, 0x136f, + 0x6311, 0x0bc5, + 0x6319, 0x068d, + 0x631f, 0x06ac, + 0x6327, 0x1372, + 0x6328, 0x046b, + 0x632b, 0x0833, + 0x632f, 0x09fc, + 0x633a, 0x0c0e, + 0x633d, 0x0d68, + 0x633e, 0x1378, + 0x633f, 0x0ae0, + 0x6349, 0x0b0a, + 0x634c, 0x0879, + 0x634d, 0x1379, + 0x634f, 0x137b, + 0x6350, 0x1377, + 0x6355, 0x0e31, + 0x6357, 0x0bd9, + 0x635c, 0x0ade, + 0x6367, 0x0e4b, + 0x6368, 0x08fa, + 0x6369, 0x1387, + 0x636b, 0x1386, + 0x636e, 0x0a3e, + 0x6372, 0x0754, + 0x6376, 0x1380, + 0x6377, 0x09a1, + 0x637a, 0x0cc0, + 0x637b, 0x0ce7, + 0x6380, 0x137e, + 0x6383, 0x0adf, + 0x6388, 0x0924, + 0x6389, 0x1383, + 0x638c, 0x09a0, + 0x638e, 0x137d, + 0x638f, 0x1382, + 0x6392, 0x0d09, + 0x6396, 0x137c, + 0x6398, 0x06f7, + 0x639b, 0x05bb, + 0x639f, 0x1384, + 0x63a0, 0x0f73, + 0x63a1, 0x083e, + 0x63a2, 0x0b73, + 0x63a3, 0x1381, + 0x63a5, 0x0a80, + 0x63a7, 0x07c7, + 0x63a8, 0x0a2a, + 0x63a9, 0x0508, + 0x63aa, 0x0abe, + 0x63ab, 0x137f, + 0x63ac, 0x065f, + 0x63b2, 0x071d, + 0x63b4, 0x0beb, + 0x63b5, 0x1385, + 0x63bb, 0x0ae1, + 0x63be, 0x1388, + 0x63c0, 0x138a, + 0x63c3, 0x0b17, + 0x63c4, 0x1390, + 0x63c6, 0x138b, + 0x63c9, 0x138d, + 0x63cf, 0x0db3, + 0x63d0, 0x0c0f, + 0x63d2, 0x138e, + 0x63d6, 0x0f16, + 0x63da, 0x0f32, + 0x63db, 0x05f5, + 0x63e1, 0x0472, + 0x63e3, 0x138c, + 0x63e9, 0x1389, + 0x63ee, 0x0634, + 0x63f4, 0x0509, + 0x63f5, 0x2113, + 0x63f6, 0x138f, + 0x63fa, 0x0f33, + 0x6406, 0x1393, + 0x640d, 0x0b1b, + 0x640f, 0x139a, + 0x6413, 0x1394, + 0x6414, 0x1e2c, + 0x6416, 0x1391, + 0x6417, 0x1398, + 0x641c, 0x137a, + 0x6426, 0x1395, + 0x6428, 0x1399, + 0x642c, 0x0d56, + 0x642d, 0x0c65, + 0x6434, 0x1392, + 0x6436, 0x1396, + 0x643a, 0x071e, + 0x643e, 0x0861, + 0x6442, 0x0a81, + 0x644e, 0x139e, + 0x6451, 0x1e43, + 0x6458, 0x0c20, + 0x6460, 0x2114, + 0x6467, 0x139b, + 0x6469, 0x0e8e, + 0x646f, 0x139c, + 0x6476, 0x139d, + 0x6478, 0x0eda, + 0x647a, 0x0a46, + 0x6483, 0x0738, + 0x6488, 0x13a4, + 0x6492, 0x0883, + 0x6493, 0x13a1, + 0x6495, 0x13a0, + 0x649a, 0x0ce8, + 0x649d, 0x2115, + 0x649e, 0x0c8d, + 0x64a4, 0x0c2b, + 0x64a5, 0x13a2, + 0x64a9, 0x13a3, + 0x64ab, 0x0de1, + 0x64ad, 0x0cfb, + 0x64ae, 0x0871, + 0x64b0, 0x0a95, + 0x64b2, 0x0e7e, + 0x64b9, 0x05a7, + 0x64bb, 0x13aa, + 0x64bc, 0x13a5, + 0x64c1, 0x0f34, + 0x64c2, 0x13ac, + 0x64c5, 0x13a8, + 0x64c7, 0x13a9, + 0x64cd, 0x0ae2, + 0x64ce, 0x2116, + 0x64d2, 0x13a7, + 0x64d4, 0x1366, + 0x64d8, 0x13ab, + 0x64da, 0x13a6, + 0x64e0, 0x13b0, + 0x64e2, 0x0c21, + 0x64e3, 0x13b3, + 0x64e6, 0x0872, + 0x64e7, 0x13ae, + 0x64ec, 0x0656, + 0x64ef, 0x13b4, + 0x64f1, 0x13ad, + 0x64f2, 0x13b8, + 0x64f4, 0x13b7, + 0x64f6, 0x13b6, + 0x64fa, 0x13b9, + 0x64fd, 0x13bb, + 0x64fe, 0x09d9, + 0x6500, 0x13ba, + 0x6505, 0x13be, + 0x6518, 0x13bc, + 0x651c, 0x13bd, + 0x651d, 0x1397, + 0x6522, 0x1e97, + 0x6523, 0x13c0, + 0x6524, 0x13bf, + 0x652a, 0x139f, + 0x652b, 0x13c1, + 0x652c, 0x13b5, + 0x652f, 0x08a7, + 0x6534, 0x13c2, + 0x6536, 0x13c5, + 0x6537, 0x13c4, + 0x6538, 0x13c6, + 0x6539, 0x057e, + 0x653b, 0x07c8, + 0x653e, 0x0e4c, + 0x653f, 0x0a53, + 0x6545, 0x0782, + 0x6548, 0x13c8, + 0x654d, 0x13cb, + 0x654e, 0x2117, + 0x654f, 0x0dc4, + 0x6551, 0x0679, + 0x6555, 0x13ca, + 0x6556, 0x13c9, + 0x6557, 0x0d0a, + 0x6558, 0x13cc, + 0x6559, 0x06ad, + 0x655d, 0x13ce, + 0x655e, 0x13cd, + 0x6562, 0x05f6, + 0x6563, 0x0884, + 0x6566, 0x0cb0, + 0x656c, 0x071f, + 0x6570, 0x0a3a, + 0x6572, 0x13cf, + 0x6574, 0x0a54, + 0x6575, 0x0c22, + 0x6577, 0x0dd1, + 0x6578, 0x13d0, + 0x6582, 0x13d1, + 0x6587, 0x0e08, + 0x6588, 0x120c, + 0x6589, 0x0a6a, + 0x658c, 0x0dbe, + 0x658e, 0x0848, + 0x6590, 0x0d79, + 0x6591, 0x0d57, + 0x6597, 0x0c47, + 0x6599, 0x0f89, + 0x659b, 0x13d4, + 0x659c, 0x08fc, + 0x659f, 0x13d5, + 0x65a1, 0x047a, + 0x65a4, 0x06cc, + 0x65a5, 0x0a71, + 0x65a7, 0x0dd2, + 0x65ab, 0x13d6, + 0x65ac, 0x0890, + 0x65ad, 0x0b85, + 0x65af, 0x08a9, + 0x65b0, 0x09fd, + 0x65b7, 0x13d7, + 0x65b9, 0x0e4d, + 0x65bc, 0x0519, + 0x65bd, 0x08aa, + 0x65c1, 0x13da, + 0x65c3, 0x13d8, + 0x65c4, 0x13db, + 0x65c5, 0x0f81, + 0x65c6, 0x13d9, + 0x65cb, 0x0a9f, + 0x65cc, 0x13dc, + 0x65cf, 0x0b12, + 0x65d2, 0x13dd, + 0x65d7, 0x0636, + 0x65d9, 0x13df, + 0x65db, 0x13de, + 0x65e0, 0x13e0, + 0x65e2, 0x0637, + 0x65e5, 0x0cd4, + 0x65e6, 0x0b74, + 0x65e7, 0x0686, + 0x65e8, 0x08ab, + 0x65e9, 0x0ae3, + 0x65ec, 0x0966, + 0x65ed, 0x0474, + 0x65f1, 0x13e2, + 0x65fa, 0x0522, + 0x65fb, 0x13e6, + 0x6600, 0x2118, + 0x6602, 0x07c9, + 0x6603, 0x13e5, + 0x6606, 0x081b, + 0x6607, 0x09a2, + 0x6609, 0x211a, + 0x660a, 0x13e4, + 0x660c, 0x09a3, + 0x660e, 0x0ecc, + 0x660f, 0x081a, + 0x6613, 0x049b, + 0x6614, 0x0a72, + 0x6615, 0x2119, + 0x661c, 0x13eb, + 0x661e, 0x211c, + 0x661f, 0x0a55, + 0x6620, 0x04e9, + 0x6624, 0x211d, + 0x6625, 0x095f, + 0x6627, 0x0e94, + 0x6628, 0x0862, + 0x662d, 0x09a4, + 0x662e, 0x211b, + 0x662f, 0x0a4b, + 0x6631, 0x20ae, + 0x6634, 0x13ea, + 0x6635, 0x13e8, + 0x663b, 0x1e00, + 0x663c, 0x0ba9, + 0x663f, 0x1409, + 0x6641, 0x13ef, + 0x6642, 0x08cc, + 0x6643, 0x07ca, + 0x6644, 0x13ed, + 0x6649, 0x13ee, + 0x664b, 0x09fe, + 0x664f, 0x13ec, + 0x6652, 0x087d, + 0x6657, 0x211f, + 0x6659, 0x2120, + 0x665d, 0x13f1, + 0x665e, 0x13f0, + 0x665f, 0x13f5, + 0x6662, 0x13f6, + 0x6664, 0x13f2, + 0x6665, 0x211e, + 0x6666, 0x0580, + 0x6667, 0x13f3, + 0x6669, 0x0d69, + 0x666e, 0x0dd3, + 0x666f, 0x0720, + 0x6670, 0x13f7, + 0x6673, 0x2122, + 0x6674, 0x0a56, + 0x6676, 0x09a5, + 0x667a, 0x0b90, + 0x6681, 0x06bf, + 0x6683, 0x13f8, + 0x6684, 0x13fc, + 0x6687, 0x054b, + 0x6688, 0x13f9, + 0x6689, 0x13fb, + 0x668e, 0x13fa, + 0x6691, 0x0975, + 0x6696, 0x0b86, + 0x6697, 0x0489, + 0x6698, 0x13fd, + 0x6699, 0x2123, + 0x669d, 0x13fe, + 0x66a0, 0x2124, + 0x66a2, 0x0bc6, + 0x66a6, 0x0fb9, + 0x66ab, 0x0891, + 0x66ae, 0x0e3b, + 0x66b2, 0x2125, + 0x66b4, 0x0e6b, + 0x66b8, 0x1405, + 0x66b9, 0x1400, + 0x66bc, 0x1403, + 0x66be, 0x1402, + 0x66bf, 0x2126, + 0x66c1, 0x13ff, + 0x66c4, 0x1404, + 0x66c7, 0x0cb6, + 0x66c9, 0x1401, + 0x66d6, 0x1406, + 0x66d9, 0x0976, + 0x66da, 0x1407, + 0x66dc, 0x0f35, + 0x66dd, 0x0d2e, + 0x66e0, 0x1408, + 0x66e6, 0x140a, + 0x66e9, 0x140b, + 0x66f0, 0x140c, + 0x66f2, 0x06c2, + 0x66f3, 0x04ea, + 0x66f4, 0x07cb, + 0x66f5, 0x140d, + 0x66f7, 0x140e, + 0x66f8, 0x097b, + 0x66f9, 0x0ae4, + 0x66fa, 0x2127, + 0x66fb, 0x20b1, + 0x66fc, 0x10ed, + 0x66fd, 0x0ac0, + 0x66fe, 0x0abf, + 0x66ff, 0x0b38, + 0x6700, 0x0837, + 0x6703, 0x104b, + 0x6708, 0x0744, + 0x6709, 0x0f17, + 0x670b, 0x0e4e, + 0x670d, 0x0df0, + 0x670e, 0x2128, + 0x670f, 0x140f, + 0x6714, 0x0863, + 0x6715, 0x0bdb, + 0x6716, 0x1410, + 0x6717, 0x0fd5, + 0x671b, 0x0e6c, + 0x671d, 0x0bc7, + 0x671e, 0x1411, + 0x671f, 0x0638, + 0x6726, 0x1412, + 0x6728, 0x0ee6, + 0x672a, 0x0eb0, + 0x672b, 0x0ea4, + 0x672c, 0x0e8a, + 0x672d, 0x0873, + 0x672e, 0x1415, + 0x6731, 0x0917, + 0x6734, 0x0e7f, + 0x6736, 0x1417, + 0x6737, 0x141a, + 0x6738, 0x1419, + 0x673a, 0x0635, + 0x673d, 0x067a, + 0x673f, 0x1416, + 0x6741, 0x1418, + 0x6746, 0x141b, + 0x6749, 0x0a3f, + 0x674e, 0x0f65, + 0x674f, 0x048d, + 0x6750, 0x0850, + 0x6751, 0x0b1c, + 0x6753, 0x0909, + 0x6756, 0x09db, + 0x6759, 0x141e, + 0x675c, 0x0c48, + 0x675e, 0x141c, + 0x675f, 0x0b0b, + 0x6760, 0x141d, + 0x6761, 0x09da, + 0x6762, 0x0ee9, + 0x6763, 0x141f, + 0x6765, 0x0f52, + 0x6766, 0x212a, + 0x676a, 0x1425, + 0x676d, 0x07cc, + 0x676f, 0x0d0b, + 0x6770, 0x1422, + 0x6771, 0x0c66, + 0x6772, 0x13e3, + 0x6773, 0x13e7, + 0x6775, 0x0669, + 0x6777, 0x0cfd, + 0x677c, 0x1424, + 0x677e, 0x09a6, + 0x677f, 0x0d58, + 0x6785, 0x142a, + 0x6787, 0x0d8e, + 0x6789, 0x1421, + 0x678b, 0x1427, + 0x678c, 0x1426, + 0x6790, 0x0a73, + 0x6795, 0x0e9b, + 0x6797, 0x0f9b, + 0x679a, 0x0e95, + 0x679c, 0x054c, + 0x679d, 0x08ac, + 0x67a0, 0x0fee, + 0x67a1, 0x1429, + 0x67a2, 0x0a3b, + 0x67a6, 0x1428, + 0x67a9, 0x1423, + 0x67af, 0x0783, + 0x67b3, 0x142f, + 0x67b4, 0x142d, + 0x67b6, 0x054d, + 0x67b7, 0x142b, + 0x67b8, 0x1431, + 0x67b9, 0x1437, + 0x67bb, 0x212b, + 0x67c0, 0x212d, + 0x67c1, 0x0b28, + 0x67c4, 0x0e11, + 0x67c6, 0x1439, + 0x67ca, 0x0d94, + 0x67ce, 0x1438, + 0x67cf, 0x0d26, + 0x67d0, 0x0e6d, + 0x67d1, 0x05f7, + 0x67d3, 0x0a9b, + 0x67d4, 0x094a, + 0x67d8, 0x0bef, + 0x67da, 0x0f18, + 0x67dd, 0x1434, + 0x67de, 0x1433, + 0x67e2, 0x1435, + 0x67e4, 0x1432, + 0x67e7, 0x143a, + 0x67e9, 0x1430, + 0x67ec, 0x142e, + 0x67ee, 0x1436, + 0x67ef, 0x142c, + 0x67f1, 0x0baa, + 0x67f3, 0x0f04, + 0x67f4, 0x08f2, + 0x67f5, 0x0864, + 0x67fb, 0x082a, + 0x67fe, 0x0e9d, + 0x67ff, 0x059f, + 0x6801, 0x212e, + 0x6802, 0x0bea, + 0x6803, 0x0ca2, + 0x6804, 0x04eb, + 0x6805, 0x1e07, + 0x6813, 0x0a96, + 0x6816, 0x0a58, + 0x6817, 0x0700, + 0x681e, 0x143c, + 0x6821, 0x07cd, + 0x6822, 0x05da, + 0x6829, 0x143e, + 0x682a, 0x05d2, + 0x682b, 0x1444, + 0x6832, 0x1441, + 0x6834, 0x0a97, + 0x6838, 0x05a9, + 0x6839, 0x081c, + 0x683c, 0x05a8, + 0x683d, 0x083f, + 0x6840, 0x143f, + 0x6841, 0x073b, + 0x6842, 0x0721, + 0x6843, 0x0c67, + 0x6844, 0x212f, + 0x6846, 0x143d, + 0x6848, 0x048a, + 0x684d, 0x1440, + 0x684e, 0x1442, + 0x6850, 0x06c5, + 0x6851, 0x0702, + 0x6852, 0x212c, + 0x6853, 0x05f8, + 0x6854, 0x0665, + 0x6859, 0x1445, + 0x685c, 0x0869, + 0x685d, 0x0e9f, + 0x685f, 0x0885, + 0x6863, 0x1446, + 0x6867, 0x0da2, + 0x6874, 0x1452, + 0x6876, 0x0533, + 0x6877, 0x1447, + 0x687e, 0x1458, + 0x687f, 0x1448, + 0x6881, 0x0f8a, + 0x6883, 0x144f, + 0x6885, 0x0d15, + 0x688d, 0x1457, + 0x688e, 0x1e9c, + 0x688f, 0x144a, + 0x6893, 0x0478, + 0x6894, 0x144c, + 0x6897, 0x07ce, + 0x689b, 0x144e, + 0x689d, 0x144d, + 0x689f, 0x1449, + 0x68a0, 0x1454, + 0x68a2, 0x09a7, + 0x68a6, 0x11be, + 0x68a7, 0x079c, + 0x68a8, 0x0f66, + 0x68ad, 0x144b, + 0x68af, 0x0c10, + 0x68b0, 0x0581, + 0x68b1, 0x081d, + 0x68b3, 0x1443, + 0x68b5, 0x1453, + 0x68b6, 0x05bf, + 0x68b9, 0x1451, + 0x68ba, 0x1455, + 0x68bc, 0x0c68, + 0x68c4, 0x063a, + 0x68c6, 0x1473, + 0x68c8, 0x20af, + 0x68c9, 0x0ed5, + 0x68ca, 0x145a, + 0x68cb, 0x0639, + 0x68cd, 0x1461, + 0x68cf, 0x2130, + 0x68d2, 0x0e6e, + 0x68d4, 0x1462, + 0x68d5, 0x1464, + 0x68d7, 0x1468, + 0x68d8, 0x145c, + 0x68da, 0x0b68, + 0x68df, 0x0c69, + 0x68e0, 0x146c, + 0x68e1, 0x145f, + 0x68e3, 0x1469, + 0x68e7, 0x1463, + 0x68ee, 0x09ff, + 0x68ef, 0x146d, + 0x68f2, 0x0a57, + 0x68f9, 0x146b, + 0x68fa, 0x05f9, + 0x6900, 0x0ff6, + 0x6901, 0x1459, + 0x6904, 0x1467, + 0x6905, 0x049c, + 0x6908, 0x145b, + 0x690b, 0x0ec6, + 0x690c, 0x1460, + 0x690d, 0x09e8, + 0x690e, 0x0be3, + 0x690f, 0x1456, + 0x6912, 0x1466, + 0x6919, 0x0a40, + 0x691a, 0x1470, + 0x691b, 0x05cf, + 0x691c, 0x0755, + 0x6921, 0x1472, + 0x6922, 0x145d, + 0x6923, 0x1471, + 0x6925, 0x146a, + 0x6926, 0x145e, + 0x6928, 0x146e, + 0x692a, 0x146f, + 0x6930, 0x1480, + 0x6934, 0x0ca6, + 0x6936, 0x1465, + 0x6939, 0x147c, + 0x693d, 0x147e, + 0x693f, 0x0bf4, + 0x694a, 0x0f36, + 0x6953, 0x0de8, + 0x6954, 0x1479, + 0x6955, 0x0b2a, + 0x6959, 0x147f, + 0x695a, 0x0ac1, + 0x695c, 0x1476, + 0x695d, 0x1483, + 0x695e, 0x1482, + 0x6960, 0x0cc7, + 0x6961, 0x1481, + 0x6962, 0x0cc2, + 0x6968, 0x2132, + 0x696a, 0x1485, + 0x696b, 0x1478, + 0x696d, 0x06c0, + 0x696e, 0x147b, + 0x696f, 0x0967, + 0x6973, 0x0d16, + 0x6974, 0x147d, + 0x6975, 0x06c3, + 0x6977, 0x1475, + 0x6978, 0x1477, + 0x6979, 0x1474, + 0x697c, 0x0fd6, + 0x697d, 0x05b8, + 0x697e, 0x147a, + 0x6981, 0x1484, + 0x6982, 0x0593, + 0x698a, 0x0857, + 0x698e, 0x04ff, + 0x6991, 0x1495, + 0x6994, 0x0fd7, + 0x6995, 0x1498, + 0x6998, 0x2134, + 0x699b, 0x0a00, + 0x699c, 0x1497, + 0x69a0, 0x1496, + 0x69a7, 0x1493, + 0x69ae, 0x1487, + 0x69b1, 0x14a4, + 0x69b2, 0x1486, + 0x69b4, 0x1499, + 0x69bb, 0x1491, + 0x69be, 0x148c, + 0x69bf, 0x1489, + 0x69c1, 0x148a, + 0x69c3, 0x1492, + 0x69c7, 0x1d33, + 0x69ca, 0x148f, + 0x69cb, 0x07cf, + 0x69cc, 0x0be4, + 0x69cd, 0x0ae6, + 0x69ce, 0x148d, + 0x69d0, 0x1488, + 0x69d3, 0x148b, + 0x69d8, 0x0f37, + 0x69d9, 0x0e98, + 0x69dd, 0x1490, + 0x69de, 0x149a, + 0x69e2, 0x2135, + 0x69e7, 0x14a2, + 0x69e8, 0x149b, + 0x69eb, 0x14a8, + 0x69ed, 0x14a6, + 0x69f2, 0x14a1, + 0x69f9, 0x14a0, + 0x69fb, 0x0bec, + 0x69fd, 0x0ae7, + 0x69ff, 0x149e, + 0x6a02, 0x149c, + 0x6a05, 0x14a3, + 0x6a0a, 0x14a9, + 0x6a0b, 0x0d89, + 0x6a0c, 0x14af, + 0x6a12, 0x14aa, + 0x6a13, 0x14ad, + 0x6a14, 0x14a7, + 0x6a17, 0x0bb2, + 0x6a19, 0x0daa, + 0x6a1b, 0x149d, + 0x6a1e, 0x14a5, + 0x6a1f, 0x09a8, + 0x6a21, 0x0edb, + 0x6a22, 0x14b9, + 0x6a23, 0x14ac, + 0x6a29, 0x0756, + 0x6a2a, 0x0523, + 0x6a2b, 0x05bd, + 0x6a2e, 0x1494, + 0x6a30, 0x2136, + 0x6a35, 0x09a9, + 0x6a36, 0x14b1, + 0x6a38, 0x14b8, + 0x6a39, 0x0925, + 0x6a3a, 0x05d0, + 0x6a3d, 0x0b6c, + 0x6a44, 0x14ae, + 0x6a46, 0x2138, + 0x6a47, 0x14b3, + 0x6a48, 0x14b7, + 0x6a4b, 0x06ae, + 0x6a58, 0x0666, + 0x6a59, 0x14b5, + 0x6a5f, 0x063b, + 0x6a61, 0x0ca3, + 0x6a62, 0x14b4, + 0x6a66, 0x14b6, + 0x6a6b, 0x2137, + 0x6a72, 0x14b0, + 0x6a73, 0x2139, + 0x6a78, 0x14b2, + 0x6a7e, 0x213a, + 0x6a7f, 0x05be, + 0x6a80, 0x0b87, + 0x6a84, 0x14bd, + 0x6a8d, 0x14bb, + 0x6a8e, 0x079d, + 0x6a90, 0x14ba, + 0x6a97, 0x14c0, + 0x6a9c, 0x143b, + 0x6aa0, 0x14bc, + 0x6aa2, 0x14be, + 0x6aaa, 0x14cb, + 0x6aac, 0x14c7, + 0x6aae, 0x1450, + 0x6ab3, 0x14c6, + 0x6ab8, 0x14c5, + 0x6abb, 0x14c2, + 0x6ac1, 0x14ab, + 0x6ac2, 0x14c4, + 0x6ac3, 0x14c3, + 0x6ad1, 0x14c9, + 0x6ad3, 0x0fcc, + 0x6ada, 0x14cc, + 0x6adb, 0x06f3, + 0x6ade, 0x14c8, + 0x6adf, 0x14ca, + 0x6ae2, 0x213b, + 0x6ae4, 0x213c, + 0x6ae8, 0x0d3b, + 0x6aea, 0x14cd, + 0x6afa, 0x14d1, + 0x6afb, 0x14ce, + 0x6b04, 0x0f5d, + 0x6b05, 0x14cf, + 0x6b0a, 0x149f, + 0x6b12, 0x14d2, + 0x6b16, 0x14d3, + 0x6b1d, 0x04d7, + 0x6b1f, 0x14d5, + 0x6b20, 0x073d, + 0x6b21, 0x08cd, + 0x6b23, 0x06cd, + 0x6b27, 0x0524, + 0x6b32, 0x0f49, + 0x6b37, 0x14d7, + 0x6b38, 0x14d6, + 0x6b39, 0x14d9, + 0x6b3a, 0x0657, + 0x6b3d, 0x06ce, + 0x6b3e, 0x05fa, + 0x6b43, 0x14dc, + 0x6b47, 0x14db, + 0x6b49, 0x14dd, + 0x6b4c, 0x054e, + 0x6b4e, 0x0b75, + 0x6b50, 0x14de, + 0x6b53, 0x05fb, + 0x6b54, 0x14e0, + 0x6b59, 0x14df, + 0x6b5b, 0x14e1, + 0x6b5f, 0x14e2, + 0x6b61, 0x14e3, + 0x6b62, 0x08ad, + 0x6b63, 0x0a59, + 0x6b64, 0x0811, + 0x6b66, 0x0de2, + 0x6b69, 0x0e32, + 0x6b6a, 0x0fea, + 0x6b6f, 0x08c3, + 0x6b73, 0x0840, + 0x6b74, 0x0fba, + 0x6b78, 0x14e4, + 0x6b7b, 0x08ae, + 0x6b7f, 0x14e6, + 0x6b83, 0x14e9, + 0x6b84, 0x14e8, + 0x6b86, 0x0e86, + 0x6b89, 0x0968, + 0x6b8a, 0x0918, + 0x6b8b, 0x0892, + 0x6b8d, 0x14ea, + 0x6b95, 0x14ec, + 0x6b96, 0x09e9, + 0x6b98, 0x14eb, + 0x6b9e, 0x14ed, + 0x6ba4, 0x14ee, + 0x6baa, 0x14ef, + 0x6baf, 0x14f1, + 0x6bb1, 0x14f3, + 0x6bb2, 0x14f2, + 0x6bb3, 0x14f4, + 0x6bb4, 0x0525, + 0x6bb5, 0x0b88, + 0x6bb7, 0x14f5, + 0x6bba, 0x0874, + 0x6bbb, 0x05aa, + 0x6bbc, 0x14f6, + 0x6bbf, 0x0c3c, + 0x6bc0, 0x119d, + 0x6bc5, 0x063d, + 0x6bc6, 0x14f7, + 0x6bcb, 0x14f8, + 0x6bcd, 0x0e3c, + 0x6bce, 0x0e96, + 0x6bd2, 0x0c9f, + 0x6bd3, 0x14f9, + 0x6bd4, 0x0d7a, + 0x6bd6, 0x213d, + 0x6bd8, 0x0d8f, + 0x6bdb, 0x0edf, + 0x6bdf, 0x14fa, + 0x6beb, 0x14fc, + 0x6bec, 0x14fb, + 0x6bef, 0x14fe, + 0x6bf3, 0x14fd, + 0x6c08, 0x1500, + 0x6c0f, 0x08af, + 0x6c11, 0x0ebd, + 0x6c13, 0x1501, + 0x6c17, 0x063e, + 0x6c1b, 0x1503, + 0x6c23, 0x1505, + 0x6c24, 0x1504, + 0x6c34, 0x0a2b, + 0x6c37, 0x0dab, + 0x6c38, 0x04ec, + 0x6c3e, 0x0d59, + 0x6c3f, 0x213e, + 0x6c40, 0x0c11, + 0x6c41, 0x094b, + 0x6c42, 0x067b, + 0x6c4e, 0x0d5a, + 0x6c50, 0x08da, + 0x6c55, 0x1507, + 0x6c57, 0x05fc, + 0x6c5a, 0x051a, + 0x6c5c, 0x213f, + 0x6c5d, 0x0cca, + 0x6c5e, 0x1506, + 0x6c5f, 0x07d0, + 0x6c60, 0x0b91, + 0x6c62, 0x1508, + 0x6c68, 0x1510, + 0x6c6a, 0x1509, + 0x6c6f, 0x2141, + 0x6c70, 0x0b21, + 0x6c72, 0x067c, + 0x6c73, 0x1511, + 0x6c7a, 0x073e, + 0x6c7d, 0x063f, + 0x6c7e, 0x150f, + 0x6c81, 0x150d, + 0x6c82, 0x150a, + 0x6c83, 0x0f4a, + 0x6c86, 0x2140, + 0x6c88, 0x0bdc, + 0x6c8c, 0x0cb1, + 0x6c8d, 0x150b, + 0x6c90, 0x1513, + 0x6c92, 0x1512, + 0x6c93, 0x06f9, + 0x6c96, 0x052d, + 0x6c99, 0x082b, + 0x6c9a, 0x150c, + 0x6c9b, 0x150e, + 0x6ca1, 0x0e85, + 0x6ca2, 0x0b54, + 0x6cab, 0x0ea5, + 0x6cae, 0x151b, + 0x6cb1, 0x151c, + 0x6cb3, 0x054f, + 0x6cb8, 0x0df8, + 0x6cb9, 0x0f09, + 0x6cba, 0x151e, + 0x6cbb, 0x08cf, + 0x6cbc, 0x09aa, + 0x6cbd, 0x1517, + 0x6cbe, 0x151d, + 0x6cbf, 0x050a, + 0x6cc1, 0x06af, + 0x6cc4, 0x1514, + 0x6cc5, 0x1519, + 0x6cc9, 0x0a98, + 0x6cca, 0x0d27, + 0x6ccc, 0x0d7b, + 0x6cd3, 0x1516, + 0x6cd5, 0x0e4f, + 0x6cd7, 0x1518, + 0x6cd9, 0x1521, + 0x6cda, 0x2142, + 0x6cdb, 0x151f, + 0x6cdd, 0x151a, + 0x6ce1, 0x0e50, + 0x6ce2, 0x0cfe, + 0x6ce3, 0x067d, + 0x6ce5, 0x0c1f, + 0x6ce8, 0x0bab, + 0x6cea, 0x1522, + 0x6cef, 0x1520, + 0x6cf0, 0x0b39, + 0x6cf1, 0x1515, + 0x6cf3, 0x04ed, + 0x6d04, 0x2143, + 0x6d0b, 0x0f38, + 0x6d0c, 0x152d, + 0x6d12, 0x152c, + 0x6d17, 0x0a9a, + 0x6d19, 0x1529, + 0x6d1b, 0x0f56, + 0x6d1e, 0x0c8e, + 0x6d1f, 0x1523, + 0x6d25, 0x0be1, + 0x6d29, 0x04ee, + 0x6d2a, 0x07d1, + 0x6d2b, 0x1526, + 0x6d32, 0x0931, + 0x6d33, 0x152b, + 0x6d35, 0x152a, + 0x6d36, 0x1525, + 0x6d38, 0x1528, + 0x6d3b, 0x05c6, + 0x6d3d, 0x1527, + 0x6d3e, 0x0cff, + 0x6d41, 0x0f76, + 0x6d44, 0x09dc, + 0x6d45, 0x0a99, + 0x6d59, 0x1533, + 0x6d5a, 0x1531, + 0x6d5c, 0x0dbf, + 0x6d63, 0x152e, + 0x6d64, 0x1530, + 0x6d66, 0x04dc, + 0x6d69, 0x07d2, + 0x6d6a, 0x0fd8, + 0x6d6c, 0x059b, + 0x6d6e, 0x0dd4, + 0x6d6f, 0x2145, + 0x6d74, 0x0f4b, + 0x6d77, 0x0582, + 0x6d78, 0x0a01, + 0x6d79, 0x1532, + 0x6d85, 0x1537, + 0x6d87, 0x2144, + 0x6d88, 0x09ab, + 0x6d8c, 0x0f1a, + 0x6d8e, 0x1534, + 0x6d93, 0x152f, + 0x6d95, 0x1535, + 0x6d96, 0x2146, + 0x6d99, 0x0fa6, + 0x6d9b, 0x0c6d, + 0x6d9c, 0x0c9a, + 0x6dac, 0x2147, + 0x6daf, 0x0594, + 0x6db2, 0x04f7, + 0x6db5, 0x153b, + 0x6db8, 0x153e, + 0x6dbc, 0x0f8b, + 0x6dc0, 0x0f4e, + 0x6dc5, 0x1545, + 0x6dc6, 0x153f, + 0x6dc7, 0x153c, + 0x6dcb, 0x0f9c, + 0x6dcc, 0x1542, + 0x6dcf, 0x2148, + 0x6dd1, 0x0954, + 0x6dd2, 0x1544, + 0x6dd5, 0x1549, + 0x6dd8, 0x0c6b, + 0x6dd9, 0x1547, + 0x6dde, 0x1541, + 0x6de1, 0x0b76, + 0x6de4, 0x1548, + 0x6de6, 0x153d, + 0x6de8, 0x1543, + 0x6dea, 0x154a, + 0x6deb, 0x04c0, + 0x6dec, 0x1540, + 0x6dee, 0x154b, + 0x6df1, 0x0a02, + 0x6df2, 0x214a, + 0x6df3, 0x0969, + 0x6df5, 0x0df5, + 0x6df7, 0x081e, + 0x6df8, 0x2149, + 0x6df9, 0x1538, + 0x6dfa, 0x1546, + 0x6dfb, 0x0c34, + 0x6dfc, 0x214b, + 0x6e05, 0x0a5a, + 0x6e07, 0x05c7, + 0x6e08, 0x0841, + 0x6e09, 0x09ac, + 0x6e0a, 0x153a, + 0x6e0b, 0x094c, + 0x6e13, 0x0722, + 0x6e15, 0x1539, + 0x6e19, 0x154f, + 0x6e1a, 0x0977, + 0x6e1b, 0x076e, + 0x6e1d, 0x155e, + 0x6e1f, 0x1558, + 0x6e20, 0x068e, + 0x6e21, 0x0c49, + 0x6e23, 0x1553, + 0x6e24, 0x155c, + 0x6e25, 0x0473, + 0x6e26, 0x04d4, + 0x6e27, 0x214e, + 0x6e29, 0x0539, + 0x6e2b, 0x1555, + 0x6e2c, 0x0b0c, + 0x6e2d, 0x154c, + 0x6e2e, 0x154e, + 0x6e2f, 0x07d3, + 0x6e38, 0x155f, + 0x6e39, 0x214c, + 0x6e3a, 0x155a, + 0x6e3c, 0x214f, + 0x6e3e, 0x1552, + 0x6e43, 0x1559, + 0x6e4a, 0x0eb7, + 0x6e4d, 0x1557, + 0x6e4e, 0x155b, + 0x6e56, 0x0784, + 0x6e58, 0x09ad, + 0x6e5b, 0x0b77, + 0x6e5c, 0x214d, + 0x6e5f, 0x1551, + 0x6e67, 0x0f19, + 0x6e6b, 0x1554, + 0x6e6e, 0x154d, + 0x6e6f, 0x0c6c, + 0x6e72, 0x1550, + 0x6e76, 0x1556, + 0x6e7e, 0x0ff7, + 0x6e7f, 0x08ea, + 0x6e80, 0x0eac, + 0x6e82, 0x1560, + 0x6e8c, 0x0d42, + 0x6e8f, 0x156c, + 0x6e90, 0x076f, + 0x6e96, 0x096a, + 0x6e98, 0x1562, + 0x6e9c, 0x0f77, + 0x6e9d, 0x07d4, + 0x6e9f, 0x156f, + 0x6ea2, 0x04b2, + 0x6ea5, 0x156d, + 0x6eaa, 0x1561, + 0x6eaf, 0x1567, + 0x6eb2, 0x1569, + 0x6eb6, 0x0f39, + 0x6eb7, 0x1564, + 0x6eba, 0x0c28, + 0x6ebd, 0x1566, + 0x6ebf, 0x2150, + 0x6ec2, 0x156e, + 0x6ec4, 0x1568, + 0x6ec5, 0x0ed3, + 0x6ec9, 0x1563, + 0x6ecb, 0x08ce, + 0x6ecc, 0x157b, + 0x6ed1, 0x05c8, + 0x6ed3, 0x1565, + 0x6ed4, 0x156a, + 0x6edd, 0x0b4c, + 0x6ede, 0x0b3a, + 0x6eec, 0x1573, + 0x6eef, 0x1579, + 0x6ef2, 0x1577, + 0x6ef4, 0x0c23, + 0x6ef7, 0x157e, + 0x6ef8, 0x1574, + 0x6efe, 0x1575, + 0x6eff, 0x155d, + 0x6f01, 0x0693, + 0x6f02, 0x0dac, + 0x6f06, 0x08eb, + 0x6f09, 0x0809, + 0x6f0f, 0x0fd9, + 0x6f11, 0x1571, + 0x6f13, 0x157d, + 0x6f14, 0x050b, + 0x6f15, 0x0ae8, + 0x6f20, 0x0d2f, + 0x6f22, 0x05fd, + 0x6f23, 0x0fc2, + 0x6f2b, 0x0ead, + 0x6f2c, 0x0bee, + 0x6f31, 0x1578, + 0x6f32, 0x157a, + 0x6f38, 0x0ab4, + 0x6f3e, 0x157c, + 0x6f3f, 0x1576, + 0x6f41, 0x1570, + 0x6f45, 0x05ff, + 0x6f51, 0x1e60, + 0x6f54, 0x073f, + 0x6f58, 0x158a, + 0x6f5b, 0x1585, + 0x6f5c, 0x0a9c, + 0x6f5f, 0x05c1, + 0x6f64, 0x096b, + 0x6f66, 0x158e, + 0x6f6d, 0x1587, + 0x6f6e, 0x0bc8, + 0x6f6f, 0x1584, + 0x6f70, 0x0bf5, + 0x6f74, 0x15a7, + 0x6f78, 0x1581, + 0x6f7a, 0x1580, + 0x6f7c, 0x1589, + 0x6f80, 0x1583, + 0x6f81, 0x1582, + 0x6f82, 0x1588, + 0x6f84, 0x0a45, + 0x6f86, 0x157f, + 0x6f88, 0x2151, + 0x6f8e, 0x158b, + 0x6f91, 0x158c, + 0x6f97, 0x05fe, + 0x6fa1, 0x1591, + 0x6fa3, 0x1590, + 0x6fa4, 0x1592, + 0x6faa, 0x1595, + 0x6fb1, 0x0c3d, + 0x6fb3, 0x158f, + 0x6fb5, 0x2152, + 0x6fb9, 0x1593, + 0x6fc0, 0x0739, + 0x6fc1, 0x0b59, + 0x6fc2, 0x158d, + 0x6fc3, 0x0cf1, + 0x6fc6, 0x1594, + 0x6fd4, 0x1599, + 0x6fd5, 0x1597, + 0x6fd8, 0x159a, + 0x6fdb, 0x159d, + 0x6fdf, 0x1596, + 0x6fe0, 0x07fc, + 0x6fe1, 0x0cde, + 0x6fe4, 0x1536, + 0x6feb, 0x0f5e, + 0x6fec, 0x1598, + 0x6fee, 0x159c, + 0x6fef, 0x0b55, + 0x6ff1, 0x159b, + 0x6ff3, 0x1586, + 0x6ff5, 0x2153, + 0x6ff6, 0x1ba4, + 0x6ffa, 0x15a0, + 0x6ffe, 0x15a4, + 0x7001, 0x15a2, + 0x7005, 0x2154, + 0x7006, 0x1e50, + 0x7007, 0x2155, + 0x7009, 0x159e, + 0x700b, 0x159f, + 0x700f, 0x15a3, + 0x7011, 0x15a1, + 0x7015, 0x0dc0, + 0x7018, 0x15a9, + 0x701a, 0x15a6, + 0x701b, 0x15a5, + 0x701d, 0x15a8, + 0x701e, 0x0cac, + 0x701f, 0x15aa, + 0x7026, 0x0bb3, + 0x7027, 0x0b4d, + 0x7028, 0x2156, + 0x702c, 0x0a49, + 0x7030, 0x15ab, + 0x7032, 0x15ad, + 0x703e, 0x15ac, + 0x704c, 0x1572, + 0x7051, 0x15ae, + 0x7058, 0x0cbf, + 0x7063, 0x15af, + 0x706b, 0x0550, + 0x706f, 0x0c6e, + 0x7070, 0x0583, + 0x7078, 0x067e, + 0x707c, 0x090a, + 0x707d, 0x0842, + 0x7085, 0x2157, + 0x7089, 0x0fcd, + 0x708a, 0x0a2c, + 0x708e, 0x050c, + 0x7092, 0x15b1, + 0x7099, 0x15b0, + 0x70ab, 0x2158, + 0x70ac, 0x15b4, + 0x70ad, 0x0b78, + 0x70ae, 0x15b7, + 0x70af, 0x15b2, + 0x70b3, 0x15b6, + 0x70b8, 0x15b5, + 0x70b9, 0x0c3a, + 0x70ba, 0x049d, + 0x70bb, 0x20ad, + 0x70c8, 0x0fbd, + 0x70cb, 0x15b9, + 0x70cf, 0x04ca, + 0x70d9, 0x15bb, + 0x70dd, 0x15ba, + 0x70df, 0x15b8, + 0x70f1, 0x15b3, + 0x70f9, 0x0e51, + 0x70fd, 0x15bd, + 0x7104, 0x215a, + 0x7109, 0x15bc, + 0x710f, 0x2159, + 0x7114, 0x050d, + 0x7119, 0x15bf, + 0x711a, 0x0e02, + 0x711c, 0x15be, + 0x7121, 0x0ec1, + 0x7126, 0x09af, + 0x7130, 0x1ddc, + 0x7136, 0x0ab5, + 0x713c, 0x09ae, + 0x7146, 0x215c, + 0x7149, 0x0fc3, + 0x714c, 0x15c5, + 0x714e, 0x0a9d, + 0x7155, 0x15c1, + 0x7156, 0x15c6, + 0x7159, 0x050e, + 0x715c, 0x215b, + 0x7162, 0x15c4, + 0x7164, 0x0d17, + 0x7165, 0x15c0, + 0x7166, 0x15c3, + 0x7167, 0x09b0, + 0x7169, 0x0d65, + 0x716c, 0x15c7, + 0x716e, 0x08fd, + 0x717d, 0x0a9e, + 0x7184, 0x15ca, + 0x7188, 0x15c2, + 0x718a, 0x06fd, + 0x718f, 0x15c8, + 0x7194, 0x0f3a, + 0x7195, 0x15cb, + 0x7199, 0x205d, + 0x719f, 0x0959, + 0x71a8, 0x15cc, + 0x71ac, 0x15cd, + 0x71b1, 0x0ce4, + 0x71b9, 0x15cf, + 0x71be, 0x15d0, + 0x71c1, 0x215f, + 0x71c3, 0x0ce9, + 0x71c8, 0x0c6f, + 0x71c9, 0x15d2, + 0x71ce, 0x15d4, + 0x71d0, 0x0f9d, + 0x71d2, 0x15d1, + 0x71d4, 0x15d3, + 0x71d5, 0x050f, + 0x71d7, 0x15ce, + 0x71df, 0x114e, + 0x71e0, 0x15d5, + 0x71e5, 0x0ae9, + 0x71e6, 0x0886, + 0x71e7, 0x15d7, + 0x71ec, 0x15d6, + 0x71ed, 0x09ea, + 0x71ee, 0x10ee, + 0x71f5, 0x15d8, + 0x71f9, 0x15da, + 0x71fb, 0x15c9, + 0x71fc, 0x15d9, + 0x71fe, 0x2160, + 0x71ff, 0x15db, + 0x7206, 0x0d30, + 0x720d, 0x15dc, + 0x7210, 0x15dd, + 0x721b, 0x15de, + 0x7228, 0x15df, + 0x722a, 0x0bfa, + 0x722c, 0x15e1, + 0x722d, 0x15e0, + 0x7230, 0x15e2, + 0x7232, 0x15e3, + 0x7235, 0x090b, + 0x7236, 0x0dd5, + 0x723a, 0x0ef8, + 0x723b, 0x15e4, + 0x723d, 0x0ad8, + 0x723e, 0x08d0, + 0x723f, 0x15e6, + 0x7246, 0x15e8, + 0x7247, 0x0e22, + 0x7248, 0x0d5b, + 0x724b, 0x15e9, + 0x724c, 0x0d0d, + 0x7252, 0x0bc9, + 0x7258, 0x15ea, + 0x7259, 0x0567, + 0x725b, 0x0687, + 0x725d, 0x0ed2, + 0x725f, 0x0ec2, + 0x7261, 0x0534, + 0x7262, 0x0fda, + 0x7267, 0x0e80, + 0x7269, 0x0dfa, + 0x7272, 0x0a5b, + 0x7274, 0x15eb, + 0x7279, 0x0c9b, + 0x727d, 0x0757, + 0x727e, 0x15ec, + 0x7280, 0x0844, + 0x7281, 0x15ee, + 0x7282, 0x15ed, + 0x7287, 0x15ef, + 0x7292, 0x15f0, + 0x7296, 0x15f1, + 0x72a0, 0x0658, + 0x72a2, 0x15f2, + 0x72a7, 0x15f3, + 0x72ac, 0x0758, + 0x72af, 0x0d5c, + 0x72b1, 0x2161, + 0x72b2, 0x15f5, + 0x72b6, 0x09dd, + 0x72b9, 0x15f4, + 0x72be, 0x2162, + 0x72c2, 0x06b0, + 0x72c3, 0x15f6, + 0x72c4, 0x15f8, + 0x72c6, 0x15f7, + 0x72ce, 0x15f9, + 0x72d0, 0x0785, + 0x72d2, 0x15fa, + 0x72d7, 0x06e1, + 0x72d9, 0x0ac2, + 0x72db, 0x080f, + 0x72e0, 0x15fc, + 0x72e2, 0x15fb, + 0x72e9, 0x0919, + 0x72ec, 0x0ca0, + 0x72ed, 0x06b1, + 0x72f7, 0x15ff, + 0x72f8, 0x0b6a, + 0x72f9, 0x15fe, + 0x72fc, 0x0fdb, + 0x72fd, 0x0d18, + 0x730a, 0x1602, + 0x7316, 0x1604, + 0x7317, 0x1601, + 0x731b, 0x0ee0, + 0x731c, 0x1603, + 0x731d, 0x1605, + 0x731f, 0x0f8c, + 0x7324, 0x2163, + 0x7325, 0x1609, + 0x7329, 0x1608, + 0x732a, 0x0bb4, + 0x732b, 0x0ce3, + 0x732e, 0x0759, + 0x732f, 0x1607, + 0x7334, 0x1606, + 0x7336, 0x0f1b, + 0x733e, 0x160a, + 0x733f, 0x0510, + 0x7344, 0x0808, + 0x7345, 0x08b0, + 0x734e, 0x160b, + 0x7357, 0x160e, + 0x7363, 0x094d, + 0x7368, 0x1610, + 0x736a, 0x160f, + 0x7370, 0x1611, + 0x7372, 0x05ab, + 0x7375, 0x1613, + 0x7377, 0x2165, + 0x7378, 0x1612, + 0x737a, 0x1615, + 0x737b, 0x1614, + 0x7384, 0x0770, + 0x7387, 0x0f70, + 0x7389, 0x06c4, + 0x738b, 0x0526, + 0x7396, 0x06e2, + 0x73a9, 0x061d, + 0x73b2, 0x0fb0, + 0x73b3, 0x1617, + 0x73bb, 0x1619, + 0x73bd, 0x2166, + 0x73c0, 0x161a, + 0x73c2, 0x0551, + 0x73c8, 0x1616, + 0x73c9, 0x2167, + 0x73ca, 0x0887, + 0x73cd, 0x0bdd, + 0x73ce, 0x1618, + 0x73d2, 0x216a, + 0x73d6, 0x2168, + 0x73de, 0x161d, + 0x73e0, 0x091a, + 0x73e3, 0x2169, + 0x73e5, 0x161b, + 0x73ea, 0x0714, + 0x73ed, 0x0d5d, + 0x73ee, 0x161c, + 0x73f1, 0x1637, + 0x73f5, 0x216c, + 0x73f8, 0x1622, + 0x73fe, 0x0771, + 0x7403, 0x067f, + 0x7405, 0x161f, + 0x7406, 0x0f67, + 0x7407, 0x216b, + 0x7409, 0x0f78, + 0x7422, 0x0b56, + 0x7425, 0x1621, + 0x7426, 0x216d, + 0x7429, 0x216f, + 0x742a, 0x216e, + 0x742e, 0x2170, + 0x7432, 0x1623, + 0x7433, 0x0f9e, + 0x7434, 0x06cf, + 0x7435, 0x0d90, + 0x7436, 0x0d00, + 0x743a, 0x1624, + 0x743f, 0x1626, + 0x7441, 0x1629, + 0x7455, 0x1625, + 0x7459, 0x1628, + 0x745a, 0x079e, + 0x745b, 0x04ef, + 0x745c, 0x162a, + 0x745e, 0x0a36, + 0x745f, 0x1627, + 0x7460, 0x0fa4, + 0x7462, 0x2171, + 0x7463, 0x162d, + 0x7464, 0x1d35, + 0x7469, 0x162b, + 0x746a, 0x162e, + 0x746f, 0x1620, + 0x7470, 0x162c, + 0x7473, 0x082c, + 0x7476, 0x162f, + 0x747e, 0x1630, + 0x7483, 0x0f68, + 0x7489, 0x2172, + 0x748b, 0x1631, + 0x749e, 0x1632, + 0x749f, 0x2173, + 0x74a2, 0x161e, + 0x74a7, 0x1633, + 0x74b0, 0x0600, + 0x74bd, 0x08d1, + 0x74ca, 0x1634, + 0x74cf, 0x1635, + 0x74d4, 0x1636, + 0x74dc, 0x04dd, + 0x74e0, 0x1638, + 0x74e2, 0x0dad, + 0x74e3, 0x1639, + 0x74e6, 0x05e0, + 0x74e7, 0x163a, + 0x74e9, 0x163b, + 0x74ee, 0x163c, + 0x74f0, 0x163e, + 0x74f2, 0x163d, + 0x74f6, 0x0dc5, + 0x74f7, 0x1641, + 0x74f8, 0x1640, + 0x7501, 0x2174, + 0x7503, 0x1643, + 0x7504, 0x1642, + 0x7505, 0x1644, + 0x750c, 0x1645, + 0x750d, 0x1647, + 0x750e, 0x1646, + 0x7511, 0x080b, + 0x7513, 0x1649, + 0x7515, 0x1648, + 0x7518, 0x0601, + 0x751a, 0x0a19, + 0x751c, 0x0c36, + 0x751e, 0x164a, + 0x751f, 0x0a5c, + 0x7523, 0x0888, + 0x7525, 0x051b, + 0x7526, 0x164b, + 0x7528, 0x0f3b, + 0x752b, 0x0e33, + 0x752c, 0x164c, + 0x752f, 0x20f2, + 0x7530, 0x0c3e, + 0x7531, 0x0f1d, + 0x7532, 0x07d5, + 0x7533, 0x0a03, + 0x7537, 0x0b89, + 0x7538, 0x10c9, + 0x753a, 0x0bca, + 0x753b, 0x0568, + 0x753c, 0x164d, + 0x7544, 0x164e, + 0x7546, 0x1653, + 0x7549, 0x1651, + 0x754a, 0x1650, + 0x754b, 0x13c7, + 0x754c, 0x0584, + 0x754d, 0x164f, + 0x754f, 0x049e, + 0x7551, 0x0d3e, + 0x7554, 0x0d5e, + 0x7559, 0x0f79, + 0x755a, 0x1654, + 0x755b, 0x1652, + 0x755c, 0x0b9a, + 0x755d, 0x0a4a, + 0x7560, 0x0d3f, + 0x7562, 0x0d9f, + 0x7564, 0x1656, + 0x7565, 0x0f74, + 0x7566, 0x0723, + 0x7567, 0x1657, + 0x7569, 0x1655, + 0x756a, 0x0d6a, + 0x756b, 0x1658, + 0x756d, 0x1659, + 0x756f, 0x2175, + 0x7570, 0x049f, + 0x7573, 0x09de, + 0x7574, 0x165e, + 0x7576, 0x165b, + 0x7577, 0x0cc5, + 0x7578, 0x165a, + 0x757f, 0x0640, + 0x7582, 0x1661, + 0x7586, 0x165c, + 0x7589, 0x1660, + 0x758a, 0x165f, + 0x758b, 0x0d97, + 0x758e, 0x0ac4, + 0x758f, 0x0ac3, + 0x7591, 0x0659, + 0x7594, 0x1662, + 0x759a, 0x1663, + 0x759d, 0x1664, + 0x75a3, 0x1666, + 0x75a5, 0x1665, + 0x75ab, 0x04f8, + 0x75b1, 0x166e, + 0x75b2, 0x0d7c, + 0x75b3, 0x1668, + 0x75b5, 0x166a, + 0x75b8, 0x166c, + 0x75b9, 0x0a04, + 0x75bc, 0x166d, + 0x75bd, 0x166b, + 0x75be, 0x08ec, + 0x75c2, 0x1667, + 0x75c3, 0x1669, + 0x75c5, 0x0db4, + 0x75c7, 0x09b1, + 0x75ca, 0x1670, + 0x75cd, 0x166f, + 0x75d2, 0x1671, + 0x75d4, 0x08d2, + 0x75d5, 0x081f, + 0x75d8, 0x0c71, + 0x75d9, 0x1672, + 0x75db, 0x0be7, + 0x75de, 0x1674, + 0x75e2, 0x0f69, + 0x75e3, 0x1673, + 0x75e9, 0x0aeb, + 0x75f0, 0x1679, + 0x75f2, 0x167b, + 0x75f4, 0x0b92, + 0x75fa, 0x167a, + 0x75fc, 0x1677, + 0x75fe, 0x1675, + 0x7601, 0x1678, + 0x7609, 0x167f, + 0x760b, 0x167d, + 0x760d, 0x167e, + 0x761f, 0x1680, + 0x7620, 0x1682, + 0x7624, 0x1685, + 0x7626, 0x1e2d, + 0x7627, 0x1681, + 0x7630, 0x1687, + 0x7634, 0x1686, + 0x763b, 0x1688, + 0x7642, 0x0f8d, + 0x7646, 0x168b, + 0x7647, 0x1689, + 0x764c, 0x061e, + 0x7652, 0x0f0a, + 0x7656, 0x0e1a, + 0x7658, 0x168d, + 0x765c, 0x168c, + 0x7661, 0x168e, + 0x7667, 0x1693, + 0x7668, 0x1690, + 0x766c, 0x1694, + 0x7670, 0x1695, + 0x7672, 0x1696, + 0x7676, 0x1697, + 0x7678, 0x1698, + 0x767a, 0x0d43, + 0x767b, 0x0c4a, + 0x767c, 0x1699, + 0x767d, 0x0d28, + 0x767e, 0x0da6, + 0x7680, 0x169a, + 0x7682, 0x2176, + 0x7683, 0x169b, + 0x7684, 0x0c24, + 0x7686, 0x0585, + 0x7687, 0x07d6, + 0x7688, 0x169c, + 0x768b, 0x169d, + 0x768e, 0x169e, + 0x7690, 0x0877, + 0x7693, 0x16a0, + 0x7696, 0x169f, + 0x7699, 0x16a1, + 0x769b, 0x2179, + 0x769c, 0x2177, + 0x769e, 0x2178, + 0x76a6, 0x217a, + 0x76ae, 0x0d7d, + 0x76b0, 0x16a3, + 0x76b4, 0x16a4, + 0x76b7, 0x1d1c, + 0x76b8, 0x16a5, + 0x76bf, 0x087c, + 0x76c2, 0x16a8, + 0x76c3, 0x0d0c, + 0x76c6, 0x0e8d, + 0x76c8, 0x04f0, + 0x76ca, 0x04f9, + 0x76cd, 0x16a9, + 0x76d2, 0x16ab, + 0x76d6, 0x16aa, + 0x76d7, 0x0c6a, + 0x76db, 0x0a5d, + 0x76dc, 0x14d8, + 0x76de, 0x16ac, + 0x76df, 0x0ecd, + 0x76e1, 0x16ad, + 0x76e3, 0x0602, + 0x76e4, 0x0d6b, + 0x76e5, 0x16ae, + 0x76e7, 0x16af, + 0x76ea, 0x16b0, + 0x76ee, 0x0ee8, + 0x76f2, 0x0ee1, + 0x76f4, 0x0bda, + 0x76f8, 0x0aec, + 0x76fb, 0x16b2, + 0x76fe, 0x096c, + 0x7701, 0x09b2, + 0x7704, 0x16b5, + 0x7707, 0x16b4, + 0x7708, 0x16b3, + 0x7709, 0x0d91, + 0x770b, 0x0603, + 0x770c, 0x075d, + 0x771b, 0x16bb, + 0x771e, 0x16b8, + 0x771f, 0x0a05, + 0x7720, 0x0ebe, + 0x7724, 0x16b7, + 0x7725, 0x16b9, + 0x7729, 0x16b6, + 0x7737, 0x16bc, + 0x773a, 0x0bcb, + 0x773c, 0x061f, + 0x7740, 0x0ba3, + 0x7746, 0x217c, + 0x7747, 0x16be, + 0x775a, 0x16bf, + 0x775b, 0x16c2, + 0x7761, 0x0a2d, + 0x7762, 0x1ec5, + 0x7763, 0x0c9c, + 0x7765, 0x16c3, + 0x7766, 0x0e81, + 0x7768, 0x16c0, + 0x776b, 0x16c1, + 0x7779, 0x16c6, + 0x777e, 0x16c5, + 0x777f, 0x16c4, + 0x778b, 0x16c8, + 0x778e, 0x16c7, + 0x7791, 0x16c9, + 0x779e, 0x16cb, + 0x77a0, 0x16ca, + 0x77a5, 0x0e1d, + 0x77ac, 0x0960, + 0x77ad, 0x0f8e, + 0x77b0, 0x16cc, + 0x77b3, 0x0c8f, + 0x77b6, 0x16cd, + 0x77b9, 0x16ce, + 0x77bb, 0x16d2, + 0x77bc, 0x16d0, + 0x77bf, 0x16cf, + 0x77c7, 0x16d3, + 0x77cd, 0x16d4, + 0x77d7, 0x16d5, + 0x77da, 0x16d6, + 0x77db, 0x0ec3, + 0x77dc, 0x16d7, + 0x77e2, 0x0efc, + 0x77e3, 0x16d8, + 0x77e5, 0x0b8c, + 0x77e7, 0x0d20, + 0x77e9, 0x06e3, + 0x77ed, 0x0b79, + 0x77ee, 0x16d9, + 0x77ef, 0x06b2, + 0x77f3, 0x0a74, + 0x77fc, 0x16da, + 0x7802, 0x082d, + 0x780c, 0x16db, + 0x7812, 0x16dc, + 0x7814, 0x075a, + 0x7815, 0x0845, + 0x7820, 0x16de, + 0x7821, 0x217e, + 0x7825, 0x0c50, + 0x7826, 0x0846, + 0x7827, 0x0668, + 0x7832, 0x0e52, + 0x7834, 0x0d01, + 0x783a, 0x0c51, + 0x783f, 0x07ee, + 0x7845, 0x16e0, + 0x784e, 0x217f, + 0x785d, 0x09b3, + 0x7864, 0x2180, + 0x786b, 0x0f7a, + 0x786c, 0x07d7, + 0x786f, 0x075b, + 0x7872, 0x0d37, + 0x7874, 0x16e2, + 0x787a, 0x2181, + 0x787c, 0x16e4, + 0x7881, 0x079f, + 0x7886, 0x16e3, + 0x7887, 0x0c12, + 0x788c, 0x16e6, + 0x788d, 0x0595, + 0x788e, 0x16e1, + 0x7891, 0x0d7e, + 0x7893, 0x04d2, + 0x7895, 0x085c, + 0x7897, 0x0ff8, + 0x789a, 0x16e5, + 0x78a3, 0x16e7, + 0x78a7, 0x0e1b, + 0x78a9, 0x0a7d, + 0x78aa, 0x16e9, + 0x78af, 0x16ea, + 0x78b5, 0x16e8, + 0x78ba, 0x05ac, + 0x78bc, 0x16f0, + 0x78be, 0x16ef, + 0x78c1, 0x08d3, + 0x78c5, 0x16f1, + 0x78c6, 0x16ec, + 0x78ca, 0x16f2, + 0x78cb, 0x16ed, + 0x78d0, 0x0d6c, + 0x78d1, 0x16eb, + 0x78d4, 0x16ee, + 0x78da, 0x16f5, + 0x78e7, 0x16f4, + 0x78e8, 0x0e8f, + 0x78ec, 0x16f3, + 0x78ef, 0x04af, + 0x78f4, 0x16f7, + 0x78fd, 0x16f6, + 0x7901, 0x09b4, + 0x7907, 0x16f8, + 0x790e, 0x0ac5, + 0x7911, 0x16fa, + 0x7912, 0x16f9, + 0x7919, 0x16fb, + 0x7926, 0x16dd, + 0x792a, 0x16df, + 0x792b, 0x16fd, + 0x792c, 0x16fc, + 0x7930, 0x2182, + 0x793a, 0x08d4, + 0x793c, 0x0fb1, + 0x793e, 0x08fe, + 0x7940, 0x16fe, + 0x7941, 0x070d, + 0x7947, 0x065a, + 0x7948, 0x0641, + 0x7949, 0x08b1, + 0x7950, 0x0f1e, + 0x7953, 0x1704, + 0x7955, 0x1703, + 0x7956, 0x0ac6, + 0x7957, 0x1700, + 0x795a, 0x1702, + 0x795d, 0x0955, + 0x795e, 0x0a06, + 0x795f, 0x1701, + 0x7960, 0x16ff, + 0x7962, 0x0ce0, + 0x7965, 0x09b5, + 0x7968, 0x0dae, + 0x796d, 0x0847, + 0x7977, 0x0c72, + 0x797a, 0x1705, + 0x797f, 0x1706, + 0x7980, 0x171c, + 0x7981, 0x06d0, + 0x7984, 0x0fe3, + 0x7985, 0x0ab7, + 0x798a, 0x1707, + 0x798d, 0x0552, + 0x798e, 0x0c13, + 0x798f, 0x0df1, + 0x7994, 0x2186, + 0x799b, 0x2188, + 0x799d, 0x1708, + 0x79a6, 0x0694, + 0x79a7, 0x1709, + 0x79aa, 0x170b, + 0x79ae, 0x170c, + 0x79b0, 0x0cdf, + 0x79b1, 0x1e4e, + 0x79b3, 0x170d, + 0x79b9, 0x170e, + 0x79bd, 0x06d1, + 0x79be, 0x0553, + 0x79bf, 0x0c9d, + 0x79c0, 0x0932, + 0x79c1, 0x08b2, + 0x79c9, 0x1710, + 0x79cb, 0x0933, + 0x79d1, 0x054a, + 0x79d2, 0x0db5, + 0x79d5, 0x1711, + 0x79d8, 0x0d7f, + 0x79df, 0x0ac7, + 0x79e1, 0x1714, + 0x79e3, 0x1715, + 0x79e4, 0x0d1f, + 0x79e6, 0x0a07, + 0x79e7, 0x1712, + 0x79e9, 0x0b9f, + 0x79ec, 0x1713, + 0x79f0, 0x09b6, + 0x79fb, 0x04a0, + 0x7a00, 0x0643, + 0x7a08, 0x1716, + 0x7a0b, 0x0c14, + 0x7a0d, 0x1717, + 0x7a0e, 0x0a6b, + 0x7a14, 0x0eb9, + 0x7a17, 0x0d95, + 0x7a18, 0x1718, + 0x7a1a, 0x0b93, + 0x7a1c, 0x0f8f, + 0x7a1f, 0x171b, + 0x7a20, 0x171a, + 0x7a2e, 0x091b, + 0x7a31, 0x171d, + 0x7a32, 0x04b4, + 0x7a37, 0x1720, + 0x7a3b, 0x171e, + 0x7a3c, 0x0554, + 0x7a3d, 0x0724, + 0x7a3e, 0x171f, + 0x7a3f, 0x07d8, + 0x7a40, 0x0804, + 0x7a42, 0x0e36, + 0x7a43, 0x1721, + 0x7a46, 0x0e82, + 0x7a49, 0x1723, + 0x7a4d, 0x0a75, + 0x7a4e, 0x04f1, + 0x7a4f, 0x053a, + 0x7a50, 0x0470, + 0x7a57, 0x1722, + 0x7a61, 0x1724, + 0x7a63, 0x09df, + 0x7a69, 0x1726, + 0x7a6b, 0x05ad, + 0x7a70, 0x1728, + 0x7a74, 0x0740, + 0x7a76, 0x0680, + 0x7a79, 0x1729, + 0x7a7a, 0x06ed, + 0x7a7d, 0x172a, + 0x7a7f, 0x0aa0, + 0x7a81, 0x0ca5, + 0x7a83, 0x0a84, + 0x7a84, 0x0865, + 0x7a88, 0x172b, + 0x7a92, 0x0ba0, + 0x7a93, 0x0aed, + 0x7a95, 0x172d, + 0x7a96, 0x172f, + 0x7a97, 0x172c, + 0x7a98, 0x172e, + 0x7a9f, 0x06f8, + 0x7aa9, 0x1730, + 0x7aaa, 0x06fc, + 0x7aae, 0x0681, + 0x7aaf, 0x0f3c, + 0x7ab0, 0x1732, + 0x7ab6, 0x1733, + 0x7aba, 0x04d0, + 0x7abf, 0x1736, + 0x7ac3, 0x05d4, + 0x7ac4, 0x1735, + 0x7ac5, 0x1734, + 0x7ac7, 0x1738, + 0x7ac8, 0x1731, + 0x7aca, 0x1739, + 0x7acb, 0x0f71, + 0x7acd, 0x173a, + 0x7acf, 0x173b, + 0x7ad1, 0x2189, + 0x7ad2, 0x11c5, + 0x7ad3, 0x173d, + 0x7ad5, 0x173c, + 0x7ad9, 0x173e, + 0x7adc, 0x0f7d, + 0x7add, 0x1740, + 0x7adf, 0x1c08, + 0x7ae0, 0x09b7, + 0x7ae1, 0x1741, + 0x7ae3, 0x0961, + 0x7ae5, 0x0c90, + 0x7ae6, 0x1743, + 0x7ae7, 0x218a, + 0x7aea, 0x0b66, + 0x7aeb, 0x218c, + 0x7aed, 0x1744, + 0x7aef, 0x0b7a, + 0x7af0, 0x1745, + 0x7af6, 0x069d, + 0x7af8, 0x1076, + 0x7af9, 0x0b9b, + 0x7afa, 0x08df, + 0x7aff, 0x0604, + 0x7b02, 0x1746, + 0x7b04, 0x1753, + 0x7b06, 0x1749, + 0x7b08, 0x0682, + 0x7b0a, 0x1748, + 0x7b0b, 0x1755, + 0x7b0f, 0x1747, + 0x7b11, 0x09b8, + 0x7b18, 0x174b, + 0x7b1b, 0x0c25, + 0x7b1e, 0x174d, + 0x7b20, 0x05bc, + 0x7b25, 0x0a20, + 0x7b26, 0x0dd6, + 0x7b28, 0x174f, + 0x7b2c, 0x0b48, + 0x7b33, 0x174a, + 0x7b35, 0x174e, + 0x7b36, 0x1750, + 0x7b39, 0x086b, + 0x7b45, 0x1757, + 0x7b46, 0x0da0, + 0x7b48, 0x0d3a, + 0x7b49, 0x0c73, + 0x7b4b, 0x06d2, + 0x7b4c, 0x1756, + 0x7b4d, 0x1754, + 0x7b4f, 0x0d49, + 0x7b50, 0x1751, + 0x7b51, 0x0b9c, + 0x7b52, 0x0c75, + 0x7b54, 0x0c74, + 0x7b56, 0x0866, + 0x7b5d, 0x1769, + 0x7b65, 0x1759, + 0x7b67, 0x175b, + 0x7b6c, 0x175e, + 0x7b6e, 0x175f, + 0x7b70, 0x175c, + 0x7b74, 0x175a, + 0x7b75, 0x1758, + 0x7b7a, 0x1752, + 0x7b86, 0x0e1f, + 0x7b87, 0x0555, + 0x7b8b, 0x1766, + 0x7b8d, 0x1763, + 0x7b8f, 0x1768, + 0x7b92, 0x1767, + 0x7b94, 0x0d29, + 0x7b95, 0x0eb3, + 0x7b97, 0x0889, + 0x7b98, 0x1761, + 0x7b99, 0x176a, + 0x7b9a, 0x1765, + 0x7b9c, 0x1764, + 0x7b9d, 0x1760, + 0x7b9e, 0x218d, + 0x7b9f, 0x1762, + 0x7ba1, 0x0605, + 0x7baa, 0x0b7b, + 0x7bad, 0x0aa1, + 0x7bb1, 0x0d36, + 0x7bb4, 0x176f, + 0x7bb8, 0x0d38, + 0x7bc0, 0x0a85, + 0x7bc1, 0x176c, + 0x7bc4, 0x0d63, + 0x7bc6, 0x1770, + 0x7bc7, 0x0e23, + 0x7bc9, 0x0b99, + 0x7bcb, 0x176b, + 0x7bcc, 0x176d, + 0x7bcf, 0x176e, + 0x7bdd, 0x1771, + 0x7be0, 0x08f0, + 0x7be4, 0x0c9e, + 0x7be5, 0x1776, + 0x7be6, 0x1775, + 0x7be9, 0x1772, + 0x7bed, 0x0fdc, + 0x7bf3, 0x177b, + 0x7bf6, 0x177f, + 0x7bf7, 0x177c, + 0x7c00, 0x1778, + 0x7c07, 0x1779, + 0x7c0d, 0x177e, + 0x7c11, 0x1773, + 0x7c12, 0x10ea, + 0x7c13, 0x177a, + 0x7c14, 0x1774, + 0x7c17, 0x177d, + 0x7c1e, 0x1e3b, + 0x7c1f, 0x1783, + 0x7c21, 0x0606, + 0x7c23, 0x1780, + 0x7c27, 0x1781, + 0x7c2a, 0x1782, + 0x7c2b, 0x1785, + 0x7c37, 0x1784, + 0x7c38, 0x0d8a, + 0x7c3d, 0x1786, + 0x7c3e, 0x0fc4, + 0x7c3f, 0x0e3d, + 0x7c40, 0x178b, + 0x7c43, 0x1788, + 0x7c4c, 0x1787, + 0x7c4d, 0x0a76, + 0x7c4f, 0x178a, + 0x7c50, 0x178c, + 0x7c54, 0x1789, + 0x7c56, 0x1790, + 0x7c58, 0x178d, + 0x7c5f, 0x178e, + 0x7c60, 0x1777, + 0x7c64, 0x178f, + 0x7c65, 0x1791, + 0x7c6c, 0x1792, + 0x7c73, 0x0e16, + 0x7c75, 0x1793, + 0x7c7e, 0x0eee, + 0x7c81, 0x06c6, + 0x7c82, 0x06ff, + 0x7c83, 0x1794, + 0x7c89, 0x0e04, + 0x7c8b, 0x0a2e, + 0x7c8d, 0x0ebc, + 0x7c90, 0x1795, + 0x7c92, 0x0f7b, + 0x7c95, 0x0d2a, + 0x7c97, 0x0ac8, + 0x7c98, 0x0cea, + 0x7c9b, 0x0957, + 0x7c9f, 0x0484, + 0x7ca1, 0x179a, + 0x7ca2, 0x1798, + 0x7ca4, 0x1796, + 0x7ca5, 0x05dd, + 0x7ca7, 0x09b9, + 0x7ca8, 0x179b, + 0x7cab, 0x1799, + 0x7cad, 0x1797, + 0x7cae, 0x179f, + 0x7cb1, 0x179e, + 0x7cb2, 0x179d, + 0x7cb3, 0x179c, + 0x7cb9, 0x17a0, + 0x7cbd, 0x17a1, + 0x7cbe, 0x0a5e, + 0x7cc0, 0x17a2, + 0x7cc2, 0x17a4, + 0x7cc5, 0x17a3, + 0x7cca, 0x0786, + 0x7cce, 0x0aba, + 0x7cd2, 0x17a6, + 0x7cd6, 0x0c76, + 0x7cd8, 0x17a5, + 0x7cdc, 0x17a7, + 0x7cde, 0x0e05, + 0x7cdf, 0x0aee, + 0x7ce0, 0x07d9, + 0x7ce2, 0x17a8, + 0x7ce7, 0x0f90, + 0x7cef, 0x17aa, + 0x7cf2, 0x17ab, + 0x7cf4, 0x17ac, + 0x7cf6, 0x17ad, + 0x7cf8, 0x08b3, + 0x7cfa, 0x17ae, + 0x7cfb, 0x0725, + 0x7cfe, 0x0684, + 0x7d00, 0x0644, + 0x7d02, 0x17b0, + 0x7d04, 0x0eff, + 0x7d05, 0x07da, + 0x7d06, 0x17af, + 0x7d0a, 0x17b3, + 0x7d0b, 0x0ef2, + 0x7d0d, 0x0cf2, + 0x7d10, 0x0da5, + 0x7d14, 0x096d, + 0x7d15, 0x17b2, + 0x7d17, 0x08ff, + 0x7d18, 0x07db, + 0x7d19, 0x08b4, + 0x7d1a, 0x0683, + 0x7d1b, 0x0e06, + 0x7d1c, 0x17b1, + 0x7d20, 0x0ac9, + 0x7d21, 0x0e70, + 0x7d22, 0x0867, + 0x7d2b, 0x08b5, + 0x7d2c, 0x0bf9, + 0x7d2e, 0x17b6, + 0x7d2f, 0x0fa7, + 0x7d30, 0x0849, + 0x7d32, 0x17b7, + 0x7d33, 0x0a08, + 0x7d35, 0x17b9, + 0x7d39, 0x09ba, + 0x7d3a, 0x0820, + 0x7d3f, 0x17b8, + 0x7d42, 0x0934, + 0x7d43, 0x0772, + 0x7d44, 0x0aca, + 0x7d45, 0x17b4, + 0x7d46, 0x17ba, + 0x7d48, 0x218f, + 0x7d4b, 0x17b5, + 0x7d4c, 0x0726, + 0x7d4e, 0x17bd, + 0x7d4f, 0x17c1, + 0x7d50, 0x0741, + 0x7d56, 0x17bc, + 0x7d5b, 0x17c5, + 0x7d5c, 0x2190, + 0x7d5e, 0x07dc, + 0x7d61, 0x0f57, + 0x7d62, 0x0480, + 0x7d63, 0x17c2, + 0x7d66, 0x0685, + 0x7d68, 0x17bf, + 0x7d6e, 0x17c0, + 0x7d71, 0x0c77, + 0x7d72, 0x17be, + 0x7d73, 0x17bb, + 0x7d75, 0x0586, + 0x7d76, 0x0a88, + 0x7d79, 0x075c, + 0x7d7d, 0x17c7, + 0x7d89, 0x17c4, + 0x7d8f, 0x17c6, + 0x7d93, 0x17c3, + 0x7d99, 0x0727, + 0x7d9a, 0x0b13, + 0x7d9b, 0x17c8, + 0x7d9c, 0x0af0, + 0x7d9f, 0x17d5, + 0x7da0, 0x2192, + 0x7da2, 0x17d1, + 0x7da3, 0x17cb, + 0x7dab, 0x17cf, + 0x7dac, 0x0926, + 0x7dad, 0x04a1, + 0x7dae, 0x17ca, + 0x7daf, 0x17d2, + 0x7db0, 0x17d6, + 0x7db1, 0x07dd, + 0x7db2, 0x0ee2, + 0x7db4, 0x0bf2, + 0x7db5, 0x17cc, + 0x7db7, 0x2191, + 0x7db8, 0x17d4, + 0x7dba, 0x17c9, + 0x7dbb, 0x0b7c, + 0x7dbd, 0x17ce, + 0x7dbe, 0x0481, + 0x7dbf, 0x0ed6, + 0x7dc7, 0x17cd, + 0x7dca, 0x06d3, + 0x7dcb, 0x0d80, + 0x7dcf, 0x0aef, + 0x7dd1, 0x0f98, + 0x7dd2, 0x0979, + 0x7dd5, 0x17fd, + 0x7dd6, 0x2193, + 0x7dd8, 0x17d7, + 0x7dda, 0x0aa2, + 0x7ddc, 0x17d3, + 0x7ddd, 0x17d8, + 0x7dde, 0x17da, + 0x7de0, 0x0c15, + 0x7de1, 0x17dd, + 0x7de4, 0x17d9, + 0x7de8, 0x0e24, + 0x7de9, 0x0607, + 0x7dec, 0x0ed7, + 0x7def, 0x04a2, + 0x7df2, 0x17dc, + 0x7df4, 0x0fc5, + 0x7dfb, 0x17db, + 0x7e01, 0x0511, + 0x7e04, 0x0cc4, + 0x7e05, 0x17de, + 0x7e09, 0x17e5, + 0x7e0a, 0x17df, + 0x7e0b, 0x17e6, + 0x7e12, 0x17e2, + 0x7e1b, 0x0d31, + 0x7e1e, 0x08f6, + 0x7e1f, 0x17e4, + 0x7e21, 0x17e1, + 0x7e22, 0x17e7, + 0x7e23, 0x17e0, + 0x7e26, 0x094e, + 0x7e2b, 0x0e53, + 0x7e2e, 0x0956, + 0x7e31, 0x17e3, + 0x7e32, 0x17ef, + 0x7e35, 0x17eb, + 0x7e37, 0x17ee, + 0x7e39, 0x17ec, + 0x7e3a, 0x17f0, + 0x7e3b, 0x17ea, + 0x7e3d, 0x17d0, + 0x7e3e, 0x0a77, + 0x7e41, 0x0d5f, + 0x7e43, 0x17ed, + 0x7e46, 0x17e8, + 0x7e4a, 0x0aa3, + 0x7e4b, 0x0728, + 0x7e4d, 0x0935, + 0x7e52, 0x2194, + 0x7e54, 0x09eb, + 0x7e55, 0x0ab8, + 0x7e56, 0x17f3, + 0x7e59, 0x17f5, + 0x7e5d, 0x17f2, + 0x7e5e, 0x17f4, + 0x7e61, 0x1e11, + 0x7e66, 0x17e9, + 0x7e67, 0x17f1, + 0x7e69, 0x17f9, + 0x7e6a, 0x17f8, + 0x7e6b, 0x1df7, + 0x7e6d, 0x0ea8, + 0x7e70, 0x0701, + 0x7e79, 0x17f7, + 0x7e7b, 0x17fb, + 0x7e7c, 0x17fa, + 0x7e7d, 0x17fe, + 0x7e7f, 0x1800, + 0x7e82, 0x088a, + 0x7e83, 0x17fc, + 0x7e88, 0x1801, + 0x7e8a, 0x20a7, + 0x7e8c, 0x1803, + 0x7e8e, 0x1809, + 0x7e8f, 0x0c35, + 0x7e90, 0x1805, + 0x7e92, 0x1804, + 0x7e93, 0x1806, + 0x7e96, 0x1808, + 0x7e9b, 0x180a, + 0x7f36, 0x0608, + 0x7f38, 0x180c, + 0x7f3a, 0x180d, + 0x7f45, 0x180e, + 0x7f47, 0x2195, + 0x7f4c, 0x180f, + 0x7f50, 0x1812, + 0x7f54, 0x1815, + 0x7f55, 0x1814, + 0x7f58, 0x1816, + 0x7f5f, 0x1817, + 0x7f67, 0x181b, + 0x7f68, 0x1819, + 0x7f6a, 0x0851, + 0x7f6b, 0x0729, + 0x7f6e, 0x0b94, + 0x7f70, 0x0d47, + 0x7f72, 0x097a, + 0x7f75, 0x0d03, + 0x7f77, 0x0d81, + 0x7f78, 0x181c, + 0x7f79, 0x1336, + 0x7f82, 0x181d, + 0x7f83, 0x181f, + 0x7f85, 0x0f4f, + 0x7f86, 0x181e, + 0x7f87, 0x1821, + 0x7f88, 0x1820, + 0x7f8a, 0x0f3d, + 0x7f8c, 0x1822, + 0x7f8e, 0x0d92, + 0x7f94, 0x1823, + 0x7f9a, 0x1826, + 0x7f9d, 0x1825, + 0x7f9e, 0x1824, + 0x7fa1, 0x2196, + 0x7fa3, 0x1827, + 0x7fa4, 0x0708, + 0x7fa8, 0x0aa4, + 0x7fa9, 0x065b, + 0x7fae, 0x182b, + 0x7faf, 0x1828, + 0x7fb2, 0x1829, + 0x7fb6, 0x182c, + 0x7fb8, 0x182d, + 0x7fb9, 0x182a, + 0x7fbd, 0x04cb, + 0x7fc1, 0x0527, + 0x7fc5, 0x182f, + 0x7fca, 0x1831, + 0x7fcc, 0x0f4c, + 0x7fd2, 0x0936, + 0x7fd4, 0x1833, + 0x7fd5, 0x1832, + 0x7fe0, 0x0a2f, + 0x7fe1, 0x1834, + 0x7fe6, 0x1835, + 0x7fe9, 0x1836, + 0x7feb, 0x0621, + 0x7ff0, 0x0609, + 0x7ff3, 0x1837, + 0x7ff9, 0x1838, + 0x7ffb, 0x0e8b, + 0x7ffc, 0x0f4d, + 0x8000, 0x0f3e, + 0x8001, 0x0fdd, + 0x8003, 0x07df, + 0x8004, 0x183b, + 0x8005, 0x0900, + 0x8006, 0x183a, + 0x800b, 0x183c, + 0x800c, 0x08d5, + 0x8010, 0x0b31, + 0x8012, 0x183d, + 0x8015, 0x07de, + 0x8017, 0x0ee3, + 0x8018, 0x183e, + 0x801c, 0x1840, + 0x8021, 0x1841, + 0x8028, 0x1842, + 0x8033, 0x08d6, + 0x8036, 0x0ef9, + 0x803b, 0x1844, + 0x803d, 0x0b7d, + 0x803f, 0x1843, + 0x8046, 0x1846, + 0x804a, 0x1845, + 0x8052, 0x1847, + 0x8056, 0x0a5f, + 0x8058, 0x1848, + 0x805a, 0x1849, + 0x805e, 0x0e09, + 0x805f, 0x184a, + 0x8061, 0x0af1, + 0x8062, 0x184b, + 0x8068, 0x184c, + 0x806f, 0x0fc6, + 0x8070, 0x184f, + 0x8072, 0x184e, + 0x8073, 0x184d, + 0x8074, 0x0bcc, + 0x8076, 0x1850, + 0x8077, 0x09ec, + 0x8079, 0x1851, + 0x807d, 0x1852, + 0x807e, 0x0fde, + 0x807f, 0x1853, + 0x8084, 0x1854, + 0x8085, 0x1856, + 0x8086, 0x1855, + 0x8087, 0x0d39, + 0x8089, 0x0cd1, + 0x808b, 0x0fe4, + 0x808c, 0x0d3d, + 0x8093, 0x1858, + 0x8096, 0x09bb, + 0x8098, 0x0d9c, + 0x809a, 0x1859, + 0x809b, 0x1857, + 0x809d, 0x060a, + 0x80a1, 0x0788, + 0x80a2, 0x08b6, + 0x80a5, 0x0d82, + 0x80a9, 0x075e, + 0x80aa, 0x0e71, + 0x80ac, 0x185c, + 0x80ad, 0x185a, + 0x80af, 0x07e0, + 0x80b1, 0x07e1, + 0x80b2, 0x04ad, + 0x80b4, 0x0858, + 0x80ba, 0x0d0f, + 0x80c3, 0x04a3, + 0x80c4, 0x1861, + 0x80c6, 0x0b7e, + 0x80cc, 0x0d0e, + 0x80ce, 0x0b3b, + 0x80d6, 0x1863, + 0x80d9, 0x185f, + 0x80da, 0x1862, + 0x80db, 0x185d, + 0x80dd, 0x1860, + 0x80de, 0x0e54, + 0x80e1, 0x0789, + 0x80e4, 0x04c1, + 0x80e5, 0x185e, + 0x80ef, 0x1865, + 0x80f1, 0x1866, + 0x80f4, 0x0c91, + 0x80f8, 0x06b3, + 0x80fc, 0x1871, + 0x80fd, 0x0cf3, + 0x8102, 0x08b7, + 0x8105, 0x06b4, + 0x8106, 0x0a6c, + 0x8107, 0x0fec, + 0x8108, 0x0eba, + 0x8109, 0x1864, + 0x810a, 0x0a78, + 0x811a, 0x066d, + 0x811b, 0x1867, + 0x8123, 0x1869, + 0x8129, 0x1868, + 0x812f, 0x186a, + 0x8131, 0x0b64, + 0x8133, 0x0cf4, + 0x8139, 0x0bcd, + 0x813e, 0x186e, + 0x8146, 0x186d, + 0x814b, 0x186b, + 0x814e, 0x0a1b, + 0x8150, 0x0dd7, + 0x8151, 0x1870, + 0x8153, 0x186f, + 0x8154, 0x07e2, + 0x8155, 0x0ff9, + 0x815f, 0x1880, + 0x8165, 0x1874, + 0x816b, 0x091c, + 0x816e, 0x1873, + 0x8170, 0x080a, + 0x8171, 0x1872, + 0x8174, 0x1876, + 0x8178, 0x0bce, + 0x8179, 0x0df2, + 0x817a, 0x0aa5, + 0x817f, 0x0b3c, + 0x8180, 0x187a, + 0x8182, 0x187b, + 0x8183, 0x1877, + 0x8188, 0x1878, + 0x818a, 0x1879, + 0x818f, 0x07e3, + 0x8193, 0x1881, + 0x8195, 0x187d, + 0x819a, 0x0dd8, + 0x819c, 0x0e9a, + 0x819d, 0x0d9a, + 0x81a0, 0x187c, + 0x81a3, 0x187f, + 0x81a4, 0x187e, + 0x81a8, 0x0e72, + 0x81a9, 0x1882, + 0x81b0, 0x1883, + 0x81b3, 0x0ab9, + 0x81b5, 0x1884, + 0x81b8, 0x1886, + 0x81ba, 0x188a, + 0x81bd, 0x1887, + 0x81be, 0x1885, + 0x81bf, 0x0cf5, + 0x81c0, 0x1888, + 0x81c2, 0x1889, + 0x81c6, 0x0532, + 0x81c8, 0x1890, + 0x81c9, 0x188b, + 0x81cd, 0x188c, + 0x81d1, 0x188d, + 0x81d3, 0x0b01, + 0x81d8, 0x188f, + 0x81d9, 0x188e, + 0x81da, 0x1891, + 0x81df, 0x1892, + 0x81e3, 0x0a09, + 0x81e5, 0x0569, + 0x81e7, 0x1894, + 0x81e8, 0x0f9f, + 0x81ea, 0x08d7, + 0x81ed, 0x0937, + 0x81f3, 0x08b8, + 0x81f4, 0x0b95, + 0x81fa, 0x1895, + 0x81fc, 0x04d3, + 0x81fe, 0x1897, + 0x8201, 0x1898, + 0x8205, 0x189a, + 0x8207, 0x189b, + 0x8208, 0x06b5, + 0x8209, 0x13af, + 0x820a, 0x189c, + 0x820c, 0x0a89, + 0x820d, 0x189d, + 0x820e, 0x08f7, + 0x8210, 0x189e, + 0x8212, 0x1009, + 0x8216, 0x189f, + 0x8217, 0x0e2e, + 0x8218, 0x0618, + 0x821b, 0x0aa6, + 0x821c, 0x0962, + 0x821e, 0x0de3, + 0x821f, 0x0938, + 0x8229, 0x18a0, + 0x822a, 0x07e4, + 0x822b, 0x18a1, + 0x822c, 0x0d60, + 0x822e, 0x18af, + 0x8233, 0x18a3, + 0x8235, 0x0b29, + 0x8236, 0x0d2b, + 0x8237, 0x0773, + 0x8238, 0x18a2, + 0x8239, 0x0aa7, + 0x8240, 0x18a4, + 0x8247, 0x0c16, + 0x8258, 0x18a6, + 0x8259, 0x18a5, + 0x825a, 0x18a8, + 0x825d, 0x18a7, + 0x825f, 0x18a9, + 0x8262, 0x18ab, + 0x8264, 0x18aa, + 0x8266, 0x060b, + 0x8268, 0x18ac, + 0x826a, 0x18ad, + 0x826e, 0x0821, + 0x826f, 0x0f91, + 0x8271, 0x18b0, + 0x8272, 0x09ed, + 0x8276, 0x0512, + 0x8277, 0x18b1, + 0x827e, 0x18b3, + 0x828b, 0x04b6, + 0x828d, 0x18b4, + 0x8292, 0x18b5, + 0x8299, 0x0dd9, + 0x829d, 0x08f3, + 0x829f, 0x18b7, + 0x82a5, 0x0587, + 0x82a6, 0x0476, + 0x82ab, 0x18b6, + 0x82ac, 0x18b9, + 0x82ad, 0x0d04, + 0x82af, 0x0a0a, + 0x82b1, 0x0556, + 0x82b3, 0x0e55, + 0x82b8, 0x0733, + 0x82b9, 0x06d4, + 0x82bb, 0x18b8, + 0x82bd, 0x056a, + 0x82c5, 0x05df, + 0x82d1, 0x0513, + 0x82d2, 0x18bd, + 0x82d3, 0x0fb2, + 0x82d4, 0x0b3d, + 0x82d7, 0x0db6, + 0x82d9, 0x18c9, + 0x82db, 0x0557, + 0x82dc, 0x18c7, + 0x82de, 0x18c5, + 0x82df, 0x18bc, + 0x82e1, 0x18ba, + 0x82e3, 0x18bb, + 0x82e5, 0x090f, + 0x82e6, 0x06e4, + 0x82e7, 0x0bb5, + 0x82eb, 0x0ca9, + 0x82f1, 0x04f3, + 0x82f3, 0x18bf, + 0x82f4, 0x18be, + 0x82f9, 0x18c4, + 0x82fa, 0x18c0, + 0x82fb, 0x18c3, + 0x8301, 0x2198, + 0x8302, 0x0edc, + 0x8303, 0x18c2, + 0x8304, 0x0558, + 0x8305, 0x05db, + 0x8306, 0x18c6, + 0x8309, 0x18c8, + 0x830e, 0x072a, + 0x8316, 0x18cc, + 0x8317, 0x18d5, + 0x831c, 0x046f, + 0x8323, 0x18dd, + 0x8328, 0x04b5, + 0x832b, 0x18d4, + 0x832f, 0x18d3, + 0x8331, 0x18ce, + 0x8332, 0x18cd, + 0x8334, 0x18cb, + 0x8335, 0x18ca, + 0x8336, 0x0ba1, + 0x8338, 0x0b5b, + 0x8339, 0x18d0, + 0x8340, 0x18cf, + 0x8345, 0x18d2, + 0x8349, 0x0af2, + 0x834a, 0x072b, + 0x834f, 0x04e3, + 0x8350, 0x18d1, + 0x8352, 0x07e5, + 0x8358, 0x0af3, + 0x8362, 0x2199, + 0x8373, 0x18e3, + 0x8375, 0x18e4, + 0x8377, 0x0559, + 0x837b, 0x052e, + 0x837c, 0x18e1, + 0x837f, 0x219a, + 0x8385, 0x18d7, + 0x8387, 0x18df, + 0x8389, 0x18e6, + 0x838a, 0x18e0, + 0x838e, 0x18de, + 0x8393, 0x18c1, + 0x8396, 0x18dc, + 0x839a, 0x18d8, + 0x839e, 0x060c, + 0x839f, 0x18da, + 0x83a0, 0x18e5, + 0x83a2, 0x18db, + 0x83a8, 0x18e7, + 0x83aa, 0x18d9, + 0x83ab, 0x0d32, + 0x83b1, 0x0f53, + 0x83b5, 0x18e2, + 0x83bd, 0x18f8, + 0x83c1, 0x18f0, + 0x83c5, 0x0a41, + 0x83c7, 0x219b, + 0x83ca, 0x0660, + 0x83cc, 0x06d5, + 0x83ce, 0x18eb, + 0x83d3, 0x055b, + 0x83d6, 0x09bc, + 0x83d8, 0x18ee, + 0x83dc, 0x084a, + 0x83df, 0x0c4b, + 0x83e0, 0x18f3, + 0x83e9, 0x0e3e, + 0x83eb, 0x18ea, + 0x83ef, 0x055a, + 0x83f0, 0x078a, + 0x83f1, 0x0d9b, + 0x83f2, 0x18f4, + 0x83f4, 0x18e8, + 0x83f6, 0x219c, + 0x83f7, 0x18f1, + 0x83fb, 0x18fb, + 0x83fd, 0x18ec, + 0x8403, 0x18ed, + 0x8404, 0x0c92, + 0x8407, 0x18f2, + 0x840a, 0x1e7f, + 0x840b, 0x18ef, + 0x840c, 0x0e56, + 0x840d, 0x18f5, + 0x840e, 0x04a4, + 0x8413, 0x18e9, + 0x8420, 0x18f7, + 0x8422, 0x18f6, + 0x8429, 0x0d21, + 0x842a, 0x18fd, + 0x842c, 0x1908, + 0x8431, 0x05dc, + 0x8435, 0x190b, + 0x8438, 0x18f9, + 0x843c, 0x18fe, + 0x843d, 0x0f58, + 0x8446, 0x1907, + 0x8448, 0x219d, + 0x8449, 0x0f3f, + 0x844e, 0x0f72, + 0x8457, 0x0bb6, + 0x845b, 0x05c9, + 0x8461, 0x0de4, + 0x8462, 0x190d, + 0x8463, 0x0c79, + 0x8466, 0x0475, + 0x8469, 0x1906, + 0x846b, 0x1902, + 0x846c, 0x0af4, + 0x846d, 0x18fc, + 0x846e, 0x1904, + 0x846f, 0x1909, + 0x8471, 0x0ce2, + 0x8475, 0x046e, + 0x8477, 0x1901, + 0x8479, 0x190a, + 0x847a, 0x0dea, + 0x8482, 0x1905, + 0x8484, 0x1900, + 0x848b, 0x09bd, + 0x8490, 0x0939, + 0x8494, 0x08d8, + 0x8499, 0x0ee4, + 0x849c, 0x0db9, + 0x849f, 0x1910, + 0x84a1, 0x1919, + 0x84ad, 0x1903, + 0x84b2, 0x05d5, + 0x84b4, 0x219e, + 0x84b8, 0x09e0, + 0x84b9, 0x190e, + 0x84bb, 0x1913, + 0x84bc, 0x0af5, + 0x84bf, 0x190f, + 0x84c1, 0x1916, + 0x84c4, 0x0b9d, + 0x84c6, 0x1917, + 0x84c9, 0x0f40, + 0x84ca, 0x190c, + 0x84cb, 0x0596, + 0x84cd, 0x1912, + 0x84d0, 0x1915, + 0x84d1, 0x0eb8, + 0x84d6, 0x1918, + 0x84d9, 0x1911, + 0x84da, 0x1914, + 0x84dc, 0x20ab, + 0x84ec, 0x0e57, + 0x84ee, 0x0fc7, + 0x84f4, 0x191c, + 0x84fc, 0x1923, + 0x84ff, 0x191b, + 0x8500, 0x08ef, + 0x8506, 0x18fa, + 0x8511, 0x0e1e, + 0x8513, 0x0eae, + 0x8514, 0x1922, + 0x8515, 0x1921, + 0x8517, 0x191d, + 0x851a, 0x04d8, + 0x851f, 0x1920, + 0x8521, 0x191a, + 0x8523, 0x1e1a, + 0x8526, 0x0bf1, + 0x852c, 0x191f, + 0x852d, 0x04c2, + 0x8535, 0x0b02, + 0x853d, 0x0e13, + 0x853e, 0x1eb5, + 0x8540, 0x1924, + 0x8541, 0x1928, + 0x8543, 0x0d6d, + 0x8548, 0x1927, + 0x8549, 0x09be, + 0x854a, 0x08f5, + 0x854b, 0x192a, + 0x854e, 0x06b6, + 0x8553, 0x219f, + 0x8555, 0x192b, + 0x8557, 0x0deb, + 0x8558, 0x1926, + 0x8559, 0x21a0, + 0x855a, 0x18ff, + 0x8563, 0x1925, + 0x8568, 0x0ff5, + 0x8569, 0x0c7a, + 0x856a, 0x0de5, + 0x856b, 0x21a1, + 0x856d, 0x1932, + 0x8577, 0x1938, + 0x857e, 0x1939, + 0x8580, 0x192c, + 0x8584, 0x0d2c, + 0x8587, 0x1936, + 0x8588, 0x192e, + 0x858a, 0x1930, + 0x8590, 0x193a, + 0x8591, 0x192f, + 0x8594, 0x1933, + 0x8597, 0x0514, + 0x8599, 0x0cbd, + 0x859b, 0x1934, + 0x859c, 0x1937, + 0x85a4, 0x192d, + 0x85a6, 0x0aa8, + 0x85a8, 0x1931, + 0x85a9, 0x0875, + 0x85aa, 0x0a0b, + 0x85ab, 0x0706, + 0x85ac, 0x0f00, + 0x85ae, 0x0f05, + 0x85af, 0x097c, + 0x85b0, 0x21a3, + 0x85b9, 0x193e, + 0x85ba, 0x193c, + 0x85c1, 0x0ff4, + 0x85c9, 0x193b, + 0x85cd, 0x0f5f, + 0x85cf, 0x193d, + 0x85d0, 0x193f, + 0x85d5, 0x1940, + 0x85dc, 0x1943, + 0x85dd, 0x1941, + 0x85e4, 0x0c7b, + 0x85e5, 0x1942, + 0x85e9, 0x0d61, + 0x85ea, 0x1935, + 0x85f7, 0x097d, + 0x85f9, 0x1944, + 0x85fa, 0x1949, + 0x85fb, 0x0af6, + 0x85fe, 0x1948, + 0x8602, 0x1929, + 0x8606, 0x194a, + 0x8607, 0x0acb, + 0x860a, 0x1945, + 0x860b, 0x1947, + 0x8613, 0x1946, + 0x8616, 0x14d0, + 0x8617, 0x14c1, + 0x861a, 0x194c, + 0x8622, 0x194b, + 0x862d, 0x0f60, + 0x862f, 0x16b1, + 0x8630, 0x194d, + 0x863f, 0x194e, + 0x864d, 0x194f, + 0x864e, 0x078b, + 0x8650, 0x066e, + 0x8654, 0x1951, + 0x8655, 0x1094, + 0x865a, 0x068f, + 0x865c, 0x0f82, + 0x865e, 0x06eb, + 0x865f, 0x1952, + 0x8667, 0x1953, + 0x866b, 0x0bac, + 0x8671, 0x1954, + 0x8679, 0x0cd2, + 0x867b, 0x047e, + 0x868a, 0x0563, + 0x868b, 0x1959, + 0x8693, 0x1955, + 0x8695, 0x088b, + 0x86a3, 0x1956, + 0x86a4, 0x0cf8, + 0x86a9, 0x1957, + 0x86ab, 0x1962, + 0x86af, 0x195c, + 0x86b0, 0x195f, + 0x86b6, 0x195b, + 0x86c4, 0x195d, + 0x86c6, 0x195e, + 0x86c7, 0x0904, + 0x86c9, 0x1960, + 0x86cb, 0x0b7f, + 0x86cd, 0x072c, + 0x86ce, 0x05a0, + 0x86d4, 0x1963, + 0x86d9, 0x059d, + 0x86db, 0x1968, + 0x86de, 0x1964, + 0x86df, 0x1967, + 0x86e4, 0x0d4e, + 0x86e9, 0x1965, + 0x86ec, 0x1966, + 0x86ed, 0x0dba, + 0x86ee, 0x0d6e, + 0x86ef, 0x1969, + 0x86f8, 0x0b5d, + 0x86f9, 0x1973, + 0x86fb, 0x196f, + 0x86fe, 0x056b, + 0x8700, 0x196d, + 0x8702, 0x0e58, + 0x8703, 0x196e, + 0x8706, 0x196b, + 0x8708, 0x196c, + 0x8709, 0x1971, + 0x870a, 0x1974, + 0x870d, 0x1972, + 0x8711, 0x1970, + 0x8712, 0x196a, + 0x8718, 0x0b96, + 0x871a, 0x197b, + 0x871c, 0x0eb6, + 0x8725, 0x1979, + 0x8729, 0x197a, + 0x8734, 0x1975, + 0x8737, 0x1977, + 0x873b, 0x1978, + 0x873f, 0x1976, + 0x8749, 0x0a8a, + 0x874b, 0x0fdf, + 0x874c, 0x197f, + 0x874e, 0x1980, + 0x8753, 0x1986, + 0x8755, 0x09f0, + 0x8757, 0x1982, + 0x8759, 0x1985, + 0x875f, 0x197d, + 0x8760, 0x197c, + 0x8763, 0x1987, + 0x8766, 0x055c, + 0x8768, 0x1983, + 0x876a, 0x1988, + 0x876e, 0x1984, + 0x8774, 0x1981, + 0x8776, 0x0bcf, + 0x8778, 0x197e, + 0x877f, 0x0d1e, + 0x8782, 0x198c, + 0x878d, 0x0f25, + 0x879f, 0x198b, + 0x87a2, 0x198a, + 0x87ab, 0x1993, + 0x87af, 0x198d, + 0x87b3, 0x1995, + 0x87ba, 0x0f50, + 0x87bb, 0x1998, + 0x87bd, 0x198f, + 0x87c0, 0x1990, + 0x87c4, 0x1994, + 0x87c6, 0x1997, + 0x87c7, 0x1996, + 0x87cb, 0x198e, + 0x87d0, 0x1991, + 0x87d2, 0x19a2, + 0x87e0, 0x199b, + 0x87ec, 0x1e23, + 0x87ef, 0x1999, + 0x87f2, 0x199a, + 0x87f6, 0x199f, + 0x87f9, 0x0588, + 0x87fb, 0x065c, + 0x87fe, 0x199e, + 0x8805, 0x1989, + 0x8807, 0x21a6, + 0x880d, 0x199d, + 0x880e, 0x19a1, + 0x880f, 0x199c, + 0x8811, 0x19a3, + 0x8815, 0x19a5, + 0x8816, 0x19a4, + 0x881f, 0x1e85, + 0x8821, 0x19a7, + 0x8822, 0x19a6, + 0x8823, 0x1961, + 0x8827, 0x19ab, + 0x8831, 0x19a8, + 0x8836, 0x19a9, + 0x8839, 0x19aa, + 0x883b, 0x19ac, + 0x8840, 0x0742, + 0x8842, 0x19ae, + 0x8844, 0x19ad, + 0x8846, 0x093a, + 0x884c, 0x07e6, + 0x884d, 0x1524, + 0x8852, 0x19af, + 0x8853, 0x095b, + 0x8857, 0x0597, + 0x8859, 0x19b0, + 0x885b, 0x04f4, + 0x885d, 0x09bf, + 0x885e, 0x19b1, + 0x8861, 0x07e7, + 0x8862, 0x19b2, + 0x8863, 0x04a5, + 0x8868, 0x0daf, + 0x886b, 0x19b3, + 0x8870, 0x0a30, + 0x8872, 0x19ba, + 0x8875, 0x19b7, + 0x8877, 0x0bad, + 0x887d, 0x19b8, + 0x887e, 0x19b5, + 0x887f, 0x06d6, + 0x8881, 0x19b4, + 0x8882, 0x19bb, + 0x8888, 0x070c, + 0x888b, 0x0b3e, + 0x888d, 0x19c1, + 0x8892, 0x19bd, + 0x8896, 0x0b15, + 0x8897, 0x19bc, + 0x8899, 0x19bf, + 0x889e, 0x19b6, + 0x88a2, 0x19c0, + 0x88a4, 0x19c2, + 0x88ab, 0x0d83, + 0x88ae, 0x19be, + 0x88b0, 0x19c3, + 0x88b1, 0x19c5, + 0x88b4, 0x0787, + 0x88b5, 0x19b9, + 0x88b7, 0x0485, + 0x88bf, 0x19c4, + 0x88c1, 0x084b, + 0x88c2, 0x0fbe, + 0x88c3, 0x19c6, + 0x88c5, 0x0af7, + 0x88cf, 0x0f6a, + 0x88d4, 0x19c8, + 0x88d5, 0x0f1f, + 0x88d8, 0x19c9, + 0x88dc, 0x0e34, + 0x88dd, 0x19cb, + 0x88df, 0x0830, + 0x88e1, 0x0f6b, + 0x88e8, 0x19d0, + 0x88f2, 0x19d1, + 0x88f3, 0x09c0, + 0x88f4, 0x19cf, + 0x88f5, 0x21a7, + 0x88f8, 0x0f51, + 0x88f9, 0x19cc, + 0x88fc, 0x19ce, + 0x88fd, 0x0a61, + 0x88fe, 0x0a44, + 0x8902, 0x19cd, + 0x8904, 0x19d2, + 0x8907, 0x0df3, + 0x890a, 0x19d4, + 0x890c, 0x19d3, + 0x8910, 0x05ca, + 0x8912, 0x0e59, + 0x8913, 0x19d5, + 0x891c, 0x20a8, + 0x891d, 0x19e1, + 0x891e, 0x19d7, + 0x8925, 0x19d8, + 0x892a, 0x19d9, + 0x8936, 0x19de, + 0x8938, 0x19df, + 0x893b, 0x19dd, + 0x8941, 0x19db, + 0x8943, 0x19d6, + 0x8944, 0x19dc, + 0x894c, 0x19e0, + 0x894d, 0x1bd0, + 0x8956, 0x0528, + 0x895e, 0x19e3, + 0x895f, 0x06d7, + 0x8960, 0x19e2, + 0x8964, 0x19e5, + 0x8966, 0x19e4, + 0x896a, 0x19e7, + 0x896d, 0x19e6, + 0x896f, 0x19e8, + 0x8972, 0x093b, + 0x8974, 0x19e9, + 0x8977, 0x19ea, + 0x897e, 0x19eb, + 0x897f, 0x0a62, + 0x8981, 0x0f41, + 0x8983, 0x19ec, + 0x8986, 0x0df4, + 0x8987, 0x0cfc, + 0x8988, 0x19ed, + 0x898a, 0x19ee, + 0x898b, 0x075f, + 0x898f, 0x0646, + 0x8993, 0x19ef, + 0x8996, 0x08b9, + 0x8997, 0x0cf7, + 0x8998, 0x19f0, + 0x899a, 0x05ae, + 0x89a1, 0x19f1, + 0x89a6, 0x19f3, + 0x89a7, 0x0f61, + 0x89a9, 0x19f2, + 0x89aa, 0x0a0c, + 0x89ac, 0x19f4, + 0x89af, 0x19f5, + 0x89b2, 0x19f6, + 0x89b3, 0x060d, + 0x89ba, 0x19f7, + 0x89bd, 0x19f8, + 0x89bf, 0x19f9, + 0x89d2, 0x05af, + 0x89da, 0x19fb, + 0x89dc, 0x19fc, + 0x89e3, 0x0572, + 0x89e6, 0x09ee, + 0x89e7, 0x19fe, + 0x89f4, 0x19ff, + 0x89f8, 0x1a00, + 0x8a00, 0x0774, + 0x8a02, 0x0c17, + 0x8a03, 0x1a01, + 0x8a08, 0x072d, + 0x8a0a, 0x0a1c, + 0x8a0c, 0x1a04, + 0x8a0e, 0x0c7c, + 0x8a10, 0x1a03, + 0x8a12, 0x21a8, + 0x8a13, 0x0707, + 0x8a16, 0x1a02, + 0x8a17, 0x0b57, + 0x8a18, 0x0647, + 0x8a1b, 0x1a05, + 0x8a1d, 0x1a06, + 0x8a1f, 0x09c1, + 0x8a23, 0x0743, + 0x8a25, 0x1a07, + 0x8a2a, 0x0e5a, + 0x8a2d, 0x0a83, + 0x8a31, 0x0690, + 0x8a33, 0x0f01, + 0x8a34, 0x0acc, + 0x8a36, 0x1a08, + 0x8a37, 0x21a9, + 0x8a3a, 0x0a0d, + 0x8a3b, 0x0bae, + 0x8a3c, 0x09c2, + 0x8a41, 0x1a09, + 0x8a46, 0x1a0c, + 0x8a48, 0x1a0d, + 0x8a50, 0x082e, + 0x8a51, 0x0b22, + 0x8a52, 0x1a0b, + 0x8a54, 0x09c3, + 0x8a55, 0x0db0, + 0x8a5b, 0x1a0a, + 0x8a5e, 0x08ba, + 0x8a60, 0x04f5, + 0x8a62, 0x1a11, + 0x8a63, 0x072e, + 0x8a66, 0x08bc, + 0x8a69, 0x08bb, + 0x8a6b, 0x0ff3, + 0x8a6c, 0x1a10, + 0x8a6d, 0x1a0f, + 0x8a6e, 0x0aa9, + 0x8a70, 0x0667, + 0x8a71, 0x0fe9, + 0x8a72, 0x0598, + 0x8a73, 0x09c4, + 0x8a79, 0x21aa, + 0x8a7c, 0x1a0e, + 0x8a82, 0x1a13, + 0x8a84, 0x1a14, + 0x8a85, 0x1a12, + 0x8a87, 0x078c, + 0x8a89, 0x0f2a, + 0x8a8c, 0x08bd, + 0x8a8d, 0x0cdd, + 0x8a91, 0x1a17, + 0x8a93, 0x0a64, + 0x8a95, 0x0b80, + 0x8a98, 0x0f20, + 0x8a9a, 0x1a1a, + 0x8a9e, 0x07a0, + 0x8aa0, 0x0a63, + 0x8aa1, 0x1a16, + 0x8aa3, 0x1a1b, + 0x8aa4, 0x07a1, + 0x8aa5, 0x1a18, + 0x8aa7, 0x21ab, + 0x8aa8, 0x1a15, + 0x8aac, 0x0a86, + 0x8aad, 0x0ca1, + 0x8ab0, 0x0b6d, + 0x8ab2, 0x055d, + 0x8ab9, 0x0d84, + 0x8abc, 0x065d, + 0x8abe, 0x21ac, + 0x8abf, 0x0bd0, + 0x8ac2, 0x1a1e, + 0x8ac4, 0x1a1c, + 0x8ac7, 0x0b8a, + 0x8acb, 0x0a65, + 0x8acc, 0x060e, + 0x8acd, 0x1a1d, + 0x8acf, 0x0a21, + 0x8ad2, 0x0f92, + 0x8ad6, 0x0fe6, + 0x8ada, 0x1a1f, + 0x8adb, 0x1a2a, + 0x8adc, 0x0bd1, + 0x8ade, 0x1a29, + 0x8adf, 0x21ad, + 0x8ae0, 0x1a26, + 0x8ae1, 0x1a2e, + 0x8ae2, 0x1a27, + 0x8ae4, 0x1a23, + 0x8ae6, 0x0c18, + 0x8ae7, 0x1a22, + 0x8aeb, 0x1a20, + 0x8aed, 0x0f0b, + 0x8aee, 0x08be, + 0x8af1, 0x1a24, + 0x8af3, 0x1a21, + 0x8af6, 0x21af, + 0x8af7, 0x1a28, + 0x8af8, 0x097e, + 0x8afa, 0x0775, + 0x8afe, 0x0b5a, + 0x8b00, 0x0e73, + 0x8b01, 0x04fc, + 0x8b02, 0x04a6, + 0x8b04, 0x0c7d, + 0x8b07, 0x1a2c, + 0x8b0c, 0x1a2b, + 0x8b0e, 0x0cbe, + 0x8b10, 0x1a30, + 0x8b14, 0x1a25, + 0x8b16, 0x1a2f, + 0x8b17, 0x1a31, + 0x8b19, 0x0760, + 0x8b1a, 0x1a2d, + 0x8b1b, 0x07e8, + 0x8b1d, 0x0901, + 0x8b20, 0x1a32, + 0x8b21, 0x0f42, + 0x8b26, 0x1a35, + 0x8b28, 0x1a38, + 0x8b2b, 0x1a36, + 0x8b2c, 0x0da7, + 0x8b33, 0x1a33, + 0x8b39, 0x06d8, + 0x8b3e, 0x1a37, + 0x8b41, 0x1a39, + 0x8b49, 0x1a3d, + 0x8b4c, 0x1a3a, + 0x8b4e, 0x1a3c, + 0x8b4f, 0x1a3b, + 0x8b53, 0x21b0, + 0x8b56, 0x1a3e, + 0x8b58, 0x08dd, + 0x8b5a, 0x1a40, + 0x8b5b, 0x1a3f, + 0x8b5c, 0x0dda, + 0x8b5f, 0x1a42, + 0x8b66, 0x072f, + 0x8b6b, 0x1a41, + 0x8b6c, 0x1a43, + 0x8b6f, 0x1a44, + 0x8b70, 0x065e, + 0x8b71, 0x182e, + 0x8b72, 0x09e1, + 0x8b74, 0x1a45, + 0x8b77, 0x07a2, + 0x8b7d, 0x1a46, + 0x8b7f, 0x21b1, + 0x8b80, 0x1a47, + 0x8b83, 0x088c, + 0x8b8a, 0x13d3, + 0x8b8c, 0x1a48, + 0x8b8e, 0x1a49, + 0x8b90, 0x093c, + 0x8b92, 0x1a4a, + 0x8b96, 0x1a4c, + 0x8b99, 0x1a4d, + 0x8c37, 0x0b69, + 0x8c3a, 0x1a4f, + 0x8c3f, 0x1a51, + 0x8c41, 0x1a50, + 0x8c46, 0x0c7e, + 0x8c48, 0x1a52, + 0x8c4a, 0x0e5b, + 0x8c4c, 0x1a53, + 0x8c4e, 0x1a54, + 0x8c50, 0x1a55, + 0x8c55, 0x1a56, + 0x8c5a, 0x0cb2, + 0x8c61, 0x09c5, + 0x8c62, 0x1a57, + 0x8c6a, 0x07fd, + 0x8c6b, 0x1007, + 0x8c6c, 0x1a58, + 0x8c78, 0x1a59, + 0x8c79, 0x0db1, + 0x8c7a, 0x1a5a, + 0x8c7c, 0x1a62, + 0x8c82, 0x1a5b, + 0x8c85, 0x1a5d, + 0x8c89, 0x1a5c, + 0x8c8a, 0x1a5e, + 0x8c8c, 0x0e74, + 0x8c8d, 0x1a5f, + 0x8c94, 0x1a61, + 0x8c98, 0x1a63, + 0x8c9d, 0x058b, + 0x8c9e, 0x0c03, + 0x8ca0, 0x0ddb, + 0x8ca1, 0x0852, + 0x8ca2, 0x07e9, + 0x8ca7, 0x0dc1, + 0x8ca8, 0x055f, + 0x8ca9, 0x0d62, + 0x8caa, 0x1a66, + 0x8cab, 0x060f, + 0x8cac, 0x0a79, + 0x8cad, 0x1a65, + 0x8cae, 0x1a6a, + 0x8caf, 0x0bb7, + 0x8cb0, 0x0eef, + 0x8cb2, 0x1a68, + 0x8cb4, 0x0648, + 0x8cb6, 0x1a6b, + 0x8cb7, 0x0d19, + 0x8cb8, 0x0b3f, + 0x8cbb, 0x0d85, + 0x8cbc, 0x0c37, + 0x8cbd, 0x1a67, + 0x8cbf, 0x0e75, + 0x8cc0, 0x056c, + 0x8cc1, 0x1a6d, + 0x8cc2, 0x0fce, + 0x8cc3, 0x0bde, + 0x8cc4, 0x0feb, + 0x8cc7, 0x08bf, + 0x8cc8, 0x1a6c, + 0x8cca, 0x0b11, + 0x8ccd, 0x1a7d, + 0x8cce, 0x0aaa, + 0x8cd1, 0x0cd0, + 0x8cd3, 0x0dc2, + 0x8cda, 0x1a70, + 0x8cdb, 0x088d, + 0x8cdc, 0x08c0, + 0x8cde, 0x09c6, + 0x8ce0, 0x0d1b, + 0x8ce2, 0x0761, + 0x8ce3, 0x1a6f, + 0x8ce4, 0x1a6e, + 0x8ce6, 0x0ddc, + 0x8cea, 0x08ed, + 0x8ced, 0x0c4c, + 0x8cf0, 0x21b2, + 0x8cf4, 0x21b3, + 0x8cfa, 0x1a72, + 0x8cfc, 0x07ea, + 0x8cfd, 0x1a71, + 0x8d04, 0x1a74, + 0x8d07, 0x1a77, + 0x8d08, 0x0b03, + 0x8d0a, 0x1a76, + 0x8d0b, 0x0622, + 0x8d0d, 0x1a79, + 0x8d0f, 0x1a78, + 0x8d10, 0x1a7a, + 0x8d12, 0x21b4, + 0x8d13, 0x1a7c, + 0x8d14, 0x1a7e, + 0x8d16, 0x1a7f, + 0x8d64, 0x0a7a, + 0x8d66, 0x08fb, + 0x8d67, 0x1a80, + 0x8d6b, 0x05b0, + 0x8d6d, 0x1a81, + 0x8d70, 0x0af8, + 0x8d71, 0x1a82, + 0x8d73, 0x1a83, + 0x8d74, 0x0ddd, + 0x8d76, 0x21b5, + 0x8d77, 0x0649, + 0x8d81, 0x1a84, + 0x8d85, 0x0bd2, + 0x8d8a, 0x04fd, + 0x8d99, 0x1a85, + 0x8da3, 0x091d, + 0x8da8, 0x0a3c, + 0x8db3, 0x0b0d, + 0x8dba, 0x1a88, + 0x8dbe, 0x1a87, + 0x8dc2, 0x1a86, + 0x8dcb, 0x1a8e, + 0x8dcc, 0x1a8c, + 0x8dcf, 0x1a89, + 0x8dd6, 0x1a8b, + 0x8dda, 0x1a8a, + 0x8ddb, 0x1a8d, + 0x8ddd, 0x0691, + 0x8ddf, 0x1a91, + 0x8de1, 0x0a7b, + 0x8de3, 0x1a92, + 0x8de8, 0x078d, + 0x8dea, 0x1a8f, + 0x8def, 0x0fcf, + 0x8df3, 0x0bd3, + 0x8df5, 0x0aab, + 0x8dfc, 0x1a93, + 0x8dff, 0x1a96, + 0x8e08, 0x1a94, + 0x8e0a, 0x0f43, + 0x8e0f, 0x0c7f, + 0x8e10, 0x1a99, + 0x8e1d, 0x1a97, + 0x8e1f, 0x1a9a, + 0x8e2a, 0x1aa8, + 0x8e30, 0x1a9d, + 0x8e34, 0x1a9e, + 0x8e35, 0x1a9c, + 0x8e42, 0x1a9b, + 0x8e44, 0x0c19, + 0x8e47, 0x1aa0, + 0x8e48, 0x1aa4, + 0x8e49, 0x1aa1, + 0x8e4a, 0x1a9f, + 0x8e4c, 0x1aa2, + 0x8e50, 0x1aa3, + 0x8e55, 0x1aaa, + 0x8e59, 0x1aa5, + 0x8e5f, 0x0a7c, + 0x8e60, 0x1aa7, + 0x8e63, 0x1aa9, + 0x8e64, 0x1aa6, + 0x8e72, 0x1aac, + 0x8e74, 0x093d, + 0x8e76, 0x1aab, + 0x8e7c, 0x1aad, + 0x8e81, 0x1aae, + 0x8e84, 0x1ab1, + 0x8e85, 0x1ab0, + 0x8e87, 0x1aaf, + 0x8e8a, 0x1ab3, + 0x8e8b, 0x1ab2, + 0x8e8d, 0x0f02, + 0x8e91, 0x1ab5, + 0x8e93, 0x1ab4, + 0x8e94, 0x1ab6, + 0x8e99, 0x1ab7, + 0x8ea1, 0x1ab9, + 0x8eaa, 0x1ab8, + 0x8eab, 0x0a0e, + 0x8eac, 0x1aba, + 0x8eaf, 0x06e5, + 0x8eb0, 0x1abb, + 0x8eb1, 0x1abd, + 0x8ebe, 0x1abe, + 0x8ec0, 0x1def, + 0x8ec5, 0x1abf, + 0x8ec6, 0x1abc, + 0x8ec8, 0x1ac0, + 0x8eca, 0x0902, + 0x8ecb, 0x1ac1, + 0x8ecc, 0x064a, + 0x8ecd, 0x0709, + 0x8ecf, 0x21b7, + 0x8ed2, 0x0762, + 0x8edb, 0x1ac2, + 0x8edf, 0x0cc8, + 0x8ee2, 0x0c38, + 0x8ee3, 0x1ac3, + 0x8eeb, 0x1ac6, + 0x8ef8, 0x08e0, + 0x8efb, 0x1ac5, + 0x8efc, 0x1ac4, + 0x8efd, 0x0730, + 0x8efe, 0x1ac7, + 0x8f03, 0x05b1, + 0x8f05, 0x1ac9, + 0x8f09, 0x084c, + 0x8f0a, 0x1ac8, + 0x8f0c, 0x1ad1, + 0x8f12, 0x1acb, + 0x8f13, 0x1acd, + 0x8f14, 0x0e35, + 0x8f15, 0x1aca, + 0x8f19, 0x1acc, + 0x8f1b, 0x1ad0, + 0x8f1c, 0x1ace, + 0x8f1d, 0x064b, + 0x8f1f, 0x1acf, + 0x8f26, 0x1ad2, + 0x8f29, 0x0d10, + 0x8f2a, 0x0fa0, + 0x8f2f, 0x093e, + 0x8f33, 0x1ad3, + 0x8f38, 0x0f0c, + 0x8f39, 0x1ad5, + 0x8f3b, 0x1ad4, + 0x8f3e, 0x1ad8, + 0x8f3f, 0x0f2b, + 0x8f42, 0x1ad7, + 0x8f44, 0x05cb, + 0x8f45, 0x1ad6, + 0x8f46, 0x1adb, + 0x8f49, 0x1ada, + 0x8f4c, 0x1ad9, + 0x8f4d, 0x0c2c, + 0x8f4e, 0x1adc, + 0x8f57, 0x1add, + 0x8f5c, 0x1ade, + 0x8f5f, 0x07fe, + 0x8f61, 0x06fb, + 0x8f62, 0x1adf, + 0x8f9b, 0x0a0f, + 0x8f9c, 0x1ae2, + 0x8f9e, 0x08d9, + 0x8f9f, 0x1ae3, + 0x8fa3, 0x1ae4, + 0x8fa7, 0x10b6, + 0x8fa8, 0x10b5, + 0x8fad, 0x1ae5, + 0x8fae, 0x17ff, + 0x8faf, 0x1ae6, + 0x8fb0, 0x0b62, + 0x8fb1, 0x09f1, + 0x8fb2, 0x0cf6, + 0x8fb7, 0x1ae7, + 0x8fba, 0x0e25, + 0x8fbb, 0x0bf0, + 0x8fbc, 0x0810, + 0x8fbf, 0x0b67, + 0x8fc2, 0x04cc, + 0x8fc4, 0x0ea6, + 0x8fc5, 0x0a1d, + 0x8fce, 0x0734, + 0x8fd1, 0x06d9, + 0x8fd4, 0x0e26, + 0x8fda, 0x1ae8, + 0x8fe2, 0x1aea, + 0x8fe5, 0x1ae9, + 0x8fe6, 0x0560, + 0x8fe9, 0x0cce, + 0x8fea, 0x1aeb, + 0x8feb, 0x0d2d, + 0x8fed, 0x0c2d, + 0x8fef, 0x1aec, + 0x8ff0, 0x095c, + 0x8ff4, 0x1aee, + 0x8ff7, 0x0ece, + 0x8ff8, 0x1afd, + 0x8ff9, 0x1af0, + 0x8ffd, 0x0be5, + 0x9000, 0x0b40, + 0x9001, 0x0af9, + 0x9003, 0x0c80, + 0x9005, 0x1aef, + 0x9006, 0x066f, + 0x900b, 0x1af8, + 0x900d, 0x1af5, + 0x900e, 0x1b02, + 0x900f, 0x0c81, + 0x9010, 0x0b9e, + 0x9011, 0x1af2, + 0x9013, 0x0c1a, + 0x9014, 0x0c4d, + 0x9015, 0x1af3, + 0x9016, 0x1af7, + 0x9017, 0x0a26, + 0x9019, 0x0d1d, + 0x901a, 0x0be8, + 0x901d, 0x0a66, + 0x901e, 0x1af6, + 0x901f, 0x0b0e, + 0x9020, 0x0b04, + 0x9021, 0x1af4, + 0x9022, 0x046d, + 0x9023, 0x0fc8, + 0x9027, 0x1af9, + 0x902e, 0x0b41, + 0x9031, 0x093f, + 0x9032, 0x0a10, + 0x9035, 0x1afb, + 0x9036, 0x1afa, + 0x9038, 0x04b3, + 0x9039, 0x1afc, + 0x903c, 0x0da1, + 0x903e, 0x1b04, + 0x9041, 0x0cb3, + 0x9042, 0x0a31, + 0x9045, 0x0b97, + 0x9047, 0x06f0, + 0x9049, 0x1b03, + 0x904a, 0x0f21, + 0x904b, 0x04e1, + 0x904d, 0x0e27, + 0x904e, 0x0561, + 0x904f, 0x1afe, + 0x9053, 0x0c93, + 0x9054, 0x0b61, + 0x9055, 0x04a7, + 0x9056, 0x1b05, + 0x9058, 0x1b06, + 0x9059, 0x1d34, + 0x905c, 0x0b1d, + 0x905e, 0x1b07, + 0x9060, 0x0515, + 0x9061, 0x0ace, + 0x9063, 0x0763, + 0x9065, 0x0f44, + 0x9067, 0x21ba, + 0x9068, 0x1b08, + 0x9069, 0x0c26, + 0x906d, 0x0afa, + 0x906e, 0x0903, + 0x906f, 0x1b09, + 0x9072, 0x1b0c, + 0x9075, 0x096f, + 0x9076, 0x1b0a, + 0x9077, 0x0aad, + 0x9078, 0x0aac, + 0x907a, 0x04a8, + 0x907c, 0x0f93, + 0x907d, 0x1b0e, + 0x907f, 0x0d86, + 0x9080, 0x1b10, + 0x9081, 0x1b0f, + 0x9082, 0x1b0d, + 0x9083, 0x1737, + 0x9084, 0x0610, + 0x9087, 0x1aed, + 0x9089, 0x1b12, + 0x908a, 0x1b11, + 0x908f, 0x1b13, + 0x9091, 0x0f22, + 0x90a3, 0x0cb9, + 0x90a6, 0x0e5c, + 0x90a8, 0x1b14, + 0x90aa, 0x0905, + 0x90af, 0x1b15, + 0x90b1, 0x1b16, + 0x90b5, 0x1b17, + 0x90b8, 0x0c1b, + 0x90c1, 0x04ae, + 0x90ca, 0x07eb, + 0x90ce, 0x0fe0, + 0x90db, 0x1b1b, + 0x90de, 0x21bb, + 0x90e1, 0x070a, + 0x90e2, 0x1b18, + 0x90e4, 0x1b19, + 0x90e8, 0x0de6, + 0x90ed, 0x05b2, + 0x90f5, 0x0f23, + 0x90f7, 0x06b7, + 0x90fd, 0x0c4e, + 0x9102, 0x1b1c, + 0x9112, 0x1b1d, + 0x9115, 0x21bd, + 0x9119, 0x1b1e, + 0x9127, 0x21be, + 0x912d, 0x0c1c, + 0x9130, 0x1b20, + 0x9132, 0x1b1f, + 0x9149, 0x0cab, + 0x914a, 0x1b21, + 0x914b, 0x0940, + 0x914c, 0x090c, + 0x914d, 0x0d11, + 0x914e, 0x0baf, + 0x9152, 0x091e, + 0x9154, 0x0a32, + 0x9156, 0x1b22, + 0x9158, 0x1b23, + 0x9162, 0x0a23, + 0x9163, 0x1b24, + 0x9165, 0x1b25, + 0x9169, 0x1b26, + 0x916a, 0x0f59, + 0x916c, 0x0941, + 0x9172, 0x1b28, + 0x9173, 0x1b27, + 0x9175, 0x07ec, + 0x9177, 0x0805, + 0x9178, 0x088e, + 0x9182, 0x1b2b, + 0x9187, 0x0970, + 0x9189, 0x1b2a, + 0x918b, 0x1b29, + 0x918d, 0x0b49, + 0x9190, 0x07a3, + 0x9192, 0x0a67, + 0x9197, 0x0d44, + 0x919c, 0x0943, + 0x91a2, 0x1b2c, + 0x91a4, 0x09c7, + 0x91aa, 0x1b2f, + 0x91ab, 0x1b2d, + 0x91ac, 0x1e1b, + 0x91af, 0x1b2e, + 0x91b1, 0x1e61, + 0x91b4, 0x1b31, + 0x91b5, 0x1b30, + 0x91b8, 0x09e2, + 0x91ba, 0x1b32, + 0x91c0, 0x1b33, + 0x91c6, 0x0d64, + 0x91c7, 0x0843, + 0x91c8, 0x090d, + 0x91c9, 0x1b35, + 0x91cb, 0x1b36, + 0x91cc, 0x0f6c, + 0x91cd, 0x094f, + 0x91ce, 0x0efa, + 0x91cf, 0x0f94, + 0x91d0, 0x1b37, + 0x91d1, 0x06da, + 0x91d6, 0x1b38, + 0x91d7, 0x21c0, + 0x91d8, 0x0c1d, + 0x91da, 0x21bf, + 0x91db, 0x1b3b, + 0x91dc, 0x05d6, + 0x91dd, 0x0a11, + 0x91de, 0x21c1, + 0x91df, 0x1b39, + 0x91e1, 0x1b3a, + 0x91e3, 0x0bfc, + 0x91e4, 0x21c4, + 0x91e6, 0x0e83, + 0x91e7, 0x06f4, + 0x91ed, 0x21c2, + 0x91f5, 0x1b3d, + 0x91fc, 0x1b3c, + 0x91ff, 0x1b40, + 0x9206, 0x21c6, + 0x920a, 0x21c8, + 0x920d, 0x0cb7, + 0x920e, 0x05a1, + 0x9210, 0x21c7, + 0x9211, 0x1b44, + 0x9214, 0x1b41, + 0x9215, 0x1b43, + 0x921e, 0x1b3f, + 0x9229, 0x1b8a, + 0x922c, 0x1b42, + 0x9234, 0x0fb3, + 0x9237, 0x078e, + 0x9239, 0x21cf, + 0x923a, 0x21c9, + 0x923c, 0x21cb, + 0x923f, 0x1b4c, + 0x9240, 0x21ca, + 0x9244, 0x0c2e, + 0x9245, 0x1b47, + 0x9248, 0x1b4a, + 0x9249, 0x1b48, + 0x924b, 0x1b4d, + 0x924e, 0x21cc, + 0x9250, 0x1b4e, + 0x9251, 0x21ce, + 0x9257, 0x1b46, + 0x9259, 0x21cd, + 0x925a, 0x1b53, + 0x925b, 0x0516, + 0x925e, 0x1b45, + 0x9262, 0x0d41, + 0x9264, 0x1b49, + 0x9266, 0x09c8, + 0x9267, 0x21d0, + 0x9271, 0x07ed, + 0x9277, 0x21d2, + 0x927e, 0x0e76, + 0x9280, 0x06dc, + 0x9283, 0x0950, + 0x9285, 0x0c94, + 0x9288, 0x20aa, + 0x9291, 0x0aaf, + 0x9293, 0x1b51, + 0x9295, 0x1b4b, + 0x9296, 0x1b50, + 0x9298, 0x0ecf, + 0x929a, 0x0bd4, + 0x929b, 0x1b52, + 0x929c, 0x1b4f, + 0x92a7, 0x21d1, + 0x92ad, 0x0aae, + 0x92b7, 0x1b56, + 0x92b9, 0x1b55, + 0x92cf, 0x1b54, + 0x92d0, 0x21d7, + 0x92d2, 0x0e5d, + 0x92d3, 0x21db, + 0x92d5, 0x21d9, + 0x92d7, 0x21d5, + 0x92d9, 0x21d6, + 0x92e0, 0x21da, + 0x92e4, 0x0985, + 0x92e7, 0x21d4, + 0x92e9, 0x1b57, + 0x92ea, 0x0e2f, + 0x92ed, 0x04f6, + 0x92f2, 0x0db8, + 0x92f3, 0x0bb0, + 0x92f8, 0x0692, + 0x92f9, 0x20b0, + 0x92fa, 0x1b59, + 0x92fb, 0x21de, + 0x92fc, 0x07ef, + 0x92ff, 0x21e1, + 0x9302, 0x21e3, + 0x9306, 0x087a, + 0x930f, 0x1b58, + 0x9310, 0x0a33, + 0x9318, 0x0a34, + 0x9319, 0x1b5c, + 0x931a, 0x1b5e, + 0x931d, 0x21e2, + 0x931e, 0x21e0, + 0x9320, 0x09e3, + 0x9321, 0x21dd, + 0x9322, 0x1b5d, + 0x9323, 0x1b5f, + 0x9325, 0x21dc, + 0x9326, 0x06cb, + 0x9328, 0x0db7, + 0x932b, 0x090e, + 0x932c, 0x0fc9, + 0x932e, 0x1b5b, + 0x932f, 0x0868, + 0x9332, 0x0fe5, + 0x9335, 0x1b61, + 0x933a, 0x1b60, + 0x933b, 0x1b62, + 0x9344, 0x1b5a, + 0x9348, 0x20a9, + 0x934b, 0x0cc1, + 0x934d, 0x0c4f, + 0x9354, 0x0bf3, + 0x9356, 0x1b67, + 0x9357, 0x21e5, + 0x935b, 0x0b81, + 0x935c, 0x1b63, + 0x9360, 0x1b64, + 0x936c, 0x0703, + 0x936e, 0x1b66, + 0x9370, 0x21e4, + 0x9375, 0x0764, + 0x937c, 0x1b65, + 0x937e, 0x09c9, + 0x938c, 0x05d7, + 0x9394, 0x1b6b, + 0x9396, 0x082f, + 0x9397, 0x0afb, + 0x939a, 0x0be6, + 0x93a4, 0x21e6, + 0x93a7, 0x0599, + 0x93ac, 0x1b69, + 0x93ae, 0x0bdf, + 0x93b0, 0x1b68, + 0x93b9, 0x1b6c, + 0x93c3, 0x1b72, + 0x93c6, 0x21e7, + 0x93c8, 0x1b75, + 0x93d0, 0x1b74, + 0x93d1, 0x0c27, + 0x93d6, 0x1b6d, + 0x93d8, 0x1b71, + 0x93dd, 0x1b73, + 0x93de, 0x21e8, + 0x93e1, 0x06b8, + 0x93e4, 0x1b76, + 0x93e5, 0x1b70, + 0x93e8, 0x1b6f, + 0x93f8, 0x21e9, + 0x9403, 0x1b7a, + 0x9407, 0x1b7b, + 0x9410, 0x1b7c, + 0x9413, 0x1b79, + 0x9414, 0x1b78, + 0x9418, 0x09ca, + 0x9419, 0x0c82, + 0x941a, 0x1b77, + 0x9421, 0x1b80, + 0x942b, 0x1b7e, + 0x9431, 0x21ea, + 0x9435, 0x1b7f, + 0x9436, 0x1b7d, + 0x9438, 0x0b58, + 0x943a, 0x1b81, + 0x9441, 0x1b82, + 0x9444, 0x1b84, + 0x9445, 0x21eb, + 0x9448, 0x21ec, + 0x9451, 0x0611, + 0x9452, 0x1b83, + 0x9453, 0x0f06, + 0x945a, 0x1b8f, + 0x945b, 0x1b85, + 0x945e, 0x1b88, + 0x9460, 0x1b86, + 0x9462, 0x1b87, + 0x946a, 0x1b89, + 0x9470, 0x1b8b, + 0x9475, 0x1b8c, + 0x9477, 0x1b8d, + 0x947c, 0x1b90, + 0x947d, 0x1b8e, + 0x947e, 0x1b91, + 0x947f, 0x1b93, + 0x9481, 0x1b92, + 0x9577, 0x0bd5, + 0x9580, 0x0ef3, + 0x9582, 0x1b94, + 0x9583, 0x0ab0, + 0x9587, 0x1b95, + 0x9589, 0x0e14, + 0x958a, 0x1b96, + 0x958b, 0x0589, + 0x958f, 0x04de, + 0x9591, 0x0613, + 0x9592, 0x21ed, + 0x9593, 0x0612, + 0x9594, 0x1b97, + 0x9596, 0x1b98, + 0x9598, 0x1b99, + 0x95a0, 0x1b9b, + 0x95a2, 0x0614, + 0x95a3, 0x05b3, + 0x95a4, 0x07f0, + 0x95a5, 0x0d4a, + 0x95a7, 0x1b9d, + 0x95a8, 0x1b9c, + 0x95ad, 0x1b9e, + 0x95b2, 0x04fe, + 0x95b9, 0x1ba1, + 0x95bb, 0x1ba0, + 0x95bc, 0x1b9f, + 0x95be, 0x1ba2, + 0x95c3, 0x1ba5, + 0x95c7, 0x048b, + 0x95ca, 0x1ba3, + 0x95cc, 0x1ba7, + 0x95cd, 0x1ba6, + 0x95d4, 0x1ba9, + 0x95d5, 0x1ba8, + 0x95d6, 0x1baa, + 0x95d8, 0x0c86, + 0x95dc, 0x1bab, + 0x95e1, 0x1bac, + 0x95e2, 0x1bae, + 0x95e5, 0x1bad, + 0x961c, 0x0dde, + 0x9621, 0x1baf, + 0x9628, 0x1bb0, + 0x962a, 0x0855, + 0x962e, 0x1bb1, + 0x9632, 0x0e77, + 0x963b, 0x0acd, + 0x963f, 0x0468, + 0x9640, 0x0b2b, + 0x9642, 0x1bb3, + 0x9644, 0x0ddf, + 0x964b, 0x1bb6, + 0x964c, 0x1bb4, + 0x964d, 0x07f1, + 0x964f, 0x1bb5, + 0x9650, 0x0776, + 0x965b, 0x0e15, + 0x965c, 0x1bb8, + 0x965d, 0x1bba, + 0x965e, 0x1bb9, + 0x965f, 0x1bbb, + 0x9662, 0x04c3, + 0x9663, 0x0a1e, + 0x9664, 0x0986, + 0x9665, 0x0615, + 0x9666, 0x1bbc, + 0x966a, 0x0d1c, + 0x966c, 0x1bbe, + 0x9670, 0x04c4, + 0x9672, 0x1bbd, + 0x9673, 0x0be0, + 0x9675, 0x0f95, + 0x9676, 0x0c83, + 0x9677, 0x1bb7, + 0x9678, 0x0f6e, + 0x967a, 0x0765, + 0x967d, 0x0f45, + 0x9685, 0x06f1, + 0x9686, 0x0f7c, + 0x9688, 0x06fe, + 0x968a, 0x0b42, + 0x968b, 0x186c, + 0x968d, 0x1bbf, + 0x968e, 0x058a, + 0x968f, 0x0a35, + 0x9694, 0x05b4, + 0x9695, 0x1bc1, + 0x9697, 0x1bc2, + 0x9698, 0x1bc0, + 0x9699, 0x073a, + 0x969b, 0x084d, + 0x969c, 0x09cb, + 0x969d, 0x21f0, + 0x96a0, 0x04c5, + 0x96a3, 0x0fa1, + 0x96a7, 0x1bc4, + 0x96a8, 0x1b0b, + 0x96aa, 0x1bc3, + 0x96af, 0x21f1, + 0x96b0, 0x1bc7, + 0x96b1, 0x1bc5, + 0x96b4, 0x1bc8, + 0x96b6, 0x1bc9, + 0x96b7, 0x0fb4, + 0x96b8, 0x1bca, + 0x96bb, 0x0a6d, + 0x96bc, 0x0d4f, + 0x96c0, 0x0a43, + 0x96c1, 0x0623, + 0x96c4, 0x0f24, + 0x96c5, 0x056d, + 0x96c6, 0x0942, + 0x96c7, 0x078f, + 0x96c9, 0x1bce, + 0x96cb, 0x1bcd, + 0x96cc, 0x08c1, + 0x96cd, 0x1bcf, + 0x96ce, 0x1bcc, + 0x96d1, 0x0876, + 0x96d5, 0x1bd3, + 0x96d6, 0x1992, + 0x96d9, 0x10eb, + 0x96db, 0x0a3d, + 0x96dc, 0x1bd1, + 0x96e2, 0x0f6d, + 0x96e3, 0x0cc9, + 0x96e8, 0x04cd, + 0x96ea, 0x0a87, + 0x96eb, 0x08e2, + 0x96f0, 0x0e07, + 0x96f2, 0x04e2, + 0x96f6, 0x0fb5, + 0x96f7, 0x0f55, + 0x96f9, 0x1bd4, + 0x96fb, 0x0c3f, + 0x9700, 0x0927, + 0x9704, 0x1bd5, + 0x9706, 0x1bd6, + 0x9707, 0x0a12, + 0x9708, 0x1bd7, + 0x970a, 0x0fb6, + 0x970d, 0x1bd2, + 0x970e, 0x1bd9, + 0x970f, 0x1bdb, + 0x9711, 0x1bda, + 0x9713, 0x1bd8, + 0x9716, 0x1bdc, + 0x9719, 0x1bdd, + 0x971c, 0x0afc, + 0x971e, 0x0562, + 0x9724, 0x1bde, + 0x9727, 0x0ec4, + 0x972a, 0x1bdf, + 0x9730, 0x1be0, + 0x9732, 0x0fd0, + 0x9733, 0x21f2, + 0x9738, 0x1414, + 0x9739, 0x1be1, + 0x973b, 0x21f3, + 0x973d, 0x1be2, + 0x9742, 0x1be7, + 0x9743, 0x21f4, + 0x9744, 0x1be4, + 0x9746, 0x1be5, + 0x9748, 0x1be6, + 0x9749, 0x1be8, + 0x974d, 0x21f5, + 0x974f, 0x21f6, + 0x9751, 0x21f7, + 0x9752, 0x0a68, + 0x9755, 0x21f8, + 0x9756, 0x0f03, + 0x9759, 0x0a69, + 0x975c, 0x1be9, + 0x975e, 0x0d87, + 0x9760, 0x1bea, + 0x9761, 0x1d06, + 0x9762, 0x0ed8, + 0x9764, 0x1beb, + 0x9766, 0x1bec, + 0x9768, 0x1bed, + 0x9769, 0x05b5, + 0x976b, 0x1bef, + 0x976d, 0x0a1f, + 0x9771, 0x1bf0, + 0x9774, 0x06fa, + 0x9779, 0x1bf1, + 0x977a, 0x1bf5, + 0x977c, 0x1bf3, + 0x9781, 0x1bf4, + 0x9784, 0x05d1, + 0x9785, 0x1bf2, + 0x9786, 0x1bf6, + 0x978b, 0x1bf7, + 0x978d, 0x048c, + 0x978f, 0x1bf8, + 0x9798, 0x09cc, + 0x979c, 0x1bfa, + 0x97a0, 0x0661, + 0x97a3, 0x1bfd, + 0x97a6, 0x1bfc, + 0x97a8, 0x1bfb, + 0x97ab, 0x1a34, + 0x97ad, 0x0e2c, + 0x97b3, 0x1bfe, + 0x97c3, 0x1c00, + 0x97c6, 0x1c01, + 0x97c8, 0x1c02, + 0x97cb, 0x1c03, + 0x97d3, 0x0616, + 0x97dc, 0x1c04, + 0x97ed, 0x1c05, + 0x97ee, 0x0cd9, + 0x97f2, 0x1c07, + 0x97f3, 0x053b, + 0x97f5, 0x1c0a, + 0x97f6, 0x1c09, + 0x97fb, 0x04c6, + 0x97ff, 0x06b9, + 0x9801, 0x0e17, + 0x9802, 0x0bd6, + 0x9803, 0x0812, + 0x9805, 0x07f2, + 0x9806, 0x0971, + 0x9808, 0x0a22, + 0x980c, 0x1c0c, + 0x980f, 0x1c0b, + 0x9810, 0x0f2c, + 0x9811, 0x0624, + 0x9812, 0x0d66, + 0x9813, 0x0cb4, + 0x9817, 0x0a42, + 0x9818, 0x0f96, + 0x981a, 0x0731, + 0x9821, 0x1c0f, + 0x9824, 0x1c0e, + 0x982c, 0x0e79, + 0x982d, 0x0c84, + 0x9830, 0x1e73, + 0x9834, 0x04f2, + 0x9837, 0x1c10, + 0x9838, 0x1c0d, + 0x983b, 0x0dc3, + 0x983c, 0x0f54, + 0x983d, 0x1c11, + 0x9846, 0x1c12, + 0x984b, 0x1c14, + 0x984c, 0x0b4a, + 0x984d, 0x05b9, + 0x984f, 0x1c13, + 0x9854, 0x0625, + 0x9855, 0x0766, + 0x9857, 0x21f9, + 0x9858, 0x0626, + 0x985a, 0x1e48, + 0x985b, 0x0c39, + 0x985e, 0x0fa8, + 0x9865, 0x21fa, + 0x9867, 0x0790, + 0x986b, 0x1c15, + 0x986f, 0x1c16, + 0x9873, 0x1c1a, + 0x9874, 0x1c19, + 0x98a8, 0x0de9, + 0x98aa, 0x1c1b, + 0x98af, 0x1c1c, + 0x98b1, 0x1c1d, + 0x98b6, 0x1c1e, + 0x98c3, 0x1c20, + 0x98c4, 0x1c1f, + 0x98c6, 0x1c21, + 0x98db, 0x0d88, + 0x98dc, 0x1839, + 0x98df, 0x09ef, + 0x98e2, 0x064c, + 0x98e9, 0x1c22, + 0x98eb, 0x1c23, + 0x98ed, 0x10c1, + 0x98ee, 0x14da, + 0x98ef, 0x0d67, + 0x98f2, 0x04bf, + 0x98f4, 0x047f, + 0x98fc, 0x08c2, + 0x98fd, 0x0e5e, + 0x98fe, 0x09e6, + 0x9903, 0x1c24, + 0x9905, 0x0eeb, + 0x9909, 0x1c25, + 0x990a, 0x0f46, + 0x990c, 0x04e4, + 0x9910, 0x088f, + 0x9912, 0x1c26, + 0x9913, 0x056e, + 0x9914, 0x1c27, + 0x9918, 0x1c28, + 0x991d, 0x1c2a, + 0x9920, 0x1c2d, + 0x9921, 0x1c29, + 0x9924, 0x1c2c, + 0x9927, 0x21fd, + 0x9928, 0x0617, + 0x992c, 0x1c2e, + 0x992e, 0x1c2f, + 0x993d, 0x1c30, + 0x9942, 0x1c32, + 0x9945, 0x1c34, + 0x9949, 0x1c33, + 0x994b, 0x1c36, + 0x994c, 0x1c39, + 0x9950, 0x1c35, + 0x9951, 0x1c37, + 0x9955, 0x1c3a, + 0x9957, 0x06ba, + 0x9996, 0x091f, + 0x9997, 0x1c3b, + 0x9999, 0x07f3, + 0x999e, 0x21ff, + 0x99a5, 0x1c3d, + 0x99a8, 0x059c, + 0x99ac, 0x0d05, + 0x99ad, 0x1c3e, + 0x99b3, 0x0b98, + 0x99b4, 0x0cc3, + 0x99bc, 0x1c40, + 0x99c1, 0x0d33, + 0x99c4, 0x0b2c, + 0x99c5, 0x04fa, + 0x99c6, 0x06e6, + 0x99c8, 0x06e7, + 0x99d0, 0x0bb1, + 0x99d1, 0x1c45, + 0x99d2, 0x06e8, + 0x99d5, 0x056f, + 0x99d8, 0x1c44, + 0x99db, 0x1c42, + 0x99dd, 0x1c43, + 0x99df, 0x1c41, + 0x99e2, 0x1c4f, + 0x99ed, 0x1c46, + 0x99f1, 0x1c48, + 0x99f8, 0x1c4b, + 0x99fb, 0x1c4a, + 0x99ff, 0x0963, + 0x9a01, 0x1c4c, + 0x9a05, 0x1c4e, + 0x9a0e, 0x064d, + 0x9a0f, 0x1c4d, + 0x9a12, 0x0afd, + 0x9a13, 0x0767, + 0x9a19, 0x1c50, + 0x9a28, 0x0b2d, + 0x9a2b, 0x1c51, + 0x9a30, 0x0c85, + 0x9a37, 0x1c52, + 0x9a3e, 0x1c57, + 0x9a40, 0x1c55, + 0x9a42, 0x1c54, + 0x9a43, 0x1c56, + 0x9a45, 0x1c53, + 0x9a4d, 0x1c59, + 0x9a4e, 0x2200, + 0x9a52, 0x1e2f, + 0x9a55, 0x1c58, + 0x9a57, 0x1c5b, + 0x9a5a, 0x06bb, + 0x9a5b, 0x1c5a, + 0x9a5f, 0x1c5c, + 0x9a62, 0x1c5d, + 0x9a64, 0x1c5f, + 0x9a65, 0x1c5e, + 0x9a69, 0x1c60, + 0x9a6a, 0x1c62, + 0x9a6b, 0x1c61, + 0x9aa8, 0x080e, + 0x9aad, 0x1c63, + 0x9ab0, 0x1c64, + 0x9ab8, 0x059a, + 0x9abc, 0x1c65, + 0x9ac0, 0x1c66, + 0x9ac4, 0x0a37, + 0x9acf, 0x1c67, + 0x9ad1, 0x1c68, + 0x9ad3, 0x1c69, + 0x9ad8, 0x07f4, + 0x9ad9, 0x2201, + 0x9adc, 0x2202, + 0x9ade, 0x1c6b, + 0x9ae2, 0x1c6d, + 0x9ae6, 0x1c6f, + 0x9aea, 0x0d45, + 0x9aeb, 0x1c71, + 0x9aed, 0x0d98, + 0x9aee, 0x1c72, + 0x9aef, 0x1c70, + 0x9af1, 0x1c74, + 0x9af4, 0x1c73, + 0x9af7, 0x1c75, + 0x9afb, 0x1c76, + 0x9b06, 0x1c77, + 0x9b18, 0x1c78, + 0x9b1a, 0x1c79, + 0x9b1f, 0x1c7a, + 0x9b22, 0x1c7b, + 0x9b25, 0x1c7d, + 0x9b27, 0x1c7e, + 0x9b2e, 0x1c82, + 0x9b31, 0x14d4, + 0x9b32, 0x1c84, + 0x9b3b, 0x17a9, + 0x9b3c, 0x064e, + 0x9b41, 0x057f, + 0x9b42, 0x0822, + 0x9b43, 0x1c86, + 0x9b44, 0x1c85, + 0x9b45, 0x0eb1, + 0x9b4d, 0x1c88, + 0x9b4f, 0x1c87, + 0x9b51, 0x1c8a, + 0x9b54, 0x0e90, + 0x9b58, 0x1c8b, + 0x9b5a, 0x0695, + 0x9b6f, 0x0fcb, + 0x9b72, 0x2204, + 0x9b74, 0x1c8c, + 0x9b75, 0x2203, + 0x9b83, 0x1c8e, + 0x9b8e, 0x0482, + 0x9b8f, 0x2205, + 0x9b91, 0x1c8f, + 0x9b92, 0x0dfb, + 0x9b93, 0x1c8d, + 0x9b96, 0x1c90, + 0x9b9f, 0x1c92, + 0x9ba8, 0x1c94, + 0x9baa, 0x0e9c, + 0x9bab, 0x087b, + 0x9bad, 0x086a, + 0x9bae, 0x0ab1, + 0x9bb1, 0x2206, + 0x9bb4, 0x1c95, + 0x9bb9, 0x1c98, + 0x9bbb, 0x2207, + 0x9bc0, 0x1c96, + 0x9bc6, 0x1c99, + 0x9bc9, 0x07a5, + 0x9bca, 0x1c97, + 0x9bcf, 0x1c9a, + 0x9bd1, 0x1c9b, + 0x9bd4, 0x1ca0, + 0x9bd6, 0x0878, + 0x9bdb, 0x0b44, + 0x9be1, 0x1ca1, + 0x9be2, 0x1c9e, + 0x9be3, 0x1c9d, + 0x9be4, 0x1c9f, + 0x9be8, 0x0735, + 0x9bf0, 0x1ca5, + 0x9bf1, 0x1ca4, + 0x9bf2, 0x1ca3, + 0x9bf5, 0x0477, + 0x9c00, 0x2208, + 0x9c04, 0x1caf, + 0x9c06, 0x1cab, + 0x9c08, 0x1cac, + 0x9c09, 0x1ca8, + 0x9c0a, 0x1cae, + 0x9c0c, 0x1caa, + 0x9c0d, 0x05c0, + 0x9c10, 0x0ff2, + 0x9c12, 0x1cad, + 0x9c13, 0x1ca9, + 0x9c14, 0x1ca7, + 0x9c15, 0x1ca6, + 0x9c1b, 0x1cb1, + 0x9c21, 0x1cb4, + 0x9c24, 0x1cb3, + 0x9c25, 0x1cb2, + 0x9c2d, 0x0dbb, + 0x9c2e, 0x1cb0, + 0x9c2f, 0x04b7, + 0x9c30, 0x1cb5, + 0x9c32, 0x1cb7, + 0x9c39, 0x05cd, + 0x9c3a, 0x1ca2, + 0x9c3b, 0x04d9, + 0x9c3e, 0x1cb9, + 0x9c46, 0x1cb8, + 0x9c47, 0x1cb6, + 0x9c48, 0x0b6b, + 0x9c52, 0x0e9e, + 0x9c57, 0x0fa2, + 0x9c5a, 0x1cba, + 0x9c60, 0x1cbb, + 0x9c67, 0x1cbc, + 0x9c76, 0x1cbd, + 0x9c78, 0x1cbe, + 0x9ce5, 0x0bd7, + 0x9ce7, 0x1cbf, + 0x9ce9, 0x0d4b, + 0x9ceb, 0x1cc4, + 0x9cec, 0x1cc0, + 0x9cf0, 0x1cc1, + 0x9cf3, 0x0e5f, + 0x9cf4, 0x0ed0, + 0x9cf6, 0x0ca8, + 0x9d03, 0x1cc5, + 0x9d06, 0x1cc6, + 0x9d07, 0x0c96, + 0x9d08, 0x1cc3, + 0x9d09, 0x1cc2, + 0x9d0e, 0x052a, + 0x9d12, 0x1cce, + 0x9d15, 0x1ccd, + 0x9d1b, 0x0517, + 0x9d1f, 0x1ccb, + 0x9d23, 0x1cca, + 0x9d26, 0x1cc8, + 0x9d28, 0x05d9, + 0x9d2a, 0x1cc7, + 0x9d2b, 0x08de, + 0x9d2c, 0x0529, + 0x9d3b, 0x07f5, + 0x9d3e, 0x1cd1, + 0x9d3f, 0x1cd0, + 0x9d41, 0x1ccf, + 0x9d44, 0x1ccc, + 0x9d46, 0x1cd2, + 0x9d48, 0x1cd3, + 0x9d50, 0x1cd8, + 0x9d51, 0x1cd7, + 0x9d59, 0x1cd9, + 0x9d5c, 0x04cf, + 0x9d5d, 0x1cd4, + 0x9d60, 0x0806, + 0x9d61, 0x0ec5, + 0x9d64, 0x1cd6, + 0x9d6b, 0x220a, + 0x9d6c, 0x0e60, + 0x9d6f, 0x1cde, + 0x9d70, 0x2209, + 0x9d72, 0x1cda, + 0x9d7a, 0x1cdf, + 0x9d87, 0x1cdc, + 0x9d89, 0x1cdb, + 0x9d8f, 0x0732, + 0x9d9a, 0x1ce0, + 0x9da4, 0x1ce1, + 0x9da9, 0x1ce2, + 0x9dab, 0x1cdd, + 0x9daf, 0x1cc9, + 0x9db2, 0x1ce3, + 0x9db4, 0x0bfd, + 0x9db8, 0x1ce7, + 0x9dba, 0x1ce8, + 0x9dbb, 0x1ce6, + 0x9dc1, 0x1ce5, + 0x9dc2, 0x1ceb, + 0x9dc4, 0x1ce4, + 0x9dc6, 0x1ce9, + 0x9dcf, 0x1cea, + 0x9dd3, 0x1ced, + 0x9dd7, 0x1dde, + 0x9dd9, 0x1cec, + 0x9de6, 0x1cef, + 0x9ded, 0x1cf0, + 0x9def, 0x1cf1, + 0x9df2, 0x0fef, + 0x9df8, 0x1cee, + 0x9df9, 0x0b4b, + 0x9dfa, 0x085d, + 0x9dfd, 0x1cf2, + 0x9e19, 0x220c, + 0x9e1a, 0x1cf3, + 0x9e1e, 0x1cf5, + 0x9e75, 0x1cf6, + 0x9e78, 0x0768, + 0x9e79, 0x1cf7, + 0x9e7c, 0x1dfd, + 0x9e7d, 0x1cf8, + 0x9e7f, 0x08db, + 0x9e81, 0x1cf9, + 0x9e88, 0x1cfa, + 0x9e8b, 0x1cfb, + 0x9e91, 0x1cff, + 0x9e92, 0x1cfd, + 0x9e93, 0x0fe2, + 0x9e95, 0x1cfe, + 0x9e97, 0x0fb7, + 0x9e9d, 0x1d00, + 0x9e9f, 0x0fa3, + 0x9ea5, 0x1d01, + 0x9ea6, 0x0d34, + 0x9ea9, 0x1d02, + 0x9eaa, 0x1d04, + 0x9ead, 0x1d05, + 0x9eb4, 0x1e02, + 0x9eb5, 0x1e75, + 0x9eb8, 0x1d03, + 0x9eb9, 0x07ff, + 0x9eba, 0x0ed9, + 0x9ebb, 0x0e91, + 0x9ebc, 0x1284, + 0x9ebe, 0x14ff, + 0x9ebf, 0x0ea9, + 0x9ec4, 0x052b, + 0x9ecc, 0x1d07, + 0x9ecd, 0x066a, + 0x9ece, 0x1d08, + 0x9ed1, 0x220d, + 0x9ed2, 0x0807, + 0x9ed4, 0x1d0b, + 0x9ed8, 0x160d, + 0x9ed9, 0x0ee7, + 0x9edb, 0x0b43, + 0x9edc, 0x1d0c, + 0x9edd, 0x1d0e, + 0x9ede, 0x1d0d, + 0x9ee0, 0x1d0f, + 0x9ee5, 0x1d10, + 0x9ee8, 0x1d11, + 0x9eef, 0x1d12, + 0x9ef4, 0x1d13, + 0x9ef6, 0x1d14, + 0x9ef9, 0x1d16, + 0x9efb, 0x1d17, + 0x9f07, 0x1d1a, + 0x9f0e, 0x0c1e, + 0x9f13, 0x0791, + 0x9f15, 0x1d1d, + 0x9f20, 0x0acf, + 0x9f21, 0x1d1e, + 0x9f2c, 0x1d1f, + 0x9f3b, 0x0d93, + 0x9f3e, 0x1d20, + 0x9f4a, 0x1d21, + 0x9f4b, 0x170a, + 0x9f4e, 0x1a7b, + 0x9f4f, 0x1c06, + 0x9f52, 0x1d22, + 0x9f54, 0x1d23, + 0x9f5f, 0x1d25, + 0x9f62, 0x0fb8, + 0x9f63, 0x1d24, + 0x9f66, 0x1d28, + 0x9f6a, 0x1d2b, + 0x9f6c, 0x1d2a, + 0x9f72, 0x1d2d, + 0x9f76, 0x1d2e, + 0x9f77, 0x1d2c, + 0x9f8d, 0x0f7e, + 0x9f95, 0x1d2f, + 0x9f9c, 0x1d30, + 0x9f9d, 0x1727, + 0x9fa0, 0x1d31, + 0xf929, 0x2129, + 0xf9dc, 0x21ee, + 0xfa0e, 0x20da, + 0xfa0f, 0x20e5, + 0xfa11, 0x20fb, + 0xfa12, 0x2121, + 0xfa13, 0x2131, + 0xfa14, 0x2133, + 0xfa15, 0x215e, + 0xfa16, 0x2164, + 0xfa17, 0x217b, + 0xfa18, 0x2183, + 0xfa1b, 0x2187, + 0xfa1c, 0x218b, + 0xfa1d, 0x218e, + 0xfa1e, 0x2197, + 0xfa1f, 0x21a2, + 0xfa20, 0x21a4, + 0xfa22, 0x21ae, + 0xfa23, 0x21b6, + 0xfa24, 0x21b8, + 0xfa26, 0x21bc, + 0xfa27, 0x21d8, + 0xfa28, 0x21df, + 0xfa29, 0x21ef, + 0xfa2a, 0x21fb, + 0xfa2c, 0x21fe, + 0xfa2d, 0x220b, + 0xfb01, 0x0070, + 0xfe30, 0x1eda, + 0xfe31, 0x1ed4, + 0xfe33, 0x1ed2, + 0xfe35, 0x1edb, + 0xfe37, 0x1ee1, + 0xfe39, 0x1edd, + 0xfe3b, 0x1eeb, + 0xfe3d, 0x1ee5, + 0xfe3f, 0x1ee3, + 0xfe41, 0x1ee7, + 0xff01, 0x0282, + 0xff02, 0x1f47, + 0xff03, 0x02cc, + 0xff04, 0x02c8, + 0xff05, 0x02cb, + 0xff06, 0x02cd, + 0xff07, 0x1f46, + 0xff08, 0x02a2, + 0xff0a, 0x02ce, + 0xff0b, 0x02b4, + 0xff0c, 0x027c, + 0xff0d, 0x0296, + 0xff0e, 0x027d, + 0xff0f, 0x0297, + 0xff10, 0x030c, + 0xff1a, 0x027f, + 0xff1c, 0x02bb, + 0xff1d, 0x02b9, + 0xff1e, 0x02bc, + 0xff1f, 0x0281, + 0xff20, 0x02cf, + 0xff21, 0x0316, + 0xff3b, 0x02a6, + 0xff3c, 0x0298, + 0xff3d, 0x02a7, + 0xff3e, 0x0288, + 0xff3f, 0x028a, + 0xff40, 0x0286, + 0xff41, 0x0330, + 0xff5b, 0x02a8, + 0xff5c, 0x029b, + 0xff5d, 0x02a9, + 0xff5e, 0x0299, + 0xff61, 0x0147, + 0xffe0, 0x02c9, + 0xffe2, 0x02ef, + 0xffe3, 0x0289, + 0xffe4, 0x1f45, + 0xffe5, 0x02c7, + 0xffe8, 0x0143, + 0x00b0, 0x204d, + 0x2015, 0x1ed4, + 0x2016, 0x1ed7, + 0x2018, 0x2059, + 0x201c, 0x2057, + 0x2025, 0x1eda, + 0x2026, 0x1ed9, + 0x2032, 0x2051, + 0x2033, 0x205b, + 0x2190, 0x02e2, + 0x2191, 0x02e0, + 0x2192, 0x02e3, + 0x2193, 0x02e1, + 0x2225, 0x1ed7, + 0x223c, 0x1ed6, + 0x22ef, 0x1ed9, + 0x2500, 0x1d39, + 0x2502, 0x1d37, + 0x2504, 0x1d3d, + 0x2506, 0x1d3b, + 0x2508, 0x1d41, + 0x250a, 0x1d3f, + 0x250c, 0x1d47, + 0x250d, 0x1d49, + 0x250e, 0x1d48, + 0x250f, 0x1d4a, + 0x2510, 0x1d4f, + 0x2511, 0x1d51, + 0x2512, 0x1d50, + 0x2513, 0x1d52, + 0x2514, 0x1d43, + 0x2515, 0x1d45, + 0x2516, 0x1d44, + 0x2517, 0x1d46, + 0x2518, 0x1d4b, + 0x2519, 0x1d4d, + 0x251a, 0x1d4c, + 0x251b, 0x1d4e, + 0x251c, 0x1d63, + 0x251d, 0x1d67, + 0x251e, 0x1d65, + 0x251f, 0x1d64, + 0x2520, 0x1d66, + 0x2521, 0x1d69, + 0x2522, 0x1d68, + 0x2523, 0x1d6a, + 0x2525, 0x1d6f, + 0x2526, 0x1d6d, + 0x2527, 0x1d6c, + 0x2528, 0x1d6e, + 0x2529, 0x1d71, + 0x252a, 0x1d70, + 0x252b, 0x1d72, + 0x252c, 0x1d5b, + 0x252d, 0x1d5d, + 0x2530, 0x1d5c, + 0x2531, 0x1d60, + 0x2534, 0x1d53, + 0x2535, 0x1d55, + 0x2538, 0x1d54, + 0x2539, 0x1d58, + 0x253d, 0x1d77, + 0x2540, 0x1d75, + 0x2541, 0x1d74, + 0x2542, 0x1d76, + 0x2543, 0x1d7b, + 0x2544, 0x1d7d, + 0x2545, 0x1d7a, + 0x2546, 0x1d7c, + 0x2547, 0x1d81, + 0x2548, 0x1d80, + 0x2549, 0x1d7e, + 0x3001, 0x1ecf, + 0x3008, 0x1ee3, + 0x3013, 0x204e, + 0x3014, 0x1edd, + 0x301c, 0x1ed6, + 0x301d, 0x1f14, + 0x301f, 0x1f15, + 0x3041, 0x1eee, + 0x3043, 0x1eef, + 0x3045, 0x1ef0, + 0x3047, 0x1ef1, + 0x3049, 0x1ef2, + 0x3063, 0x1ef3, + 0x3083, 0x1ef4, + 0x3085, 0x1ef5, + 0x3087, 0x1ef6, + 0x308e, 0x1ef7, + 0x309b, 0x2050, + 0x309c, 0x204f, + 0x30a1, 0x1ef8, + 0x30a3, 0x1ef9, + 0x30a5, 0x1efa, + 0x30a7, 0x1efb, + 0x30a9, 0x1efc, + 0x30c3, 0x1efd, + 0x30e3, 0x1efe, + 0x30e5, 0x1eff, + 0x30e7, 0x1f00, + 0x30ee, 0x1f01, + 0x30f5, 0x1f02, + 0x30fc, 0x1ed3, + 0x3300, 0x209e, + 0x3303, 0x2092, + 0x3305, 0x208d, + 0x330d, 0x1f0e, + 0x3314, 0x1f05, + 0x3315, 0x2094, + 0x3316, 0x208a, + 0x3318, 0x2093, + 0x331e, 0x20a1, + 0x3322, 0x2089, + 0x3323, 0x209c, + 0x3326, 0x1f0f, + 0x3327, 0x1f09, + 0x332a, 0x20a4, + 0x332b, 0x1f11, + 0x3331, 0x20a6, + 0x3333, 0x208e, + 0x3336, 0x1f0b, + 0x3339, 0x2097, + 0x333b, 0x209d, + 0x3342, 0x209b, + 0x3347, 0x20a5, + 0x3349, 0x1f04, + 0x334a, 0x1f12, + 0x334d, 0x1f07, + 0x334e, 0x2091, + 0x3351, 0x1f0c, + 0x3357, 0x2098, + 0x337f, 0x2084, + 0xff08, 0x1edb, + 0xff0c, 0x204c, + 0xff0d, 0x1ed5, + 0xff0e, 0x2052, + 0xff1d, 0x1eed, + 0xff3b, 0x1edf, + 0xff3d, 0x1ee0, + 0xff3f, 0x1ed2, + 0xff5b, 0x1ee1, + 0xff5c, 0x1ed8, + 0xff5d, 0x1ee2, + 0xff5e, 0x1ed6, + 0xffe3, 0x1ed1, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12UniJISUCS2VEnc16 = { + 1, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12UniJISUCS2VMap2, 7108 +}; + +static Gushort japan12VMap2[294] = { + 0x0000, 0x0000, + 0x2121, 0x0279, + 0x2221, 0x02d7, + 0x223a, 0x02e5, + 0x224a, 0x02ed, + 0x225c, 0x02f4, + 0x2272, 0x0303, + 0x227e, 0x030b, + 0x2330, 0x030c, + 0x2341, 0x0316, + 0x2361, 0x0330, + 0x2421, 0x034a, + 0x2521, 0x039d, + 0x2621, 0x03f3, + 0x2641, 0x040b, + 0x2721, 0x0423, + 0x2751, 0x0444, + 0x2821, 0x1d37, + 0x2822, 0x1d39, + 0x2823, 0x1d43, + 0x2824, 0x1d47, + 0x2825, 0x1d4f, + 0x2826, 0x1d4b, + 0x2827, 0x1d53, + 0x2828, 0x1d63, + 0x2829, 0x1d5b, + 0x282a, 0x1d6b, + 0x282b, 0x1d73, + 0x282c, 0x1d38, + 0x282d, 0x1d3a, + 0x282e, 0x1d46, + 0x282f, 0x1d4a, + 0x2830, 0x1d52, + 0x2831, 0x1d4e, + 0x2832, 0x1d5a, + 0x2833, 0x1d6a, + 0x2834, 0x1d62, + 0x2835, 0x1d72, + 0x2836, 0x1d82, + 0x2837, 0x1d57, + 0x2838, 0x1d66, + 0x2839, 0x1d5f, + 0x283a, 0x1d6e, + 0x283b, 0x1d76, + 0x283c, 0x1d54, + 0x283d, 0x1d67, + 0x283e, 0x1d5c, + 0x283f, 0x1d6f, + 0x2840, 0x1d79, + 0x3021, 0x0465, + 0x3121, 0x04c3, + 0x3221, 0x0521, + 0x3321, 0x057f, + 0x3421, 0x05dd, + 0x3521, 0x063b, + 0x3621, 0x0699, + 0x3721, 0x06f7, + 0x3821, 0x0755, + 0x3921, 0x07b3, + 0x3a21, 0x0811, + 0x3b21, 0x086f, + 0x3c21, 0x08cd, + 0x3d21, 0x092b, + 0x3e21, 0x0989, + 0x3f21, 0x09e7, + 0x4021, 0x0a45, + 0x4121, 0x0aa3, + 0x4221, 0x0b01, + 0x4321, 0x0b5f, + 0x4421, 0x0bbd, + 0x4521, 0x0c1b, + 0x4621, 0x0c79, + 0x4721, 0x0cd7, + 0x4821, 0x0d35, + 0x4921, 0x0d93, + 0x4a21, 0x0df1, + 0x4b21, 0x0e4f, + 0x4c21, 0x0ead, + 0x4d21, 0x0f0b, + 0x4e21, 0x0f69, + 0x4f21, 0x0fc7, + 0x5021, 0x0ffa, + 0x5121, 0x1058, + 0x5221, 0x10b6, + 0x5321, 0x1114, + 0x5421, 0x1172, + 0x5521, 0x11d0, + 0x5621, 0x122e, + 0x5721, 0x128c, + 0x5821, 0x12ea, + 0x5921, 0x1348, + 0x5a21, 0x13a6, + 0x5b21, 0x1404, + 0x5c21, 0x1462, + 0x5d21, 0x14c0, + 0x5e21, 0x151e, + 0x5f21, 0x157c, + 0x6021, 0x15da, + 0x6121, 0x1638, + 0x6221, 0x1696, + 0x6321, 0x16f4, + 0x6421, 0x1752, + 0x6521, 0x17b0, + 0x6621, 0x180e, + 0x6721, 0x186c, + 0x6821, 0x18ca, + 0x6921, 0x1928, + 0x6a21, 0x1986, + 0x6b21, 0x19e4, + 0x6c21, 0x1a42, + 0x6d21, 0x1aa0, + 0x6e21, 0x1afe, + 0x6f21, 0x1b5c, + 0x7021, 0x1bba, + 0x7121, 0x1c18, + 0x7221, 0x1c76, + 0x7321, 0x1cd4, + 0x7421, 0x1d32, + 0x7425, 0x205c, + 0x2122, 0x1ecf, + 0x2131, 0x1ed1, + 0x213c, 0x1ed3, + 0x2141, 0x1ed6, + 0x214a, 0x1edb, + 0x2161, 0x1eed, + 0x2421, 0x1eee, + 0x2423, 0x1eef, + 0x2425, 0x1ef0, + 0x2427, 0x1ef1, + 0x2429, 0x1ef2, + 0x2443, 0x1ef3, + 0x2463, 0x1ef4, + 0x2465, 0x1ef5, + 0x2467, 0x1ef6, + 0x246e, 0x1ef7, + 0x2521, 0x1ef8, + 0x2523, 0x1ef9, + 0x2525, 0x1efa, + 0x2527, 0x1efb, + 0x2529, 0x1efc, + 0x2543, 0x1efd, + 0x2563, 0x1efe, + 0x2565, 0x1eff, + 0x2567, 0x1f00, + 0x256e, 0x1f01, + 0x2575, 0x1f02, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12VEnc16 = { + 1, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12VMap2, 147 +}; + +static Gushort japan12WPSymbolMap2[4] = { + 0x0000, 0x0000, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12WPSymbolEnc16 = { + 0, + { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x1f78, 0x1f7a, 0x1fff, 0x2004, 0x1f7d, 0x1f7e, 0x1f7f, + 0x1f80, 0x1f81, 0x1f82, 0x1f83, 0x1f84, 0x1f85, 0x1f86, 0x1f87, + 0x1f88, 0x1f89, 0x1f8a, 0x1f8b, 0x1f8c, 0x1f8d, 0x1f8e, 0x1f8f, + 0x1f90, 0x1f9c, 0x1f9d, 0x1f9e, 0x1f9f, 0x1fa0, 0x1fa1, 0x1fa2, + 0x1fa3, 0x1fa4, 0x1fa5, 0x1ffa, 0x1f54, 0x1f55, 0x1ffb, 0x1f56, + 0x1f57, 0x1ffc, 0x1f65, 0x1f58, 0x1f59, 0x1f5a, 0x1ffd, 0x1ffe, + 0x2000, 0x2001, 0x1edb, 0x1edc, 0x1ed6, 0x2002, 0x1f63, 0x1f5b, + 0x1f5c, 0x1f5d, 0x2003, 0x1fb0, 0x1fb1, 0x1fb2, 0x1fb3, 0x1fb4, + 0x1fb5, 0x1fb6, 0x1fb7, 0x1fb8, 0x1fb9, 0x1fba, 0x1fbb, 0x1fbc, + 0x1fbd, 0x1fbe, 0x1fbf, 0x1fc0, 0x1fc1, 0x1fc2, 0x1fc3, 0x1fc4, + 0x1fc5, 0x1fc6, 0x1fc7, 0x1fc8, 0x1fc9, 0x2005, 0x2006, 0x2007, + 0x2008, 0x2009, 0x200a, 0x200b, 0x200c, 0x200d, 0x1fd7, 0x0000, + 0x0000, 0x200e, 0x200f, 0x2010, 0x2011, 0x2012, 0x2013, 0x2014, + 0x2015, 0x2016, 0x2017, 0x2018, 0x2019, 0x201a, 0x201b, 0x201c, + 0x201d, 0x201e, 0x1f79, 0x201f, 0x2020, 0x2021, 0x2022, 0x2023, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12WPSymbolMap2, 2 +}; + +static Gushort japan12AdobeJapan12VMap2[74] = { + 0x0000, 0x0000, + 0x0000, 0x0000, + 0x0100, 0x0100, + 0x0200, 0x0200, + 0x0300, 0x0300, + 0x0400, 0x0400, + 0x0500, 0x0500, + 0x0600, 0x0600, + 0x0700, 0x0700, + 0x0800, 0x0800, + 0x0900, 0x0900, + 0x0a00, 0x0a00, + 0x0b00, 0x0b00, + 0x0c00, 0x0c00, + 0x0d00, 0x0d00, + 0x0e00, 0x0e00, + 0x0f00, 0x0f00, + 0x1000, 0x1000, + 0x1100, 0x1100, + 0x1200, 0x1200, + 0x1300, 0x1300, + 0x1400, 0x1400, + 0x1500, 0x1500, + 0x1600, 0x1600, + 0x1700, 0x1700, + 0x1800, 0x1800, + 0x1900, 0x1900, + 0x1a00, 0x1a00, + 0x1b00, 0x1b00, + 0x1c00, 0x1c00, + 0x1d00, 0x1d00, + 0x1e00, 0x1e00, + 0x1f00, 0x1f00, + 0x2000, 0x2000, + 0x2100, 0x2100, + 0x2200, 0x2200, + 0xffff, 0x0000 +}; + +static GfxFontEncoding16 japan12AdobeJapan12VEnc16 = { + 1, + { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }, + { 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, + 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000 }, + japan12AdobeJapan12VMap2, 37 +}; + +struct GfxFontEnc16Entry { + char *name; + GfxFontEncoding16 *enc; +}; + +static GfxFontEnc16Entry gfxFontEnc16Tab[] = { + { "78-EUC-H", &japan1278EUCHEnc16 }, + { "78-EUC-V", &japan1278EUCVEnc16 }, + { "78-H", &japan1278HEnc16 }, + { "78-RKSJ-H", &japan1278RKSJHEnc16 }, + { "78-RKSJ-V", &japan1278RKSJVEnc16 }, + { "78-V", &japan1278VEnc16 }, + { "78ms-RKSJ-H", &japan1278msRKSJHEnc16 }, + { "78ms-RKSJ-V", &japan1278msRKSJVEnc16 }, + { "83pv-RKSJ-H", &japan1283pvRKSJHEnc16 }, + { "90ms-RKSJ-H", &japan1290msRKSJHEnc16 }, + { "90ms-RKSJ-V", &japan1290msRKSJVEnc16 }, + { "90msp-RKSJ-H", &japan1290mspRKSJHEnc16 }, + { "90msp-RKSJ-V", &japan1290mspRKSJVEnc16 }, + { "90pv-RKSJ-H", &japan1290pvRKSJHEnc16 }, + { "90pv-RKSJ-V", &japan1290pvRKSJVEnc16 }, + { "Add-H", &japan12AddHEnc16 }, + { "Add-RKSJ-H", &japan12AddRKSJHEnc16 }, + { "Add-RKSJ-V", &japan12AddRKSJVEnc16 }, + { "Add-V", &japan12AddVEnc16 }, + { "Adobe-Japan1-0", &japan12AdobeJapan10Enc16 }, + { "Adobe-Japan1-1", &japan12AdobeJapan11Enc16 }, + { "Adobe-Japan1-2", &japan12AdobeJapan12Enc16 }, + { "EUC-H", &japan12EUCHEnc16 }, + { "EUC-V", &japan12EUCVEnc16 }, + { "Ext-H", &japan12ExtHEnc16 }, + { "Ext-RKSJ-H", &japan12ExtRKSJHEnc16 }, + { "Ext-RKSJ-V", &japan12ExtRKSJVEnc16 }, + { "Ext-V", &japan12ExtVEnc16 }, + { "H", &japan12HEnc16 }, + { "Hankaku", &japan12HankakuEnc16 }, + { "Hiragana", &japan12HiraganaEnc16 }, + { "Katakana", &japan12KatakanaEnc16 }, + { "NWP-H", &japan12NWPHEnc16 }, + { "NWP-V", &japan12NWPVEnc16 }, + { "RKSJ-H", &japan12RKSJHEnc16 }, + { "RKSJ-V", &japan12RKSJVEnc16 }, + { "Roman", &japan12RomanEnc16 }, + { "UniJIS-UCS2-H", &japan12UniJISUCS2HEnc16 }, + { "UniJIS-UCS2-V", &japan12UniJISUCS2VEnc16 }, + { "V", &japan12VEnc16 }, + { "WP-Symbol", &japan12WPSymbolEnc16 }, + { "Identity-H", &japan12AdobeJapan12Enc16 }, + { "Identity-V", &japan12AdobeJapan12VEnc16 }, + { NULL, NULL } +}; + +#endif diff --git a/pdftops/COPYING b/pdftops/COPYING new file mode 100644 index 0000000000..a43ea2126f --- /dev/null +++ b/pdftops/COPYING @@ -0,0 +1,339 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/pdftops/Catalog.cxx b/pdftops/Catalog.cxx new file mode 100644 index 0000000000..ea968ee82c --- /dev/null +++ b/pdftops/Catalog.cxx @@ -0,0 +1,284 @@ +//======================================================================== +// +// Catalog.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include "gmem.h" +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Page.h" +#include "Error.h" +#include "Link.h" +#include "Catalog.h" + +//------------------------------------------------------------------------ +// Catalog +//------------------------------------------------------------------------ + +Catalog::Catalog(Object *catDict) { + Object pagesDict; + Object obj, obj2; + int i; + + ok = gTrue; + pages = NULL; + pageRefs = NULL; + numPages = 0; + + if (!catDict->isDict("Catalog")) { + error(-1, "Catalog object is wrong type (%s)", catDict->getTypeName()); + goto err1; + } + + // read page tree + catDict->dictLookup("Pages", &pagesDict); + if (!pagesDict.isDict("Pages")) { + error(-1, "Top-level pages object is wrong type (%s)", + pagesDict.getTypeName()); + goto err2; + } + pagesDict.dictLookup("Count", &obj); + if (!obj.isInt()) { + error(-1, "Page count in top-level pages object is wrong type (%s)", + obj.getTypeName()); + goto err3; + } + numPages = obj.getInt(); + obj.free(); + pages = (Page **)gmalloc(numPages * sizeof(Page *)); + pageRefs = (Ref *)gmalloc(numPages * sizeof(Ref)); + for (i = 0; i < numPages; ++i) { + pages[i] = NULL; + pageRefs[i].num = -1; + pageRefs[i].gen = -1; + } + readPageTree(pagesDict.getDict(), NULL, 0); + pagesDict.free(); + + // read named destination dictionary + catDict->dictLookup("Dests", &dests); + + // read root of named destination tree + if (catDict->dictLookup("Names", &obj)->isDict()) + obj.dictLookup("Dests", &nameTree); + else + nameTree.initNull(); + obj.free(); + + // read base URI + baseURI = NULL; + if (catDict->dictLookup("URI", &obj)->isDict()) { + if (obj.dictLookup("Base", &obj2)->isString()) { + baseURI = obj2.getString()->copy(); + } + obj2.free(); + } + obj.free(); + + return; + + err3: + obj.free(); + err2: + pagesDict.free(); + err1: + dests.initNull(); + nameTree.initNull(); + ok = gFalse; +} + +Catalog::~Catalog() { + int i; + + if (pages) { + for (i = 0; i < numPages; ++i) { + if (pages[i]) + delete pages[i]; + } + gfree(pages); + gfree(pageRefs); + } + dests.free(); + nameTree.free(); + if (baseURI) { + delete baseURI; + } +} + +int Catalog::readPageTree(Dict *pagesDict, PageAttrs *attrs, int start) { + Object kids; + Object kid; + Object kidRef; + PageAttrs *attrs1, *attrs2; + Page *page; + int i; + + attrs1 = new PageAttrs(attrs, pagesDict); + pagesDict->lookup("Kids", &kids); + if (!kids.isArray()) { + error(-1, "Kids object (page %d) is wrong type (%s)", + start+1, kids.getTypeName()); + goto err1; + } + for (i = 0; i < kids.arrayGetLength(); ++i) { + kids.arrayGet(i, &kid); + if (kid.isDict("Page")) { + attrs2 = new PageAttrs(attrs1, kid.getDict()); + page = new Page(start+1, kid.getDict(), attrs2); + if (!page->isOk()) { + ++start; + goto err3; + } + pages[start] = page; + kids.arrayGetNF(i, &kidRef); + if (kidRef.isRef()) { + pageRefs[start].num = kidRef.getRefNum(); + pageRefs[start].gen = kidRef.getRefGen(); + } + kidRef.free(); + ++start; + //~ found one PDF file where a Pages object is missing the /Type entry + // } else if (kid.isDict("Pages")) { + } else if (kid.isDict()) { + if ((start = readPageTree(kid.getDict(), attrs1, start)) < 0) + goto err2; + } else { + error(-1, "Kid object (page %d) is wrong type (%s)", + start+1, kid.getTypeName()); + goto err2; + } + kid.free(); + } + delete attrs1; + kids.free(); + return start; + + err3: + delete page; + err2: + kid.free(); + err1: + kids.free(); + delete attrs1; + ok = gFalse; + return -1; +} + +int Catalog::findPage(int num, int gen) { + int i; + + for (i = 0; i < numPages; ++i) { + if (pageRefs[i].num == num && pageRefs[i].gen == gen) + return i + 1; + } + return 0; +} + +LinkDest *Catalog::findDest(GString *name) { + LinkDest *dest; + Object obj1, obj2; + GBool found; + + // try named destination dictionary then name tree + found = gFalse; + if (dests.isDict()) { + if (!dests.dictLookup(name->getCString(), &obj1)->isNull()) + found = gTrue; + else + obj1.free(); + } + if (!found && nameTree.isDict()) { + if (!findDestInTree(&nameTree, name, &obj1)->isNull()) + found = gTrue; + else + obj1.free(); + } + if (!found) + return NULL; + + // construct LinkDest + dest = NULL; + if (obj1.isArray()) { + dest = new LinkDest(obj1.getArray(), gTrue); + } else if (obj1.isDict()) { + if (obj1.dictLookup("D", &obj2)->isArray()) + dest = new LinkDest(obj2.getArray(), gTrue); + else + error(-1, "Bad named destination value"); + obj2.free(); + } else { + error(-1, "Bad named destination value"); + } + obj1.free(); + + return dest; +} + +Object *Catalog::findDestInTree(Object *tree, GString *name, Object *obj) { + Object names, name1; + Object kids, kid, limits, low, high; + GBool done, found; + int cmp, i; + + // leaf node + if (tree->dictLookup("Names", &names)->isArray()) { + done = found = gFalse; + for (i = 0; !done && i < names.arrayGetLength(); i += 2) { + if (names.arrayGet(i, &name1)->isString()) { + cmp = name->cmp(name1.getString()); + if (cmp == 0) { + names.arrayGet(i+1, obj); + found = gTrue; + done = gTrue; + } else if (cmp < 0) { + done = gTrue; + } + name1.free(); + } + } + names.free(); + if (!found) + obj->initNull(); + return obj; + } + names.free(); + + // root or intermediate node + done = gFalse; + if (tree->dictLookup("Kids", &kids)->isArray()) { + for (i = 0; !done && i < kids.arrayGetLength(); ++i) { + if (kids.arrayGet(i, &kid)->isDict()) { + if (kid.dictLookup("Limits", &limits)->isArray()) { + if (limits.arrayGet(0, &low)->isString() && + name->cmp(low.getString()) >= 0) { + if (limits.arrayGet(1, &high)->isString() && + name->cmp(high.getString()) <= 0) { + findDestInTree(&kid, name, obj); + done = gTrue; + } + high.free(); + } + low.free(); + } + limits.free(); + } + kid.free(); + } + } + kids.free(); + + // name was outside of ranges of all kids + if (!done) + obj->initNull(); + + return obj; +} diff --git a/pdftops/Catalog.h b/pdftops/Catalog.h new file mode 100644 index 0000000000..abda62d226 --- /dev/null +++ b/pdftops/Catalog.h @@ -0,0 +1,69 @@ +//======================================================================== +// +// Catalog.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef CATALOG_H +#define CATALOG_H + +#ifdef __GNUC__ +#pragma interface +#endif + +class Object; +class Page; +class PageAttrs; +struct Ref; +class LinkDest; + +//------------------------------------------------------------------------ +// Catalog +//------------------------------------------------------------------------ + +class Catalog { +public: + + // Constructor. + Catalog(Object *catDict); + + // Destructor. + ~Catalog(); + + // Is catalog valid? + GBool isOk() { return ok; } + + // Get number of pages. + int getNumPages() { return numPages; } + + // Get a page. + Page *getPage(int i) { return pages[i-1]; } + + // Return base URI, or NULL if none. + GString *getBaseURI() { return baseURI; } + + // Find a page, given its object ID. Returns page number, or 0 if + // not found. + int findPage(int num, int gen); + + // Find a named destination. Returns the link destination, or + // NULL if is not a destination. + LinkDest *findDest(GString *name); + +private: + + Page **pages; // array of pages + Ref *pageRefs; // object ID for each page + int numPages; // number of pages + Object dests; // named destination dictionary + Object nameTree; // name tree + GString *baseURI; // base URI for URI-type links + GBool ok; // true if catalog is valid + + int readPageTree(Dict *pages, PageAttrs *attrs, int start); + Object *findDestInTree(Object *tree, GString *name, Object *obj); +}; + +#endif diff --git a/pdftops/CompactFontInfo.h b/pdftops/CompactFontInfo.h new file mode 100644 index 0000000000..c642660297 --- /dev/null +++ b/pdftops/CompactFontInfo.h @@ -0,0 +1,464 @@ +//======================================================================== +// +// CompactFontInfo.h +// +// Copyright 1999 Derek B. Noonburg +// +//======================================================================== + +#ifndef COMPACTFONTINFO_H +#define COMPACTFONTINFO_H + +static char *type1CStdStrings[391] = { + ".notdef", + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quoteright", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "quoteleft", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "endash", + "dagger", + "daggerdbl", + "periodcentered", + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + "questiondown", + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron", + "emdash", + "AE", + "ordfeminine", + "Lslash", + "Oslash", + "OE", + "ordmasculine", + "ae", + "dotlessi", + "lslash", + "oslash", + "oe", + "germandbls", + "onesuperior", + "logicalnot", + "mu", + "trademark", + "Eth", + "onehalf", + "plusminus", + "Thorn", + "onequarter", + "divide", + "brokenbar", + "degree", + "thorn", + "threequarters", + "twosuperior", + "registered", + "minus", + "eth", + "multiply", + "threesuperior", + "copyright", + "Aacute", + "Acircumflex", + "Adieresis", + "Agrave", + "Aring", + "Atilde", + "Ccedilla", + "Eacute", + "Ecircumflex", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Ntilde", + "Oacute", + "Ocircumflex", + "Odieresis", + "Ograve", + "Otilde", + "Scaron", + "Uacute", + "Ucircumflex", + "Udieresis", + "Ugrave", + "Yacute", + "Ydieresis", + "Zcaron", + "aacute", + "acircumflex", + "adieresis", + "agrave", + "aring", + "atilde", + "ccedilla", + "eacute", + "ecircumflex", + "edieresis", + "egrave", + "iacute", + "icircumflex", + "idieresis", + "igrave", + "ntilde", + "oacute", + "ocircumflex", + "odieresis", + "ograve", + "otilde", + "scaron", + "uacute", + "ucircumflex", + "udieresis", + "ugrave", + "yacute", + "ydieresis", + "zcaron", + "exclamsmall", + "Hungarumlautsmall", + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + "isuperior", + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + "rsuperior", + "ssuperior", + "tsuperior", + "ff", + "ffi", + "ffl", + "parenleftinferior", + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + "Dotaccentsmall", + "Macronsmall", + "figuredash", + "hypheninferior", + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + "zerosuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall", + "001.000", + "001.001", + "001.002", + "001.003", + "Black", + "Bold", + "Book", + "Light", + "Medium", + "Regular", + "Roman", + "Semibold" +}; + +static Gushort type1CISOAdobeCharset[229] = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, + 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, + 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, + 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, + 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, + 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, + 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, + 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, + 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, + 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, + 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, + 220, 221, 222, 223, 224, 225, 226, 227, 228 +}; + +static Gushort type1CExpertCharset[166] = { + 0, 1, 229, 230, 231, 232, 233, 234, 235, 236, + 237, 238, 13, 14, 15, 99, 239, 240, 241, 242, + 243, 244, 245, 246, 247, 248, 27, 28, 249, 250, + 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, + 261, 262, 263, 264, 265, 266, 109, 110, 267, 268, + 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, + 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, + 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, + 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, + 158, 155, 163, 319, 320, 321, 322, 323, 324, 325, + 326, 150, 164, 169, 327, 328, 329, 330, 331, 332, + 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, + 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, + 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, + 373, 374, 375, 376, 377, 378 +}; + +static Gushort type1CExpertSubsetCharset[87] = { + 0, 1, 231, 232, 235, 236, 237, 238, 13, 14, + 15, 99, 239, 240, 241, 242, 243, 244, 245, 246, + 247, 248, 27, 28, 249, 250, 251, 253, 254, 255, + 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 109, 110, 267, 268, 269, 270, 272, 300, 301, + 302, 305, 314, 315, 158, 155, 163, 320, 321, 322, + 323, 324, 325, 326, 150, 164, 169, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346 +}; + +#endif diff --git a/pdftops/Dict.cxx b/pdftops/Dict.cxx new file mode 100644 index 0000000000..c9f4feca69 --- /dev/null +++ b/pdftops/Dict.cxx @@ -0,0 +1,88 @@ +//======================================================================== +// +// Dict.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include "gmem.h" +#include "Object.h" +#include "XRef.h" +#include "Dict.h" + +//------------------------------------------------------------------------ +// Dict +//------------------------------------------------------------------------ + +Dict::Dict() { + entries = NULL; + size = length = 0; + ref = 1; +} + +Dict::~Dict() { + int i; + + for (i = 0; i < length; ++i) { + gfree(entries[i].key); + entries[i].val.free(); + } + gfree(entries); +} + +void Dict::add(char *key, Object *val) { + if (length + 1 > size) { + size += 8; + entries = (DictEntry *)grealloc(entries, size * sizeof(DictEntry)); + } + entries[length].key = key; + entries[length].val = *val; + ++length; +} + +inline DictEntry *Dict::find(char *key) { + int i; + + for (i = 0; i < length; ++i) { + if (!strcmp(key, entries[i].key)) + return &entries[i]; + } + return NULL; +} + +GBool Dict::is(char *type) { + DictEntry *e; + + return (e = find("Type")) && e->val.isName(type); +} + +Object *Dict::lookup(char *key, Object *obj) { + DictEntry *e; + + return (e = find(key)) ? e->val.fetch(obj) : obj->initNull(); +} + +Object *Dict::lookupNF(char *key, Object *obj) { + DictEntry *e; + + return (e = find(key)) ? e->val.copy(obj) : obj->initNull(); +} + +char *Dict::getKey(int i) { + return entries[i].key; +} + +Object *Dict::getVal(int i, Object *obj) { + return entries[i].val.fetch(obj); +} + +Object *Dict::getValNF(int i, Object *obj) { + return entries[i].val.copy(obj); +} diff --git a/pdftops/Dict.h b/pdftops/Dict.h new file mode 100644 index 0000000000..cfc64d3b22 --- /dev/null +++ b/pdftops/Dict.h @@ -0,0 +1,69 @@ +//======================================================================== +// +// Dict.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef DICT_H +#define DICT_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "Object.h" + +//------------------------------------------------------------------------ +// Dict +//------------------------------------------------------------------------ + +struct DictEntry { + char *key; + Object val; +}; + +class Dict { +public: + + // Constructor. + Dict(); + + // Destructor. + ~Dict(); + + // Reference counting. + int incRef() { return ++ref; } + int decRef() { return --ref; } + + // Get number of entries. + int getLength() { return length; } + + // Add an entry. NB: does not copy key. + void add(char *key, Object *val); + + // Check if dictionary is of specified type. + GBool is(char *type); + + // Look up an entry and return the value. Returns a null object + // if is not in the dictionary. + Object *lookup(char *key, Object *obj); + Object *lookupNF(char *key, Object *obj); + + // Iterative accessors. + char *getKey(int i); + Object *getVal(int i, Object *obj); + Object *getValNF(int i, Object *obj); + +private: + + DictEntry *entries; // array of entries + int size; // size of array + int length; // number of entries in dictionary + int ref; // reference count + + DictEntry *find(char *key); +}; + +#endif diff --git a/pdftops/Error.cxx b/pdftops/Error.cxx new file mode 100644 index 0000000000..291cefdd01 --- /dev/null +++ b/pdftops/Error.cxx @@ -0,0 +1,49 @@ +//======================================================================== +// +// Error.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include "gtypes.h" +#include "Params.h" +#include "Error.h" + +// Send error messages to /dev/tty instead of stderr. +GBool errorsToTTY = gFalse; + +FILE *errFile; +GBool errQuiet; + +void errorInit() { + errFile = stderr; +} + +void CDECL error(int pos, char *msg, ...) { + va_list args; + + if (errQuiet) { + return; + } + if (printCommands) { + fflush(stdout); + } + if (pos >= 0) { + fprintf(errFile, "ERROR: (%d): ", pos); + } else { + fprintf(errFile, "ERROR: "); + } + va_start(args, msg); + vfprintf(errFile, msg, args); + va_end(args); + fprintf(errFile, "\n"); + fflush(errFile); +} diff --git a/pdftops/Error.h b/pdftops/Error.h new file mode 100644 index 0000000000..f651678c85 --- /dev/null +++ b/pdftops/Error.h @@ -0,0 +1,26 @@ +//======================================================================== +// +// Error.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef ERROR_H +#define ERROR_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include +#include "config.h" + +// File to send error (and other) messages to. +extern FILE *errFile; + +extern void errorInit(); + +extern void CDECL error(int pos, char *msg, ...); + +#endif diff --git a/pdftops/FontEncoding.cxx b/pdftops/FontEncoding.cxx new file mode 100644 index 0000000000..3dd2e3bd80 --- /dev/null +++ b/pdftops/FontEncoding.cxx @@ -0,0 +1,143 @@ +//======================================================================== +// +// FontEncoding.cc +// +// Copyright 1999 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include "gmem.h" +#include "FontEncoding.h" + +//------------------------------------------------------------------------ +// FontEncoding +//------------------------------------------------------------------------ + +inline int FontEncoding::hash(char *name) { + int h; + + h = name[0]; + if (name[1]) + h = h * 61 + name[1]; + return h % fontEncHashSize; +} + +FontEncoding::FontEncoding() { + int i; + + encoding = (char **)gmalloc(256 * sizeof(char *)); + size = 256; + freeEnc = gTrue; + for (i = 0; i < 256; ++i) + encoding[i] = NULL; + for (i = 0; i < fontEncHashSize; ++i) + hashTab[i] = -1; +} + +FontEncoding::FontEncoding(char **encoding, int size) { + int i; + + this->encoding = encoding; + this->size = size; + freeEnc = gFalse; + for (i = 0; i < fontEncHashSize; ++i) + hashTab[i] = -1; + for (i = 0; i < size; ++i) { + if (encoding[i]) + addChar1(i, encoding[i]); + } +} + +FontEncoding::FontEncoding(FontEncoding *fontEnc) { + int i; + + encoding = (char **)gmalloc(fontEnc->size * sizeof(char *)); + size = fontEnc->size; + freeEnc = gTrue; + for (i = 0; i < size; ++i) { + encoding[i] = + fontEnc->encoding[i] ? copyString(fontEnc->encoding[i]) : NULL; + } + memcpy(hashTab, fontEnc->hashTab, fontEncHashSize * sizeof(short)); +} + +void FontEncoding::addChar(int code, char *name) { + int h, i; + + // replace character associated with code + if (encoding[code]) { + h = hash(encoding[code]); + for (i = 0; i < fontEncHashSize; ++i) { + if (hashTab[h] == code) { + hashTab[h] = -2; + break; + } + if (++h == fontEncHashSize) + h = 0; + } + gfree(encoding[code]); + } + + // associate name with code + encoding[code] = name; + + // insert name in hash table + addChar1(code, name); +} + +void FontEncoding::addChar1(int code, char *name) { + int h, i, code2; + + // insert name in hash table + h = hash(name); + for (i = 0; i < fontEncHashSize; ++i) { + code2 = hashTab[h]; + if (code2 < 0) { + hashTab[h] = code; + break; + } else if (encoding[code2] && !strcmp(encoding[code2], name)) { + // keep the highest code for each char -- this is needed because + // X won't display chars with codes < 32 + if (code > code2) + hashTab[h] = code; + break; + } + if (++h == fontEncHashSize) + h = 0; + } +} + +FontEncoding::~FontEncoding() { + int i; + + if (freeEnc) { + for (i = 0; i < size; ++i) { + if (encoding[i]) + gfree(encoding[i]); + } + gfree(encoding); + } +} + +int FontEncoding::getCharCode(char *name) { + int h, i, code; + + h = hash(name); + for (i = 0; i < fontEncHashSize; ++i) { + code = hashTab[h]; + if (code == -1 || + (code >= 0 && encoding[code] && !strcmp(encoding[code], name))) + return code; + if (++h >= fontEncHashSize) + h = 0; + } + return -1; +} diff --git a/pdftops/FontEncoding.h b/pdftops/FontEncoding.h new file mode 100644 index 0000000000..7c811536a8 --- /dev/null +++ b/pdftops/FontEncoding.h @@ -0,0 +1,64 @@ +//======================================================================== +// +// FontEncoding.h +// +// Copyright 1999 Derek B. Noonburg +// +//======================================================================== + +#ifndef FONTENCODING_H +#define FONTENCODING_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "gtypes.h" + +//------------------------------------------------------------------------ +// FontEncoding +//------------------------------------------------------------------------ + +#define fontEncHashSize 419 + +class FontEncoding { +public: + + // Construct an empty encoding. + FontEncoding(); + + // Construct an encoding from an array of char names. + FontEncoding(char **encoding, int size); + + // Destructor. + ~FontEncoding(); + + // Create a copy of the encoding. + FontEncoding *copy() { return new FontEncoding(this); } + + // Return number of codes in encoding, i.e., max code + 1. + int getSize() { return size; } + + // Add a char to the encoding. + void addChar(int code, char *name); + + // Return the character name associated with . + char *getCharName(int code) { return encoding[code]; } + + // Return the code associated with . + int getCharCode(char *name); + +private: + + FontEncoding(FontEncoding *fontEnc); + int hash(char *name); + void addChar1(int code, char *name); + + char **encoding; // code --> name mapping + int size; // number of codes + GBool freeEnc; // should we free the encoding array? + short // name --> code hash table + hashTab[fontEncHashSize]; +}; + +#endif diff --git a/pdftops/FontFile.cxx b/pdftops/FontFile.cxx new file mode 100644 index 0000000000..4195ec04db --- /dev/null +++ b/pdftops/FontFile.cxx @@ -0,0 +1,1620 @@ +//======================================================================== +// +// FontFile.cc +// +// Copyright 1999 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include "gmem.h" +#include "Error.h" +#include "FontFile.h" + +#include "StdFontInfo.h" +#include "CompactFontInfo.h" + +//------------------------------------------------------------------------ + +static Guint getWord(Guchar *ptr, int size); +static double getNum(Guchar **ptr, GBool *fp); +static char *getString(int sid, Guchar *stringIdxPtr, + Guchar *stringStartPtr, int stringOffSize, + char *buf); + +//------------------------------------------------------------------------ + +static inline char *nextLine(char *line, char *end) { + while (line < end && *line != '\n' && *line != '\r') + ++line; + while (line < end && *line == '\n' || *line == '\r') + ++line; + return line; +} + +static char hexChars[17] = "0123456789ABCDEF"; + +//------------------------------------------------------------------------ +// FontFile +//------------------------------------------------------------------------ + +FontFile::FontFile() { +} + +FontFile::~FontFile() { +} + +//------------------------------------------------------------------------ +// Type1FontFile +//------------------------------------------------------------------------ + +Type1FontFile::Type1FontFile(char *file, int len) { + char *line, *line1, *p; + char buf[256]; + int n, code, i; + + name = NULL; + encoding = NULL; + freeEnc = gTrue; + + for (i = 1, line = file; i <= 100 && line < file + len && !encoding; ++i) { + + // get font name + if (!strncmp(line, "/FontName", 9)) { + strncpy(buf, line, 255); + buf[255] = '\0'; + if ((p = strchr(buf+9, '/')) && + (p = strtok(p+1, " \t\n\r"))) + name = copyString(p); + line = nextLine(line, file + len); + + // get encoding + } else if (!strncmp(line, "/Encoding StandardEncoding def", 30)) { + encoding = type1StdEncoding.copy(); + } else if (!strncmp(line, "/Encoding 256 array", 19)) { + encoding = new FontEncoding(); + for (i = 0; i < 300; ++i) { + line1 = nextLine(line, file + len); + if ((n = line1 - line) > 255) + n = 255; + strncpy(buf, line, n); + buf[n] = '\0'; + p = strtok(buf, " \t"); + if (p && !strcmp(p, "dup")) { + if ((p = strtok(NULL, " \t"))) { + if ((code = atoi(p)) < 256) { + if ((p = strtok(NULL, " \t"))) { + if (p[0] == '/') { + encoding->addChar(code, copyString(p+1)); + } + } + } + } + } else { + if ((p = strtok(NULL, " \t\n\r")) && !strcmp(p, "def")) { + break; + } + } + line = line1; + } + //~ check for getinterval/putinterval junk + + } else { + line = nextLine(line, file + len); + } + } +} + +Type1FontFile::~Type1FontFile() { + if (name) + delete name; + if (encoding && freeEnc) + delete encoding; +} + +FontEncoding *Type1FontFile::getEncoding(GBool taken) { + if (taken) + freeEnc = gFalse; + return encoding; +} + +//------------------------------------------------------------------------ +// Type1CFontFile +//------------------------------------------------------------------------ + +Type1CFontFile::Type1CFontFile(char *file, int len) { + char buf[256]; + Guchar *topPtr, *idxStartPtr, *idxPtr0, *idxPtr1; + Guchar *stringIdxPtr, *stringStartPtr; + int topOffSize, idxOffSize, stringOffSize; + int nFonts, nStrings, nGlyphs; + int nCodes, nRanges, nLeft, nSups; + Gushort *glyphNames; + int charset, enc, charstrings; + int charsetFormat, encFormat; + int c, sid; + double op[48]; + double x; + GBool isFP; + int key; + int i, j, n; + + name = NULL; + encoding = NULL; + freeEnc = gTrue; + + // read header + topPtr = (Guchar *)file + (file[2] & 0xff); + topOffSize = file[3] & 0xff; + + // read name index (first font only) + nFonts = getWord(topPtr, 2); + idxOffSize = topPtr[2]; + topPtr += 3; + idxStartPtr = topPtr + (nFonts + 1) * idxOffSize - 1; + idxPtr0 = idxStartPtr + getWord(topPtr, idxOffSize); + idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize); + if ((n = idxPtr1 - idxPtr0) > 255) + n = 255; + strncpy(buf, (char *)idxPtr0, n); + buf[n] = '\0'; + name = copyString(buf); + topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize); + + // read top dict index (first font only) + nFonts = getWord(topPtr, 2); + idxOffSize = topPtr[2]; + topPtr += 3; + idxStartPtr = topPtr + (nFonts + 1) * idxOffSize - 1; + idxPtr0 = idxStartPtr + getWord(topPtr, idxOffSize); + idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize); + charset = 0; + enc = 0; + charstrings = 0; + i = 0; + while (idxPtr0 < idxPtr1) { + if (*idxPtr0 <= 27 || *idxPtr0 == 31) { + key = *idxPtr0++; + if (key == 0x0c) + key = (key << 8) | *idxPtr0++; + if (key == 0x0f) { // charset + charset = (int)op[0]; + } else if (key == 0x10) { // encoding + enc = (int)op[0]; + } else if (key == 0x11) { // charstrings + charstrings = (int)op[0]; + } + i = 0; + } else { + x = getNum(&idxPtr0, &isFP); + if (i < 48) + op[i++] = x; + } + } + topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize); + + // read string index + nStrings = getWord(topPtr, 2); + stringOffSize = topPtr[2]; + topPtr += 3; + stringIdxPtr = topPtr; + stringStartPtr = topPtr + (nStrings + 1) * stringOffSize - 1; + topPtr = stringStartPtr + getWord(topPtr + nStrings * stringOffSize, + stringOffSize); + + // get number of glyphs from charstrings index + topPtr = (Guchar *)file + charstrings; + nGlyphs = getWord(topPtr, 2); + + // read charset + if (charset == 0) { + glyphNames = type1CISOAdobeCharset; + } else if (charset == 1) { + glyphNames = type1CExpertCharset; + } else if (charset == 2) { + glyphNames = type1CExpertSubsetCharset; + } else { + glyphNames = (Gushort *)gmalloc(nGlyphs * sizeof(Gushort)); + glyphNames[0] = 0; + topPtr = (Guchar *)file + charset; + charsetFormat = *topPtr++; + if (charsetFormat == 0) { + for (i = 1; i < nGlyphs; ++i) { + glyphNames[i] = getWord(topPtr, 2); + topPtr += 2; + } + } else if (charsetFormat == 1) { + i = 1; + while (i < nGlyphs) { + c = getWord(topPtr, 2); + topPtr += 2; + nLeft = *topPtr++; + for (j = 0; j <= nLeft; ++j) + glyphNames[i++] = c++; + } + } else if (charsetFormat == 2) { + i = 1; + while (i < nGlyphs) { + c = getWord(topPtr, 2); + topPtr += 2; + nLeft = getWord(topPtr, 2); + topPtr += 2; + for (j = 0; j <= nLeft; ++j) + glyphNames[i++] = c++; + } + } + } + + // read encoding (glyph -> code mapping) + if (enc == 0) { + encoding = type1StdEncoding.copy(); + } else if (enc == 1) { + encoding = type1ExpertEncoding.copy(); + } else { + encoding = new FontEncoding(); + topPtr = (Guchar *)file + enc; + encFormat = *topPtr++; + if ((encFormat & 0x7f) == 0) { + nCodes = 1 + *topPtr++; + if (nCodes > nGlyphs) { + nCodes = nGlyphs; + } + for (i = 1; i < nCodes; ++i) { + c = *topPtr++; + getString(glyphNames[i], stringIdxPtr, stringStartPtr, + stringOffSize, buf); + encoding->addChar(c, copyString(buf)); + } + } else if ((encFormat & 0x7f) == 1) { + nRanges = *topPtr++; + nCodes = 1; + for (i = 0; i < nRanges; ++i) { + c = *topPtr++; + nLeft = *topPtr++; + for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) { + getString(glyphNames[nCodes], stringIdxPtr, stringStartPtr, + stringOffSize, buf); + encoding->addChar(c, copyString(buf)); + ++nCodes; + ++c; + } + } + } + if (encFormat & 0x80) { + nSups = *topPtr++; + for (i = 0; i < nSups; ++i) { + c = *topPtr++; + sid = getWord(topPtr, 2); + topPtr += 2; + getString(sid, stringIdxPtr, stringStartPtr, + stringOffSize, buf); + encoding->addChar(c, copyString(buf)); + } + } + } + + if (charset > 2) + gfree(glyphNames); +} + +Type1CFontFile::~Type1CFontFile() { + if (name) + delete name; + if (encoding && freeEnc) + delete encoding; +} + +FontEncoding *Type1CFontFile::getEncoding(GBool taken) { + if (taken) + freeEnc = gFalse; + return encoding; +} + +static Guint getWord(Guchar *ptr, int size) { + Guint x; + int i; + + x = 0; + for (i = 0; i < size; ++i) + x = (x << 8) + *ptr++; + return x; +} + +static double getNum(Guchar **ptr, GBool *fp) { + static char nybChars[16] = "0123456789.ee -"; + int b0, b, nyb0, nyb1; + double x; + char buf[65]; + int i; + + x = 0; + *fp = gFalse; + b0 = (*ptr)[0]; + if (b0 < 28) { + x = 0; + } else if (b0 == 28) { + x = ((*ptr)[1] << 8) + (*ptr)[2]; + *ptr += 3; + } else if (b0 == 29) { + x = ((*ptr)[1] << 24) + ((*ptr)[2] << 16) + ((*ptr)[3] << 8) + (*ptr)[4]; + *ptr += 5; + } else if (b0 == 30) { + *ptr += 1; + i = 0; + do { + b = *(*ptr)++; + nyb0 = b >> 4; + nyb1 = b & 0x0f; + if (nyb0 == 0xf) + break; + buf[i++] = nybChars[nyb0]; + if (i == 64) + break; + if (nyb0 == 0xc) + buf[i++] = '-'; + if (i == 64) + break; + if (nyb1 == 0xf) + break; + buf[i++] = nybChars[nyb1]; + if (i == 64) + break; + if (nyb1 == 0xc) + buf[i++] = '-'; + } while (i < 64); + buf[i] = '\0'; + x = atof(buf); + *fp = gTrue; + } else if (b0 == 31) { + x = 0; + } else if (b0 < 247) { + x = b0 - 139; + *ptr += 1; + } else if (b0 < 251) { + x = ((b0 - 247) << 8) + (*ptr)[1] + 108; + *ptr += 2; + } else { + x = -((b0 - 251) << 8) - (*ptr)[1] - 108; + *ptr += 2; + } + return x; +} + +static char *getString(int sid, Guchar *stringIdxPtr, + Guchar *stringStartPtr, int stringOffSize, + char *buf) { + Guchar *idxPtr0, *idxPtr1; + int len; + + if (sid < 391) { + strcpy(buf, type1CStdStrings[sid]); + } else { + sid -= 391; + idxPtr0 = stringStartPtr + getWord(stringIdxPtr + sid * stringOffSize, + stringOffSize); + idxPtr1 = stringStartPtr + getWord(stringIdxPtr + (sid+1) * stringOffSize, + stringOffSize); + if ((len = idxPtr1 - idxPtr0) > 255) + len = 255; + strncpy(buf, (char *)idxPtr0, len); + buf[len] = '\0'; + } + return buf; +} + +//------------------------------------------------------------------------ +// Type1CFontConverter +//------------------------------------------------------------------------ + +Type1CFontConverter::Type1CFontConverter(char *file, int len, FILE *out) { + this->file = file; + this->len = len; + this->out = out; + r1 = 55665; + line = 0; +} + +Type1CFontConverter::~Type1CFontConverter() { +} + +void Type1CFontConverter::convert() { + char *fontName; + struct { + int version; + int notice; + int copyright; + int fullName; + int familyName; + int weight; + int isFixedPitch; + double italicAngle; + double underlinePosition; + double underlineThickness; + int paintType; + int charstringType; //~ ??? + double fontMatrix[6]; + int uniqueID; + double fontBBox[4]; + double strokeWidth; //~ ??? + int charset; + int encoding; + int charStrings; + int privateSize; + int privateOffset; + } dict; + char buf[256], eBuf[256]; + Guchar *topPtr, *idxStartPtr, *idxPtr0, *idxPtr1; + Guchar *stringIdxPtr, *stringStartPtr; + int topOffSize, idxOffSize, stringOffSize; + int nFonts, nStrings, nGlyphs; + int nCodes, nRanges, nLeft, nSups; + Gushort *glyphNames; + int charsetFormat, encFormat; + int subrsOffset, nSubrs; + int nCharStrings; + int c, sid; + double x; + GBool isFP; + int key; + int i, j, n; + + // read header + topPtr = (Guchar *)file + (file[2] & 0xff); + topOffSize = file[3] & 0xff; + + // read name (first font only) + nFonts = getWord(topPtr, 2); + idxOffSize = topPtr[2]; + topPtr += 3; + idxStartPtr = topPtr + (nFonts + 1) * idxOffSize - 1; + idxPtr0 = idxStartPtr + getWord(topPtr, idxOffSize); + idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize); + if ((n = idxPtr1 - idxPtr0) > 255) + n = 255; + strncpy(buf, (char *)idxPtr0, n); + buf[n] = '\0'; + fontName = copyString(buf); + topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize); + + // read top dict (first font only) + nFonts = getWord(topPtr, 2); + idxOffSize = topPtr[2]; + topPtr += 3; + idxStartPtr = topPtr + (nFonts + 1) * idxOffSize - 1; + idxPtr0 = idxStartPtr + getWord(topPtr, idxOffSize); + idxPtr1 = idxStartPtr + getWord(topPtr + idxOffSize, idxOffSize); + dict.version = 0; + dict.notice = 0; + dict.copyright = 0; + dict.fullName = 0; + dict.familyName = 0; + dict.weight = 0; + dict.isFixedPitch = 0; + dict.italicAngle = 0; + dict.underlinePosition = -100; + dict.underlineThickness = 50; + dict.paintType = 0; + dict.charstringType = 2; + dict.fontMatrix[0] = 0.001; + dict.fontMatrix[1] = 0; + dict.fontMatrix[2] = 0; + dict.fontMatrix[3] = 0.001; + dict.fontMatrix[4] = 0; + dict.fontMatrix[5] = 0; + dict.uniqueID = 0; + dict.fontBBox[0] = 0; + dict.fontBBox[1] = 0; + dict.fontBBox[2] = 0; + dict.fontBBox[3] = 0; + dict.strokeWidth = 0; + dict.charset = 0; + dict.encoding = 0; + dict.charStrings = 0; + dict.privateSize = 0; + dict.privateOffset = 0; + i = 0; + while (idxPtr0 < idxPtr1) { + if (*idxPtr0 <= 27 || *idxPtr0 == 31) { + key = *idxPtr0++; + if (key == 0x0c) + key = (key << 8) | *idxPtr0++; + switch (key) { + case 0x0000: dict.version = (int)op[0]; break; + case 0x0001: dict.notice = (int)op[0]; break; + case 0x0c00: dict.copyright = (int)op[0]; break; + case 0x0002: dict.fullName = (int)op[0]; break; + case 0x0003: dict.familyName = (int)op[0]; break; + case 0x0004: dict.weight = (int)op[0]; break; + case 0x0c01: dict.isFixedPitch = (int)op[0]; break; + case 0x0c02: dict.italicAngle = op[0]; break; + case 0x0c03: dict.underlinePosition = op[0]; break; + case 0x0c04: dict.underlineThickness = op[0]; break; + case 0x0c05: dict.paintType = (int)op[0]; break; + case 0x0c06: dict.charstringType = (int)op[0]; break; + case 0x0c07: dict.fontMatrix[0] = op[0]; + dict.fontMatrix[1] = op[1]; + dict.fontMatrix[2] = op[2]; + dict.fontMatrix[3] = op[3]; + dict.fontMatrix[4] = op[4]; + dict.fontMatrix[5] = op[5]; break; + case 0x000d: dict.uniqueID = (int)op[0]; break; + case 0x0005: dict.fontBBox[0] = op[0]; + dict.fontBBox[1] = op[1]; + dict.fontBBox[2] = op[2]; + dict.fontBBox[3] = op[3]; break; + case 0x0c08: dict.strokeWidth = op[0]; break; + case 0x000f: dict.charset = (int)op[0]; break; + case 0x0010: dict.encoding = (int)op[0]; break; + case 0x0011: dict.charStrings = (int)op[0]; break; + case 0x0012: dict.privateSize = (int)op[0]; + dict.privateOffset = (int)op[1]; break; + } + i = 0; + } else { + x = getNum(&idxPtr0, &isFP); + if (i < 48) { + op[i] = x; + fp[i++] = isFP; + } + } + } + topPtr = idxStartPtr + getWord(topPtr + nFonts * idxOffSize, idxOffSize); + + // read string index + nStrings = getWord(topPtr, 2); + stringOffSize = topPtr[2]; + topPtr += 3; + stringIdxPtr = topPtr; + stringStartPtr = topPtr + (nStrings + 1) * stringOffSize - 1; + topPtr = stringStartPtr + getWord(topPtr + nStrings * stringOffSize, + stringOffSize); + +#if 1 //~ + // get global subrs + int nGSubrs; + int gSubrOffSize; + + nGSubrs = getWord(topPtr, 2); + gSubrOffSize = topPtr[2]; + topPtr += 3; +#endif + + // write header and font dictionary, up to encoding + fprintf(out, "%%!FontType1-1.0: %s", fontName); + if (dict.version != 0) { + fprintf(out, "%s", + getString(dict.version, stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + } + fprintf(out, "\n"); + fprintf(out, "11 dict begin\n"); + fprintf(out, "/FontInfo 10 dict dup begin\n"); + if (dict.version != 0) { + fprintf(out, "/version (%s) readonly def\n", + getString(dict.version, stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + } + if (dict.notice != 0) { + fprintf(out, "/Notice (%s) readonly def\n", + getString(dict.notice, stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + } + if (dict.copyright != 0) { + fprintf(out, "/Copyright (%s) readonly def\n", + getString(dict.copyright, stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + } + if (dict.fullName != 0) { + fprintf(out, "/FullName (%s) readonly def\n", + getString(dict.fullName, stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + } + if (dict.familyName != 0) { + fprintf(out, "/FamilyName (%s) readonly def\n", + getString(dict.familyName, stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + } + if (dict.weight != 0) { + fprintf(out, "/Weight (%s) readonly def\n", + getString(dict.weight, stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + } + fprintf(out, "/isFixedPitch %s def\n", dict.isFixedPitch ? "true" : "false"); + fprintf(out, "/ItalicAngle %g def\n", dict.italicAngle); + fprintf(out, "/UnderlinePosition %g def\n", dict.underlinePosition); + fprintf(out, "/UnderlineThickness %g def\n", dict.underlineThickness); + fprintf(out, "end readonly def\n"); + fprintf(out, "/FontName /%s def\n", fontName); + fprintf(out, "/PaintType %d def\n", dict.paintType); + fprintf(out, "/FontType 1 def\n"); + fprintf(out, "/FontMatrix [%g %g %g %g %g %g] readonly def\n", + dict.fontMatrix[0], dict.fontMatrix[1], dict.fontMatrix[2], + dict.fontMatrix[3], dict.fontMatrix[4], dict.fontMatrix[5]); + fprintf(out, "/FontBBox [%g %g %g %g] readonly def\n", + dict.fontBBox[0], dict.fontBBox[1], + dict.fontBBox[2], dict.fontBBox[3]); + if (dict.uniqueID != 0) { + fprintf(out, "/UniqueID %d def\n", dict.uniqueID); + } + + // get number of glyphs from charstrings index + topPtr = (Guchar *)file + dict.charStrings; + nGlyphs = getWord(topPtr, 2); + + // read charset + if (dict.charset == 0) { + glyphNames = type1CISOAdobeCharset; + } else if (dict.charset == 1) { + glyphNames = type1CExpertCharset; + } else if (dict.charset == 2) { + glyphNames = type1CExpertSubsetCharset; + } else { + glyphNames = (Gushort *)gmalloc(nGlyphs * sizeof(Gushort)); + glyphNames[0] = 0; + topPtr = (Guchar *)file + dict.charset; + charsetFormat = *topPtr++; + if (charsetFormat == 0) { + for (i = 1; i < nGlyphs; ++i) { + glyphNames[i] = getWord(topPtr, 2); + topPtr += 2; + } + } else if (charsetFormat == 1) { + i = 1; + while (i < nGlyphs) { + c = getWord(topPtr, 2); + topPtr += 2; + nLeft = *topPtr++; + for (j = 0; j <= nLeft; ++j) + glyphNames[i++] = c++; + } + } else if (charsetFormat == 2) { + i = 1; + while (i < nGlyphs) { + c = getWord(topPtr, 2); + topPtr += 2; + nLeft = getWord(topPtr, 2); + topPtr += 2; + for (j = 0; j <= nLeft; ++j) + glyphNames[i++] = c++; + } + } + } + + // read encoding (glyph -> code mapping), write Type 1 encoding + fprintf(out, "/Encoding "); + if (dict.encoding == 0) { + fprintf(out, "StandardEncoding def\n"); + } else { + fprintf(out, "256 array\n"); + fprintf(out, "0 1 255 {1 index exch /.notdef put} for\n"); + if (dict.encoding == 1) { + for (i = 0; i < 256; ++i) { + if (type1ExpertEncodingNames[i]) + fprintf(out, "dup %d /%s put\n", i, type1ExpertEncodingNames[i]); + } + } else { + topPtr = (Guchar *)file + dict.encoding; + encFormat = *topPtr++; + if ((encFormat & 0x7f) == 0) { + nCodes = 1 + *topPtr++; + if (nCodes > nGlyphs) { + nCodes = nGlyphs; + } + for (i = 1; i < nCodes; ++i) { + c = *topPtr++; + fprintf(out, "dup %d /%s put\n", c, + getString(glyphNames[i], stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + } + } else if ((encFormat & 0x7f) == 1) { + nRanges = *topPtr++; + nCodes = 1; + for (i = 0; i < nRanges; ++i) { + c = *topPtr++; + nLeft = *topPtr++; + for (j = 0; j <= nLeft && nCodes < nGlyphs; ++j) { + fprintf(out, "dup %d /%s put\n", c, + getString(glyphNames[nCodes], stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + ++nCodes; + ++c; + } + } + } + if (encFormat & 0x80) { + nSups = *topPtr++; + for (i = 0; i < nSups; ++i) { + c = *topPtr++; + sid = getWord(topPtr, 2); + topPtr += 2; + fprintf(out, "dup %d /%s put\n", c, + getString(sid, stringIdxPtr, stringStartPtr, + stringOffSize, buf)); + } + } + } + fprintf(out, "readonly def\n"); + } + fprintf(out, "currentdict end\n"); + fprintf(out, "currentfile eexec\n"); + + // get private dictionary + eexecWrite("\x83\xca\x73\xd5"); + eexecWrite("dup /Private 32 dict dup begin\n"); + eexecWrite("/RD {string currentfile exch readstring pop} executeonly def\n"); + eexecWrite("/ND {noaccess def} executeonly def\n"); + eexecWrite("/NP {noaccess put} executeonly def\n"); + eexecWrite("/MinFeature {16 16} ND\n"); + eexecWrite("/password 5839 def\n"); + subrsOffset = 0; + defaultWidthX = 0; + nominalWidthX = 0; + topPtr = (Guchar *)file + dict.privateOffset; + idxPtr0 = topPtr; + idxPtr1 = idxPtr0 + dict.privateSize; + i = 0; + while (idxPtr0 < idxPtr1) { + if (*idxPtr0 <= 27 || *idxPtr0 == 31) { + key = *idxPtr0++; + if (key == 0x0c) + key = (key << 8) | *idxPtr0++; + switch (key) { + case 0x0006: + getDeltaInt(eBuf, "BlueValues", op, i); + eexecWrite(eBuf); + break; + case 0x0007: + getDeltaInt(eBuf, "OtherBlues", op, i); + eexecWrite(eBuf); + break; + case 0x0008: + getDeltaInt(eBuf, "FamilyBlues", op, i); + eexecWrite(eBuf); + break; + case 0x0009: + getDeltaInt(eBuf, "FamilyOtherBlues", op, i); + eexecWrite(eBuf); + break; + case 0x0c09: + sprintf(eBuf, "/BlueScale %g def\n", op[0]); + eexecWrite(eBuf); + break; + case 0x0c0a: + sprintf(eBuf, "/BlueShift %d def\n", (int)op[0]); + eexecWrite(eBuf); + break; + case 0x0c0b: + sprintf(eBuf, "/BlueFuzz %d def\n", (int)op[0]); + eexecWrite(eBuf); + break; + case 0x000a: + sprintf(eBuf, "/StdHW [%g] def\n", op[0]); + eexecWrite(eBuf); + break; + case 0x000b: + sprintf(eBuf, "/StdVW [%g] def\n", op[0]); + eexecWrite(eBuf); + break; + case 0x0c0c: + getDeltaReal(eBuf, "StemSnapH", op, i); + eexecWrite(eBuf); + break; + case 0x0c0d: + getDeltaReal(eBuf, "StemSnapV", op, i); + eexecWrite(eBuf); + break; + case 0x0c0e: + sprintf(eBuf, "/ForceBold %s def\n", op[0] ? "true" : "false"); + eexecWrite(eBuf); + break; + case 0x0c0f: + sprintf(eBuf, "/ForceBoldThreshold %g def\n", op[0]); + eexecWrite(eBuf); + break; + case 0x0c11: + sprintf(eBuf, "/LanguageGroup %d def\n", (int)op[0]); + eexecWrite(eBuf); + break; + case 0x0c12: + sprintf(eBuf, "/ExpansionFactor %g def\n", op[0]); + eexecWrite(eBuf); + break; + case 0x0c13: + error(-1, "Got Type 1C InitialRandomSeed"); + break; + case 0x0013: + subrsOffset = (int)op[0]; + break; + case 0x0014: + defaultWidthX = op[0]; + defaultWidthXFP = fp[0]; + break; + case 0x0015: + nominalWidthX = op[0]; + nominalWidthXFP = fp[0]; + break; + default: + error(-1, "Uknown Type 1C private dict entry %04x", key); + break; + } + i = 0; + } else { + x = getNum(&idxPtr0, &isFP); + if (i < 48) { + op[i] = x; + fp[i++] = isFP; + } + } + } + + // get subrs + if (subrsOffset != 0) { + topPtr += subrsOffset; + nSubrs = getWord(topPtr, 2); + idxOffSize = topPtr[2]; + topPtr += 3; + sprintf(eBuf, "/Subrs %d array\n", nSubrs); + eexecWrite(eBuf); + idxStartPtr = topPtr + (nSubrs + 1) * idxOffSize - 1; + idxPtr1 = idxStartPtr + getWord(topPtr, idxOffSize); + for (i = 0; i < nSubrs; ++i) { + idxPtr0 = idxPtr1; + idxPtr1 = idxStartPtr + getWord(topPtr + (i+1)*idxOffSize, idxOffSize); + n = idxPtr1 - idxPtr0; +#if 1 //~ + error(-1, "Unimplemented Type 2 subrs"); +#else + sprintf(eBuf, "dup %d %d RD ", i, n); + eexecWrite(eBuf); + cvtGlyph(idxPtr0, n); + eexecWrite(" NP\n"); +#endif + } + eexecWrite("ND\n"); + } + + // get CharStrings + topPtr = (Guchar *)file + dict.charStrings; + nCharStrings = getWord(topPtr, 2); + idxOffSize = topPtr[2]; + topPtr += 3; + sprintf(eBuf, "2 index /CharStrings %d dict dup begin\n", nCharStrings); + eexecWrite(eBuf); + idxStartPtr = topPtr + (nCharStrings + 1) * idxOffSize - 1; + idxPtr1 = idxStartPtr + getWord(topPtr, idxOffSize); + for (i = 0; i < nCharStrings; ++i) { + idxPtr0 = idxPtr1; + idxPtr1 = idxStartPtr + getWord(topPtr + (i+1)*idxOffSize, idxOffSize); + n = idxPtr1 - idxPtr0; + cvtGlyph(getString(glyphNames[i], stringIdxPtr, stringStartPtr, + stringOffSize, buf), + idxPtr0, n); + } + eexecWrite("end\n"); + eexecWrite("end\n"); + eexecWrite("readonly put\n"); + eexecWrite("noaccess put\n"); + eexecWrite("dup /FontName get exch definefont pop\n"); + eexecWrite("mark currentfile closefile\n"); + + // trailer + if (line > 0) + fputc('\n', out); + for (i = 0; i < 8; ++i) { + fprintf(out, "0000000000000000000000000000000000000000000000000000000000000000\n"); + } + fprintf(out, "cleartomark\n"); + + // clean up + if (dict.charset > 2) + gfree(glyphNames); + gfree(fontName); +} + +void Type1CFontConverter::eexecWrite(char *s) { + Guchar *p; + Guchar x; + + for (p = (Guchar *)s; *p; ++p) { + x = *p ^ (r1 >> 8); + r1 = (x + r1) * 52845 + 22719; + fputc(hexChars[x >> 4], out); + fputc(hexChars[x & 0x0f], out); + line += 2; + if (line == 64) { + fputc('\n', out); + line = 0; + } + } +} + +void Type1CFontConverter::cvtGlyph(char *name, Guchar *s, int n) { + int nHints; + int x; + GBool first = gTrue; + char eBuf[256]; + double d, dx, dy; + GBool dFP; + int i, k; + + charBuf = new GString(); + charBuf->append((char)73); + charBuf->append((char)58); + charBuf->append((char)147); + charBuf->append((char)134); + + i = 0; + nOps = 0; + nHints = 0; + while (i < n) { + if (s[i] == 12) { + switch (s[i+1]) { + case 0: // dotsection (should be Type 1 only?) + //~ ignored + break; + case 34: // hflex + if (nOps != 7) { + error(-1, "Wrong number of args (%d) to Type 2 hflex", nOps); + } + eexecDumpNum(op[0], fp[0]); + eexecDumpNum(0, gFalse); + eexecDumpNum(op[1], fp[1]); + eexecDumpNum(op[2], fp[2]); + eexecDumpNum(op[3], fp[3]); + eexecDumpNum(0, gFalse); + eexecDumpOp1(8); + eexecDumpNum(op[4], fp[4]); + eexecDumpNum(0, gFalse); + eexecDumpNum(op[5], fp[5]); + eexecDumpNum(-op[2], fp[2]); + eexecDumpNum(op[6], fp[6]); + eexecDumpNum(0, gFalse); + eexecDumpOp1(8); + break; + case 35: // flex + if (nOps != 13) { + error(-1, "Wrong number of args (%d) to Type 2 flex", nOps); + } + eexecDumpNum(op[0], fp[0]); + eexecDumpNum(op[1], fp[1]); + eexecDumpNum(op[2], fp[2]); + eexecDumpNum(op[3], fp[3]); + eexecDumpNum(op[4], fp[4]); + eexecDumpNum(op[5], fp[5]); + eexecDumpOp1(8); + eexecDumpNum(op[6], fp[6]); + eexecDumpNum(op[7], fp[7]); + eexecDumpNum(op[8], fp[8]); + eexecDumpNum(op[9], fp[9]); + eexecDumpNum(op[10], fp[10]); + eexecDumpNum(op[11], fp[11]); + eexecDumpOp1(8); + break; + case 36: // hflex1 + if (nOps != 9) { + error(-1, "Wrong number of args (%d) to Type 2 hflex1", nOps); + } + eexecDumpNum(op[0], fp[0]); + eexecDumpNum(op[1], fp[1]); + eexecDumpNum(op[2], fp[2]); + eexecDumpNum(op[3], fp[3]); + eexecDumpNum(op[4], fp[4]); + eexecDumpNum(0, gFalse); + eexecDumpOp1(8); + eexecDumpNum(op[5], fp[5]); + eexecDumpNum(0, gFalse); + eexecDumpNum(op[6], fp[6]); + eexecDumpNum(op[7], fp[7]); + eexecDumpNum(op[8], fp[8]); + eexecDumpNum(-(op[1] + op[3] + op[7]), fp[1] | fp[3] | fp[7]); + eexecDumpOp1(8); + break; + case 37: // flex1 + if (nOps != 11) { + error(-1, "Wrong number of args (%d) to Type 2 flex1", nOps); + } + eexecDumpNum(op[0], fp[0]); + eexecDumpNum(op[1], fp[1]); + eexecDumpNum(op[2], fp[2]); + eexecDumpNum(op[3], fp[3]); + eexecDumpNum(op[4], fp[4]); + eexecDumpNum(op[5], fp[5]); + eexecDumpOp1(8); + eexecDumpNum(op[6], fp[6]); + eexecDumpNum(op[7], fp[7]); + eexecDumpNum(op[8], fp[8]); + eexecDumpNum(op[9], fp[9]); + dx = op[0] + op[2] + op[4] + op[6] + op[8]; + dy = op[1] + op[3] + op[5] + op[7] + op[9]; + if (fabs(dx) > fabs(dy)) { + eexecDumpNum(op[10], fp[10]); + eexecDumpNum(-dy, fp[1] | fp[3] | fp[5] | fp[7] | fp[9]); + } else { + eexecDumpNum(-dx, fp[0] | fp[2] | fp[4] | fp[6] | fp[8]); + eexecDumpNum(op[10], fp[10]); + } + eexecDumpOp1(8); + break; + case 3: // and + case 4: // or + case 5: // not + case 8: // store + case 9: // abs + case 10: // add + case 11: // sub + case 12: // div + case 13: // load + case 14: // neg + case 15: // eq + case 18: // drop + case 20: // put + case 21: // get + case 22: // ifelse + case 23: // random + case 24: // mul + case 26: // sqrt + case 27: // dup + case 28: // exch + case 29: // index + case 30: // roll + error(-1, "Unimplemented Type 2 charstring op: 12.%d", s[i+1]); + break; + default: + error(-1, "Illegal Type 2 charstring op: 12.%d", s[i+1]); + break; + } + i += 2; + nOps = 0; + } else if (s[i] == 19) { // hintmask + //~ ignored + if (first) { + cvtGlyphWidth(nOps == 1); + first = gFalse; + } + if (nOps > 0) { + if (nOps & 1) { + error(-1, "Wrong number of args (%d) to Type 2 hintmask/vstemhm", + nOps); + } + nHints += nOps / 2; + } + i += 1 + ((nHints + 7) >> 3); + nOps = 0; + } else if (s[i] == 20) { // cntrmask + //~ ignored + if (first) { + cvtGlyphWidth(nOps == 1); + first = gFalse; + } + if (nOps > 0) { + if (nOps & 1) { + error(-1, "Wrong number of args (%d) to Type 2 cntrmask/vstemhm", + nOps); + } + nHints += nOps / 2; + } + i += 1 + ((nHints + 7) >> 3); + nOps = 0; + } else if (s[i] == 28) { + x = (s[i+1] << 8) + s[i+2]; + if (x & 0x8000) + x |= -1 << 15; + if (nOps < 48) { + fp[nOps] = gFalse; + op[nOps++] = x; + } + i += 3; + } else if (s[i] <= 31) { + switch (s[i]) { + case 4: // vmoveto + if (first) { + cvtGlyphWidth(nOps == 2); + first = gFalse; + } + if (nOps != 1) + error(-1, "Wrong number of args (%d) to Type 2 vmoveto", nOps); + eexecDumpNum(op[0], fp[0]); + eexecDumpOp1(4); + break; + case 5: // rlineto + if (nOps < 2 || nOps % 2 != 0) + error(-1, "Wrong number of args (%d) to Type 2 rlineto", nOps); + for (k = 0; k < nOps; k += 2) { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpOp1(5); + } + break; + case 6: // hlineto + if (nOps < 1) + error(-1, "Wrong number of args (%d) to Type 2 hlineto", nOps); + for (k = 0; k < nOps; ++k) { + eexecDumpNum(op[k], fp[k]); + eexecDumpOp1((k & 1) ? 7 : 6); + } + break; + case 7: // vlineto + if (nOps < 1) + error(-1, "Wrong number of args (%d) to Type 2 vlineto", nOps); + for (k = 0; k < nOps; ++k) { + eexecDumpNum(op[k], fp[k]); + eexecDumpOp1((k & 1) ? 6 : 7); + } + break; + case 8: // rrcurveto + if (nOps < 6 || nOps % 6 != 0) + error(-1, "Wrong number of args (%d) to Type 2 rrcurveto", nOps); + for (k = 0; k < nOps; k += 6) { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpNum(op[k+4], fp[k+4]); + eexecDumpNum(op[k+5], fp[k+5]); + eexecDumpOp1(8); + } + break; + case 14: // endchar / seac + if (first) { + cvtGlyphWidth(nOps == 1 || nOps == 5); + first = gFalse; + } + if (nOps == 4) { + eexecDumpNum(0, 0); + eexecDumpNum(op[0], fp[0]); + eexecDumpNum(op[1], fp[1]); + eexecDumpNum(op[2], fp[2]); + eexecDumpNum(op[3], fp[3]); + eexecDumpOp2(6); + } else if (nOps == 0) { + eexecDumpOp1(14); + } else { + error(-1, "Wrong number of args (%d) to Type 2 endchar", nOps); + } + break; + case 21: // rmoveto + if (first) { + cvtGlyphWidth(nOps == 3); + first = gFalse; + } + if (nOps != 2) + error(-1, "Wrong number of args (%d) to Type 2 rmoveto", nOps); + eexecDumpNum(op[0], fp[0]); + eexecDumpNum(op[1], fp[1]); + eexecDumpOp1(21); + break; + case 22: // hmoveto + if (first) { + cvtGlyphWidth(nOps == 2); + first = gFalse; + } + if (nOps != 1) + error(-1, "Wrong number of args (%d) to Type 2 hmoveto", nOps); + eexecDumpNum(op[0], fp[0]); + eexecDumpOp1(22); + break; + case 24: // rcurveline + if (nOps < 8 || (nOps - 2) % 6 != 0) + error(-1, "Wrong number of args (%d) to Type 2 rcurveline", nOps); + for (k = 0; k < nOps - 2; k += 6) { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpNum(op[k+4], fp[k+4]); + eexecDumpNum(op[k+5], fp[k+5]); + eexecDumpOp1(8); + } + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k]); + eexecDumpOp1(5); + break; + case 25: // rlinecurve + if (nOps < 8 || (nOps - 6) % 2 != 0) + error(-1, "Wrong number of args (%d) to Type 2 rlinecurve", nOps); + for (k = 0; k < nOps - 6; k += 2) { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k]); + eexecDumpOp1(5); + } + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpNum(op[k+4], fp[k+4]); + eexecDumpNum(op[k+5], fp[k+5]); + eexecDumpOp1(8); + break; + case 26: // vvcurveto + if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) + error(-1, "Wrong number of args (%d) to Type 2 vvcurveto", nOps); + if (nOps % 2 == 1) { + eexecDumpNum(op[0], fp[0]); + eexecDumpNum(op[1], fp[1]); + eexecDumpNum(op[2], fp[2]); + eexecDumpNum(op[3], fp[3]); + eexecDumpNum(0, gFalse); + eexecDumpNum(op[4], fp[4]); + eexecDumpOp1(8); + k = 5; + } else { + k = 0; + } + for (; k < nOps; k += 4) { + eexecDumpNum(0, gFalse); + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(0, gFalse); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpOp1(8); + } + break; + case 27: // hhcurveto + if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) + error(-1, "Wrong number of args (%d) to Type 2 hhcurveto", nOps); + if (nOps % 2 == 1) { + eexecDumpNum(op[1], fp[1]); + eexecDumpNum(op[0], fp[0]); + eexecDumpNum(op[2], fp[2]); + eexecDumpNum(op[3], fp[3]); + eexecDumpNum(op[4], fp[4]); + eexecDumpNum(0, gFalse); + eexecDumpOp1(8); + k = 5; + } else { + k = 0; + } + for (; k < nOps; k += 4) { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(0, gFalse); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpNum(0, gFalse); + eexecDumpOp1(8); + } + break; + case 30: // vhcurveto + if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) + error(-1, "Wrong number of args (%d) to Type 2 vhcurveto", nOps); + for (k = 0; k < nOps && k != nOps-5; k += 4) { + if (k % 8 == 0) { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpOp1(30); + } else { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpOp1(31); + } + } + if (k == nOps-5) { + if (k % 8 == 0) { + eexecDumpNum(0, gFalse); + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpNum(op[k+4], fp[k+4]); + } else { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(0, gFalse); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+4], fp[k+4]); + eexecDumpNum(op[k+3], fp[k+3]); + } + eexecDumpOp1(8); + } + break; + case 31: // hvcurveto + if (nOps < 4 || !(nOps % 4 == 0 || (nOps-1) % 4 == 0)) + error(-1, "Wrong number of args (%d) to Type 2 hvcurveto", nOps); + for (k = 0; k < nOps && k != nOps-5; k += 4) { + if (k % 8 == 0) { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpOp1(31); + } else { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpOp1(30); + } + } + if (k == nOps-5) { + if (k % 8 == 0) { + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(0, gFalse); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+4], fp[k+4]); + eexecDumpNum(op[k+3], fp[k+3]); + } else { + eexecDumpNum(0, gFalse); + eexecDumpNum(op[k], fp[k]); + eexecDumpNum(op[k+1], fp[k+1]); + eexecDumpNum(op[k+2], fp[k+2]); + eexecDumpNum(op[k+3], fp[k+3]); + eexecDumpNum(op[k+4], fp[k+4]); + } + eexecDumpOp1(8); + } + break; + case 1: // hstem + if (first) { + cvtGlyphWidth(nOps & 1); + first = gFalse; + } + if (nOps & 1) { + error(-1, "Wrong number of args (%d) to Type 2 hstem", nOps); + } + d = 0; + dFP = gFalse; + for (k = 0; k < nOps; k += 2) { + if (op[k+1] < 0) { + d += op[k] + op[k+1]; + dFP |= fp[k] | fp[k+1]; + eexecDumpNum(d, dFP); + eexecDumpNum(-op[k+1], fp[k+1]); + } else { + d += op[k]; + dFP |= fp[k]; + eexecDumpNum(d, dFP); + eexecDumpNum(op[k+1], fp[k+1]); + d += op[k+1]; + dFP |= fp[k+1]; + } + eexecDumpOp1(1); + } + nHints += nOps / 2; + break; + case 3: // vstem + if (first) { + cvtGlyphWidth(nOps & 1); + first = gFalse; + } + if (nOps & 1) { + error(-1, "Wrong number of args (%d) to Type 2 vstem", nOps); + } + d = 0; + dFP = gFalse; + for (k = 0; k < nOps; k += 2) { + if (op[k+1] < 0) { + d += op[k] + op[k+1]; + dFP |= fp[k] | fp[k+1]; + eexecDumpNum(d, dFP); + eexecDumpNum(-op[k+1], fp[k+1]); + } else { + d += op[k]; + dFP |= fp[k]; + eexecDumpNum(d, dFP); + eexecDumpNum(op[k+1], fp[k+1]); + d += op[k+1]; + dFP |= fp[k+1]; + } + eexecDumpOp1(3); + } + nHints += nOps / 2; + break; + case 18: // hstemhm + //~ ignored + if (first) { + cvtGlyphWidth(nOps & 1); + first = gFalse; + } + if (nOps & 1) { + error(-1, "Wrong number of args (%d) to Type 2 hstemhm", nOps); + } + nHints += nOps / 2; + break; + case 23: // vstemhm + //~ ignored + if (first) { + cvtGlyphWidth(nOps & 1); + first = gFalse; + } + if (nOps & 1) { + error(-1, "Wrong number of args (%d) to Type 2 vstemhm", nOps); + } + nHints += nOps / 2; + break; + case 10: // callsubr + case 11: // return + case 16: // blend + case 29: // callgsubr + error(-1, "Unimplemented Type 2 charstring op: %d", s[i]); + break; + default: + error(-1, "Illegal Type 2 charstring op: %d", s[i]); + break; + } + ++i; + nOps = 0; + } else if (s[i] <= 246) { + if (nOps < 48) { + fp[nOps] = gFalse; + op[nOps++] = (int)s[i] - 139; + } + ++i; + } else if (s[i] <= 250) { + if (nOps < 48) { + fp[nOps] = gFalse; + op[nOps++] = (((int)s[i] - 247) << 8) + (int)s[i+1] + 108; + } + i += 2; + } else if (s[i] <= 254) { + if (nOps < 48) { + fp[nOps] = gFalse; + op[nOps++] = -(((int)s[i] - 251) << 8) - (int)s[i+1] - 108; + } + i += 2; + } else { + x = (s[i+1] << 24) | (s[i+2] << 16) | (s[i+3] << 8) | s[i+4]; + if (x & 0x80000000) + x |= -1 << 31; + if (nOps < 48) { + fp[nOps] = gTrue; + op[nOps++] = (double)x / 65536.0; + } + i += 5; + } + } + + sprintf(eBuf, "/%s %d RD ", name, charBuf->getLength()); + eexecWrite(eBuf); + eexecWriteCharstring((Guchar *)charBuf->getCString(), charBuf->getLength()); + eexecWrite(" ND\n"); + delete charBuf; +} + +void Type1CFontConverter::cvtGlyphWidth(GBool useOp) { + double w; + GBool wFP; + int i; + + if (useOp) { + w = nominalWidthX + op[0]; + wFP = nominalWidthXFP | fp[0]; + for (i = 1; i < nOps; ++i) { + op[i-1] = op[i]; + fp[i-1] = fp[i]; + } + --nOps; + } else { + w = defaultWidthX; + wFP = defaultWidthXFP; + } + eexecDumpNum(0, gFalse); + eexecDumpNum(w, wFP); + eexecDumpOp1(13); +} + +void Type1CFontConverter::eexecDumpNum(double x, GBool fp) { + Guchar buf[12]; + int y, n; + + n = 0; + if (fp) { + if (x >= -32768 && x < 32768) { + y = (int)(x * 256.0); + buf[0] = 255; + buf[1] = (Guchar)(y >> 24); + buf[2] = (Guchar)(y >> 16); + buf[3] = (Guchar)(y >> 8); + buf[4] = (Guchar)y; + buf[5] = 255; + buf[6] = 0; + buf[7] = 0; + buf[8] = 1; + buf[9] = 0; + buf[10] = 12; + buf[11] = 12; + n = 12; + } else { + error(-1, "Type 2 fixed point constant out of range"); + } + } else { + y = (int)x; + if (y >= -107 && y <= 107) { + buf[0] = (Guchar)(y + 139); + n = 1; + } else if (y > 107 && y <= 1131) { + y -= 108; + buf[0] = (Guchar)((y >> 8) + 247); + buf[1] = (Guchar)(y & 0xff); + n = 2; + } else if (y < -107 && y >= -1131) { + y = -y - 108; + buf[0] = (Guchar)((y >> 8) + 251); + buf[1] = (Guchar)(y & 0xff); + n = 2; + } else { + buf[0] = 255; + buf[1] = (Guchar)(y >> 24); + buf[2] = (Guchar)(y >> 16); + buf[3] = (Guchar)(y >> 8); + buf[4] = (Guchar)y; + n = 5; + } + } + charBuf->append((char *)buf, n); +} + +void Type1CFontConverter::eexecDumpOp1(int op) { + charBuf->append((char)op); +} + +void Type1CFontConverter::eexecDumpOp2(int op) { + charBuf->append((char)12); + charBuf->append((char)op); +} + +void Type1CFontConverter::eexecWriteCharstring(Guchar *s, int n) { + Gushort r2; + Guchar x; + int i; + + r2 = 4330; + + for (i = 0; i < n; ++i) { + // charstring encryption + x = s[i]; + x ^= (r2 >> 8); + r2 = (x + r2) * 52845 + 22719; + + // eexec encryption + x ^= (r1 >> 8); + r1 = (x + r1) * 52845 + 22719; + fputc(hexChars[x >> 4], out); + fputc(hexChars[x & 0x0f], out); + line += 2; + if (line == 64) { + fputc('\n', out); + line = 0; + } + } +} + +void Type1CFontConverter::getDeltaInt(char *buf, char *name, double *op, + int n) { + int x, i; + + buf += sprintf(buf, "/%s [", name); + x = 0; + for (i = 0; i < n; ++i) { + x += (int)op[i]; + buf += sprintf(buf, "%s%d", i > 0 ? " " : "", x); + } + sprintf(buf, "] def\n"); +} + +void Type1CFontConverter::getDeltaReal(char *buf, char *name, double *op, + int n) { + double x; + int i; + + buf += sprintf(buf, "/%s [", name); + x = 0; + for (i = 0; i < n; ++i) { + x += op[i]; + buf += sprintf(buf, "%s%g", i > 0 ? " " : "", x); + } + sprintf(buf, "] def\n"); +} diff --git a/pdftops/FontFile.h b/pdftops/FontFile.h new file mode 100644 index 0000000000..ec625ef28b --- /dev/null +++ b/pdftops/FontFile.h @@ -0,0 +1,117 @@ +//======================================================================== +// +// FontFile.h +// +// Copyright 1999 Derek B. Noonburg +// +//======================================================================== + +#ifndef FONTFILE_H +#define FONTFILE_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include +#include "gtypes.h" +#include "GString.h" +#include "FontEncoding.h" + +//------------------------------------------------------------------------ +// FontFile +//------------------------------------------------------------------------ + +class FontFile { +public: + + FontFile(); + virtual ~FontFile(); + + // Returns the font name, as specified internally by the font file. + // Returns NULL if no name is available. + virtual char *getName() = 0; + + // Returns the custom font encoding, or NULL if the encoding is + // not available. If is set, the caller of this function + // will be responsible for freeing the encoding object. + virtual FontEncoding *getEncoding(GBool taken) = 0; +}; + +//------------------------------------------------------------------------ +// Type1FontFile +//------------------------------------------------------------------------ + +class Type1FontFile: public FontFile { +public: + + Type1FontFile(char *file, int len); + virtual ~Type1FontFile(); + virtual char *getName() { return name; } + virtual FontEncoding *getEncoding(GBool taken); + +private: + + char *name; + FontEncoding *encoding; + GBool freeEnc; +}; + +//------------------------------------------------------------------------ +// Type1CFontFile +//------------------------------------------------------------------------ + +class Type1CFontFile: public FontFile { +public: + + Type1CFontFile(char *file, int len); + virtual ~Type1CFontFile(); + virtual char *getName() { return name; } + virtual FontEncoding *getEncoding(GBool taken); + +private: + + char *name; + FontEncoding *encoding; + GBool freeEnc; +}; + +//------------------------------------------------------------------------ +// Type1CFontConverter +//------------------------------------------------------------------------ + +class Type1CFontConverter { +public: + + Type1CFontConverter(char *file, int len, FILE *out); + ~Type1CFontConverter(); + void convert(); + +private: + + void eexecWrite(char *s); + void cvtGlyph(char *name, Guchar *s, int n); + void cvtGlyphWidth(GBool useOp); + void eexecDumpNum(double x, GBool fp); + void eexecDumpOp1(int op); + void eexecDumpOp2(int op); + void eexecWriteCharstring(Guchar *s, int n); + void getDeltaInt(char *buf, char *name, double *op, int n); + void getDeltaReal(char *buf, char *name, double *op, int n); + + char *file; + int len; + FILE *out; + double op[48]; // operands + GBool fp[48]; // true if operand is fixed point + int nOps; // number of operands + double defaultWidthX; // default glyph width + double nominalWidthX; // nominal glyph width + GBool defaultWidthXFP; // true if defaultWidthX is fixed point + GBool nominalWidthXFP; // true if nominalWidthX is fixed point + Gushort r1; // eexec encryption key + GString *charBuf; // charstring output buffer + int line; // number of eexec chars on current line +}; + +#endif diff --git a/pdftops/FontInfo.h b/pdftops/FontInfo.h new file mode 100644 index 0000000000..ee85b95b49 --- /dev/null +++ b/pdftops/FontInfo.h @@ -0,0 +1,2068 @@ +//======================================================================== +// +// FontInfo.h +// +// This file was automatically generated by makeFontInfo. +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef FONTINFO_H +#define FONTINFO_H + +//------------------------------------------------------------------------ +// Character encodings. +//------------------------------------------------------------------------ + +#define standardEncodingSize 335 +static char *standardEncodingNames[standardEncodingSize] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quoteright", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "quoteleft", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + NULL, + "endash", + "dagger", + "daggerdbl", + "periodcentered", + NULL, + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + NULL, + "questiondown", + NULL, + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + NULL, + "ring", + "cedilla", + NULL, + "hungarumlaut", + "ogonek", + "caron", + "emdash", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "AE", + NULL, + "ordfeminine", + NULL, + NULL, + NULL, + NULL, + "Lslash", + "Oslash", + "OE", + "ordmasculine", + NULL, + NULL, + NULL, + NULL, + NULL, + "ae", + NULL, + NULL, + NULL, + "dotlessi", + NULL, + NULL, + "lslash", + "oslash", + "oe", + "germandbls", + NULL, + NULL, + NULL, + NULL, + "Aacute", + "Acircumflex", + "Adieresis", + "Agrave", + "Aring", + "Atilde", + "Ccedilla", + "Eacute", + "Ecircumflex", + "Edieresis", + "Egrave", + "Eth", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Ntilde", + "Oacute", + "Ocircumflex", + "Odieresis", + "Ograve", + "Otilde", + "Scaron", + "Thorn", + "Uacute", + "Ucircumflex", + "Udieresis", + "Ugrave", + "Yacute", + "Ydieresis", + "Zcaron", + "aacute", + "acircumflex", + "adieresis", + "agrave", + "aring", + "atilde", + "brokenbar", + "ccedilla", + "copyright", + "degree", + "divide", + "eacute", + "ecircumflex", + "edieresis", + "egrave", + "eth", + "iacute", + "icircumflex", + "idieresis", + "igrave", + "logicalnot", + "minus", + "mu", + "multiply", + "ntilde", + "oacute", + "ocircumflex", + "odieresis", + "ograve", + "onehalf", + "onequarter", + "onesuperior", + "otilde", + "plusminus", + "registered", + "scaron", + "thorn", + "threequarters", + "threesuperior", + "trademark", + "twosuperior", + "uacute", + "ucircumflex", + "udieresis", + "ugrave", + "yacute", + "ydieresis", + "zcaron" +}; +static FontEncoding standardEncoding(standardEncodingNames, + standardEncodingSize); + +#define symbolEncodingSize 257 +static char *symbolEncodingNames[symbolEncodingSize] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclam", + "universal", + "numbersign", + "existential", + "percent", + "ampersand", + "suchthat", + "parenleft", + "parenright", + "asteriskmath", + "plus", + "comma", + "minus", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "congruent", + "Alpha", + "Beta", + "Chi", + "Delta", + "Epsilon", + "Phi", + "Gamma", + "Eta", + "Iota", + "theta1", + "Kappa", + "Lambda", + "Mu", + "Nu", + "Omicron", + "Pi", + "Theta", + "Rho", + "Sigma", + "Tau", + "Upsilon", + "sigma1", + "Omega", + "Xi", + "Psi", + "Zeta", + "bracketleft", + "therefore", + "bracketright", + "perpendicular", + "underscore", + "radicalex", + "alpha", + "beta", + "chi", + "delta", + "epsilon", + "phi", + "gamma", + "eta", + "iota", + "phi1", + "kappa", + "lambda", + "mu", + "nu", + "omicron", + "pi", + "theta", + "rho", + "sigma", + "tau", + "upsilon", + "omega1", + "omega", + "xi", + "psi", + "zeta", + "braceleft", + "bar", + "braceright", + "similar", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "Upsilon1", + "minute", + "lessequal", + "fraction", + "infinity", + "florin", + "club", + "diamond", + "heart", + "spade", + "arrowboth", + "arrowleft", + "arrowup", + "arrowright", + "arrowdown", + "degree", + "plusminus", + "second", + "greaterequal", + "multiply", + "proportional", + "partialdiff", + "bullet", + "divide", + "notequal", + "equivalence", + "approxequal", + "ellipsis", + "arrowvertex", + "arrowhorizex", + "carriagereturn", + "aleph", + "Ifraktur", + "Rfraktur", + "weierstrass", + "circlemultiply", + "circleplus", + "emptyset", + "intersection", + "union", + "propersuperset", + "reflexsuperset", + "notsubset", + "propersubset", + "reflexsubset", + "element", + "notelement", + "angle", + "gradient", + "registerserif", + "copyrightserif", + "trademarkserif", + "product", + "radical", + "dotmath", + "logicalnot", + "logicaland", + "logicalor", + "arrowdblboth", + "arrowdblleft", + "arrowdblup", + "arrowdblright", + "arrowdbldown", + "lozenge", + "angleleft", + "registersans", + "copyrightsans", + "trademarksans", + "summation", + "parenlefttp", + "parenleftex", + "parenleftbt", + "bracketlefttp", + "bracketleftex", + "bracketleftbt", + "bracelefttp", + "braceleftmid", + "braceleftbt", + "braceex", + NULL, + "angleright", + "integral", + "integraltp", + "integralex", + "integralbt", + "parenrighttp", + "parenrightex", + "parenrightbt", + "bracketrighttp", + "bracketrightex", + "bracketrightbt", + "bracerighttp", + "bracerightmid", + "bracerightbt", + NULL, + "apple" +}; +static FontEncoding symbolEncoding(symbolEncodingNames, + symbolEncodingSize); + +#define zapfDingbatsEncodingSize 270 +static char *zapfDingbatsEncodingNames[zapfDingbatsEncodingSize] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "a1", + "a2", + "a202", + "a3", + "a4", + "a5", + "a119", + "a118", + "a117", + "a11", + "a12", + "a13", + "a14", + "a15", + "a16", + "a105", + "a17", + "a18", + "a19", + "a20", + "a21", + "a22", + "a23", + "a24", + "a25", + "a26", + "a27", + "a28", + "a6", + "a7", + "a8", + "a9", + "a10", + "a29", + "a30", + "a31", + "a32", + "a33", + "a34", + "a35", + "a36", + "a37", + "a38", + "a39", + "a40", + "a41", + "a42", + "a43", + "a44", + "a45", + "a46", + "a47", + "a48", + "a49", + "a50", + "a51", + "a52", + "a53", + "a54", + "a55", + "a56", + "a57", + "a58", + "a59", + "a60", + "a61", + "a62", + "a63", + "a64", + "a65", + "a66", + "a67", + "a68", + "a69", + "a70", + "a71", + "a72", + "a73", + "a74", + "a203", + "a75", + "a204", + "a76", + "a77", + "a78", + "a79", + "a81", + "a82", + "a83", + "a84", + "a97", + "a98", + "a99", + "a100", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "a101", + "a102", + "a103", + "a104", + "a106", + "a107", + "a108", + "a112", + "a111", + "a110", + "a109", + "a120", + "a121", + "a122", + "a123", + "a124", + "a125", + "a126", + "a127", + "a128", + "a129", + "a130", + "a131", + "a132", + "a133", + "a134", + "a135", + "a136", + "a137", + "a138", + "a139", + "a140", + "a141", + "a142", + "a143", + "a144", + "a145", + "a146", + "a147", + "a148", + "a149", + "a150", + "a151", + "a152", + "a153", + "a154", + "a155", + "a156", + "a157", + "a158", + "a159", + "a160", + "a161", + "a163", + "a164", + "a196", + "a165", + "a192", + "a166", + "a167", + "a168", + "a169", + "a170", + "a171", + "a172", + "a173", + "a162", + "a174", + "a175", + "a176", + "a177", + "a178", + "a179", + "a193", + "a180", + "a199", + "a181", + "a200", + "a182", + NULL, + "a201", + "a183", + "a184", + "a197", + "a185", + "a194", + "a198", + "a186", + "a195", + "a187", + "a188", + "a189", + "a190", + "a191", + NULL, + "a205", + "a206", + "a85", + "a86", + "a87", + "a88", + "a89", + "a90", + "a91", + "a92", + "a93", + "a94", + "a95", + "a96" +}; +static FontEncoding zapfDingbatsEncoding(zapfDingbatsEncodingNames, + zapfDingbatsEncodingSize); + +#define macRomanEncodingSize 256 +static char *macRomanEncodingNames[macRomanEncodingSize] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "grave", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + NULL, + "Adieresis", + "Aring", + "Ccedilla", + "Eacute", + "Ntilde", + "Odieresis", + "Udieresis", + "aacute", + "agrave", + "acircumflex", + "adieresis", + "atilde", + "aring", + "ccedilla", + "eacute", + "egrave", + "ecircumflex", + "edieresis", + "iacute", + "igrave", + "icircumflex", + "idieresis", + "ntilde", + "oacute", + "ograve", + "ocircumflex", + "odieresis", + "otilde", + "uacute", + "ugrave", + "ucircumflex", + "udieresis", + "dagger", + "degree", + "cent", + "sterling", + "section", + "bullet", + "paragraph", + "germandbls", + "registered", + "copyright", + "trademark", + "acute", + "dieresis", + NULL, + "AE", + "Oslash", + NULL, + "plusminus", + NULL, + NULL, + "yen", + "mu", + NULL, + NULL, + NULL, + NULL, + NULL, + "ordfeminine", + "ordmasculine", + NULL, + "ae", + "oslash", + "questiondown", + "exclamdown", + "logicalnot", + NULL, + "florin", + NULL, + NULL, + "guillemotleft", + "guillemotright", + "ellipsis", + "space", + "Agrave", + "Atilde", + "Otilde", + "OE", + "oe", + "endash", + "emdash", + "quotedblleft", + "quotedblright", + "quoteleft", + "quoteright", + "divide", + NULL, + "ydieresis", + "Ydieresis", + "fraction", + "currency", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + "daggerdbl", + "periodcentered", + "quotesinglbase", + "quotedblbase", + "perthousand", + "Acircumflex", + "Ecircumflex", + "Aacute", + "Edieresis", + "Egrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Igrave", + "Oacute", + "Ocircumflex", + NULL, + "Ograve", + "Uacute", + "Ucircumflex", + "Ugrave", + "dotlessi", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "ring", + "cedilla", + "hungarumlaut", + "ogonek", + "caron" +}; +static FontEncoding macRomanEncoding(macRomanEncodingNames, + macRomanEncodingSize); + +#define winAnsiEncodingSize 256 +static char *winAnsiEncodingNames[winAnsiEncodingSize] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quotesingle", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "grave", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + "bullet", + "bullet", + "bullet", + "quotesinglbase", + "florin", + "quotedblbase", + "ellipsis", + "dagger", + "daggerdbl", + "circumflex", + "perthousand", + "Scaron", + "guilsinglleft", + "OE", + "bullet", + "bullet", + "bullet", + "bullet", + "quoteleft", + "quoteright", + "quotedblleft", + "quotedblright", + "bullet", + "endash", + "emdash", + "tilde", + "trademark", + "scaron", + "guilsinglright", + "oe", + "bullet", + "bullet", + "Ydieresis", + "space", + "exclamdown", + "cent", + "sterling", + "currency", + "yen", + "brokenbar", + "section", + "dieresis", + "copyright", + "ordfeminine", + "guillemotleft", + "logicalnot", + "hyphen", + "registered", + "macron", + "degree", + "plusminus", + "twosuperior", + "threesuperior", + "acute", + "mu", + "paragraph", + "periodcentered", + "cedilla", + "onesuperior", + "ordmasculine", + "guillemotright", + "onequarter", + "onehalf", + "threequarters", + "questiondown", + "Agrave", + "Aacute", + "Acircumflex", + "Atilde", + "Adieresis", + "Aring", + "AE", + "Ccedilla", + "Egrave", + "Eacute", + "Ecircumflex", + "Edieresis", + "Igrave", + "Iacute", + "Icircumflex", + "Idieresis", + "Eth", + "Ntilde", + "Ograve", + "Oacute", + "Ocircumflex", + "Otilde", + "Odieresis", + "multiply", + "Oslash", + "Ugrave", + "Uacute", + "Ucircumflex", + "Udieresis", + "Yacute", + "Thorn", + "germandbls", + "agrave", + "aacute", + "acircumflex", + "atilde", + "adieresis", + "aring", + "ae", + "ccedilla", + "egrave", + "eacute", + "ecircumflex", + "edieresis", + "igrave", + "iacute", + "icircumflex", + "idieresis", + "eth", + "ntilde", + "ograve", + "oacute", + "ocircumflex", + "otilde", + "odieresis", + "divide", + "oslash", + "ugrave", + "uacute", + "ucircumflex", + "udieresis", + "yacute", + "thorn", + "ydieresis" +}; +static FontEncoding winAnsiEncoding(winAnsiEncodingNames, + winAnsiEncodingSize); + +//------------------------------------------------------------------------ +// Character widths for built-in fonts. +//------------------------------------------------------------------------ + +static Gushort courierWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 0, 600, 600, 600, 600, 0, 600, 600, + 600, 600, 600, 600, 600, 600, 0, 600, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 0, 600, 600, 0, 600, 600, 600, + 600, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 0, 600, 0, 0, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0, + 0, 600, 0, 0, 0, 600, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600 +}; + +static Gushort courierBoldWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 0, 600, 600, 600, 600, 0, 600, 600, + 600, 600, 600, 600, 600, 600, 0, 600, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 0, 600, 600, 0, 600, 600, 600, + 600, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 0, 600, 0, 0, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0, + 0, 600, 0, 0, 0, 600, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600 +}; + +static Gushort courierBoldObliqueWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 0, 600, 600, 600, 600, 0, 600, 600, + 600, 600, 600, 600, 600, 600, 0, 600, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 0, 600, 600, 0, 600, 600, 600, + 600, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 0, 600, 0, 0, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0, + 0, 600, 0, 0, 0, 600, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600 +}; + +static Gushort courierObliqueWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 0, 600, 600, 600, 600, 0, 600, 600, + 600, 600, 600, 600, 600, 600, 0, 600, + 0, 600, 600, 600, 600, 600, 600, 600, + 600, 0, 600, 600, 0, 600, 600, 600, + 600, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 600, 0, 600, 0, 0, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0, + 0, 600, 0, 0, 0, 600, 0, 0, + 600, 600, 600, 600, 0, 0, 0, 0, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600, 600, + 600, 600, 600, 600, 600, 600, 600 +}; + +static Gushort helveticaWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 278, 278, 355, 556, 556, 889, 667, 222, + 333, 333, 389, 584, 278, 333, 278, 278, + 556, 556, 556, 556, 556, 556, 556, 556, + 556, 556, 278, 278, 584, 584, 584, 556, + 1015, 667, 667, 722, 722, 667, 611, 778, + 722, 278, 500, 667, 556, 833, 722, 778, + 667, 778, 722, 667, 611, 722, 667, 944, + 667, 667, 611, 278, 278, 278, 469, 556, + 222, 556, 556, 500, 556, 556, 278, 556, + 556, 222, 222, 500, 222, 833, 556, 556, + 556, 556, 333, 500, 278, 556, 500, 722, + 500, 500, 500, 334, 260, 334, 584, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 333, 556, 556, 167, 556, 556, 556, + 556, 191, 333, 556, 333, 333, 500, 500, + 0, 556, 556, 556, 278, 0, 537, 350, + 222, 333, 333, 556, 1000, 1000, 0, 611, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 1000, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1000, 0, 370, 0, 0, 0, 0, + 556, 778, 1000, 365, 0, 0, 0, 0, + 0, 889, 0, 0, 0, 278, 0, 0, + 222, 611, 944, 611, 0, 0, 0, 0, + 667, 667, 667, 667, 667, 667, 722, 667, + 667, 667, 667, 722, 278, 278, 278, 278, + 722, 778, 778, 778, 778, 778, 667, 667, + 722, 722, 722, 722, 667, 667, 611, 556, + 556, 556, 556, 556, 556, 260, 500, 737, + 400, 584, 556, 556, 556, 556, 556, 278, + 278, 278, 278, 584, 584, 556, 584, 556, + 556, 556, 556, 556, 834, 834, 333, 556, + 584, 737, 500, 556, 834, 333, 1000, 333, + 556, 556, 556, 556, 500, 500, 500 +}; + +static Gushort helveticaBoldWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 278, 333, 474, 556, 556, 889, 722, 278, + 333, 333, 389, 584, 278, 333, 278, 278, + 556, 556, 556, 556, 556, 556, 556, 556, + 556, 556, 333, 333, 584, 584, 584, 611, + 975, 722, 722, 722, 722, 667, 611, 778, + 722, 278, 556, 722, 611, 833, 722, 778, + 667, 778, 722, 667, 611, 722, 667, 944, + 667, 667, 611, 333, 278, 333, 584, 556, + 278, 556, 611, 556, 611, 556, 333, 611, + 611, 278, 278, 556, 278, 889, 611, 611, + 611, 611, 389, 556, 333, 611, 556, 778, + 556, 556, 500, 389, 280, 389, 584, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 333, 556, 556, 167, 556, 556, 556, + 556, 238, 500, 556, 333, 333, 611, 611, + 0, 556, 556, 556, 278, 0, 556, 350, + 278, 500, 500, 556, 1000, 1000, 0, 611, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 1000, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1000, 0, 370, 0, 0, 0, 0, + 611, 778, 1000, 365, 0, 0, 0, 0, + 0, 889, 0, 0, 0, 278, 0, 0, + 278, 611, 944, 611, 0, 0, 0, 0, + 722, 722, 722, 722, 722, 722, 722, 667, + 667, 667, 667, 722, 278, 278, 278, 278, + 722, 778, 778, 778, 778, 778, 667, 667, + 722, 722, 722, 722, 667, 667, 611, 556, + 556, 556, 556, 556, 556, 280, 556, 737, + 400, 584, 556, 556, 556, 556, 611, 278, + 278, 278, 278, 584, 584, 611, 584, 611, + 611, 611, 611, 611, 834, 834, 333, 611, + 584, 737, 556, 611, 834, 333, 1000, 333, + 611, 611, 611, 611, 556, 556, 500 +}; + +static Gushort helveticaBoldObliqueWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 278, 333, 474, 556, 556, 889, 722, 278, + 333, 333, 389, 584, 278, 333, 278, 278, + 556, 556, 556, 556, 556, 556, 556, 556, + 556, 556, 333, 333, 584, 584, 584, 611, + 975, 722, 722, 722, 722, 667, 611, 778, + 722, 278, 556, 722, 611, 833, 722, 778, + 667, 778, 722, 667, 611, 722, 667, 944, + 667, 667, 611, 333, 278, 333, 584, 556, + 278, 556, 611, 556, 611, 556, 333, 611, + 611, 278, 278, 556, 278, 889, 611, 611, + 611, 611, 389, 556, 333, 611, 556, 778, + 556, 556, 500, 389, 280, 389, 584, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 333, 556, 556, 167, 556, 556, 556, + 556, 238, 500, 556, 333, 333, 611, 611, + 0, 556, 556, 556, 278, 0, 556, 350, + 278, 500, 500, 556, 1000, 1000, 0, 611, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 1000, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1000, 0, 370, 0, 0, 0, 0, + 611, 778, 1000, 365, 0, 0, 0, 0, + 0, 889, 0, 0, 0, 278, 0, 0, + 278, 611, 944, 611, 0, 0, 0, 0, + 722, 722, 722, 722, 722, 722, 722, 667, + 667, 667, 667, 722, 278, 278, 278, 278, + 722, 778, 778, 778, 778, 778, 667, 667, + 722, 722, 722, 722, 667, 667, 611, 556, + 556, 556, 556, 556, 556, 280, 556, 737, + 400, 584, 556, 556, 556, 556, 611, 278, + 278, 278, 278, 584, 584, 611, 584, 611, + 611, 611, 611, 611, 834, 834, 333, 611, + 584, 737, 556, 611, 834, 333, 1000, 333, + 611, 611, 611, 611, 556, 556, 500 +}; + +static Gushort helveticaObliqueWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 278, 278, 355, 556, 556, 889, 667, 222, + 333, 333, 389, 584, 278, 333, 278, 278, + 556, 556, 556, 556, 556, 556, 556, 556, + 556, 556, 278, 278, 584, 584, 584, 556, + 1015, 667, 667, 722, 722, 667, 611, 778, + 722, 278, 500, 667, 556, 833, 722, 778, + 667, 778, 722, 667, 611, 722, 667, 944, + 667, 667, 611, 278, 278, 278, 469, 556, + 222, 556, 556, 500, 556, 556, 278, 556, + 556, 222, 222, 500, 222, 833, 556, 556, + 556, 556, 333, 500, 278, 556, 500, 722, + 500, 500, 500, 334, 260, 334, 584, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 333, 556, 556, 167, 556, 556, 556, + 556, 191, 333, 556, 333, 333, 500, 500, + 0, 556, 556, 556, 278, 0, 537, 350, + 222, 333, 333, 556, 1000, 1000, 0, 611, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 1000, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1000, 0, 370, 0, 0, 0, 0, + 556, 778, 1000, 365, 0, 0, 0, 0, + 0, 889, 0, 0, 0, 278, 0, 0, + 222, 611, 944, 611, 0, 0, 0, 0, + 667, 667, 667, 667, 667, 667, 722, 667, + 667, 667, 667, 722, 278, 278, 278, 278, + 722, 778, 778, 778, 778, 778, 667, 667, + 722, 722, 722, 722, 667, 667, 611, 556, + 556, 556, 556, 556, 556, 260, 500, 737, + 400, 584, 556, 556, 556, 556, 556, 278, + 278, 278, 278, 584, 584, 556, 584, 556, + 556, 556, 556, 556, 834, 834, 333, 556, + 584, 737, 500, 556, 834, 333, 1000, 333, + 556, 556, 556, 556, 500, 500, 500 +}; + +static Gushort symbolWidths[257] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 250, 333, 713, 500, 549, 833, 778, 439, + 333, 333, 500, 549, 250, 549, 250, 278, + 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 278, 278, 549, 549, 549, 444, + 549, 722, 667, 722, 612, 611, 763, 603, + 722, 333, 631, 722, 686, 889, 722, 722, + 768, 741, 556, 592, 611, 690, 439, 768, + 645, 795, 611, 333, 863, 333, 658, 500, + 500, 631, 549, 549, 494, 439, 521, 411, + 603, 329, 603, 549, 549, 576, 521, 549, + 549, 521, 549, 603, 439, 576, 713, 686, + 493, 686, 494, 480, 200, 480, 549, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 620, 247, 549, 167, 713, 500, 753, + 753, 753, 753, 1042, 987, 603, 987, 603, + 400, 549, 411, 549, 549, 713, 494, 460, + 549, 549, 549, 549, 1000, 603, 1000, 658, + 823, 686, 795, 987, 768, 768, 823, 768, + 768, 713, 713, 713, 713, 713, 713, 713, + 768, 713, 790, 790, 890, 823, 549, 250, + 713, 603, 603, 1042, 987, 603, 987, 603, + 494, 329, 790, 790, 786, 713, 384, 384, + 384, 384, 384, 384, 494, 494, 494, 494, + 0, 329, 274, 686, 686, 686, 384, 384, + 384, 384, 384, 384, 494, 494, 494, 0, + 790 +}; + +static Gushort timesBoldWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 250, 333, 555, 500, 500, 1000, 833, 333, + 333, 333, 500, 570, 250, 333, 250, 278, + 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 333, 333, 570, 570, 570, 500, + 930, 722, 667, 722, 722, 667, 611, 778, + 778, 389, 500, 778, 667, 944, 722, 778, + 611, 778, 722, 556, 667, 722, 722, 1000, + 722, 722, 667, 333, 278, 333, 581, 500, + 333, 500, 556, 444, 556, 444, 333, 500, + 556, 278, 333, 556, 278, 833, 556, 500, + 556, 556, 444, 389, 333, 556, 500, 722, + 500, 500, 444, 394, 220, 394, 520, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 333, 500, 500, 167, 500, 500, 500, + 500, 278, 500, 500, 333, 333, 556, 556, + 0, 500, 500, 500, 250, 0, 540, 350, + 333, 500, 500, 500, 1000, 1000, 0, 500, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 1000, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1000, 0, 300, 0, 0, 0, 0, + 667, 778, 1000, 330, 0, 0, 0, 0, + 0, 722, 0, 0, 0, 278, 0, 0, + 278, 500, 722, 556, 0, 0, 0, 0, + 722, 722, 722, 722, 722, 722, 722, 667, + 667, 667, 667, 722, 389, 389, 389, 389, + 722, 778, 778, 778, 778, 778, 556, 611, + 722, 722, 722, 722, 722, 722, 667, 500, + 500, 500, 500, 500, 500, 220, 444, 747, + 400, 570, 444, 444, 444, 444, 500, 278, + 278, 278, 278, 570, 570, 556, 570, 556, + 500, 500, 500, 500, 750, 750, 300, 500, + 570, 747, 389, 556, 750, 300, 1000, 300, + 556, 556, 556, 556, 500, 500, 444 +}; + +static Gushort timesBoldItalicWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 250, 389, 555, 500, 500, 833, 778, 333, + 333, 333, 500, 570, 250, 333, 250, 278, + 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 333, 333, 570, 570, 570, 500, + 832, 667, 667, 667, 722, 667, 667, 722, + 778, 389, 500, 667, 611, 889, 722, 722, + 611, 722, 667, 556, 611, 722, 667, 889, + 667, 611, 611, 333, 278, 333, 570, 500, + 333, 500, 500, 444, 500, 444, 333, 500, + 556, 278, 278, 500, 278, 778, 556, 500, + 500, 500, 389, 389, 278, 556, 444, 667, + 500, 444, 389, 348, 220, 348, 570, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 389, 500, 500, 167, 500, 500, 500, + 500, 278, 500, 500, 333, 333, 556, 556, + 0, 500, 500, 500, 250, 0, 500, 350, + 333, 500, 500, 500, 1000, 1000, 0, 500, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 1000, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 944, 0, 266, 0, 0, 0, 0, + 611, 722, 944, 300, 0, 0, 0, 0, + 0, 722, 0, 0, 0, 278, 0, 0, + 278, 500, 722, 500, 0, 0, 0, 0, + 667, 667, 667, 667, 667, 667, 667, 667, + 667, 667, 667, 722, 389, 389, 389, 389, + 722, 722, 722, 722, 722, 722, 556, 611, + 722, 722, 722, 722, 611, 611, 611, 500, + 500, 500, 500, 500, 500, 220, 444, 747, + 400, 570, 444, 444, 444, 444, 500, 278, + 278, 278, 278, 606, 606, 576, 570, 556, + 500, 500, 500, 500, 750, 750, 300, 500, + 570, 747, 389, 500, 750, 300, 1000, 300, + 556, 556, 556, 556, 444, 444, 389 +}; + +static Gushort timesItalicWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 250, 333, 420, 500, 500, 833, 778, 333, + 333, 333, 500, 675, 250, 333, 250, 278, + 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 333, 333, 675, 675, 675, 500, + 920, 611, 611, 667, 722, 611, 611, 722, + 722, 333, 444, 667, 556, 833, 667, 722, + 611, 722, 611, 500, 556, 722, 611, 833, + 611, 556, 556, 389, 278, 389, 422, 500, + 333, 500, 500, 444, 500, 444, 278, 500, + 500, 278, 278, 444, 278, 722, 500, 500, + 500, 500, 389, 389, 278, 500, 444, 667, + 444, 444, 389, 400, 275, 400, 541, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 389, 500, 500, 167, 500, 500, 500, + 500, 214, 556, 500, 333, 333, 500, 500, + 0, 500, 500, 500, 250, 0, 523, 350, + 333, 556, 556, 500, 889, 1000, 0, 500, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 889, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 889, 0, 276, 0, 0, 0, 0, + 556, 722, 944, 310, 0, 0, 0, 0, + 0, 667, 0, 0, 0, 278, 0, 0, + 278, 500, 667, 500, 0, 0, 0, 0, + 611, 611, 611, 611, 611, 611, 667, 611, + 611, 611, 611, 722, 333, 333, 333, 333, + 667, 722, 722, 722, 722, 722, 500, 611, + 722, 722, 722, 722, 556, 556, 556, 500, + 500, 500, 500, 500, 500, 275, 444, 760, + 400, 675, 444, 444, 444, 444, 500, 278, + 278, 278, 278, 675, 675, 500, 675, 500, + 500, 500, 500, 500, 750, 750, 300, 500, + 675, 760, 389, 500, 750, 300, 980, 300, + 500, 500, 500, 500, 444, 444, 389 +}; + +static Gushort timesRomanWidths[335] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 250, 333, 408, 500, 500, 833, 778, 333, + 333, 333, 500, 564, 250, 333, 250, 278, + 500, 500, 500, 500, 500, 500, 500, 500, + 500, 500, 278, 278, 564, 564, 564, 444, + 921, 722, 667, 667, 722, 611, 556, 722, + 722, 333, 389, 722, 611, 889, 722, 722, + 556, 722, 667, 556, 611, 722, 722, 944, + 722, 722, 611, 333, 278, 333, 469, 500, + 333, 444, 500, 444, 500, 444, 333, 500, + 500, 278, 278, 500, 278, 778, 500, 500, + 500, 500, 333, 389, 278, 500, 500, 722, + 500, 500, 444, 480, 200, 480, 541, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 333, 500, 500, 167, 500, 500, 500, + 500, 180, 444, 500, 333, 333, 556, 556, + 0, 500, 500, 500, 250, 0, 453, 350, + 333, 444, 444, 500, 1000, 1000, 0, 444, + 0, 333, 333, 333, 333, 333, 333, 333, + 333, 0, 333, 333, 0, 333, 333, 333, + 1000, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 889, 0, 276, 0, 0, 0, 0, + 611, 722, 889, 310, 0, 0, 0, 0, + 0, 667, 0, 0, 0, 278, 0, 0, + 278, 500, 722, 500, 0, 0, 0, 0, + 722, 722, 722, 722, 722, 722, 667, 611, + 611, 611, 611, 722, 333, 333, 333, 333, + 722, 722, 722, 722, 722, 722, 556, 556, + 722, 722, 722, 722, 722, 722, 611, 444, + 444, 444, 444, 444, 444, 200, 444, 760, + 400, 564, 444, 444, 444, 444, 500, 278, + 278, 278, 278, 564, 564, 500, 564, 500, + 500, 500, 500, 500, 750, 750, 300, 500, + 564, 760, 389, 500, 750, 300, 980, 300, + 500, 500, 500, 500, 500, 500, 444 +}; + +static Gushort zapfDingbatsWidths[270] = { + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 278, 974, 961, 974, 980, 719, 789, 790, + 791, 690, 960, 939, 549, 855, 911, 933, + 911, 945, 974, 755, 846, 762, 761, 571, + 677, 763, 760, 759, 754, 494, 552, 537, + 577, 692, 786, 788, 788, 790, 793, 794, + 816, 823, 789, 841, 823, 833, 816, 831, + 923, 744, 723, 749, 790, 792, 695, 776, + 768, 792, 759, 707, 708, 682, 701, 826, + 815, 789, 789, 707, 687, 696, 689, 786, + 787, 713, 791, 785, 791, 873, 761, 762, + 762, 759, 759, 892, 892, 788, 784, 438, + 138, 277, 415, 392, 392, 668, 668, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 732, 544, 544, 910, 667, 760, 760, + 776, 595, 694, 626, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 788, 788, 788, 788, + 788, 788, 788, 788, 894, 838, 1016, 458, + 748, 924, 748, 918, 927, 928, 928, 834, + 873, 828, 924, 924, 917, 930, 931, 463, + 883, 836, 836, 867, 867, 696, 696, 874, + 0, 874, 760, 946, 771, 865, 771, 888, + 967, 888, 831, 873, 927, 970, 918, 0, + 509, 410, 509, 410, 234, 234, 390, 390, + 276, 276, 317, 317, 334, 334 +}; + +//------------------------------------------------------------------------ +// Built-in font table. +//------------------------------------------------------------------------ + +struct BuiltinFont { + char *name; + Gushort *widths; + FontEncoding *encoding; +}; + +#define numBuiltinFonts ((int)(sizeof(builtinFonts)/sizeof(BuiltinFont))) + +static BuiltinFont builtinFonts[] = { + {"Courier", courierWidths, &standardEncoding}, + {"Courier-Bold", courierBoldWidths, &standardEncoding}, + {"Courier-BoldOblique", courierBoldObliqueWidths, &standardEncoding}, + {"Courier-Oblique", courierObliqueWidths, &standardEncoding}, + {"Helvetica", helveticaWidths, &standardEncoding}, + {"Helvetica-Bold", helveticaBoldWidths, &standardEncoding}, + {"Helvetica-BoldOblique", helveticaBoldObliqueWidths, &standardEncoding}, + {"Helvetica-Oblique", helveticaObliqueWidths, &standardEncoding}, + {"Symbol", symbolWidths, &symbolEncoding}, + {"Times-Bold", timesBoldWidths, &standardEncoding}, + {"Times-BoldItalic", timesBoldItalicWidths, &standardEncoding}, + {"Times-Italic", timesItalicWidths, &standardEncoding}, + {"Times-Roman", timesRomanWidths, &standardEncoding}, + {"ZapfDingbats", zapfDingbatsWidths, &zapfDingbatsEncoding} +}; + +#endif diff --git a/pdftops/GString.cxx b/pdftops/GString.cxx new file mode 100644 index 0000000000..e0890912d5 --- /dev/null +++ b/pdftops/GString.cxx @@ -0,0 +1,196 @@ +//======================================================================== +// +// GString.cc +// +// Simple variable-length string type. +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include "GString.h" + +static inline int size(int len) { + int delta; + + delta = len < 256 ? 7 : 255; + return ((len + 1) + delta) & ~delta; +} + +inline void GString::resize(int length1) { + char *s1; + + if (!s) { + s = new char[size(length1)]; + } else if (size(length1) != size(length)) { + s1 = new char[size(length1)]; + memcpy(s1, s, length + 1); + delete[] s; + s = s1; + } +} + +GString::GString() { + s = NULL; + resize(length = 0); + s[0] = '\0'; +} + +GString::GString(char *s1) { + int n = strlen(s1); + + s = NULL; + resize(length = n); + memcpy(s, s1, n + 1); +} + +GString::GString(char *s1, int length1) { + s = NULL; + resize(length = length1); + memcpy(s, s1, length * sizeof(char)); + s[length] = '\0'; +} + +GString::GString(GString *str) { + s = NULL; + resize(length = str->getLength()); + memcpy(s, str->getCString(), length + 1); +} + +GString::GString(GString *str1, GString *str2) { + int n1 = str1->getLength(); + int n2 = str2->getLength(); + + s = NULL; + resize(length = n1 + n2); + memcpy(s, str1->getCString(), n1); + memcpy(s + n1, str2->getCString(), n2 + 1); +} + +GString::~GString() { + delete[] s; +} + +GString *GString::clear() { + s[length = 0] = '\0'; + resize(0); + return this; +} + +GString *GString::append(char c) { + resize(length + 1); + s[length++] = c; + s[length] = '\0'; + return this; +} + +GString *GString::append(GString *str) { + int n = str->getLength(); + + resize(length + n); + memcpy(s + length, str->getCString(), n + 1); + length += n; + return this; +} + +GString *GString::append(char *str) { + int n = strlen(str); + + resize(length + n); + memcpy(s + length, str, n + 1); + length += n; + return this; +} + +GString *GString::append(char *str, int length1) { + resize(length + length1); + memcpy(s + length, str, length1); + length += length1; + s[length] = '\0'; + return this; +} + +GString *GString::insert(int i, char c) { + int j; + + resize(length + 1); + for (j = length + 1; j > i; --j) + s[j] = s[j-1]; + s[i] = c; + ++length; + return this; +} + +GString *GString::insert(int i, GString *str) { + int n = str->getLength(); + int j; + + resize(length + n); + for (j = length; j >= i; --j) + s[j+n] = s[j]; + memcpy(s+i, str->getCString(), n); + length += n; + return this; +} + +GString *GString::insert(int i, char *str) { + int n = strlen(str); + int j; + + resize(length + n); + for (j = length; j >= i; --j) + s[j+n] = s[j]; + memcpy(s+i, str, n); + length += n; + return this; +} + +GString *GString::insert(int i, char *str, int length1) { + int j; + + resize(length + length1); + for (j = length; j >= i; --j) + s[j+length1] = s[j]; + memcpy(s+i, str, length1); + length += length1; + return this; +} + +GString *GString::del(int i, int n) { + int j; + + if (n > 0) { + for (j = i; j <= length - n; ++j) + s[j] = s[j + n]; + resize(length -= n); + } + return this; +} + +GString *GString::upperCase() { + int i; + + for (i = 0; i < length; ++i) { + if (islower(s[i])) + s[i] = toupper(s[i]); + } + return this; +} + +GString *GString::lowerCase() { + int i; + + for (i = 0; i < length; ++i) { + if (isupper(s[i])) + s[i] = tolower(s[i]); + } + return this; +} diff --git a/pdftops/GString.h b/pdftops/GString.h new file mode 100644 index 0000000000..904f425a44 --- /dev/null +++ b/pdftops/GString.h @@ -0,0 +1,92 @@ +//======================================================================== +// +// GString.h +// +// Simple variable-length string type. +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef GSTRING_H +#define GSTRING_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include + +class GString { +public: + + // Create an empty string. + GString(); + + // Create a string from a C string. + GString(char *s1); + + // Create a string from chars at . This string + // can contain null characters. + GString (char *s1, int length1); + + // Copy a string. + GString(GString *str); + GString *copy() { return new GString(this); } + + // Concatenate two strings. + GString(GString *str1, GString *str2); + + // Destructor. + ~GString(); + + // Get length. + int getLength() { return length; } + + // Get C string. + char *getCString() { return s; } + + // Get th character. + char getChar(int i) { return s[i]; } + + // Change th character. + void setChar(int i, char c) { s[i] = c; } + + // Clear string to zero length. + GString *clear(); + + // Append a character or string. + GString *append(char c); + GString *append(GString *str); + GString *append(char *str); + GString *append(char *str, int length1); + + // Insert a character or string. + GString *insert(int i, char c); + GString *insert(int i, GString *str); + GString *insert(int i, char *str); + GString *insert(int i, char *str, int length1); + + // Delete a character or range of characters. + GString *del(int i, int n = 1); + + // Convert string to all-upper/all-lower case. + GString *upperCase(); + GString *lowerCase(); + + // Compare two strings: -1:< 0:= +1:> + // These functions assume the strings do not contain null characters. + int cmp(GString *str) { return strcmp(s, str->getCString()); } + int cmpN(GString *str, int n) { return strncmp(s, str->getCString(), n); } + int cmp(char *s1) { return strcmp(s, s1); } + int cmpN(char *s1, int n) { return strncmp(s, s1, n); } + +private: + + int length; + char *s; + + void resize(int length1); +}; + +#endif diff --git a/pdftops/Gfx.cxx b/pdftops/Gfx.cxx new file mode 100644 index 0000000000..bbf5bdf2d6 --- /dev/null +++ b/pdftops/Gfx.cxx @@ -0,0 +1,1588 @@ +//======================================================================== +// +// Gfx.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include "gmem.h" +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Stream.h" +#include "Lexer.h" +#include "Parser.h" +#include "GfxFont.h" +#include "GfxState.h" +#include "OutputDev.h" +#include "Params.h" +#include "Error.h" +#include "Gfx.h" + +//------------------------------------------------------------------------ +// Operator table +//------------------------------------------------------------------------ + +Operator Gfx::opTab[] = { + {"\"", 3, {tchkNum, tchkNum, tchkString}, + &Gfx::opMoveSetShowText}, + {"'", 1, {tchkString}, + &Gfx::opMoveShowText}, + {"B", 0, {tchkNone}, + &Gfx::opFillStroke}, + {"B*", 0, {tchkNone}, + &Gfx::opEOFillStroke}, + {"BDC", 2, {tchkName, tchkProps}, + &Gfx::opBeginMarkedContent}, + {"BI", 0, {tchkNone}, + &Gfx::opBeginImage}, + {"BMC", 1, {tchkName}, + &Gfx::opBeginMarkedContent}, + {"BT", 0, {tchkNone}, + &Gfx::opBeginText}, + {"BX", 0, {tchkNone}, + &Gfx::opBeginIgnoreUndef}, + {"CS", 1, {tchkName}, + &Gfx::opSetStrokeColorSpace}, + {"DP", 2, {tchkName, tchkProps}, + &Gfx::opMarkPoint}, + {"Do", 1, {tchkName}, + &Gfx::opXObject}, + {"EI", 0, {tchkNone}, + &Gfx::opEndImage}, + {"EMC", 0, {tchkNone}, + &Gfx::opEndMarkedContent}, + {"ET", 0, {tchkNone}, + &Gfx::opEndText}, + {"EX", 0, {tchkNone}, + &Gfx::opEndIgnoreUndef}, + {"F", 0, {tchkNone}, + &Gfx::opFill}, + {"G", 1, {tchkNum}, + &Gfx::opSetStrokeGray}, + {"ID", 0, {tchkNone}, + &Gfx::opImageData}, + {"J", 1, {tchkInt}, + &Gfx::opSetLineCap}, + {"K", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opSetStrokeCMYKColor}, + {"M", 1, {tchkNum}, + &Gfx::opSetMiterLimit}, + {"MP", 1, {tchkName}, + &Gfx::opMarkPoint}, + {"Q", 0, {tchkNone}, + &Gfx::opRestore}, + {"RG", 3, {tchkNum, tchkNum, tchkNum}, + &Gfx::opSetStrokeRGBColor}, + {"S", 0, {tchkNone}, + &Gfx::opStroke}, + {"SC", -4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opSetStrokeColor}, + {"SCN", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN, + tchkSCN}, + &Gfx::opSetStrokeColorN}, + {"T*", 0, {tchkNone}, + &Gfx::opTextNextLine}, + {"TD", 2, {tchkNum, tchkNum}, + &Gfx::opTextMoveSet}, + {"TJ", 1, {tchkArray}, + &Gfx::opShowSpaceText}, + {"TL", 1, {tchkNum}, + &Gfx::opSetTextLeading}, + {"Tc", 1, {tchkNum}, + &Gfx::opSetCharSpacing}, + {"Td", 2, {tchkNum, tchkNum}, + &Gfx::opTextMove}, + {"Tf", 2, {tchkName, tchkNum}, + &Gfx::opSetFont}, + {"Tj", 1, {tchkString}, + &Gfx::opShowText}, + {"Tm", 6, {tchkNum, tchkNum, tchkNum, tchkNum, + tchkNum, tchkNum}, + &Gfx::opSetTextMatrix}, + {"Tr", 1, {tchkInt}, + &Gfx::opSetTextRender}, + {"Ts", 1, {tchkNum}, + &Gfx::opSetTextRise}, + {"Tw", 1, {tchkNum}, + &Gfx::opSetWordSpacing}, + {"Tz", 1, {tchkNum}, + &Gfx::opSetHorizScaling}, + {"W", 0, {tchkNone}, + &Gfx::opClip}, + {"W*", 0, {tchkNone}, + &Gfx::opEOClip}, + {"b", 0, {tchkNone}, + &Gfx::opCloseFillStroke}, + {"b*", 0, {tchkNone}, + &Gfx::opCloseEOFillStroke}, + {"c", 6, {tchkNum, tchkNum, tchkNum, tchkNum, + tchkNum, tchkNum}, + &Gfx::opCurveTo}, + {"cm", 6, {tchkNum, tchkNum, tchkNum, tchkNum, + tchkNum, tchkNum}, + &Gfx::opConcat}, + {"cs", 1, {tchkName}, + &Gfx::opSetFillColorSpace}, + {"d", 2, {tchkArray, tchkNum}, + &Gfx::opSetDash}, + {"d0", 2, {tchkNum, tchkNum}, + &Gfx::opSetCharWidth}, + {"d1", 6, {tchkNum, tchkNum, tchkNum, tchkNum, + tchkNum, tchkNum}, + &Gfx::opSetCacheDevice}, + {"f", 0, {tchkNone}, + &Gfx::opFill}, + {"f*", 0, {tchkNone}, + &Gfx::opEOFill}, + {"g", 1, {tchkNum}, + &Gfx::opSetFillGray}, + {"gs", 1, {tchkName}, + &Gfx::opSetExtGState}, + {"h", 0, {tchkNone}, + &Gfx::opClosePath}, + {"i", 1, {tchkNum}, + &Gfx::opSetFlat}, + {"j", 1, {tchkInt}, + &Gfx::opSetLineJoin}, + {"k", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opSetFillCMYKColor}, + {"l", 2, {tchkNum, tchkNum}, + &Gfx::opLineTo}, + {"m", 2, {tchkNum, tchkNum}, + &Gfx::opMoveTo}, + {"n", 0, {tchkNone}, + &Gfx::opEndPath}, + {"q", 0, {tchkNone}, + &Gfx::opSave}, + {"re", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opRectangle}, + {"rg", 3, {tchkNum, tchkNum, tchkNum}, + &Gfx::opSetFillRGBColor}, + {"ri", 1, {tchkName}, + &Gfx::opSetRenderingIntent}, + {"s", 0, {tchkNone}, + &Gfx::opCloseStroke}, + {"sc", -4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opSetFillColor}, + {"scn", -5, {tchkSCN, tchkSCN, tchkSCN, tchkSCN, + tchkSCN}, + &Gfx::opSetFillColorN}, + {"sh", 1, {tchkName}, + &Gfx::opShFill}, + {"v", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opCurveTo1}, + {"w", 1, {tchkNum}, + &Gfx::opSetLineWidth}, + {"y", 4, {tchkNum, tchkNum, tchkNum, tchkNum}, + &Gfx::opCurveTo2}, +}; + +#define numOps (sizeof(opTab) / sizeof(Operator)) + +//------------------------------------------------------------------------ +// Gfx +//------------------------------------------------------------------------ + +Gfx::Gfx(OutputDev *out1, int pageNum, Dict *resDict, + int dpi, double x1, double y1, double x2, double y2, GBool crop, + double cropX1, double cropY1, double cropX2, double cropY2, + int rotate) { + Object obj1; + + // start the resource stack + res = new GfxResources(NULL); + + // build font dictionary + res->fonts = NULL; + if (resDict) { + resDict->lookup("Font", &obj1); + if (obj1.isDict()) + res->fonts = new GfxFontDict(obj1.getDict()); + obj1.free(); + } + + // get XObject dictionary + if (resDict) + resDict->lookup("XObject", &res->xObjDict); + else + res->xObjDict.initNull(); + + // get colorspace dictionary + if (resDict) + resDict->lookup("ColorSpace", &res->colorSpaceDict); + else + res->colorSpaceDict.initNull(); + + // initialize + out = out1; + state = new GfxState(dpi, x1, y1, x2, y2, rotate, out->upsideDown()); + fontChanged = gFalse; + clip = clipNone; + ignoreUndef = 0; + out->startPage(pageNum, state); + out->setDefaultCTM(state->getCTM()); + out->updateAll(state); + + // set crop box + if (crop) { + state->moveTo(cropX1, cropY1); + state->lineTo(cropX2, cropY1); + state->lineTo(cropX2, cropY2); + state->lineTo(cropX1, cropY2); + state->closePath(); + out->clip(state); + state->clearPath(); + } +} + +Gfx::~Gfx() { + GfxResources *resPtr; + + while (state->hasSaves()) { + state = state->restore(); + out->restoreState(state); + } + out->endPage(); + while (res) { + resPtr = res->next; + delete res; + res = resPtr; + } + if (state) + delete state; +} + +GfxResources::~GfxResources() { + if (fonts) + delete fonts; + xObjDict.free(); + colorSpaceDict.free(); +} + +void Gfx::display(Object *obj) { + Object obj2; + int i; + + if (obj->isArray()) { + for (i = 0; i < obj->arrayGetLength(); ++i) { + obj->arrayGet(i, &obj2); + if (!obj2.isStream()) { + error(-1, "Weird page contents"); + obj2.free(); + return; + } + obj2.free(); + } + } else if (!obj->isStream()) { + error(-1, "Weird page contents"); + return; + } + parser = new Parser(new Lexer(obj)); + go(); +} + +void Gfx::go() { + Object obj; + Object args[maxArgs]; + int numCmds, numArgs; + int i; + + // scan a sequence of objects + numCmds = 0; + numArgs = 0; + parser->getObj(&obj); + while (!obj.isEOF()) { + + // got a command - execute it + if (obj.isCmd()) { + if (printCommands) { + obj.print(stdout); + for (i = 0; i < numArgs; ++i) { + printf(" "); + args[i].print(stdout); + } + printf("\n"); + } + execOp(&obj, args, numArgs); + obj.free(); + for (i = 0; i < numArgs; ++i) + args[i].free(); + numArgs = 0; + + // periodically update display + if (++numCmds == 200) { + out->dump(); + numCmds = 0; + } + + // got an argument - save it + } else if (numArgs < maxArgs) { + args[numArgs++] = obj; + + // too many arguments - something is wrong + } else { + error(getPos(), "Too many args in content stream"); + if (printCommands) { + printf("throwing away arg: "); + obj.print(stdout); + printf("\n"); + } + obj.free(); + } + + // grab the next object + parser->getObj(&obj); + } + obj.free(); + + // args at end with no command + if (numArgs > 0) { + error(getPos(), "Leftover args in content stream"); + if (printCommands) { + printf("%d leftovers:", numArgs); + for (i = 0; i < numArgs; ++i) { + printf(" "); + args[i].print(stdout); + } + printf("\n"); + } + for (i = 0; i < numArgs; ++i) + args[i].free(); + } + + // update display + if (numCmds > 0) + out->dump(); + + // clean up + if (parser) + delete parser; + if (printCommands) + fflush(stdout); +} + +void Gfx::execOp(Object *cmd, Object args[], int numArgs) { + Operator *op; + char *name; + int i; + + // find operator + name = cmd->getName(); + if (!(op = findOp(name))) { + if (ignoreUndef == 0) + error(getPos(), "Unknown operator '%s'", name); + return; + } + + // type check args + if (op->numArgs >= 0) { + if (numArgs != op->numArgs) { + error(getPos(), "Wrong number (%d) of args to '%s' operator", + numArgs, name); + return; + } + } else { + if (numArgs > -op->numArgs) { + error(getPos(), "Too many (%d) args to '%s' operator", + numArgs, name); + return; + } + } + for (i = 0; i < numArgs; ++i) { + if (!checkArg(&args[i], op->tchk[i])) { + error(getPos(), "Arg #%d to '%s' operator is wrong type (%s)", + i, name, args[i].getTypeName()); + return; + } + } + + // do it + (this->*op->func)(args, numArgs); +} + +Operator *Gfx::findOp(char *name) { + int a, b, m, cmp; + + a = -1; + b = numOps; + // invariant: opTab[a] < name < opTab[b] + while (b - a > 1) { + m = (a + b) / 2; + cmp = strcmp(opTab[m].name, name); + if (cmp < 0) + a = m; + else if (cmp > 0) + b = m; + else + a = b = m; + } + if (cmp != 0) + return NULL; + return &opTab[a]; +} + +GBool Gfx::checkArg(Object *arg, TchkType type) { + switch (type) { + case tchkBool: return arg->isBool(); + case tchkInt: return arg->isInt(); + case tchkNum: return arg->isNum(); + case tchkString: return arg->isString(); + case tchkName: return arg->isName(); + case tchkArray: return arg->isArray(); + case tchkProps: return arg->isDict() || arg->isName(); + case tchkSCN: return arg->isNum() || arg->isName(); + case tchkNone: return gFalse; + } + return gFalse; +} + +int Gfx::getPos() { + return parser->getPos(); +} + +GfxFont *Gfx::lookupFont(char *name) { + GfxFont *font; + GfxResources *resPtr; + + for (resPtr = res; resPtr; resPtr = resPtr->next) { + if (resPtr->fonts) { + if ((font = resPtr->fonts->lookup(name))) + return font; + } + } + error(getPos(), "unknown font tag '%s'", name); + return NULL; +} + +GBool Gfx::lookupXObject(char *name, Object *obj) { + GfxResources *resPtr; + + for (resPtr = res; resPtr; resPtr = resPtr->next) { + if (resPtr->xObjDict.isDict()) { + if (!resPtr->xObjDict.dictLookup(name, obj)->isNull()) + return gTrue; + obj->free(); + } + } + error(getPos(), "XObject '%s' is unknown", name); + return gFalse; +} + +void Gfx::lookupColorSpace(char *name, Object *obj) { + GfxResources *resPtr; + + for (resPtr = res; resPtr; resPtr = resPtr->next) { + if (resPtr->colorSpaceDict.isDict()) { + if (!resPtr->colorSpaceDict.dictLookup(name, obj)->isNull()) + return; + obj->free(); + } + } + obj->initNull(); +} + +//------------------------------------------------------------------------ +// graphics state operators +//------------------------------------------------------------------------ + +void Gfx::opSave(Object args[], int numArgs) { + out->saveState(state); + state = state->save(); +} + +void Gfx::opRestore(Object args[], int numArgs) { + state = state->restore(); + out->restoreState(state); +} + +void Gfx::opConcat(Object args[], int numArgs) { + state->concatCTM(args[0].getNum(), args[1].getNum(), + args[2].getNum(), args[3].getNum(), + args[4].getNum(), args[5].getNum()); + out->updateCTM(state, args[0].getNum(), args[1].getNum(), + args[2].getNum(), args[3].getNum(), + args[4].getNum(), args[5].getNum()); + fontChanged = gTrue; +} + +void Gfx::opSetDash(Object args[], int numArgs) { + Array *a; + int length; + Object obj; + double *dash; + int i; + + a = args[0].getArray(); + length = a->getLength(); + if (length == 0) { + dash = NULL; + } else { + dash = (double *)gmalloc(length * sizeof(double)); + for (i = 0; i < length; ++i) { + dash[i] = a->get(i, &obj)->getNum(); + obj.free(); + } + } + state->setLineDash(dash, length, args[1].getNum()); + out->updateLineDash(state); +} + +void Gfx::opSetFlat(Object args[], int numArgs) { + state->setFlatness((int)args[0].getNum()); + out->updateFlatness(state); +} + +void Gfx::opSetLineJoin(Object args[], int numArgs) { + state->setLineJoin(args[0].getInt()); + out->updateLineJoin(state); +} + +void Gfx::opSetLineCap(Object args[], int numArgs) { + state->setLineCap(args[0].getInt()); + out->updateLineCap(state); +} + +void Gfx::opSetMiterLimit(Object args[], int numArgs) { + state->setMiterLimit(args[0].getNum()); + out->updateMiterLimit(state); +} + +void Gfx::opSetLineWidth(Object args[], int numArgs) { + state->setLineWidth(args[0].getNum()); + out->updateLineWidth(state); +} + +void Gfx::opSetExtGState(Object args[], int numArgs) { +} + +void Gfx::opSetRenderingIntent(Object args[], int numArgs) { +} + +//------------------------------------------------------------------------ +// color operators +//------------------------------------------------------------------------ + +void Gfx::opSetFillGray(Object args[], int numArgs) { + state->setFillColorSpace(new GfxColorSpace(colorGray)); + state->setFillGray(args[0].getNum()); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeGray(Object args[], int numArgs) { + state->setStrokeColorSpace(new GfxColorSpace(colorGray)); + state->setStrokeGray(args[0].getNum()); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillCMYKColor(Object args[], int numArgs) { + state->setFillColorSpace(new GfxColorSpace(colorCMYK)); + state->setFillCMYK(args[0].getNum(), args[1].getNum(), + args[2].getNum(), args[3].getNum()); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeCMYKColor(Object args[], int numArgs) { + state->setStrokeColorSpace(new GfxColorSpace(colorCMYK)); + state->setStrokeCMYK(args[0].getNum(), args[1].getNum(), + args[2].getNum(), args[3].getNum()); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillRGBColor(Object args[], int numArgs) { + state->setFillColorSpace(new GfxColorSpace(colorRGB)); + state->setFillRGB(args[0].getNum(), args[1].getNum(), args[2].getNum()); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeRGBColor(Object args[], int numArgs) { + state->setStrokeColorSpace(new GfxColorSpace(colorRGB)); + state->setStrokeRGB(args[0].getNum(), args[1].getNum(), args[2].getNum()); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillColorSpace(Object args[], int numArgs) { + Object obj; + GfxColorSpace *colorSpace; + double x[4]; + + lookupColorSpace(args[0].getName(), &obj); + if (obj.isNull()) + colorSpace = new GfxColorSpace(&args[0]); + else + colorSpace = new GfxColorSpace(&obj); + obj.free(); + if (colorSpace->isOk()) { + state->setFillColorSpace(colorSpace); + } else { + delete colorSpace; + error(getPos(), "Bad colorspace"); + } + x[0] = x[1] = x[2] = x[3] = 0; + state->setFillColor(x); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeColorSpace(Object args[], int numArgs) { + Object obj; + GfxColorSpace *colorSpace; + double x[4]; + + lookupColorSpace(args[0].getName(), &obj); + if (obj.isNull()) + colorSpace = new GfxColorSpace(&args[0]); + else + colorSpace = new GfxColorSpace(&obj); + obj.free(); + if (colorSpace->isOk()) { + state->setStrokeColorSpace(colorSpace); + } else { + delete colorSpace; + error(getPos(), "Bad colorspace"); + } + x[0] = x[1] = x[2] = x[3] = 0; + state->setStrokeColor(x); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillColor(Object args[], int numArgs) { + double x[4]; + int i; + + x[0] = x[1] = x[2] = x[3] = 0; + for (i = 0; i < numArgs; ++i) + x[i] = args[i].getNum(); + state->setFillColor(x); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeColor(Object args[], int numArgs) { + double x[4]; + int i; + + x[0] = x[1] = x[2] = x[3] = 0; + for (i = 0; i < numArgs; ++i) + x[i] = args[i].getNum(); + state->setStrokeColor(x); + out->updateStrokeColor(state); +} + +void Gfx::opSetFillColorN(Object args[], int numArgs) { + double x[4]; + int i; + + x[0] = x[1] = x[2] = x[3] = 0; + for (i = 0; i < numArgs && i < 4; ++i) { + if (args[i].isNum()) + x[i] = args[i].getNum(); + else + break; + } + state->setFillColor(x); + out->updateFillColor(state); +} + +void Gfx::opSetStrokeColorN(Object args[], int numArgs) { + double x[4]; + int i; + + x[0] = x[1] = x[2] = x[3] = 0; + for (i = 0; i < numArgs && i < 4; ++i) { + if (args[i].isNum()) + x[i] = args[i].getNum(); + else + break; + } + state->setStrokeColor(x); + out->updateStrokeColor(state); +} + +//------------------------------------------------------------------------ +// path segment operators +//------------------------------------------------------------------------ + +void Gfx::opMoveTo(Object args[], int numArgs) { + state->moveTo(args[0].getNum(), args[1].getNum()); +} + +void Gfx::opLineTo(Object args[], int numArgs) { + if (!state->isCurPt()) { + error(getPos(), "No current point in lineto"); + return; + } + state->lineTo(args[0].getNum(), args[1].getNum()); +} + +void Gfx::opCurveTo(Object args[], int numArgs) { + double x1, y1, x2, y2, x3, y3; + + if (!state->isCurPt()) { + error(getPos(), "No current point in curveto"); + return; + } + x1 = args[0].getNum(); + y1 = args[1].getNum(); + x2 = args[2].getNum(); + y2 = args[3].getNum(); + x3 = args[4].getNum(); + y3 = args[5].getNum(); + state->curveTo(x1, y1, x2, y2, x3, y3); +} + +void Gfx::opCurveTo1(Object args[], int numArgs) { + double x1, y1, x2, y2, x3, y3; + + if (!state->isCurPt()) { + error(getPos(), "No current point in curveto1"); + return; + } + x1 = state->getCurX(); + y1 = state->getCurY(); + x2 = args[0].getNum(); + y2 = args[1].getNum(); + x3 = args[2].getNum(); + y3 = args[3].getNum(); + state->curveTo(x1, y1, x2, y2, x3, y3); +} + +void Gfx::opCurveTo2(Object args[], int numArgs) { + double x1, y1, x2, y2, x3, y3; + + if (!state->isCurPt()) { + error(getPos(), "No current point in curveto2"); + return; + } + x1 = args[0].getNum(); + y1 = args[1].getNum(); + x2 = args[2].getNum(); + y2 = args[3].getNum(); + x3 = x2; + y3 = y2; + state->curveTo(x1, y1, x2, y2, x3, y3); +} + +void Gfx::opRectangle(Object args[], int numArgs) { + double x, y, w, h; + + x = args[0].getNum(); + y = args[1].getNum(); + w = args[2].getNum(); + h = args[3].getNum(); + state->moveTo(x, y); + state->lineTo(x + w, y); + state->lineTo(x + w, y + h); + state->lineTo(x, y + h); + state->closePath(); +} + +void Gfx::opClosePath(Object args[], int numArgs) { + if (!state->isPath()) { + error(getPos(), "No current point in closepath"); + return; + } + state->closePath(); +} + +//------------------------------------------------------------------------ +// path painting operators +//------------------------------------------------------------------------ + +void Gfx::opEndPath(Object args[], int numArgs) { + doEndPath(); +} + +void Gfx::opStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in stroke"); + return; + } + if (state->isPath()) + out->stroke(state); + doEndPath(); +} + +void Gfx::opCloseStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in closepath/stroke"); + return; + } + if (state->isPath()) { + state->closePath(); + out->stroke(state); + } + doEndPath(); +} + +void Gfx::opFill(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in fill"); + return; + } + if (state->isPath()) + out->fill(state); + doEndPath(); +} + +void Gfx::opEOFill(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in eofill"); + return; + } + if (state->isPath()) + out->eoFill(state); + doEndPath(); +} + +void Gfx::opFillStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in fill/stroke"); + return; + } + if (state->isPath()) { + out->fill(state); + out->stroke(state); + } + doEndPath(); +} + +void Gfx::opCloseFillStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in closepath/fill/stroke"); + return; + } + if (state->isPath()) { + state->closePath(); + out->fill(state); + out->stroke(state); + } + doEndPath(); +} + +void Gfx::opEOFillStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in eofill/stroke"); + return; + } + if (state->isPath()) { + out->eoFill(state); + out->stroke(state); + } + doEndPath(); +} + +void Gfx::opCloseEOFillStroke(Object args[], int numArgs) { + if (!state->isCurPt()) { + //error(getPos(), "No path in closepath/eofill/stroke"); + return; + } + if (state->isPath()) { + state->closePath(); + out->eoFill(state); + out->stroke(state); + } + doEndPath(); +} + +void Gfx::opShFill(Object args[], int numArgs) { +} + +void Gfx::doEndPath() { + if (state->isPath()) { + if (clip == clipNormal) + out->clip(state); + else if (clip == clipEO) + out->eoClip(state); + } + clip = clipNone; + state->clearPath(); +} + +//------------------------------------------------------------------------ +// path clipping operators +//------------------------------------------------------------------------ + +void Gfx::opClip(Object args[], int numArgs) { + clip = clipNormal; +} + +void Gfx::opEOClip(Object args[], int numArgs) { + clip = clipEO; +} + +//------------------------------------------------------------------------ +// text object operators +//------------------------------------------------------------------------ + +void Gfx::opBeginText(Object args[], int numArgs) { + state->setTextMat(1, 0, 0, 1, 0, 0); + state->textMoveTo(0, 0); + out->updateTextMat(state); + out->updateTextPos(state); + fontChanged = gTrue; +} + +void Gfx::opEndText(Object args[], int numArgs) { +} + +//------------------------------------------------------------------------ +// text state operators +//------------------------------------------------------------------------ + +void Gfx::opSetCharSpacing(Object args[], int numArgs) { + state->setCharSpace(args[0].getNum()); + out->updateCharSpace(state); +} + +void Gfx::opSetFont(Object args[], int numArgs) { + GfxFont *font; + + if (!(font = lookupFont(args[0].getName()))) + return; + if (printCommands) { + printf(" font: '%s' %g\n", + font->getName() ? font->getName()->getCString() : "???", + args[1].getNum()); + } + state->setFont(font, args[1].getNum()); + fontChanged = gTrue; +} + +void Gfx::opSetTextLeading(Object args[], int numArgs) { + state->setLeading(args[0].getNum()); +} + +void Gfx::opSetTextRender(Object args[], int numArgs) { + state->setRender(args[0].getInt()); + out->updateRender(state); +} + +void Gfx::opSetTextRise(Object args[], int numArgs) { + state->setRise(args[0].getNum()); + out->updateRise(state); +} + +void Gfx::opSetWordSpacing(Object args[], int numArgs) { + state->setWordSpace(args[0].getNum()); + out->updateWordSpace(state); +} + +void Gfx::opSetHorizScaling(Object args[], int numArgs) { + state->setHorizScaling(args[0].getNum()); + out->updateHorizScaling(state); +} + +//------------------------------------------------------------------------ +// text positioning operators +//------------------------------------------------------------------------ + +void Gfx::opTextMove(Object args[], int numArgs) { + double tx, ty; + + tx = state->getLineX() + args[0].getNum(); + ty = state->getLineY() + args[1].getNum(); + state->textMoveTo(tx, ty); + out->updateTextPos(state); +} + +void Gfx::opTextMoveSet(Object args[], int numArgs) { + double tx, ty; + + tx = state->getLineX() + args[0].getNum(); + ty = args[1].getNum(); + state->setLeading(-ty); + ty += state->getLineY(); + state->textMoveTo(tx, ty); + out->updateTextPos(state); +} + +void Gfx::opSetTextMatrix(Object args[], int numArgs) { + state->setTextMat(args[0].getNum(), args[1].getNum(), + args[2].getNum(), args[3].getNum(), + args[4].getNum(), args[5].getNum()); + state->textMoveTo(0, 0); + out->updateTextMat(state); + out->updateTextPos(state); + fontChanged = gTrue; +} + +void Gfx::opTextNextLine(Object args[], int numArgs) { + double tx, ty; + + tx = state->getLineX(); + ty = state->getLineY() - state->getLeading(); + state->textMoveTo(tx, ty); + out->updateTextPos(state); +} + +//------------------------------------------------------------------------ +// text string operators +//------------------------------------------------------------------------ + +void Gfx::opShowText(Object args[], int numArgs) { + if (!state->getFont()) { + error(getPos(), "No font in show"); + return; + } + doShowText(args[0].getString()); +} + +void Gfx::opMoveShowText(Object args[], int numArgs) { + double tx, ty; + + if (!state->getFont()) { + error(getPos(), "No font in move/show"); + return; + } + tx = state->getLineX(); + ty = state->getLineY() - state->getLeading(); + state->textMoveTo(tx, ty); + out->updateTextPos(state); + doShowText(args[0].getString()); +} + +void Gfx::opMoveSetShowText(Object args[], int numArgs) { + double tx, ty; + + if (!state->getFont()) { + error(getPos(), "No font in move/set/show"); + return; + } + state->setWordSpace(args[0].getNum()); + state->setCharSpace(args[1].getNum()); + tx = state->getLineX(); + ty = state->getLineY() - state->getLeading(); + state->textMoveTo(tx, ty); + out->updateWordSpace(state); + out->updateCharSpace(state); + out->updateTextPos(state); + doShowText(args[2].getString()); +} + +void Gfx::opShowSpaceText(Object args[], int numArgs) { + Array *a; + Object obj; + int i; + + if (!state->getFont()) { + error(getPos(), "No font in show/space"); + return; + } + a = args[0].getArray(); + for (i = 0; i < a->getLength(); ++i) { + a->get(i, &obj); + if (obj.isNum()) { + state->textShift(-obj.getNum() * 0.001 * state->getFontSize()); + out->updateTextShift(state, obj.getNum()); + } else if (obj.isString()) { + doShowText(obj.getString()); + } else { + error(getPos(), "Element of show/space array must be number or string"); + } + obj.free(); + } +} + +void Gfx::doShowText(GString *s) { + GfxFont *font; + GfxFontEncoding16 *enc; + Guchar *p; + Guchar c8; + int c16; + GString *s16; + int m, n; + double dx, dy, width, height, w, h; + + if (fontChanged) { + out->updateFont(state); + fontChanged = gFalse; + } + font = state->getFont(); + + //----- 16-bit font + if (font->is16Bit()) { + enc = font->getEncoding16(); + if (out->useDrawChar()) { + out->beginString(state, s); + s16 = NULL; + } else { + s16 = new GString(" "); + } + state->textTransformDelta(0, state->getRise(), &dx, &dy); + p = (Guchar *)s->getCString(); + n = s->getLength(); + while (n > 0) { + m = getNextChar16(enc, p, &c16); + if (enc->wMode == 0) { + width = state->getFontSize() * state->getHorizScaling() * + font->getWidth16(c16) + + state->getCharSpace(); + if (c16 == ' ') { + width += state->getWordSpace(); + } + height = 0; + } else { + width = 0; + height = state->getFontSize() * font->getHeight16(c16); + } + state->textTransformDelta(width, height, &w, &h); + if (out->useDrawChar()) { + out->drawChar16(state, state->getCurX() + dx, state->getCurY() + dy, + w, h, c16); + } else { + s16->setChar(0, (char)(c16 >> 8)); + s16->setChar(1, (char)c16); + out->drawString16(state, s16); + } + state->textShift(width, height); + n -= m; + p += m; + } + if (out->useDrawChar()) + out->endString(state); + else + delete s16; + + //----- 8-bit font + } else { + if (out->useDrawChar()) { + out->beginString(state, s); + state->textTransformDelta(0, state->getRise(), &dx, &dy); + for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) { + c8 = *p; + width = state->getFontSize() * state->getHorizScaling() * + font->getWidth(c8) + + state->getCharSpace(); + if (c8 == ' ') + width += state->getWordSpace(); + state->textTransformDelta(width, 0, &w, &h); + out->drawChar(state, state->getCurX() + dx, state->getCurY() + dy, + w, h, c8); + state->textShift(width); + } + out->endString(state); + } else { + out->drawString(state, s); + width = state->getFontSize() * state->getHorizScaling() * + font->getWidth(s) + + s->getLength() * state->getCharSpace(); + for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) { + if (*p == ' ') + width += state->getWordSpace(); + } + state->textShift(width); + } + } +} + +int Gfx::getNextChar16(GfxFontEncoding16 *enc, Guchar *p, int *c16) { + int n; + int code; + int a, b, m; + + n = enc->codeLen[*p]; + if (n == 1) { + *c16 = enc->map1[*p]; + } else { + code = (p[0] << 8) + p[1]; + a = 0; + b = enc->map2Len; + // invariant: map2[2*a] <= code < map2[2*b] + while (b - a > 1) { + m = (a + b) / 2; + if (enc->map2[2*m] <= code) + a = m; + else if (enc->map2[2*m] > code) + b = m; + else + break; + } + *c16 = enc->map2[2*a+1] + (code - enc->map2[2*a]); + } + return n; +} + +//------------------------------------------------------------------------ +// XObject operators +//------------------------------------------------------------------------ + +void Gfx::opXObject(Object args[], int numArgs) { + Object obj1, obj2; + + if (!lookupXObject(args[0].getName(), &obj1)) + return; + if (!obj1.isStream("XObject")) { + error(getPos(), "XObject '%s' is wrong type", args[0].getName()); + obj1.free(); + return; + } + obj1.streamGetDict()->lookup("Subtype", &obj2); + if (obj2.isName("Image")) + doImage(obj1.getStream(), gFalse); + else if (obj2.isName("Form")) + doForm(&obj1); + else if (obj2.isName()) + error(getPos(), "Unknown XObject subtype '%s'", obj2.getName()); + else + error(getPos(), "XObject subtype is missing or wrong type"); + obj2.free(); + obj1.free(); +} + +void Gfx::doImage(Stream *str, GBool inlineImg) { + Dict *dict; + Object obj1, obj2; + int width, height; + int bits; + GBool mask; + GfxColorSpace *colorSpace; + GfxImageColorMap *colorMap; + GBool invert; + + // get stream dict + dict = str->getDict(); + + // get size + dict->lookup("Width", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("W", &obj1); + } + if (!obj1.isInt()) + goto err2; + width = obj1.getInt(); + obj1.free(); + dict->lookup("Height", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("H", &obj1); + } + if (!obj1.isInt()) + goto err2; + height = obj1.getInt(); + obj1.free(); + + // image or mask? + dict->lookup("ImageMask", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("IM", &obj1); + } + mask = gFalse; + if (obj1.isBool()) + mask = obj1.getBool(); + else if (!obj1.isNull()) + goto err2; + obj1.free(); + + // bit depth + dict->lookup("BitsPerComponent", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("BPC", &obj1); + } + if (!obj1.isInt()) + goto err2; + bits = obj1.getInt(); + obj1.free(); + + // display a mask + if (mask) { + + // check for inverted mask + if (bits != 1) + goto err1; + invert = gFalse; + dict->lookup("Decode", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("D", &obj1); + } + if (obj1.isArray()) { + obj1.arrayGet(0, &obj2); + if (obj2.isInt() && obj2.getInt() == 1) + invert = gTrue; + obj2.free(); + } else if (!obj1.isNull()) { + goto err2; + } + obj1.free(); + + // draw it + out->drawImageMask(state, str, width, height, invert, inlineImg); + + } else { + + // get color space and color map + dict->lookup("ColorSpace", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("CS", &obj1); + } + if (obj1.isName()) { + lookupColorSpace(obj1.getName(), &obj2); + if (!obj2.isNull()) { + obj1.free(); + obj1 = obj2; + } else { + obj2.free(); + } + } + colorSpace = new GfxColorSpace(&obj1); + obj1.free(); + if (!colorSpace->isOk()) { + delete colorSpace; + goto err1; + } + dict->lookup("Decode", &obj1); + if (obj1.isNull()) { + obj1.free(); + dict->lookup("D", &obj1); + } + colorMap = new GfxImageColorMap(bits, &obj1, colorSpace); + obj1.free(); + if (!colorMap->isOk()) { + delete colorSpace; + goto err1; + } + + // draw it + out->drawImage(state, str, width, height, colorMap, inlineImg); + delete colorMap; + } + + return; + + err2: + obj1.free(); + err1: + error(getPos(), "Bad image parameters"); +} + +void Gfx::doForm(Object *str) { + Parser *oldParser; + GfxResources *resPtr; + Dict *dict; + Dict *resDict; + Object matrixObj, bboxObj; + double m[6]; + Object obj1, obj2; + int i; + + // get stream dict + dict = str->streamGetDict(); + + // check form type + dict->lookup("FormType", &obj1); + if (!(obj1.isInt() && obj1.getInt() == 1)) { + error(getPos(), "Unknown form type"); + } + obj1.free(); + + // get matrix and bounding box + dict->lookup("Matrix", &matrixObj); + if (!matrixObj.isArray()) { + matrixObj.free(); + error(getPos(), "Bad form matrix"); + return; + } + dict->lookup("BBox", &bboxObj); + if (!bboxObj.isArray()) { + matrixObj.free(); + bboxObj.free(); + error(getPos(), "Bad form bounding box"); + return; + } + + // push new resources on stack + res = new GfxResources(res); + dict->lookup("Resources", &obj1); + if (obj1.isDict()) { + resDict = obj1.getDict(); + res->fonts = NULL; + resDict->lookup("Font", &obj2); + if (obj2.isDict()) + res->fonts = new GfxFontDict(obj2.getDict()); + obj2.free(); + resDict->lookup("XObject", &res->xObjDict); + resDict->lookup("ColorSpace", &res->colorSpaceDict); + obj1.free(); + } + + // save current graphics state + out->saveState(state); + state = state->save(); + + // save current parser + oldParser = parser; + + // set form transformation matrix + for (i = 0; i < 6; ++i) { + matrixObj.arrayGet(i, &obj1); + m[i] = obj1.getNum(); + obj1.free(); + } + state->concatCTM(m[0], m[1], m[2], m[3], m[4], m[5]); + out->updateCTM(state, m[0], m[1], m[2], m[3], m[4], m[5]); + + // set form bounding box + for (i = 0; i < 4; ++i) { + bboxObj.arrayGet(i, &obj1); + m[i] = obj1.getNum(); + obj1.free(); + } + state->moveTo(m[0], m[1]); + state->lineTo(m[0]+m[2], m[1]); + state->lineTo(m[0]+m[2], m[1]+m[3]); + state->lineTo(m[0], m[1]+m[3]); + state->closePath(); + out->clip(state); + state->clearPath(); + + // draw the form + display(str); + + // free matrix and bounding box + matrixObj.free(); + bboxObj.free(); + + // restore parser + parser = oldParser; + + // restore graphics state + state = state->restore(); + out->restoreState(state); + + // pop resource stack + resPtr = res->next; + delete res; + res = resPtr; + + return; +} + +//------------------------------------------------------------------------ +// in-line image operators +//------------------------------------------------------------------------ + +void Gfx::opBeginImage(Object args[], int numArgs) { + Stream *str; + int c1, c2; + + // build dict/stream + str = buildImageStream(); + + // display the image + if (str) { + doImage(str, gTrue); + + // skip 'EI' tag + c1 = str->getBaseStream()->getChar(); + c2 = str->getBaseStream()->getChar(); + while (!(c1 == 'E' && c2 == 'I') && c2 != EOF) { + c1 = c2; + c2 = str->getBaseStream()->getChar(); + } + delete str; + } +} + +Stream *Gfx::buildImageStream() { + Object dict; + Object obj; + char *key; + Stream *str; + + // build dictionary + dict.initDict(); + parser->getObj(&obj); + while (!obj.isCmd("ID") && !obj.isEOF()) { + if (!obj.isName()) { + error(getPos(), "Inline image dictionary key must be a name object"); + obj.free(); + parser->getObj(&obj); + } else { + key = copyString(obj.getName()); + obj.free(); + parser->getObj(&obj); + if (obj.isEOF() || obj.isError()) + break; + dict.dictAdd(key, &obj); + } + parser->getObj(&obj); + } + if (obj.isEOF()) + error(getPos(), "End of file in inline image"); + obj.free(); + + // make stream + str = new SubStream(parser->getStream(), &dict); + str = str->addFilters(&dict); + + return str; +} + +void Gfx::opImageData(Object args[], int numArgs) { + error(getPos(), "Internal: got 'ID' operator"); +} + +void Gfx::opEndImage(Object args[], int numArgs) { + error(getPos(), "Internal: got 'EI' operator"); +} + +//------------------------------------------------------------------------ +// type 3 font operators +//------------------------------------------------------------------------ + +void Gfx::opSetCharWidth(Object args[], int numArgs) { + error(getPos(), "Encountered 'd0' operator in content stream"); +} + +void Gfx::opSetCacheDevice(Object args[], int numArgs) { + error(getPos(), "Encountered 'd1' operator in content stream"); +} + +//------------------------------------------------------------------------ +// compatibility operators +//------------------------------------------------------------------------ + +void Gfx::opBeginIgnoreUndef(Object args[], int numArgs) { + ++ignoreUndef; +} + +void Gfx::opEndIgnoreUndef(Object args[], int numArgs) { + if (ignoreUndef > 0) + --ignoreUndef; +} + +//------------------------------------------------------------------------ +// marked content operators +//------------------------------------------------------------------------ + +void Gfx::opBeginMarkedContent(Object args[], int numArgs) { + if (printCommands) { + printf(" marked content: %s ", args[0].getName()); + if (numArgs == 2) + args[2].print(stdout); + printf("\n"); + } +} + +void Gfx::opEndMarkedContent(Object args[], int numArgs) { +} + +void Gfx::opMarkPoint(Object args[], int numArgs) { + if (printCommands) { + printf(" mark point: %s ", args[0].getName()); + if (numArgs == 2) + args[2].print(stdout); + printf("\n"); + } +} diff --git a/pdftops/Gfx.h b/pdftops/Gfx.h new file mode 100644 index 0000000000..f725f85d6f --- /dev/null +++ b/pdftops/Gfx.h @@ -0,0 +1,216 @@ +//======================================================================== +// +// Gfx.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef GFX_H +#define GFX_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "gtypes.h" + +class GString; +class Array; +class Stream; +class Parser; +class Dict; +class OutputDev; +class GfxFontDict; +class GfxFont; +struct GfxFontEncoding16; +class GfxState; +class Gfx; + +//------------------------------------------------------------------------ +// Gfx +//------------------------------------------------------------------------ + +enum GfxClipType { + clipNone, + clipNormal, + clipEO +}; + +enum TchkType { + tchkBool, // boolean + tchkInt, // integer + tchkNum, // number (integer or real) + tchkString, // string + tchkName, // name + tchkArray, // array + tchkProps, // properties (dictionary or name) + tchkSCN, // scn/SCN args (number of name) + tchkNone // used to avoid empty initializer lists +}; + +#define maxArgs 8 + +struct Operator { + char name[4]; + int numArgs; + TchkType tchk[maxArgs]; + void (Gfx::*func)(Object args[], int numArgs); +}; + +class GfxResources { +public: + + GfxResources(GfxResources *next1) { fonts = NULL; next = next1; } + ~GfxResources(); + + GfxFontDict *fonts; + Object xObjDict; + Object colorSpaceDict; + GfxResources *next; +}; + +class Gfx { +public: + + // Constructor for regular output. + Gfx(OutputDev *out1, int pageNum, Dict *resDict, + int dpi, double x1, double y1, double x2, double y2, GBool crop, + double cropX1, double cropY1, double cropX2, double cropY2, + int rotate); + + // Destructor. + ~Gfx(); + + // Interpret a stream or array of streams. + void display(Object *obj); + +private: + + OutputDev *out; // output device + GfxResources *res; // resource stack + + GfxState *state; // current graphics state + GBool fontChanged; // set if font or text matrix has changed + GfxClipType clip; // do a clip? + int ignoreUndef; // current BX/EX nesting level + + Parser *parser; // parser for page content stream(s) + + static Operator opTab[]; // table of operators + + void go(); + void execOp(Object *cmd, Object args[], int numArgs); + Operator *findOp(char *name); + GBool checkArg(Object *arg, TchkType type); + int getPos(); + GfxFont *lookupFont(char *name); + GBool lookupXObject(char *name, Object *obj); + void lookupColorSpace(char *name, Object *obj); + + // graphics state operators + void opSave(Object args[], int numArgs); + void opRestore(Object args[], int numArgs); + void opConcat(Object args[], int numArgs); + void opSetDash(Object args[], int numArgs); + void opSetFlat(Object args[], int numArgs); + void opSetLineJoin(Object args[], int numArgs); + void opSetLineCap(Object args[], int numArgs); + void opSetMiterLimit(Object args[], int numArgs); + void opSetLineWidth(Object args[], int numArgs); + void opSetExtGState(Object args[], int numArgs); + void opSetRenderingIntent(Object args[], int numArgs); + + // color operators + void opSetFillGray(Object args[], int numArgs); + void opSetStrokeGray(Object args[], int numArgs); + void opSetFillCMYKColor(Object args[], int numArgs); + void opSetStrokeCMYKColor(Object args[], int numArgs); + void opSetFillRGBColor(Object args[], int numArgs); + void opSetStrokeRGBColor(Object args[], int numArgs); + void opSetFillColorSpace(Object args[], int numArgs); + void opSetStrokeColorSpace(Object args[], int numArgs); + void opSetFillColor(Object args[], int numArgs); + void opSetStrokeColor(Object args[], int numArgs); + void opSetFillColorN(Object args[], int numArgs); + void opSetStrokeColorN(Object args[], int numArgs); + + // path segment operators + void opMoveTo(Object args[], int numArgs); + void opLineTo(Object args[], int numArgs); + void opCurveTo(Object args[], int numArgs); + void opCurveTo1(Object args[], int numArgs); + void opCurveTo2(Object args[], int numArgs); + void opRectangle(Object args[], int numArgs); + void opClosePath(Object args[], int numArgs); + + // path painting operators + void opEndPath(Object args[], int numArgs); + void opStroke(Object args[], int numArgs); + void opCloseStroke(Object args[], int numArgs); + void opFill(Object args[], int numArgs); + void opEOFill(Object args[], int numArgs); + void opFillStroke(Object args[], int numArgs); + void opCloseFillStroke(Object args[], int numArgs); + void opEOFillStroke(Object args[], int numArgs); + void opCloseEOFillStroke(Object args[], int numArgs); + void opShFill(Object args[], int numArgs); + void doEndPath(); + + // path clipping operators + void opClip(Object args[], int numArgs); + void opEOClip(Object args[], int numArgs); + + // text object operators + void opBeginText(Object args[], int numArgs); + void opEndText(Object args[], int numArgs); + + // text state operators + void opSetCharSpacing(Object args[], int numArgs); + void opSetFont(Object args[], int numArgs); + void opSetTextLeading(Object args[], int numArgs); + void opSetTextRender(Object args[], int numArgs); + void opSetTextRise(Object args[], int numArgs); + void opSetWordSpacing(Object args[], int numArgs); + void opSetHorizScaling(Object args[], int numArgs); + + // text positioning operators + void opTextMove(Object args[], int numArgs); + void opTextMoveSet(Object args[], int numArgs); + void opSetTextMatrix(Object args[], int numArgs); + void opTextNextLine(Object args[], int numArgs); + + // text string operators + void opShowText(Object args[], int numArgs); + void opMoveShowText(Object args[], int numArgs); + void opMoveSetShowText(Object args[], int numArgs); + void opShowSpaceText(Object args[], int numArgs); + void doShowText(GString *s); + int getNextChar16(GfxFontEncoding16 *enc, Guchar *p, int *c16); + + // XObject operators + void opXObject(Object args[], int numArgs); + void doImage(Stream *str, GBool inlineImg); + void doForm(Object *str); + + // in-line image operators + void opBeginImage(Object args[], int numArgs); + Stream *buildImageStream(); + void opImageData(Object args[], int numArgs); + void opEndImage(Object args[], int numArgs); + + // type 3 font operators + void opSetCharWidth(Object args[], int numArgs); + void opSetCacheDevice(Object args[], int numArgs); + + // compatibility operators + void opBeginIgnoreUndef(Object args[], int numArgs); + void opEndIgnoreUndef(Object args[], int numArgs); + + // marked content operators + void opBeginMarkedContent(Object args[], int numArgs); + void opEndMarkedContent(Object args[], int numArgs); + void opMarkPoint(Object args[], int numArgs); +}; + +#endif diff --git a/pdftops/GfxFont.cxx b/pdftops/GfxFont.cxx new file mode 100644 index 0000000000..d93a81f99b --- /dev/null +++ b/pdftops/GfxFont.cxx @@ -0,0 +1,887 @@ +//======================================================================== +// +// GfxFont.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include "GString.h" +#include "gmem.h" +#include "gfile.h" +#include "config.h" +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Error.h" +#include "Params.h" +#include "FontFile.h" +#include "GfxFont.h" + +#include "FontInfo.h" +#if JAPANESE_SUPPORT +#include "CMapInfo.h" +#endif + +//------------------------------------------------------------------------ + +static int CDECL cmpWidthExcep(const void *w1, const void *w2); +static int CDECL cmpWidthExcepV(const void *w1, const void *w2); + +//------------------------------------------------------------------------ + +static Gushort *defCharWidths[12] = { + courierWidths, + courierObliqueWidths, + courierBoldWidths, + courierBoldObliqueWidths, + helveticaWidths, + helveticaObliqueWidths, + helveticaBoldWidths, + helveticaBoldObliqueWidths, + timesRomanWidths, + timesItalicWidths, + timesBoldWidths, + timesBoldItalicWidths +}; + +//------------------------------------------------------------------------ +// GfxFont +//------------------------------------------------------------------------ + +GfxFont::GfxFont(char *tag1, Ref id1, Dict *fontDict) { + BuiltinFont *builtinFont; + Object obj1, obj2, obj3, obj4; + int i; + + // get font tag and ID + tag = new GString(tag1); + id = id1; + + // get base font name + name = NULL; + fontDict->lookup("BaseFont", &obj1); + if (obj1.isName()) + name = new GString(obj1.getName()); + obj1.free(); + + // is it a built-in font? + builtinFont = NULL; + if (name) { + for (i = 0; i < numBuiltinFonts; ++i) { + if (!strcmp(builtinFonts[i].name, name->getCString())) { + builtinFont = &builtinFonts[i]; + break; + } + } + } + + // get font type + type = fontUnknownType; + fontDict->lookup("Subtype", &obj1); + if (obj1.isName("Type1")) + type = fontType1; + else if (obj1.isName("Type1C")) + type = fontType1C; + else if (obj1.isName("Type3")) + type = fontType3; + else if (obj1.isName("TrueType")) + type = fontTrueType; + else if (obj1.isName("Type0")) + type = fontType0; + obj1.free(); + is16 = gFalse; + + // assume Times-Roman (or TimesNewRoman), but explicitly check for + // Arial and CourierNew -- certain PDF generators apparently don't + // include FontDescriptors for Arial, TimesNewRoman, and CourierNew + flags = fontSerif; // assume Times-Roman by default + if (type == fontTrueType && !name->cmp("Arial")) + flags = 0; + else if (type == fontTrueType && !name->cmp("CourierNew")) + flags = fontFixedWidth; + + // get info from font descriptor + embFontName = NULL; + embFontID.num = -1; + embFontID.gen = -1; + fontDict->lookup("FontDescriptor", &obj1); + if (obj1.isDict()) { + + // get flags + obj1.dictLookup("Flags", &obj2); + if (obj2.isInt()) + flags = obj2.getInt(); + obj2.free(); + + // get name + obj1.dictLookup("FontName", &obj2); + if (obj2.isName()) + embFontName = new GString(obj2.getName()); + obj2.free(); + + // look for embedded font file + if (type == fontType1) { + obj1.dictLookupNF("FontFile", &obj2); + if (obj2.isRef()) + embFontID = obj2.getRef(); + obj2.free(); + } + if (embFontID.num == -1 && type == fontTrueType) { + obj1.dictLookupNF("FontFile2", &obj2); + if (obj2.isRef()) + embFontID = obj2.getRef(); + obj2.free(); + } + if (embFontID.num == -1) { + obj1.dictLookupNF("FontFile3", &obj2); + if (obj2.isRef()) { + embFontID = obj2.getRef(); + obj2.fetch(&obj3); + if (obj3.isStream()) { + obj3.streamGetDict()->lookup("Subtype", &obj4); + if (obj4.isName("Type1")) + type = fontType1; + else if (obj4.isName("Type1C")) + type = fontType1C; + else if (obj4.isName("Type3")) + type = fontType3; + else if (obj4.isName("TrueType")) + type = fontTrueType; + else if (obj4.isName("Type0")) + type = fontType0; + obj4.free(); + } + obj3.free(); + } + obj2.free(); + } + } + obj1.free(); + + // look for an external font file + extFontFile = NULL; + if (type == fontType1 && name) + findExtFontFile(); + + // get font matrix + fontMat[0] = fontMat[3] = 1; + fontMat[1] = fontMat[2] = fontMat[4] = fontMat[5] = 0; + if (fontDict->lookup("FontMatrix", &obj1)->isArray()) { + for (i = 0; i < 6 && i < obj1.arrayGetLength(); ++i) { + if (obj1.arrayGet(i, &obj2)->isNum()) + fontMat[i] = obj2.getNum(); + obj2.free(); + } + } + obj1.free(); + + // get encoding and character widths + if (type == fontType0) + getType0EncAndWidths(fontDict); + else + getEncAndWidths(fontDict, builtinFont); +} + +GfxFont::~GfxFont() { + delete tag; + if (name) + delete name; + if (!is16 && encoding) + delete encoding; + if (embFontName) + delete embFontName; + if (extFontFile) + delete extFontFile; + if (is16) { + gfree(widths16.exceps); + gfree(widths16.excepsV); + } +} + +double GfxFont::getWidth(GString *s) { + double w; + int i; + + w = 0; + for (i = 0; i < s->getLength(); ++i) + w += widths[s->getChar(i) & 0xff]; + return w; +} + +double GfxFont::getWidth16(int c) { + double w; + int a, b, m; + + w = widths16.defWidth; + a = -1; + b = widths16.numExceps; + // invariant: widths16.exceps[a].last < c < widths16.exceps[b].first + while (b - a > 1) { + m = (a + b) / 2; + if (widths16.exceps[m].last < c) { + a = m; + } else if (c < widths16.exceps[m].first) { + b = m; + } else { + w = widths16.exceps[m].width; + break; + } + } + return w; +} + +double GfxFont::getHeight16(int c) { + double h; + int a, b, m; + + h = widths16.defHeight; + a = -1; + b = widths16.numExcepsV; + // invariant: widths16.excepsV[a].last < c < widths16.excepsV[b].first + while (b - a > 1) { + m = (a + b) / 2; + if (widths16.excepsV[m].last < c) { + a = m; + } else if (c < widths16.excepsV[m].first) { + b = m; + } else { + h = widths16.excepsV[m].height; + break; + } + } + return h; +} + +double GfxFont::getOriginX16(int c) { + double vx; + int a, b, m; + + vx = widths16.defWidth / 2; + a = -1; + b = widths16.numExcepsV; + // invariant: widths16.excepsV[a].last < c < widths16.excepsV[b].first + while (b - a > 1) { + m = (a + b) / 2; + if (widths16.excepsV[m].last < c) { + a = m; + } else if (c < widths16.excepsV[m].first) { + b = m; + } else { + vx = widths16.excepsV[m].vx; + break; + } + } + return vx; +} + +double GfxFont::getOriginY16(int c) { + double vy; + int a, b, m; + + vy = widths16.defVY; + a = -1; + b = widths16.numExcepsV; + // invariant: widths16.excepsV[a].last < c < widths16.excepsV[b].first + while (b - a > 1) { + m = (a + b) / 2; + if (widths16.excepsV[m].last < c) { + a = m; + } else if (c < widths16.excepsV[m].first) { + b = m; + } else { + vy = widths16.excepsV[m].vy; + break; + } + } + return vy; +} + +void GfxFont::getEncAndWidths(Dict *fontDict, BuiltinFont *builtinFont) { + Object obj1, obj2, obj3; + char *buf; + int len; + FontFile *fontFile; + int code, i; + + // Encodings start with a base encoding, which can come from + // (in order of priority): + // 1. FontDict.Encoding or FontDict.Encoding.BaseEncoding + // - MacRoman / WinAnsi / Standard + // 2. embedded font file + // 3. default: + // - builtin --> builtin encoding + // - TrueType --> MacRomanEncoding + // - others --> StandardEncoding + // and then add a list of differences from + // FontDict.Encoding.Differences. + + // check FontDict for base encoding + encoding = NULL; + fontDict->lookup("Encoding", &obj1); + if (obj1.isDict()) { + obj1.dictLookup("BaseEncoding", &obj2); + if (obj2.isName("MacRomanEncoding")) { + encoding = macRomanEncoding.copy(); + } else if (obj2.isName("WinAnsiEncoding")) { + encoding = winAnsiEncoding.copy(); + } else if (obj2.isName("StandardEncoding")) { + encoding = standardEncoding.copy(); + } + obj2.free(); + } else if (obj1.isName("MacRomanEncoding")) { + encoding = macRomanEncoding.copy(); + } else if (obj1.isName("WinAnsiEncoding")) { + encoding = winAnsiEncoding.copy(); + } else if (obj1.isName("StandardEncoding")) { + encoding = standardEncoding.copy(); + } + obj1.free(); + + // check embedded or external font file for base encoding + if ((type == fontType1 || type == fontType1C) && + (extFontFile || embFontID.num >= 0)) { + if (extFontFile) + buf = readExtFontFile(&len); + else + buf = readEmbFontFile(&len); + if (buf) { + if (type == fontType1) + fontFile = new Type1FontFile(buf, len); + else + fontFile = new Type1CFontFile(buf, len); + if (fontFile->getName()) { + if (embFontName) + delete embFontName; + embFontName = new GString(fontFile->getName()); + } + if (!encoding) + encoding = fontFile->getEncoding(gTrue); + delete fontFile; + gfree(buf); + } + } + + // get default base encoding + if (!encoding) { + if (builtinFont) + encoding = builtinFont->encoding->copy(); + else if (type == fontTrueType) + encoding = macRomanEncoding.copy(); + else + encoding = standardEncoding.copy(); + } + + // merge differences into encoding + fontDict->lookup("Encoding", &obj1); + if (obj1.isDict()) { + obj1.dictLookup("Differences", &obj2); + if (obj2.isArray()) { + code = 0; + for (i = 0; i < obj2.arrayGetLength(); ++i) { + obj2.arrayGet(i, &obj3); + if (obj3.isInt()) { + code = obj3.getInt(); + } else if (obj3.isName()) { + if (code < 256) + encoding->addChar(code, copyString(obj3.getName())); + ++code; + } else { + error(-1, "Wrong type in font encoding resource differences (%s)", + obj3.getTypeName()); + } + obj3.free(); + } + } + obj2.free(); + } + obj1.free(); + + // get character widths + if (builtinFont) + makeWidths(fontDict, builtinFont->encoding, builtinFont->widths); + else + makeWidths(fontDict, NULL, NULL); +} + +void GfxFont::findExtFontFile() { + char **path; + FILE *f; + + for (path = fontPath; *path; ++path) { + extFontFile = appendToPath(new GString(*path), name->getCString()); + f = fopen(extFontFile->getCString(), "rb"); + if (!f) { + extFontFile->append(".pfb"); + f = fopen(extFontFile->getCString(), "rb"); + } + if (!f) { + extFontFile->del(extFontFile->getLength() - 4, 4); + extFontFile->append(".pfa"); + f = fopen(extFontFile->getCString(), "rb"); + } + if (f) { + fclose(f); + break; + } + delete extFontFile; + extFontFile = NULL; + } +} + +char *GfxFont::readExtFontFile(int *len) { + FILE *f; + char *buf; + + if (!(f = fopen(extFontFile->getCString(), "rb"))) { + error(-1, "Internal: external font file '%s' vanished", extFontFile); + return NULL; + } + fseek(f, 0, SEEK_END); + *len = (int)ftell(f); + fseek(f, 0, SEEK_SET); + buf = (char *)gmalloc(*len); + if ((int)fread(buf, 1, *len, f) != *len) + error(-1, "Error reading external font file '%s'", extFontFile); + fclose(f); + return buf; +} + +char *GfxFont::readEmbFontFile(int *len) { + char *buf; + Object obj1, obj2; + Stream *str; + int c; + int size, i; + + obj1.initRef(embFontID.num, embFontID.gen); + obj1.fetch(&obj2); + if (!obj2.isStream()) { + error(-1, "Embedded font file is not a stream"); + obj2.free(); + obj1.free(); + return NULL; + } + str = obj2.getStream(); + + buf = NULL; + i = size = 0; + str->reset(); + while ((c = str->getChar()) != EOF) { + if (i == size) { + size += 4096; + buf = (char *)grealloc(buf, size); + } + buf[i++] = c; + } + *len = i; + + obj2.free(); + obj1.free(); + + return buf; +} + +void GfxFont::makeWidths(Dict *fontDict, FontEncoding *builtinEncoding, + Gushort *builtinWidths) { + Object obj1, obj2; + int firstChar, lastChar; + int code, code2; + char *charName; + Gushort *defWidths; + int index; + double mult; + + // initialize all widths to zero + for (code = 0; code < 256; ++code) + widths[code] = 0; + + // use widths from built-in font + if (builtinEncoding) { + code2 = 0; // to make gcc happy + for (code = 0; code < 256; ++code) { + if ((charName = encoding->getCharName(code)) && + (code2 = builtinEncoding->getCharCode(charName)) >= 0) + widths[code] = builtinWidths[code2] * 0.001; + } + + // get widths from font dict + } else { + fontDict->lookup("FirstChar", &obj1); + firstChar = obj1.isInt() ? obj1.getInt() : 0; + obj1.free(); + fontDict->lookup("LastChar", &obj1); + lastChar = obj1.isInt() ? obj1.getInt() : 255; + obj1.free(); + if (type == fontType3) + mult = fontMat[0]; + else + mult = 0.001; + fontDict->lookup("Widths", &obj1); + if (obj1.isArray()) { + for (code = firstChar; code <= lastChar; ++code) { + obj1.arrayGet(code - firstChar, &obj2); + if (obj2.isNum()) + widths[code] = obj2.getNum() * mult; + obj2.free(); + } + } else { + + // couldn't find widths -- use defaults +#if 0 //~ + //~ certain PDF generators apparently don't include widths + //~ for Arial and TimesNewRoman -- and this error message + //~ is a nuisance + error(-1, "No character widths resource for non-builtin font"); +#endif + if (isFixedWidth()) + index = 0; + else if (isSerif()) + index = 8; + else + index = 4; + if (isBold()) + index += 2; + if (isItalic()) + index += 1; + defWidths = defCharWidths[index]; + code2 = 0; // to make gcc happy + for (code = 0; code < 256; ++code) { + if ((charName = encoding->getCharName(code)) && + (code2 = standardEncoding.getCharCode(charName)) >= 0) + widths[code] = defWidths[code2] * 0.001; + } + } + obj1.free(); + } +} + +void GfxFont::getType0EncAndWidths(Dict *fontDict) { + Object obj1, obj2, obj3, obj4, obj5, obj6, obj7, obj8; + int excepsSize; + int i, j, k, n; + + widths16.exceps = NULL; + widths16.excepsV = NULL; + + // get the CIDFont + fontDict->lookup("DescendantFonts", &obj1); + if (!obj1.isArray() || obj1.arrayGetLength() != 1) { + error(-1, "Bad DescendantFonts entry for Type 0 font"); + goto err1; + } + obj1.arrayGet(0, &obj2); + if (!obj2.isDict("Font")) { + error(-1, "Bad descendant font of Type 0 font"); + goto err2; + } + + // get font info + obj2.dictLookup("CIDSystemInfo", &obj3); + if (!obj3.isDict()) { + error(-1, "Bad CIDSystemInfo in Type 0 font descendant"); + goto err3; + } + obj3.dictLookup("Registry", &obj4); + obj3.dictLookup("Ordering", &obj5); + if (obj4.isString() && obj5.isString()) { + if (obj4.getString()->cmp("Adobe") == 0 && + obj5.getString()->cmp("Japan1") == 0) { +#if JAPANESE_SUPPORT + is16 = gTrue; + enc16.charSet = font16AdobeJapan12; +#else + error(-1, "Xpdf was compiled without Japanese font support"); + goto err4; +#endif + } else { + error(-1, "Uknown Type 0 character set: %s-%s", + obj4.getString()->getCString(), obj5.getString()->getCString()); + goto err4; + } + } else { + error(-1, "Unknown Type 0 character set"); + goto err4; + } + obj5.free(); + obj4.free(); + obj3.free(); + + // get default char width + obj2.dictLookup("DW", &obj3); + if (obj3.isInt()) + widths16.defWidth = obj3.getInt() * 0.001; + else + widths16.defWidth = 1.0; + obj3.free(); + + // get default char metrics for vertical font + obj2.dictLookup("DW2", &obj3); + widths16.defVY = 0.880; + widths16.defHeight = -1; + if (obj3.isArray() && obj3.arrayGetLength() == 2) { + obj3.arrayGet(0, &obj4); + if (obj4.isInt()) { + widths16.defVY = obj4.getInt() * 0.001; + } + obj4.free(); + obj3.arrayGet(1, &obj4); + if (obj4.isInt()) { + widths16.defHeight = obj4.getInt() * 0.001; + } + obj4.free(); + } + obj3.free(); + + // get char width exceptions + widths16.exceps = NULL; + widths16.numExceps = 0; + obj2.dictLookup("W", &obj3); + if (obj3.isArray()) { + excepsSize = 0; + k = 0; + i = 0; + while (i+1 < obj3.arrayGetLength()) { + obj3.arrayGet(i, &obj4); + obj3.arrayGet(i+1, &obj5); + if (obj4.isInt() && obj5.isInt()) { + obj3.arrayGet(i+2, &obj6); + if (!obj6.isNum()) { + error(-1, "Bad widths array in Type 0 font"); + obj6.free(); + obj5.free(); + obj4.free(); + break; + } + if (k == excepsSize) { + excepsSize += 16; + widths16.exceps = (GfxFontWidthExcep *) + grealloc(widths16.exceps, + excepsSize * sizeof(GfxFontWidthExcep)); + } + widths16.exceps[k].first = obj4.getInt(); + widths16.exceps[k].last = obj5.getInt(); + widths16.exceps[k].width = obj6.getNum() * 0.001; + obj6.free(); + ++k; + i += 3; + } else if (obj4.isInt() && obj5.isArray()) { + if (k + obj5.arrayGetLength() >= excepsSize) { + excepsSize = (k + obj5.arrayGetLength() + 15) & ~15; + widths16.exceps = (GfxFontWidthExcep *) + grealloc(widths16.exceps, + excepsSize * sizeof(GfxFontWidthExcep)); + } + n = obj4.getInt(); + for (j = 0; j < obj5.arrayGetLength(); ++j) { + obj5.arrayGet(j, &obj6); + if (!obj6.isNum()) { + error(-1, "Bad widths array in Type 0 font"); + obj6.free(); + break; + } + widths16.exceps[k].first = widths16.exceps[k].last = n++; + widths16.exceps[k].width = obj6.getNum() * 0.001; + obj6.free(); + ++k; + } + i += 2; + } else { + error(-1, "Bad widths array in Type 0 font"); + obj6.free(); + obj5.free(); + obj4.free(); + break; + } + obj5.free(); + obj4.free(); + } + widths16.numExceps = k; + if (k > 0) + qsort(widths16.exceps, k, sizeof(GfxFontWidthExcep), &cmpWidthExcep); + } + obj3.free(); + + // get char metric exceptions for vertical font + widths16.excepsV = NULL; + widths16.numExcepsV = 0; + obj2.dictLookup("W2", &obj3); + if (obj3.isArray()) { + excepsSize = 0; + k = 0; + i = 0; + while (i+1 < obj3.arrayGetLength()) { + obj3.arrayGet(i, &obj4); + obj3.arrayGet(i+1, &obj5); + if (obj4.isInt() && obj5.isInt()) { + obj3.arrayGet(i+2, &obj6); + obj3.arrayGet(i+3, &obj7); + obj3.arrayGet(i+4, &obj8); + if (!obj6.isNum() || !obj7.isNum() || !obj8.isNum()) { + error(-1, "Bad widths (W2) array in Type 0 font"); + obj8.free(); + obj7.free(); + obj6.free(); + obj5.free(); + obj4.free(); + break; + } + if (k == excepsSize) { + excepsSize += 16; + widths16.excepsV = (GfxFontWidthExcepV *) + grealloc(widths16.excepsV, + excepsSize * sizeof(GfxFontWidthExcepV)); + } + widths16.excepsV[k].first = obj4.getInt(); + widths16.excepsV[k].last = obj5.getInt(); + widths16.excepsV[k].height = obj6.getNum() * 0.001; + widths16.excepsV[k].vx = obj7.getNum() * 0.001; + widths16.excepsV[k].vy = obj8.getNum() * 0.001; + obj8.free(); + obj7.free(); + obj6.free(); + ++k; + i += 5; + } else if (obj4.isInt() && obj5.isArray()) { + if (k + obj5.arrayGetLength() / 3 >= excepsSize) { + excepsSize = (k + obj5.arrayGetLength() / 3 + 15) & ~15; + widths16.excepsV = (GfxFontWidthExcepV *) + grealloc(widths16.excepsV, + excepsSize * sizeof(GfxFontWidthExcepV)); + } + n = obj4.getInt(); + for (j = 0; j < obj5.arrayGetLength(); j += 3) { + obj5.arrayGet(j, &obj6); + obj5.arrayGet(j+1, &obj7); + obj5.arrayGet(j+1, &obj8); + if (!obj6.isNum() || !obj7.isNum() || !obj8.isNum()) { + error(-1, "Bad widths (W2) array in Type 0 font"); + obj6.free(); + break; + } + widths16.excepsV[k].first = widths16.exceps[k].last = n++; + widths16.excepsV[k].height = obj6.getNum() * 0.001; + widths16.excepsV[k].vx = obj7.getNum() * 0.001; + widths16.excepsV[k].vy = obj8.getNum() * 0.001; + obj8.free(); + obj7.free(); + obj6.free(); + ++k; + } + i += 2; + } else { + error(-1, "Bad widths array in Type 0 font"); + obj5.free(); + obj4.free(); + break; + } + obj5.free(); + obj4.free(); + } + widths16.numExcepsV = k; + if (k > 0) { + qsort(widths16.excepsV, k, sizeof(GfxFontWidthExcepV), &cmpWidthExcepV); + } + } + obj3.free(); + + obj2.free(); + obj1.free(); + + // get encoding (CMap) + fontDict->lookup("Encoding", &obj1); + if (!obj1.isName()) { + error(-1, "Bad encoding for Type 0 font"); + goto err1; + } +#if JAPANESE_SUPPORT + if (enc16.charSet == font16AdobeJapan12) { + for (i = 0; gfxFontEnc16Tab[i].name; ++i) { + if (!strcmp(obj1.getName(), gfxFontEnc16Tab[i].name)) + break; + } + if (!gfxFontEnc16Tab[i].name) { + error(-1, "Unknown encoding '%s' for Adobe-Japan1-2 font", + obj1.getName()); + goto err1; + } + enc16.enc = gfxFontEnc16Tab[i].enc; + } +#endif + obj1.free(); + + return; + + err4: + obj5.free(); + obj4.free(); + err3: + obj3.free(); + err2: + obj2.free(); + err1: + obj1.free(); + //~ fix this --> add 16-bit font support to FontFile + encoding = new FontEncoding(); + makeWidths(fontDict, NULL, NULL); +} + +static int CDECL cmpWidthExcep(const void *w1, const void *w2) { + return ((GfxFontWidthExcep *)w1)->first - ((GfxFontWidthExcep *)w2)->first; +} + +static int CDECL cmpWidthExcepV(const void *w1, const void *w2) { + return ((GfxFontWidthExcepV *)w1)->first - ((GfxFontWidthExcepV *)w2)->first; +} + +//------------------------------------------------------------------------ +// GfxFontDict +//------------------------------------------------------------------------ + +GfxFontDict::GfxFontDict(Dict *fontDict) { + int i; + Object obj1, obj2; + + numFonts = fontDict->getLength(); + fonts = (GfxFont **)gmalloc(numFonts * sizeof(GfxFont *)); + for (i = 0; i < numFonts; ++i) { + fontDict->getValNF(i, &obj1); + obj1.fetch(&obj2); + if (obj1.isRef() && obj2.isDict("Font")) { + fonts[i] = new GfxFont(fontDict->getKey(i), obj1.getRef(), + obj2.getDict()); + } else { + error(-1, "font resource is not a dictionary"); + fonts[i] = NULL; + } + obj1.free(); + obj2.free(); + } +} + +GfxFontDict::~GfxFontDict() { + int i; + + for (i = 0; i < numFonts; ++i) + delete fonts[i]; + gfree(fonts); +} + +GfxFont *GfxFontDict::lookup(char *tag) { + int i; + + for (i = 0; i < numFonts; ++i) { + if (fonts[i]->matches(tag)) + return fonts[i]; + } + return NULL; +} diff --git a/pdftops/GfxFont.h b/pdftops/GfxFont.h new file mode 100644 index 0000000000..30bcf1a572 --- /dev/null +++ b/pdftops/GfxFont.h @@ -0,0 +1,234 @@ +//======================================================================== +// +// GfxFont.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef GFXFONT_H +#define GFXFONT_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "gtypes.h" +#include "GString.h" +#include "Object.h" +#include "FontEncoding.h" + +class Dict; +struct BuiltinFont; + +//------------------------------------------------------------------------ +// GfxFontCharSet16 +//------------------------------------------------------------------------ + +enum GfxFontCharSet16 { + font16AdobeJapan12 // Adobe-Japan1-2 +}; + +//------------------------------------------------------------------------ +// GfxFontEncoding16 +//------------------------------------------------------------------------ + +struct GfxFontEncoding16 { + int wMode; // writing mode (0=horizontal, 1=vertical) + Guchar codeLen[256]; // length of codes, in bytes, indexed by + // first byte of code + Gushort map1[256]; // one-byte code mapping: + // map1[code] --> 16-bit char selector + Gushort *map2; // two-byte code mapping + // map2[2*i] --> first code in range + // map2[2*i+1] --> 16-bit char selector + // for map2[2*i] + int map2Len; // length of map2 array (divided by 2) +}; + +//------------------------------------------------------------------------ +// GfxFontWidths16 +//------------------------------------------------------------------------ + +struct GfxFontWidthExcep { + int first; // this record applies to + int last; // chars .. + double width; // char width +}; + +struct GfxFontWidthExcepV { + int first; // this record applies to + int last; // chars .. + double height; // char height + double vx, vy; // origin position +}; + +struct GfxFontWidths16 { + double defWidth; // default char width + double defHeight; // default char height + double defVY; // default origin position + GfxFontWidthExcep *exceps; // exceptions + int numExceps; // number of valid entries in exceps + GfxFontWidthExcepV *excepsV; // exceptions for vertical font + int numExcepsV; // number of valid entries in excepsV +}; + +//------------------------------------------------------------------------ +// GfxFont +//------------------------------------------------------------------------ + +#define fontFixedWidth (1 << 0) +#define fontSerif (1 << 1) +#define fontSymbolic (1 << 2) +#define fontItalic (1 << 6) +#define fontBold (1 << 18) + +enum GfxFontType { + fontUnknownType, + fontType1, + fontType1C, + fontType3, + fontTrueType, + fontType0 +}; + +class GfxFont { +public: + + // Constructor. + GfxFont(char *tag1, Ref id1, Dict *fontDict); + + // Destructor. + ~GfxFont(); + + // Get font tag. + GString *getTag() { return tag; } + + // Get font dictionary ID. + Ref getID() { return id; } + + // Does this font match the tag? + GBool matches(char *tag1) { return !tag->cmp(tag1); } + + // Get base font name. + GString *getName() { return name; } + + // Get font type. + GfxFontType getType() { return type; } + + // Does this font use 16-bit characters? + GBool is16Bit() { return is16; } + + // Get embedded font ID, i.e., a ref for the font file stream. + // Returns false if there is no embedded font. + GBool getEmbeddedFontID(Ref *embID) + { *embID = embFontID; return embFontID.num >= 0; } + + // Get the PostScript font name for the embedded font. Returns + // NULL if there is no embedded font. + char *getEmbeddedFontName() + { return embFontName ? embFontName->getCString() : (char *)NULL; } + + // Get the name of the external font file. Returns NULL if there + // is no external font file. + char *getExtFontFile() + { return extFontFile ? extFontFile->getCString() : (char *)NULL; } + + // Get font descriptor flags. + GBool isFixedWidth() { return flags & fontFixedWidth; } + GBool isSerif() { return flags & fontSerif; } + GBool isSymbolic() { return flags & fontSymbolic; } + GBool isItalic() { return flags & fontItalic; } + GBool isBold() { return flags & fontBold; } + + // Get width of a character or string. + double getWidth(Guchar c) { return widths[c]; } + double getWidth(GString *s); + + // Get character metrics for 16-bit font. + double getWidth16(int c); + double getHeight16(int c); + double getOriginX16(int c); + double getOriginY16(int c); + + // Return the encoding. + FontEncoding *getEncoding() { return encoding; } + + // Return the character name associated with . + char *getCharName(int code) { return encoding->getCharName(code); } + + // Return the code associated with . + int getCharCode(char *charName) { return encoding->getCharCode(charName); } + + // Return the 16-bit character set and encoding. + GfxFontCharSet16 getCharSet16() { return enc16.charSet; } + GfxFontEncoding16 *getEncoding16() { return enc16.enc; } + + // Get the writing mode (0=horizontal, 1=vertical). + int getWMode16() { return enc16.enc->wMode; } + + // Return the font matrix. + double *getFontMatrix() { return fontMat; } + + // Read an external or embedded font file into a buffer. + char *readExtFontFile(int *len); + char *readEmbFontFile(int *len); + +private: + + void getEncAndWidths(Dict *fontDict, BuiltinFont *builtinFont); + void findExtFontFile(); + void makeWidths(Dict *fontDict, FontEncoding *builtinEncoding, + Gushort *builtinWidths); + void getType0EncAndWidths(Dict *fontDict); + + GString *tag; // PDF font tag + Ref id; // reference (used as unique ID) + GString *name; // font name + int flags; // font descriptor flags + GfxFontType type; // type of font + GBool is16; // set if font uses 16-bit chars + GString *embFontName; // name of embedded font + Ref embFontID; // ref to embedded font file stream + GString *extFontFile; // external font file name + double fontMat[6]; // font matrix + union { + FontEncoding *encoding; // 8-bit font encoding + struct { + GfxFontCharSet16 charSet; // 16-bit character set + GfxFontEncoding16 *enc; // 16-bit encoding (CMap) + } enc16; + }; + union { + double widths[256]; // width of each char for 8-bit font + GfxFontWidths16 widths16; // char widths for 16-bit font + }; +}; + +//------------------------------------------------------------------------ +// GfxFontDict +//------------------------------------------------------------------------ + +class GfxFontDict { +public: + + // Build the font dictionary, given the PDF font dictionary. + GfxFontDict(Dict *fontDict); + + // Destructor. + ~GfxFontDict(); + + // Get the specified font. + GfxFont *lookup(char *tag); + + // Iterative access. + int getNumFonts() { return numFonts; } + GfxFont *getFont(int i) { return fonts[i]; } + +private: + + GfxFont **fonts; // list of fonts + int numFonts; // number of fonts +}; + +#endif diff --git a/pdftops/GfxState.cxx b/pdftops/GfxState.cxx new file mode 100644 index 0000000000..03b1cbea88 --- /dev/null +++ b/pdftops/GfxState.cxx @@ -0,0 +1,971 @@ +//======================================================================== +// +// GfxState.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include // for memcpy() +#include "gmem.h" +#include "Error.h" +#include "Object.h" +#include "GfxState.h" + +//------------------------------------------------------------------------ +// GfxColor +//------------------------------------------------------------------------ + +void GfxColor::setCMYK(double c, double m, double y, double k) { + if ((r = 1 - (c + k)) < 0) + r = 0; + if ((g = 1 - (m + k)) < 0) + g = 0; + if ((b = 1 - (y + k)) < 0) + b = 0; +} + +//------------------------------------------------------------------------ +// GfxColorSpace +//------------------------------------------------------------------------ + +GfxColorSpace::GfxColorSpace(Object *colorSpace) { + Object csObj; + Object obj, obj2; + char *s; + int x; + int i, j; + + ok = gTrue; + lookup = NULL; + + // check for Separation, DeviceN, and Pattern colorspaces + colorSpace->copy(&csObj); + sepFunc = NULL; + if (colorSpace->isArray()) { + colorSpace->arrayGet(0, &obj); + if (obj.isName("Separation") || obj.isName("DeviceN")) { + csObj.free(); + colorSpace->arrayGet(2, &csObj); + sepFunc = new Function(colorSpace->arrayGet(3, &obj2)); + obj2.free(); + if (!sepFunc->isOk()) { + delete sepFunc; + sepFunc = NULL; + } + } else if (obj.isName("Pattern")) { + csObj.free(); + colorSpace->arrayGet(1, &csObj); + } + obj.free(); + } + + // get mode + indexed = gFalse; + if (csObj.isName()) { + setMode(&csObj); + } else if (csObj.isArray()) { + csObj.arrayGet(0, &obj); + if (obj.isName("Indexed") || obj.isName("I")) { + indexed = gTrue; + setMode(csObj.arrayGet(1, &obj2)); + obj2.free(); + } else { + setMode(&csObj); + } + obj.free(); + } else { + goto err1; + } + if (!ok) { + goto err1; + } + + // get lookup table for indexed colorspace + if (indexed) { + csObj.arrayGet(2, &obj); + if (!obj.isInt()) + goto err2; + indexHigh = obj.getInt(); + obj.free(); + lookup = (Guchar (*)[4])gmalloc((indexHigh + 1) * 4 * sizeof(Guchar)); + csObj.arrayGet(3, &obj); + if (obj.isStream()) { + obj.streamReset(); + for (i = 0; i <= indexHigh; ++i) { + for (j = 0; j < numComps; ++j) { + if ((x = obj.streamGetChar()) == EOF) + goto err2; + lookup[i][j] = (Guchar)x; + } + } + } else if (obj.isString()) { + s = obj.getString()->getCString(); + for (i = 0; i <= indexHigh; ++i) + for (j = 0; j < numComps; ++j) + lookup[i][j] = (Guchar)*s++; + } else { + goto err2; + } + obj.free(); + } + + csObj.free(); + return; + + err2: + obj.free(); + err1: + csObj.free(); + ok = gFalse; +} + +GfxColorSpace::GfxColorSpace(GfxColorMode mode1) { + sepFunc = NULL; + mode = mode1; + indexed = gFalse; + switch (mode) { + case colorGray: numComps = 1; break; + case colorCMYK: numComps = 4; break; + case colorRGB: numComps = 3; break; + } + lookup = NULL; + ok = gTrue; +} + +GfxColorSpace::~GfxColorSpace() { + if (sepFunc) + delete sepFunc; + gfree(lookup); +} + +GfxColorSpace::GfxColorSpace(GfxColorSpace *colorSpace) { + int size; + + if (colorSpace->sepFunc) + sepFunc = colorSpace->sepFunc->copy(); + else + sepFunc = NULL; + mode = colorSpace->mode; + indexed = colorSpace->indexed; + numComps = colorSpace->numComps; + indexHigh = colorSpace->indexHigh; + if (indexed) { + size = (indexHigh + 1) * 4 * sizeof(Guchar); + lookup = (Guchar (*)[4])gmalloc(size); + memcpy(lookup, colorSpace->lookup, size); + } else { + lookup = NULL; + } + ok = gTrue; +} + +void GfxColorSpace::setMode(Object *colorSpace) { + Object obj; + + if (colorSpace->isName("DeviceGray") || colorSpace->isName("G")) { + mode = colorGray; + numComps = 1; + } else if (colorSpace->isName("DeviceRGB") || colorSpace->isName("RGB")) { + mode = colorRGB; + numComps = 3; + } else if (colorSpace->isName("DeviceCMYK") || colorSpace->isName("CMYK")) { + mode = colorCMYK; + numComps = 4; + } else if (colorSpace->isArray()) { + colorSpace->arrayGet(0, &obj); + if (obj.isName("CalGray")) { + mode = colorGray; + numComps = 1; + } else if (obj.isName("CalRGB")) { + mode = colorRGB; + numComps = 3; + } else if (obj.isName("CalCMYK")) { + mode = colorCMYK; + numComps = 4; + } else { + ok = gFalse; + } + obj.free(); + } else { + ok = gFalse; + } +} + +void GfxColorSpace::getColor(double x[4], GfxColor *color) { + double y[4]; + Guchar *p; + + if (sepFunc) { + sepFunc->transform(x, y); + } else { + y[0] = x[0]; + y[1] = x[1]; + y[2] = x[2]; + y[3] = x[3]; + } + if (indexed) { + p = lookup[(int)(y[0] + 0.5)]; + switch (mode) { + case colorGray: + color->setGray(p[0] / 255.0); + break; + case colorCMYK: + color->setCMYK(p[0] / 255.0, p[1] / 255.0, p[2] / 255.0, p[3] / 255.0); + break; + case colorRGB: + color->setRGB(p[0] / 255.0, p[1] / 255.0, p[2] / 255.0); + break; + } + } else { + switch (mode) { + case colorGray: + color->setGray(y[0]); + break; + case colorCMYK: + color->setCMYK(y[0], y[1], y[2], y[3]); + break; + case colorRGB: + color->setRGB(y[0], y[1], y[2]); + break; + } + } +} + +//------------------------------------------------------------------------ +// Function +//------------------------------------------------------------------------ + +Function::Function(Object *funcObj) { + Stream *str; + Dict *dict; + int nSamples, sampleBits; + double sampleMul; + Object obj1, obj2; + Guint buf, bitMask; + int bits; + int s; + int i; + + ok = gFalse; + samples = NULL; + + if (!funcObj->isStream()) { + error(-1, "Expected function dictionary"); + goto err3; + } + str = funcObj->getStream(); + dict = str->getDict(); + + //----- FunctionType + if (!dict->lookup("FunctionType", &obj1)->isInt() || + obj1.getInt() != 0) { + error(-1, "Unknown function type"); + goto err2; + } + obj1.free(); + + //----- Domain + if (!dict->lookup("Domain", &obj1)->isArray()) { + error(-1, "Function is missing domain"); + goto err2; + } + m = obj1.arrayGetLength() / 2; + if (m > 4) { + error(-1, "Functions with more than 1 input are unsupported"); + goto err2; + } + for (i = 0; i < m; ++i) { + obj1.arrayGet(2*i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function domain array"); + goto err1; + } + domain[i][0] = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2*i+1, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function domain array"); + goto err1; + } + domain[i][1] = obj2.getNum(); + obj2.free(); + } + obj1.free(); + + //----- Range + if (!dict->lookup("Range", &obj1)->isArray()) { + error(-1, "Function is missing range"); + goto err2; + } + n = obj1.arrayGetLength() / 2; + if (n > 4) { + error(-1, "Functions with more than 4 outputs are unsupported"); + goto err2; + } + for (i = 0; i < n; ++i) { + obj1.arrayGet(2*i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function range array"); + goto err1; + } + range[i][0] = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2*i+1, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function range array"); + goto err1; + } + range[i][1] = obj2.getNum(); + obj2.free(); + } + obj1.free(); + + //----- Size + if (!dict->lookup("Size", &obj1)->isArray() || + obj1.arrayGetLength() != m) { + error(-1, "Function has missing or invalid size array"); + goto err2; + } + for (i = 0; i < m; ++i) { + obj1.arrayGet(i, &obj2); + if (!obj2.isInt()) { + error(-1, "Illegal value in function size array"); + goto err1; + } + sampleSize[i] = obj2.getInt(); + obj2.free(); + } + obj1.free(); + + //----- BitsPerSample + if (!dict->lookup("BitsPerSample", &obj1)->isInt()) { + error(-1, "Function has missing or invalid BitsPerSample"); + goto err2; + } + sampleBits = obj1.getInt(); + sampleMul = 1.0 / (double)((1 << sampleBits) - 1); + obj1.free(); + + //----- Encode + if (dict->lookup("Encode", &obj1)->isArray() && + obj1.arrayGetLength() == 2*m) { + for (i = 0; i < m; ++i) { + obj1.arrayGet(2*i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function encode array"); + goto err1; + } + encode[i][0] = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2*i+1, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function encode array"); + goto err1; + } + encode[i][1] = obj2.getNum(); + obj2.free(); + } + } else { + for (i = 0; i < m; ++i) { + encode[i][0] = 0; + encode[i][1] = sampleSize[i] - 1; + } + } + obj1.free(); + + //----- Decode + if (dict->lookup("Decode", &obj1)->isArray() && + obj1.arrayGetLength() == 2*n) { + for (i = 0; i < n; ++i) { + obj1.arrayGet(2*i, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function decode array"); + goto err1; + } + decode[i][0] = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2*i+1, &obj2); + if (!obj2.isNum()) { + error(-1, "Illegal value in function decode array"); + goto err1; + } + decode[i][1] = obj2.getNum(); + obj2.free(); + } + } else { + for (i = 0; i < n; ++i) { + decode[i][0] = range[i][0]; + decode[i][1] = range[i][1]; + } + } + obj1.free(); + + //----- samples + nSamples = n; + for (i = 0; i < m; ++i) + nSamples *= sampleSize[i]; + samples = (double *)gmalloc(nSamples * sizeof(double)); + buf = 0; + bits = 0; + bitMask = (1 << sampleBits) - 1; + str->reset(); + for (i = 0; i < nSamples; ++i) { + if (sampleBits == 8) { + s = str->getChar(); + } else if (sampleBits == 16) { + s = str->getChar(); + s = (s << 8) + str->getChar(); + } else if (sampleBits == 32) { + s = str->getChar(); + s = (s << 8) + str->getChar(); + s = (s << 8) + str->getChar(); + s = (s << 8) + str->getChar(); + } else { + while (bits < sampleBits) { + buf = (buf << 8) | (str->getChar() & 0xff); + bits += 8; + } + s = (buf >> (bits - sampleBits)) & bitMask; + bits -= sampleBits; + } + samples[i] = (double)s * sampleMul; + } + + ok = gTrue; + return; + + err1: + obj2.free(); + err2: + obj1.free(); + err3: + return; +} + +Function::Function(Function *func) { + int nSamples, i; + + m = func->m; + n = func->n; + memcpy(domain, func->domain, sizeof(domain)); + memcpy(range, func->range, sizeof(range)); + memcpy(sampleSize, func->sampleSize, sizeof(sampleSize)); + memcpy(encode, func->encode, sizeof(encode)); + memcpy(decode, func->decode, sizeof(decode)); + + nSamples = n; + for (i = 0; i < m; ++i) + nSamples *= sampleSize[i]; + samples = (double *)gmalloc(nSamples * sizeof(double)); + memcpy(samples, func->samples, nSamples * sizeof(double)); + + ok = gTrue; +} + +Function::~Function() { + if (samples) + gfree(samples); +} + +void Function::transform(double *in, double *out) { + double e[4]; + double s; + double x0, x1; + int e0, e1; + double efrac; + int i; + + // map input values into sample array + for (i = 0; i < m; ++i) { + e[i] = ((in[i] - domain[i][0]) / (domain[i][1] - domain[i][0])) * + (encode[i][1] - encode[i][0]) + encode[i][0]; + if (e[i] < 0) + e[i] = 0; + else if (e[i] > sampleSize[i] - 1) + e[i] = sampleSize[i] - 1; + } + + for (i = 0; i < n; ++i) { + + // m-linear interpolation + // (only m=1 is currently supported) + e0 = (int)floor(e[0]); + e1 = (int)ceil(e[0]); + efrac = e[0] - e0; + x0 = samples[e0 * n + i]; + x1 = samples[e1 * n + i]; + s = (1 - efrac) * x0 + efrac * x1; + + // map output values to range + out[i] = s * (decode[i][1] - decode[i][0]) + decode[i][0]; + if (out[i] < range[i][0]) + out[i] = range[i][0]; + else if (out[i] > range[i][1]) + out[i] = range[i][1]; + } +} + +//------------------------------------------------------------------------ +// GfxImageColorMap +//------------------------------------------------------------------------ + +GfxImageColorMap::GfxImageColorMap(int bits1, Object *decode, + GfxColorSpace *colorSpace1) { + GfxColor color; + double x[4]; + int maxPixel; + Object obj; + int i, j; + + ok = gTrue; + + // bits per component and colorspace + bits = bits1; + maxPixel = (1 << bits) - 1; + colorSpace = colorSpace1; + mode = colorSpace->getMode(); + + // get decode map + if (decode->isNull()) { + if (colorSpace->isIndexed()) { + indexed = gTrue; + numComps = 1; + decodeLow[0] = 0; + decodeRange[0] = maxPixel; + } else { + indexed = gFalse; + numComps = colorSpace->getNumPixelComps(); + for (i = 0; i < numComps; ++i) { + decodeLow[i] = 0; + decodeRange[i] = 1; + } + } + } else if (decode->isArray()) { + numComps = decode->arrayGetLength() / 2; + if (numComps != colorSpace->getNumPixelComps()) + goto err1; + indexed = colorSpace->isIndexed(); + for (i = 0; i < numComps; ++i) { + decode->arrayGet(2*i, &obj); + if (!obj.isNum()) + goto err2; + decodeLow[i] = obj.getNum(); + obj.free(); + decode->arrayGet(2*i+1, &obj); + if (!obj.isNum()) + goto err2; + decodeRange[i] = obj.getNum() - decodeLow[i]; + obj.free(); + } + } else { + goto err1; + } + + // handle the case where fewer than 2^n palette entries of an n-bit + // indexed color space are populated (this happens, e.g., in files + // optimized by Distiller) + if (colorSpace->isIndexed() && maxPixel > colorSpace->getIndexHigh()) { + maxPixel = colorSpace->getIndexHigh(); + } + + // construct lookup table + lookup = (double (*)[4])gmalloc((maxPixel + 1) * 4 * sizeof(double)); + if (indexed) { + for (i = 0; i <= maxPixel; ++i) { + x[0] = (double)i; + colorSpace->getColor(x, &color); + lookup[i][0] = color.getR(); + lookup[i][1] = color.getG(); + lookup[i][2] = color.getB(); + } + } else { + for (i = 0; i <= maxPixel; ++i) + for (j = 0; j < numComps; ++j) + lookup[i][j] = decodeLow[j] + (i * decodeRange[j]) / maxPixel; + } + + return; + + err2: + obj.free(); + err1: + ok = gFalse; +} + +GfxImageColorMap::~GfxImageColorMap() { + delete colorSpace; + gfree(lookup); +} + +void GfxImageColorMap::getColor(Guchar x[4], GfxColor *color) { + double *p; + + if (indexed) { + p = lookup[x[0]]; + color->setRGB(p[0], p[1], p[2]); + } else { + switch (mode) { + case colorGray: + color->setGray(lookup[x[0]][0]); + break; + case colorCMYK: + color->setCMYK(lookup[x[0]][0], lookup[x[1]][1], + lookup[x[2]][2], lookup[x[3]][3]); + break; + case colorRGB: + color->setRGB(lookup[x[0]][0], lookup[x[1]][1], lookup[x[2]][2]); + break; + } + } +} + +//------------------------------------------------------------------------ +// GfxSubpath and GfxPath +//------------------------------------------------------------------------ + +GfxSubpath::GfxSubpath(double x1, double y1) { + size = 16; + x = (double *)gmalloc(size * sizeof(double)); + y = (double *)gmalloc(size * sizeof(double)); + curve = (GBool *)gmalloc(size * sizeof(GBool)); + n = 1; + x[0] = x1; + y[0] = y1; + curve[0] = gFalse; +} + +GfxSubpath::~GfxSubpath() { + gfree(x); + gfree(y); + gfree(curve); +} + +// Used for copy(). +GfxSubpath::GfxSubpath(GfxSubpath *subpath) { + size = subpath->size; + n = subpath->n; + x = (double *)gmalloc(size * sizeof(double)); + y = (double *)gmalloc(size * sizeof(double)); + curve = (GBool *)gmalloc(size * sizeof(GBool)); + memcpy(x, subpath->x, n * sizeof(double)); + memcpy(y, subpath->y, n * sizeof(double)); + memcpy(curve, subpath->curve, n * sizeof(GBool)); +} + +void GfxSubpath::lineTo(double x1, double y1) { + if (n >= size) { + size += 16; + x = (double *)grealloc(x, size * sizeof(double)); + y = (double *)grealloc(y, size * sizeof(double)); + curve = (GBool *)grealloc(curve, size * sizeof(GBool)); + } + x[n] = x1; + y[n] = y1; + curve[n] = gFalse; + ++n; +} + +void GfxSubpath::curveTo(double x1, double y1, double x2, double y2, + double x3, double y3) { + if (n+3 > size) { + size += 16; + x = (double *)grealloc(x, size * sizeof(double)); + y = (double *)grealloc(y, size * sizeof(double)); + curve = (GBool *)grealloc(curve, size * sizeof(GBool)); + } + x[n] = x1; + y[n] = y1; + x[n+1] = x2; + y[n+1] = y2; + x[n+2] = x3; + y[n+2] = y3; + curve[n] = curve[n+1] = gTrue; + curve[n+2] = gFalse; + n += 3; +} + +GfxPath::GfxPath() { + justMoved = gFalse; + size = 16; + n = 0; + subpaths = (GfxSubpath **)gmalloc(size * sizeof(GfxSubpath *)); +} + +GfxPath::~GfxPath() { + int i; + + for (i = 0; i < n; ++i) + delete subpaths[i]; + gfree(subpaths); +} + +// Used for copy(). +GfxPath::GfxPath(GBool justMoved1, double firstX1, double firstY1, + GfxSubpath **subpaths1, int n1, int size1) { + int i; + + justMoved = justMoved1; + firstX = firstX1; + firstY = firstY1; + size = size1; + n = n1; + subpaths = (GfxSubpath **)gmalloc(size * sizeof(GfxSubpath *)); + for (i = 0; i < n; ++i) + subpaths[i] = subpaths1[i]->copy(); +} + +void GfxPath::moveTo(double x, double y) { + justMoved = gTrue; + firstX = x; + firstY = y; +} + +void GfxPath::lineTo(double x, double y) { + if (justMoved) { + if (n >= size) { + size += 16; + subpaths = (GfxSubpath **) + grealloc(subpaths, size * sizeof(GfxSubpath *)); + } + subpaths[n] = new GfxSubpath(firstX, firstY); + ++n; + justMoved = gFalse; + } + subpaths[n-1]->lineTo(x, y); +} + +void GfxPath::curveTo(double x1, double y1, double x2, double y2, + double x3, double y3) { + if (justMoved) { + if (n >= size) { + size += 16; + subpaths = (GfxSubpath **) + grealloc(subpaths, size * sizeof(GfxSubpath *)); + } + subpaths[n] = new GfxSubpath(firstX, firstY); + ++n; + justMoved = gFalse; + } + subpaths[n-1]->curveTo(x1, y1, x2, y2, x3, y3); +} + + +//------------------------------------------------------------------------ +// GfxState +//------------------------------------------------------------------------ + +GfxState::GfxState(int dpi, double px1a, double py1a, double px2a, double py2a, + int rotate, GBool upsideDown) { + double k; + + px1 = px1a; + py1 = py1a; + px2 = px2a; + py2 = py2a; + k = (double)dpi / 72.0; + if (rotate == 90) { + ctm[0] = 0; + ctm[1] = upsideDown ? k : -k; + ctm[2] = k; + ctm[3] = 0; + ctm[4] = -k * py1; + ctm[5] = k * (upsideDown ? -px1 : px2); + pageWidth = (int)(k * (py2 - py1)); + pageHeight = (int)(k * (px2 - px1)); + } else if (rotate == 180) { + ctm[0] = -k; + ctm[1] = 0; + ctm[2] = 0; + ctm[3] = upsideDown ? k : -k; + ctm[4] = k * px2; + ctm[5] = k * (upsideDown ? -py1 : py2); + pageWidth = (int)(k * (px2 - px1)); + pageHeight = (int)(k * (py2 - py1)); + } else if (rotate == 270) { + ctm[0] = 0; + ctm[1] = upsideDown ? -k : k; + ctm[2] = -k; + ctm[3] = 0; + ctm[4] = k * py2; + ctm[5] = k * (upsideDown ? px2 : -px1); + pageWidth = (int)(k * (py2 - py1)); + pageHeight = (int)(k * (px2 - px1)); + } else { + ctm[0] = k; + ctm[1] = 0; + ctm[2] = 0; + ctm[3] = upsideDown ? -k : k; + ctm[4] = -k * px1; + ctm[5] = k * (upsideDown ? py2 : -py1); + pageWidth = (int)(k * (px2 - px1)); + pageHeight = (int)(k * (py2 - py1)); + } + + fillColorSpace = new GfxColorSpace(colorGray); + strokeColorSpace = new GfxColorSpace(colorGray); + fillColor.setGray(0); + strokeColor.setGray(0); + + lineWidth = 1; + lineDash = NULL; + lineDashLength = 0; + lineDashStart = 0; + flatness = 0; + lineJoin = 0; + lineCap = 0; + miterLimit = 10; + + font = NULL; + fontSize = 0; + textMat[0] = 1; textMat[1] = 0; + textMat[2] = 0; textMat[3] = 1; + textMat[4] = 0; textMat[5] = 0; + charSpace = 0; + wordSpace = 0; + horizScaling = 1; + leading = 0; + rise = 0; + render = 0; + + path = new GfxPath(); + curX = curY = 0; + lineX = lineY = 0; + + saved = NULL; +} + +GfxState::~GfxState() { + if (fillColorSpace) + delete fillColorSpace; + if (strokeColorSpace) + delete strokeColorSpace; + gfree(lineDash); + delete path; + if (saved) + delete saved; +} + +// Used for copy(); +GfxState::GfxState(GfxState *state) { + memcpy(this, state, sizeof(GfxState)); + if (fillColorSpace) + fillColorSpace = state->fillColorSpace->copy(); + if (strokeColorSpace) + strokeColorSpace = state->strokeColorSpace->copy(); + if (lineDashLength > 0) { + lineDash = (double *)gmalloc(lineDashLength * sizeof(double)); + memcpy(lineDash, state->lineDash, lineDashLength * sizeof(double)); + } + path = state->path->copy(); + saved = NULL; +} + +double GfxState::transformWidth(double w) { + double x, y; + + x = ctm[0] + ctm[2]; + y = ctm[1] + ctm[3]; + return w * sqrt(0.5 * (x * x + y * y)); +} + +double GfxState::getTransformedFontSize() { + double x1, y1, x2, y2; + + x1 = textMat[2] * fontSize; + y1 = textMat[3] * fontSize; + x2 = ctm[0] * x1 + ctm[2] * y1; + y2 = ctm[1] * x1 + ctm[3] * y1; + return sqrt(x2 * x2 + y2 * y2); +} + +void GfxState::getFontTransMat(double *m11, double *m12, + double *m21, double *m22) { + *m11 = (textMat[0] * ctm[0] + textMat[1] * ctm[2]) * fontSize; + *m12 = (textMat[0] * ctm[1] + textMat[1] * ctm[3]) * fontSize; + *m21 = (textMat[2] * ctm[0] + textMat[3] * ctm[2]) * fontSize; + *m22 = (textMat[2] * ctm[1] + textMat[3] * ctm[3]) * fontSize; +} + +void GfxState::concatCTM(double a, double b, double c, + double d, double e, double f) { + double a1 = ctm[0]; + double b1 = ctm[1]; + double c1 = ctm[2]; + double d1 = ctm[3]; + + ctm[0] = a * a1 + b * c1; + ctm[1] = a * b1 + b * d1; + ctm[2] = c * a1 + d * c1; + ctm[3] = c * b1 + d * d1; + ctm[4] = e * a1 + f * c1 + ctm[4]; + ctm[5] = e * b1 + f * d1 + ctm[5]; +} + +void GfxState::setFillColorSpace(GfxColorSpace *colorSpace) { + if (fillColorSpace) + delete fillColorSpace; + fillColorSpace = colorSpace; +} + +void GfxState::setStrokeColorSpace(GfxColorSpace *colorSpace) { + if (strokeColorSpace) + delete strokeColorSpace; + strokeColorSpace = colorSpace; +} + +void GfxState::setLineDash(double *dash, int length, double start) { + if (lineDash) + gfree(lineDash); + lineDash = dash; + lineDashLength = length; + lineDashStart = start; +} + +void GfxState::clearPath() { + delete path; + path = new GfxPath(); +} + +void GfxState::textShift(double tx) { + double dx, dy; + + textTransformDelta(tx, 0, &dx, &dy); + curX += dx; + curY += dy; +} + +void GfxState::textShift(double tx, double ty) { + double dx, dy; + + textTransformDelta(tx, ty, &dx, &dy); + curX += dx; + curY += dy; +} + +GfxState *GfxState::save() { + GfxState *newState; + + newState = copy(); + newState->saved = this; + return newState; +} + +GfxState *GfxState::restore() { + GfxState *oldState; + + if (saved) { + oldState = saved; + saved = NULL; + delete this; + } else { + oldState = this; + } + return oldState; +} diff --git a/pdftops/GfxState.h b/pdftops/GfxState.h new file mode 100644 index 0000000000..f93ef89036 --- /dev/null +++ b/pdftops/GfxState.h @@ -0,0 +1,473 @@ +//======================================================================== +// +// GfxState.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef GFXSTATE_H +#define GFXSTATE_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "gtypes.h" + +class Object; +class Function; +class GfxFont; + +//------------------------------------------------------------------------ +// GfxColor +//------------------------------------------------------------------------ + +class GfxColor { +public: + + GfxColor(): r(0), g(0), b(0) {} + + // Set color. + void setGray(double gray) + { r = g = b = gray; } + void setCMYK(double c, double m, double y, double k); + void setRGB(double r1, double g1, double b1) + { r = r1; g = g1; b = b1; } + + // Accessors. + double getR() { return r; } + double getG() { return g; } + double getB() { return b; } + double getGray() { return 0.299 * r + 0.587 * g + 0.114 * b; } + +private: + + double r, g, b; +}; + +//------------------------------------------------------------------------ +// GfxColorSpace +//------------------------------------------------------------------------ + +enum GfxColorMode { + colorGray, colorCMYK, colorRGB +}; + +class GfxColorSpace { +public: + + // Construct a colorspace. + GfxColorSpace(Object *colorSpace); + + // Construct a simple colorspace: DeviceGray, DeviceCMYK, or + // DeviceRGB. + GfxColorSpace(GfxColorMode mode1); + + // Destructor. + ~GfxColorSpace(); + + // Copy. + GfxColorSpace *copy() { return new GfxColorSpace(this); } + + // Is color space valid? + GBool isOk() { return ok; } + + // Get the color mode. + GfxColorMode getMode() { return mode; } + + // Get number of components in pixels of this colorspace. + int getNumPixelComps() { return indexed ? 1 : numComps; } + + // Get number of components in colors of this colorspace. + int getNumColorComps() { return numComps; } + + // Return true if colorspace is indexed. + GBool isIndexed() { return indexed; } + + // Get lookup table (only for indexed colorspaces). + int getIndexHigh() { return indexHigh; } + Guchar *getLookupVal(int i) { return lookup[i]; } + + // Convert a pixel to a color. + void getColor(double x[4], GfxColor *color); + +private: + + Function *sepFunc; // separation tint transform function + GfxColorMode mode; // color mode + GBool indexed; // set for indexed colorspaces + int numComps; // number of components in colors + int indexHigh; // max pixel for indexed colorspace + Guchar (*lookup)[4]; // lookup table (only for indexed + // colorspaces) + GBool ok; // is color space valid? + + GfxColorSpace(GfxColorSpace *colorSpace); + void setMode(Object *colorSpace); +}; + +//------------------------------------------------------------------------ +// Function +//------------------------------------------------------------------------ + +class Function { +public: + + // Create a PDF function object. + Function(Object *funcObj); + + ~Function(); + + Function *copy() { return new Function(this); } + + GBool isOk() { return ok; } + + // Return size of input and output tuples. + int getInputSize() { return m; } + int getOutputSize() { return n; } + + // Transform an input tuple into an output tuple. + void transform(double *in, double *out); + +private: + + Function(Function *func); + + int m, n; + double domain[1][2]; + double range[4][2]; + int sampleSize[1]; + double encode[1][2]; + double decode[4][2]; + double *samples; + GBool ok; +}; + +//------------------------------------------------------------------------ +// GfxImageColorMap +//------------------------------------------------------------------------ + +class GfxImageColorMap { +public: + + // Constructor. + GfxImageColorMap(int bits1, Object *decode, GfxColorSpace *colorSpace1); + + // Destructor. + ~GfxImageColorMap(); + + // Is color map valid? + GBool isOk() { return ok; } + + // Get the color space. + GfxColorSpace *getColorSpace() { return colorSpace; } + + // Get stream decoding info. + int getNumPixelComps() { return numComps; } + int getBits() { return bits; } + + // Get decode table. + double getDecodeLow(int i) { return decodeLow[i]; } + double getDecodeHigh(int i) { return decodeLow[i] + decodeRange[i]; } + + // Convert a pixel to a color. + void getColor(Guchar x[4], GfxColor *color); + +private: + + GfxColorSpace *colorSpace; // the image colorspace + int bits; // bits per component + int numComps; // number of components in a pixel + GBool indexed; // set for indexed color space + GfxColorMode mode; // color mode + double (*lookup)[4]; // lookup table + double decodeLow[4]; // minimum values for each component + double decodeRange[4]; // max - min value for each component + GBool ok; +}; + +//------------------------------------------------------------------------ +// GfxSubpath and GfxPath +//------------------------------------------------------------------------ + +class GfxSubpath { +public: + + // Constructor. + GfxSubpath(double x1, double y1); + + // Destructor. + ~GfxSubpath(); + + // Copy. + GfxSubpath *copy() { return new GfxSubpath(this); } + + // Get points. + int getNumPoints() { return n; } + double getX(int i) { return x[i]; } + double getY(int i) { return y[i]; } + GBool getCurve(int i) { return curve[i]; } + + // Get last point. + double getLastX() { return x[n-1]; } + double getLastY() { return y[n-1]; } + + // Add a line segment. + void lineTo(double x1, double y1); + + // Add a Bezier curve. + void curveTo(double x1, double y1, double x2, double y2, + double x3, double y3); + + // Close the subpath. + void close() + { if (x[n-1] != x[0] || y[n-1] != y[0]) lineTo(x[0], y[0]); } + +private: + + double *x, *y; // points + GBool *curve; // curve[i] => point i is a control point + // for a Bezier curve + int n; // number of points + int size; // size of x/y arrays + + GfxSubpath(GfxSubpath *subpath); +}; + +class GfxPath { +public: + + // Constructor. + GfxPath(); + + // Destructor. + ~GfxPath(); + + // Copy. + GfxPath *copy() + { return new GfxPath(justMoved, firstX, firstY, subpaths, n, size); } + + // Is there a current point? + GBool isCurPt() { return n > 0 || justMoved; } + + // Is the path non-empty, i.e., is there at least one segment? + GBool isPath() { return n > 0; } + + // Get subpaths. + int getNumSubpaths() { return n; } + GfxSubpath *getSubpath(int i) { return subpaths[i]; } + + // Get last point on last subpath. + double getLastX() { return subpaths[n-1]->getLastX(); } + double getLastY() { return subpaths[n-1]->getLastY(); } + + // Move the current point. + void moveTo(double x, double y); + + // Add a segment to the last subpath. + void lineTo(double x, double y); + + // Add a Bezier curve to the last subpath + void curveTo(double x1, double y1, double x2, double y2, + double x3, double y3); + + // Close the last subpath. + void close() { subpaths[n-1]->close(); } + +private: + + GBool justMoved; // set if a new subpath was just started + double firstX, firstY; // first point in new subpath + GfxSubpath **subpaths; // subpaths + int n; // number of subpaths + int size; // size of subpaths array + + GfxPath(GBool justMoved1, double firstX1, double firstY1, + GfxSubpath **subpaths1, int n1, int size1); +}; + +//------------------------------------------------------------------------ +// GfxState +//------------------------------------------------------------------------ + +class GfxState { +public: + + // Construct a default GfxState, for a device with resolution , + // page box (,)-(,), page rotation , and + // coordinate system specified by . + GfxState(int dpi, double px1a, double py1a, double px2a, double py2a, + int rotate, GBool upsideDown); + + // Destructor. + ~GfxState(); + + // Copy. + GfxState *copy() { return new GfxState(this); } + + // Accessors. + double *getCTM() { return ctm; } + double getX1() { return px1; } + double getY1() { return py1; } + double getX2() { return px2; } + double getY2() { return py2; } + double getPageWidth() { return pageWidth; } + double getPageHeight() { return pageHeight; } + GfxColor *getFillColor() { return &fillColor; } + GfxColor *getStrokeColor() { return &strokeColor; } + double getLineWidth() { return lineWidth; } + void getLineDash(double **dash, int *length, double *start) + { *dash = lineDash; *length = lineDashLength; *start = lineDashStart; } + int getFlatness() { return flatness; } + int getLineJoin() { return lineJoin; } + int getLineCap() { return lineCap; } + double getMiterLimit() { return miterLimit; } + GfxFont *getFont() { return font; } + double getFontSize() { return fontSize; } + double *getTextMat() { return textMat; } + double getCharSpace() { return charSpace; } + double getWordSpace() { return wordSpace; } + double getHorizScaling() { return horizScaling; } + double getLeading() { return leading; } + double getRise() { return rise; } + int getRender() { return render; } + GfxPath *getPath() { return path; } + double getCurX() { return curX; } + double getCurY() { return curY; } + double getLineX() { return lineX; } + double getLineY() { return lineY; } + + // Is there a current point/path? + GBool isCurPt() { return path->isCurPt(); } + GBool isPath() { return path->isPath(); } + + // Transforms. + void transform(double x1, double y1, double *x2, double *y2) + { *x2 = ctm[0] * x1 + ctm[2] * y1 + ctm[4]; + *y2 = ctm[1] * x1 + ctm[3] * y1 + ctm[5]; } + void transformDelta(double x1, double y1, double *x2, double *y2) + { *x2 = ctm[0] * x1 + ctm[2] * y1; + *y2 = ctm[1] * x1 + ctm[3] * y1; } + void textTransform(double x1, double y1, double *x2, double *y2) + { *x2 = textMat[0] * x1 + textMat[2] * y1 + textMat[4]; + *y2 = textMat[1] * x1 + textMat[3] * y1 + textMat[5]; } + void textTransformDelta(double x1, double y1, double *x2, double *y2) + { *x2 = textMat[0] * x1 + textMat[2] * y1; + *y2 = textMat[1] * x1 + textMat[3] * y1; } + double transformWidth(double w); + double getTransformedLineWidth() + { return transformWidth(lineWidth); } + double getTransformedFontSize(); + void getFontTransMat(double *m11, double *m12, double *m21, double *m22); + + // Change state parameters. + void concatCTM(double a, double b, double c, + double d, double e, double f); + void setFillGray(double gray) + { fillColor.setGray(gray); } + void setFillCMYK(double c, double m, double y, double k) + { fillColor.setCMYK(c, m, y, k); } + void setFillRGB(double r, double g, double b) + { fillColor.setRGB(r, g, b); } + void setStrokeGray(double gray) + { strokeColor.setGray(gray); } + void setStrokeCMYK(double c, double m, double y, double k) + { strokeColor.setCMYK(c, m, y, k); } + void setStrokeRGB(double r, double g, double b) + { strokeColor.setRGB(r, g, b); } + void setFillColorSpace(GfxColorSpace *colorSpace); + void setStrokeColorSpace(GfxColorSpace *colorSpace); + void setFillColor(double x[4]) + { fillColorSpace->getColor(x, &fillColor); } + void setStrokeColor(double x[4]) + { strokeColorSpace->getColor(x, &strokeColor); } + void setLineWidth(double width) + { lineWidth = width; } + void setLineDash(double *dash, int length, double start); + void setFlatness(int flatness1) { flatness = flatness1; } + void setLineJoin(int lineJoin1) { lineJoin = lineJoin1; } + void setLineCap(int lineCap1) { lineCap = lineCap1; } + void setMiterLimit(double miterLimit1) { miterLimit = miterLimit1; } + void setFont(GfxFont *font1, double fontSize1) + { font = font1; fontSize = fontSize1; } + void setTextMat(double a, double b, double c, + double d, double e, double f) + { textMat[0] = a; textMat[1] = b; textMat[2] = c; + textMat[3] = d; textMat[4] = e; textMat[5] = f; } + void setCharSpace(double space) + { charSpace = space; } + void setWordSpace(double space) + { wordSpace = space; } + void setHorizScaling(double scale) + { horizScaling = 0.01 * scale; } + void setLeading(double leading1) + { leading = leading1; } + void setRise(double rise1) + { rise = rise1; } + void setRender(int render1) + { render = render1; } + + // Add to path. + void moveTo(double x, double y) + { path->moveTo(curX = x, curY = y); } + void lineTo(double x, double y) + { path->lineTo(curX = x, curY = y); } + void curveTo(double x1, double y1, double x2, double y2, + double x3, double y3) + { path->curveTo(x1, y1, x2, y2, curX = x3, curY = y3); } + void closePath() + { path->close(); curX = path->getLastX(); curY = path->getLastY(); } + void clearPath(); + + // Text position. + void textMoveTo(double tx, double ty) + { lineX = tx; lineY = ty; textTransform(tx, ty, &curX, &curY); } + void textShift(double tx); + void textShift(double tx, double ty); + + // Push/pop GfxState on/off stack. + GfxState *save(); + GfxState *restore(); + GBool hasSaves() { return saved != NULL; } + +private: + + double ctm[6]; // coord transform matrix + double px1, py1, px2, py2; // page corners (user coords) + double pageWidth, pageHeight; // page size (pixels) + + GfxColorSpace *fillColorSpace; // fill color space + GfxColorSpace *strokeColorSpace; // stroke color space + GfxColor fillColor; // fill color + GfxColor strokeColor; // stroke color + + double lineWidth; // line width + double *lineDash; // line dash + int lineDashLength; + double lineDashStart; + int flatness; // curve flatness + int lineJoin; // line join style + int lineCap; // line cap style + double miterLimit; // line miter limit + + GfxFont *font; // font + double fontSize; // font size + double textMat[6]; // text matrix + double charSpace; // character spacing + double wordSpace; // word spacing + double horizScaling; // horizontal scaling + double leading; // text leading + double rise; // text rise + int render; // text rendering mode + + GfxPath *path; // array of path elements + double curX, curY; // current point (user coords) + double lineX, lineY; // start of current text line (text coords) + + GfxState *saved; // next GfxState on stack + + GfxState(GfxState *state); +}; + +#endif diff --git a/pdftops/ImageOutputDev.cxx b/pdftops/ImageOutputDev.cxx new file mode 100644 index 0000000000..93d1c31237 --- /dev/null +++ b/pdftops/ImageOutputDev.cxx @@ -0,0 +1,155 @@ +//======================================================================== +// +// ImageOutputDev.cc +// +// Copyright 1998 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include "gmem.h" +#include "config.h" +#include "Error.h" +#include "GfxState.h" +#include "Object.h" +#include "Stream.h" +#include "ImageOutputDev.h" + +ImageOutputDev::ImageOutputDev(char *fileRoot1, GBool dumpJPEG1) { + fileRoot = copyString(fileRoot1); + fileName = (char *)gmalloc(strlen(fileRoot) + 20); + dumpJPEG = dumpJPEG1; + imgNum = 0; + ok = gTrue; +} + +ImageOutputDev::~ImageOutputDev() { + gfree(fileName); + gfree(fileRoot); +} + +void ImageOutputDev::drawImageMask(GfxState *state, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) { + FILE *f; + int c; + + // dump JPEG file + if (dumpJPEG && str->getKind() == strDCT) { + + // open the image file + sprintf(fileName, "%s-%03d.jpg", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(-1, "Couldn't open image file '%s'", fileName); + return; + } + + // initialize stream + str = ((DCTStream *)str)->getRawStream(); + str->reset(); + + // copy the stream + while ((c = str->getChar()) != EOF) + fputc(c, f); + + fclose(f); + + // dump PBM file + } else { + + // open the image file and write the PBM header + sprintf(fileName, "%s-%03d.pbm", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(-1, "Couldn't open image file '%s'", fileName); + return; + } + fprintf(f, "P4\n"); + fprintf(f, "%d %d\n", width, height); + + // initialize stream + str->reset(); + + // copy the stream + while ((c = str->getChar()) != EOF) + fputc(c, f); + + fclose(f); + } +} + +void ImageOutputDev::drawImage(GfxState *state, Stream *str, int width, + int height, GfxImageColorMap *colorMap, + GBool inlineImg) { + FILE *f; + ImageStream *imgStr; + Guchar pixBuf[4]; + GfxColor color; + int x, y; + int c; + + // dump JPEG file + if (dumpJPEG && str->getKind() == strDCT) { + + // open the image file + sprintf(fileName, "%s-%03d.jpg", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(-1, "Couldn't open image file '%s'", fileName); + return; + } + + // initialize stream + str = ((DCTStream *)str)->getRawStream(); + str->reset(); + + // copy the stream + while ((c = str->getChar()) != EOF) + fputc(c, f); + + fclose(f); + + // dump PPM file + } else { + + // open the image file and write the PPM header + sprintf(fileName, "%s-%03d.ppm", fileRoot, imgNum); + ++imgNum; + if (!(f = fopen(fileName, "wb"))) { + error(-1, "Couldn't open image file '%s'", fileName); + return; + } + fprintf(f, "P6\n"); + fprintf(f, "%d %d\n", width, height); + fprintf(f, "255\n"); + + // initialize stream + imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + // for each line... + for (y = 0; y < height; ++y) { + + // write the line + for (x = 0; x < width; ++x) { + imgStr->getPixel(pixBuf); + colorMap->getColor(pixBuf, &color); + fputc((int)(color.getR() * 255 + 0.5), f); + fputc((int)(color.getG() * 255 + 0.5), f); + fputc((int)(color.getB() * 255 + 0.5), f); + } + } + delete imgStr; + + fclose(f); + } +} diff --git a/pdftops/ImageOutputDev.h b/pdftops/ImageOutputDev.h new file mode 100644 index 0000000000..84766dd1f0 --- /dev/null +++ b/pdftops/ImageOutputDev.h @@ -0,0 +1,67 @@ +//======================================================================== +// +// ImageOutputDev.h +// +// Copyright 1998 Derek B. Noonburg +// +//======================================================================== + +#ifndef IMAGEOUTPUTDEV_H +#define IMAGEOUTPUTDEV_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include +#include "gtypes.h" +#include "OutputDev.h" + +class GfxState; + +//------------------------------------------------------------------------ +// ImageOutputDev +//------------------------------------------------------------------------ + +class ImageOutputDev: public OutputDev { +public: + + // Create an OutputDev which will write images to files named + // -NNN.. Normally, all images are written as PBM + // (.pbm) or PPM (.ppm) files. If is set, JPEG images are + // written as JPEG (.jpg) files. + ImageOutputDev(char *fileRoot1, GBool dumpJPEG1); + + // Destructor. + virtual ~ImageOutputDev(); + + // Check if file was successfully created. + virtual GBool isOk() { return ok; } + + //---- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() { return gTrue; } + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() { return gFalse; } + + //----- image drawing + virtual void drawImageMask(GfxState *state, Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Stream *str, int width, + int height, GfxImageColorMap *colorMap, + GBool inlineImg); + +private: + + char *fileRoot; // root of output file names + char *fileName; // buffer for output file names + GBool dumpJPEG; // set to dump native JPEG files + int imgNum; // current image number + GBool ok; // set up ok? +}; + +#endif diff --git a/pdftops/Lexer.cxx b/pdftops/Lexer.cxx new file mode 100644 index 0000000000..302a024873 --- /dev/null +++ b/pdftops/Lexer.cxx @@ -0,0 +1,453 @@ +//======================================================================== +// +// Lexer.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include "Lexer.h" +#include "Error.h" + +//------------------------------------------------------------------------ + +// A '1' in this array means the corresponding character ends a name +// or command. +static char endOfNameChars[128] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, // 0x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1x + 1, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, // 2x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, // 3x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 4x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, // 5x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 6x + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0 // 7x +}; + +//------------------------------------------------------------------------ +// Lexer +//------------------------------------------------------------------------ + +Lexer::Lexer(Stream *str) { + Object obj; + + curStr.initStream(str); + streams = new Array(); + streams->add(curStr.copy(&obj)); + strPtr = 0; + freeArray = gTrue; + curStr.streamReset(); +} + +Lexer::Lexer(Object *obj) { + Object obj2; + + if (obj->isStream()) { + streams = new Array(); + freeArray = gTrue; + streams->add(obj->copy(&obj2)); + } else { + streams = obj->getArray(); + freeArray = gFalse; + } + strPtr = 0; + if (streams->getLength() > 0) { + streams->get(strPtr, &curStr); + curStr.streamReset(); + } +} + +Lexer::~Lexer() { + if (!curStr.isNone()) + curStr.free(); + if (freeArray) + delete streams; +} + +int Lexer::getChar() { + int c; + + c = EOF; + while (!curStr.isNone() && (c = curStr.streamGetChar()) == EOF) { + curStr.free(); + ++strPtr; + if (strPtr < streams->getLength()) { + streams->get(strPtr, &curStr); + curStr.streamReset(); + } + } + return c; +} + +int Lexer::lookChar() { + int c; + + c = EOF; + while (!curStr.isNone() && (c = curStr.streamLookChar()) == EOF) { + curStr.free(); + ++strPtr; + if (strPtr < streams->getLength()) { + streams->get(strPtr, &curStr); + curStr.streamReset(); + } + } + return c; +} + +Object *Lexer::getObj(Object *obj) { + char *p; + int c, c2; + GBool comment, neg, done; + int numParen; + int xi; + double xf, scale; + GString *s; + int n, m; + + // skip whitespace and comments + comment = gFalse; + while (1) { + if ((c = getChar()) == EOF) + return obj->initEOF(); + if (comment) { + if (c == '\r' || c == '\n') + comment = gFalse; + } else if (c == '%') { + comment = gTrue; + } else if (!isspace(c)) { + break; + } + } + + // start reading token + switch (c) { + + // number + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + case '-': case '.': + neg = gFalse; + xi = 0; + if (c == '-') { + neg = gTrue; + } else if (c == '.') { + goto doReal; + } else { + xi = c - '0'; + } + while (1) { + c = lookChar(); + if (isdigit(c)) { + getChar(); + xi = xi * 10 + (c - '0'); + } else if (c == '.') { + getChar(); + goto doReal; + } else { + break; + } + } + if (neg) + xi = -xi; + obj->initInt(xi); + break; + doReal: + xf = xi; + scale = 0.1; + while (1) { + c = lookChar(); + if (!isdigit(c)) + break; + getChar(); + xf = xf + scale * (c - '0'); + scale *= 0.1; + } + if (neg) + xf = -xf; + obj->initReal(xf); + break; + + // string + case '(': + p = tokBuf; + n = 0; + numParen = 1; + done = gFalse; + s = NULL; + do { + c2 = EOF; + switch (c = getChar()) { + + case EOF: + case '\r': + case '\n': + error(getPos(), "Unterminated string"); + done = gTrue; + break; + + case '(': + ++numParen; + break; + + case ')': + if (--numParen == 0) + done = gTrue; + break; + + case '\\': + switch (c = getChar()) { + case 'n': + c2 = '\n'; + break; + case 'r': + c2 = '\r'; + break; + case 't': + c2 = '\t'; + break; + case 'b': + c2 = '\b'; + break; + case 'f': + c2 = '\f'; + break; + case '\\': + case '(': + case ')': + c2 = c; + break; + case '0': case '1': case '2': case '3': + case '4': case '5': case '6': case '7': + c2 = c - '0'; + c = lookChar(); + if (c >= '0' && c <= '7') { + getChar(); + c2 = (c2 << 3) + (c - '0'); + c = lookChar(); + if (c >= '0' && c <= '7') { + getChar(); + c2 = (c2 << 3) + (c - '0'); + } + } + break; + case '\r': + c = lookChar(); + if (c == '\n') + getChar(); + break; + case '\n': + break; + case EOF: + error(getPos(), "Unterminated string"); + done = gTrue; + break; + default: + c2 = c; + break; + } + break; + + default: + c2 = c; + break; + } + + if (c2 != EOF) { + if (n == tokBufSize) { + if (!s) + s = new GString(tokBuf, tokBufSize); + else + s->append(tokBuf, tokBufSize); + p = tokBuf; + n = 0; + } + *p++ = (char)c2; + ++n; + } + } while (!done); + if (!s) + s = new GString(tokBuf, n); + else + s->append(tokBuf, n); + obj->initString(s); + break; + + // name + case '/': + p = tokBuf; + n = 0; + while ((c = lookChar()) != EOF && !(c < 128 && endOfNameChars[c])) { + getChar(); + if (c == '#') { + c2 = lookChar(); + if (c2 >= '0' && c2 <= '9') + c = c2 - '0'; + else if (c2 >= 'A' && c2 <= 'F') + c = c2 - 'A' + 10; + else if (c2 >= 'a' && c2 <= 'f') + c = c2 - 'a' + 10; + else + goto notEscChar; + getChar(); + c <<= 4; + c2 = getChar(); + if (c2 >= '0' && c2 <= '9') + c += c2 - '0'; + else if (c2 >= 'A' && c2 <= 'F') + c += c2 - 'A' + 10; + else if (c2 >= 'a' && c2 <= 'f') + c += c2 - 'a' + 10; + else + error(getPos(), "Illegal digit in hex char in name"); + } + notEscChar: + if (++n == tokBufSize) { + error(getPos(), "Name token too long"); + break; + } + *p++ = c; + } + *p = '\0'; + obj->initName(tokBuf); + break; + + // array punctuation + case '[': + case ']': + tokBuf[0] = c; + tokBuf[1] = '\0'; + obj->initCmd(tokBuf); + break; + + // hex string or dict punctuation + case '<': + c = lookChar(); + + // dict punctuation + if (c == '<') { + getChar(); + tokBuf[0] = tokBuf[1] = '<'; + tokBuf[2] = '\0'; + obj->initCmd(tokBuf); + + // hex string + } else { + p = tokBuf; + m = n = 0; + c2 = 0; + s = NULL; + while (1) { + c = getChar(); + if (c == '>') { + break; + } else if (c == EOF) { + error(getPos(), "Unterminated hex string"); + break; + } else if (!isspace(c)) { + c2 = c2 << 4; + if (c >= '0' && c <= '9') + c2 += c - '0'; + else if (c >= 'A' && c <= 'F') + c2 += c - 'A' + 10; + else if (c >= 'a' && c <= 'f') + c2 += c - 'a' + 10; + else + error(getPos(), "Illegal character <%02x> in hex string", c); + if (++m == 2) { + if (n == tokBufSize) { + if (!s) + s = new GString(tokBuf, tokBufSize); + else + s->append(tokBuf, tokBufSize); + p = tokBuf; + n = 0; + } + *p++ = (char)c2; + ++n; + c2 = 0; + m = 0; + } + } + } + if (!s) + s = new GString(tokBuf, n); + else + s->append(tokBuf, n); + if (m == 1) + s->append((char)(c2 << 4)); + obj->initString(s); + } + break; + + // dict punctuation + case '>': + c = lookChar(); + if (c == '>') { + getChar(); + tokBuf[0] = tokBuf[1] = '>'; + tokBuf[2] = '\0'; + obj->initCmd(tokBuf); + } else { + error(getPos(), "Illegal character '>'"); + obj->initError(); + } + break; + + // error + case ')': + case '{': + case '}': + error(getPos(), "Illegal character '%c'", c); + obj->initError(); + break; + + // command + default: + p = tokBuf; + *p++ = c; + n = 1; + while ((c = lookChar()) != EOF && !(c < 128 && endOfNameChars[c])) { + getChar(); + if (++n == tokBufSize) { + error(getPos(), "Command token too long"); + break; + } + *p++ = c; + } + *p = '\0'; + if (tokBuf[0] == 't' && !strcmp(tokBuf, "true")) + obj->initBool(gTrue); + else if (tokBuf[0] == 'f' && !strcmp(tokBuf, "false")) + obj->initBool(gFalse); + else if (tokBuf[0] == 'n' && !strcmp(tokBuf, "null")) + obj->initNull(); + else + obj->initCmd(tokBuf); + break; + } + + return obj; +} + +void Lexer::skipToNextLine() { + int c; + + while (1) { + c = getChar(); + if (c == EOF || c == '\n') + return; + if (c == '\r') { + if ((c = lookChar()) == '\n') + getChar(); + return; + } + } +} diff --git a/pdftops/Lexer.h b/pdftops/Lexer.h new file mode 100644 index 0000000000..70144b86bc --- /dev/null +++ b/pdftops/Lexer.h @@ -0,0 +1,72 @@ +//======================================================================== +// +// Lexer.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef LEXER_H +#define LEXER_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "Object.h" +#include "Stream.h" + +#define tokBufSize 128 // size of token buffer + +//------------------------------------------------------------------------ +// Lexer +//------------------------------------------------------------------------ + +class Lexer { +public: + + // Construct a lexer for a single stream. Deletes the stream when + // lexer is deleted. + Lexer(Stream *str); + + // Construct a lexer for a stream or array of streams (assumes obj + // is either a stream or array of streams). + Lexer(Object *obj); + + // Destructor. + ~Lexer(); + + // Get the next object from the input stream. + Object *getObj(Object *obj); + + // Skip to the beginning of the next line in the input stream. + void skipToNextLine(); + + // Skip over one character. + void skipChar() { getChar(); } + + // Get stream. + Stream *getStream() + { return curStr.isNone() ? (Stream *)NULL : curStr.getStream(); } + + // Get current position in file. + int getPos() + { return curStr.isNone() ? -1 : curStr.streamGetPos(); } + + // Set position in file. + void setPos(int pos) + { if (!curStr.isNone()) curStr.streamSetPos(pos); } + +private: + + int getChar(); + int lookChar(); + + Array *streams; // array of input streams + int strPtr; // index of current stream + Object curStr; // current stream + GBool freeArray; // should lexer free the streams array? + char tokBuf[tokBufSize]; // temporary token buffer +}; + +#endif diff --git a/pdftops/Link.cxx b/pdftops/Link.cxx new file mode 100644 index 0000000000..538618bcf9 --- /dev/null +++ b/pdftops/Link.cxx @@ -0,0 +1,609 @@ +//======================================================================== +// +// Link.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include "gmem.h" +#include "GString.h" +#include "Error.h" +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Link.h" + +//------------------------------------------------------------------------ + +static GString *getFileSpecName(Object *fileSpecObj); + +//------------------------------------------------------------------------ +// LinkDest +//------------------------------------------------------------------------ + +LinkDest::LinkDest(Array *a, GBool pageIsRef1) { + Object obj1, obj2; + + // initialize fields + pageIsRef = pageIsRef1; + left = bottom = right = top = zoom = 0; + ok = gFalse; + + // get page + if (pageIsRef) { + if (!a->getNF(0, &obj1)->isRef()) { + error(-1, "Bad annotation destination"); + goto err2; + } + pageRef.num = obj1.getRefNum(); + pageRef.gen = obj1.getRefGen(); + obj1.free(); + } else { + if (!a->get(0, &obj1)->isInt()) { + error(-1, "Bad annotation destination"); + goto err2; + } + pageNum = obj1.getInt() + 1; + obj1.free(); + } + + // get destination type + a->get(1, &obj1); + + // XYZ link + if (obj1.isName("XYZ")) { + kind = destXYZ; + a->get(2, &obj2); + if (obj2.isNull()) { + changeLeft = gFalse; + } else if (obj2.isNum()) { + changeLeft = gTrue; + left = obj2.getNum(); + } else { + error(-1, "Bad annotation destination position"); + goto err1; + } + obj2.free(); + a->get(3, &obj2); + if (obj2.isNull()) { + changeTop = gFalse; + } else if (obj2.isNum()) { + changeTop = gTrue; + top = obj2.getNum(); + } else { + error(-1, "Bad annotation destination position"); + goto err1; + } + obj2.free(); + a->get(4, &obj2); + if (obj2.isNull()) { + changeZoom = gFalse; + } else if (obj2.isNum()) { + changeZoom = gTrue; + zoom = obj2.getNum(); + } else { + error(-1, "Bad annotation destination position"); + goto err1; + } + obj2.free(); + + // Fit link + } else if (obj1.isName("Fit")) { + kind = destFit; + + // FitH link + } else if (obj1.isName("FitH")) { + kind = destFitH; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + top = obj2.getNum(); + obj2.free(); + + // FitV link + } else if (obj1.isName("FitV")) { + kind = destFitV; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + left = obj2.getNum(); + obj2.free(); + + // FitR link + } else if (obj1.isName("FitR")) { + kind = destFitR; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + left = obj2.getNum(); + obj2.free(); + if (!a->get(3, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + bottom = obj2.getNum(); + obj2.free(); + if (!a->get(4, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + right = obj2.getNum(); + obj2.free(); + if (!a->get(5, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + top = obj2.getNum(); + obj2.free(); + + // FitB link + } else if (obj1.isName("FitB")) { + kind = destFitB; + + // FitBH link + } else if (obj1.isName("FitBH")) { + kind = destFitBH; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + top = obj2.getNum(); + obj2.free(); + + // FitBV link + } else if (obj1.isName("FitBV")) { + kind = destFitBV; + if (!a->get(2, &obj2)->isNum()) { + error(-1, "Bad annotation destination position"); + goto err1; + } + left = obj2.getNum(); + obj2.free(); + + // unknown link kind + } else { + error(-1, "Unknown annotation destination type"); + goto err2; + } + + obj1.free(); + ok = gTrue; + return; + + err1: + obj2.free(); + err2: + obj1.free(); +} + +LinkDest::LinkDest(LinkDest *dest) { + kind = dest->kind; + pageIsRef = dest->pageIsRef; + if (pageIsRef) + pageRef = dest->pageRef; + else + pageNum = dest->pageNum; + left = dest->left; + bottom = dest->bottom; + right = dest->right; + top = dest->top; + zoom = dest->zoom; + changeLeft = dest->changeLeft; + changeTop = dest->changeTop; + changeZoom = dest->changeZoom; + ok = gTrue; +} + +//------------------------------------------------------------------------ +// LinkGoTo +//------------------------------------------------------------------------ + +LinkGoTo::LinkGoTo(Object *destObj) { + dest = NULL; + namedDest = NULL; + + // named destination + if (destObj->isName()) { + namedDest = new GString(destObj->getName()); + } else if (destObj->isString()) { + namedDest = destObj->getString()->copy(); + + // destination dictionary + } else if (destObj->isArray()) { + dest = new LinkDest(destObj->getArray(), gTrue); + if (!dest->isOk()) { + delete dest; + dest = NULL; + } + + // error + } else { + error(-1, "Illegal annotation destination"); + } +} + +LinkGoTo::~LinkGoTo() { + if (dest) + delete dest; + if (namedDest) + delete namedDest; +} + +//------------------------------------------------------------------------ +// LinkGoToR +//------------------------------------------------------------------------ + +LinkGoToR::LinkGoToR(Object *fileSpecObj, Object *destObj) { + dest = NULL; + namedDest = NULL; + + // get file name + fileName = getFileSpecName(fileSpecObj); + + // named destination + if (destObj->isName()) { + namedDest = new GString(destObj->getName()); + } else if (destObj->isString()) { + namedDest = destObj->getString()->copy(); + + // destination dictionary + } else if (destObj->isArray()) { + dest = new LinkDest(destObj->getArray(), gFalse); + if (!dest->isOk()) { + delete dest; + dest = NULL; + } + + // error + } else { + error(-1, "Illegal annotation destination"); + } +} + +LinkGoToR::~LinkGoToR() { + if (fileName) + delete fileName; + if (dest) + delete dest; + if (namedDest) + delete namedDest; +} + + +//------------------------------------------------------------------------ +// LinkLaunch +//------------------------------------------------------------------------ + +LinkLaunch::LinkLaunch(Object *actionObj) { + Object obj1, obj2; + + fileName = NULL; + params = NULL; + + if (actionObj->isDict()) { + if (!actionObj->dictLookup("F", &obj1)->isNull()) { + fileName = getFileSpecName(&obj1); + } else { + obj1.free(); + //~ This hasn't been defined by Adobe yet, so assume it looks + //~ just like the Win dictionary until they say otherwise. + if (actionObj->dictLookup("Unix", &obj1)->isDict()) { + obj1.dictLookup("F", &obj2); + fileName = getFileSpecName(&obj2); + obj2.free(); + if (obj1.dictLookup("P", &obj2)->isString()) + params = obj2.getString()->copy(); + obj2.free(); + } else { + error(-1, "Bad launch-type link action"); + } + } + obj1.free(); + } +} + +LinkLaunch::~LinkLaunch() { + if (fileName) + delete fileName; + if (params) + delete params; +} + +//------------------------------------------------------------------------ +// LinkURI +//------------------------------------------------------------------------ + +LinkURI::LinkURI(Object *uriObj, GString *baseURI) { + GString *uri2; + int n; + char c; + + uri = NULL; + if (uriObj->isString()) { + uri2 = uriObj->getString()->copy(); + if (baseURI) { + n = strcspn(uri2->getCString(), "/:"); + if (n == uri2->getLength() || uri2->getChar(n) == '/') { + uri = baseURI->copy(); + c = uri->getChar(uri->getLength() - 1); + if (c == '/' || c == '?') { + if (uri2->getChar(0) == '/') { + uri2->del(0); + } + } else { + if (uri2->getChar(0) != '/') { + uri->append('/'); + } + } + uri->append(uri2); + delete uri2; + } else { + uri = uri2; + } + } else { + uri = uri2; + } + } else { + error(-1, "Illegal URI-type link"); + } +} + +LinkURI::~LinkURI() { + if (uri) + delete uri; +} + +//------------------------------------------------------------------------ +// LinkUnknown +//------------------------------------------------------------------------ + +LinkUnknown::LinkUnknown(char *action1) { + action = new GString(action1); +} + +LinkUnknown::~LinkUnknown() { + delete action; +} + +//------------------------------------------------------------------------ +// Link +//------------------------------------------------------------------------ + +Link::Link(Dict *dict, GString *baseURI) { + Object obj1, obj2, obj3, obj4; + double t; + + action = NULL; + ok = gFalse; + + // get rectangle + if (!dict->lookup("Rect", &obj1)->isArray()) { + error(-1, "Annotation rectangle is wrong type"); + goto err2; + } + if (!obj1.arrayGet(0, &obj2)->isNum()) { + error(-1, "Bad annotation rectangle"); + goto err1; + } + x1 = obj2.getNum(); + obj2.free(); + if (!obj1.arrayGet(1, &obj2)->isNum()) { + error(-1, "Bad annotation rectangle"); + goto err1; + } + y1 = obj2.getNum(); + obj2.free(); + if (!obj1.arrayGet(2, &obj2)->isNum()) { + error(-1, "Bad annotation rectangle"); + goto err1; + } + x2 = obj2.getNum(); + obj2.free(); + if (!obj1.arrayGet(3, &obj2)->isNum()) { + error(-1, "Bad annotation rectangle"); + goto err1; + } + y2 = obj2.getNum(); + obj2.free(); + obj1.free(); + if (x1 > x2) { + t = x1; + x1 = x2; + x2 = t; + } + if (y1 > y2) { + t = y1; + y1 = y2; + y2 = t; + } + + // get border + borderW = 0; + if (!dict->lookup("Border", &obj1)->isNull()) { + if (obj1.isArray() && obj1.arrayGet(2, &obj2)->isNum()) + borderW = obj2.getNum(); + else + error(-1, "Bad annotation border"); + obj2.free(); + } + obj1.free(); + + // look for destination + if (!dict->lookup("Dest", &obj1)->isNull()) { + action = new LinkGoTo(&obj1); + + // look for action + } else { + obj1.free(); + if (dict->lookup("A", &obj1)->isDict()) { + obj1.dictLookup("S", &obj2); + + // GoTo action + if (obj2.isName("GoTo")) { + obj1.dictLookup("D", &obj3); + action = new LinkGoTo(&obj3); + obj3.free(); + + // GoToR action + } else if (obj2.isName("GoToR")) { + obj1.dictLookup("F", &obj3); + obj1.dictLookup("D", &obj4); + action = new LinkGoToR(&obj3, &obj4); + obj3.free(); + obj4.free(); + + // Launch action + } else if (obj2.isName("Launch")) { + action = new LinkLaunch(&obj1); + + // URI action + } else if (obj2.isName("URI")) { + obj1.dictLookup("URI", &obj3); + action = new LinkURI(&obj3, baseURI); + obj3.free(); + + // unknown action + } else if (obj2.isName()) { + action = new LinkUnknown(obj2.getName()); + + // action is missing or wrong type + } else { + error(-1, "Bad annotation action"); + action = NULL; + } + + obj2.free(); + + } else { + error(-1, "Missing annotation destination/action"); + action = NULL; + } + } + obj1.free(); + + // check for bad action + if (action && action->isOk()) + ok = gTrue; + + return; + + err1: + obj2.free(); + err2: + obj1.free(); +} + +Link::~Link() { + if (action) + delete action; +} + +//------------------------------------------------------------------------ +// Links +//------------------------------------------------------------------------ + +Links::Links(Object *annots, GString *baseURI) { + Link *link; + Object obj1, obj2; + int size; + int i; + + links = NULL; + size = 0; + numLinks = 0; + + if (annots->isArray()) { + for (i = 0; i < annots->arrayGetLength(); ++i) { + if (annots->arrayGet(i, &obj1)->isDict()) { + if (obj1.dictLookup("Subtype", &obj2)->isName("Link")) { + link = new Link(obj1.getDict(), baseURI); + if (link->isOk()) { + if (numLinks >= size) { + size += 16; + links = (Link **)grealloc(links, size * sizeof(Link *)); + } + links[numLinks++] = link; + } else { + delete link; + } + } + obj2.free(); + } + obj1.free(); + } + } +} + +Links::~Links() { + int i; + + for (i = 0; i < numLinks; ++i) + delete links[i]; + gfree(links); +} + +LinkAction *Links::find(double x, double y) { + int i; + + for (i = 0; i < numLinks; ++i) { + if (links[i]->inRect(x, y)) { + if (links[i]->getAction()) + return links[i]->getAction(); + return NULL; + } + } + return NULL; +} + +GBool Links::onLink(double x, double y) { + int i; + + for (i = 0; i < numLinks; ++i) { + if (links[i]->inRect(x, y)) + return gTrue; + } + return gFalse; +} + +//------------------------------------------------------------------------ + +// Extract a file name from a file specification (string or dictionary). +static GString *getFileSpecName(Object *fileSpecObj) { + GString *name; + Object obj1; + + name = NULL; + + // string + if (fileSpecObj->isString()) { + name = fileSpecObj->getString()->copy(); + + // dictionary + } else if (fileSpecObj->isDict()) { + if (!fileSpecObj->dictLookup("Unix", &obj1)->isString()) { + obj1.free(); + fileSpecObj->dictLookup("F", &obj1); + } + if (obj1.isString()) + name = obj1.getString()->copy(); + else + error(-1, "Illegal file spec in link"); + obj1.free(); + + // error + } else { + error(-1, "Illegal file spec in link"); + } + + return name; +} diff --git a/pdftops/Link.h b/pdftops/Link.h new file mode 100644 index 0000000000..71ad0c5cd1 --- /dev/null +++ b/pdftops/Link.h @@ -0,0 +1,313 @@ +//======================================================================== +// +// Link.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef LINK_H +#define LINK_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "Object.h" + +class GString; +class Array; +class Dict; + +//------------------------------------------------------------------------ +// LinkAction +//------------------------------------------------------------------------ + +enum LinkActionKind { + actionGoTo, // go to destination + actionGoToR, // go to destination in new file + actionLaunch, // launch app (or open document) + actionURI, // URI + actionUnknown // anything else +}; + +class LinkAction { +public: + + // Destructor. + virtual ~LinkAction() {} + + // Was the LinkAction created successfully? + virtual GBool isOk() = 0; + + // Check link action type. + virtual LinkActionKind getKind() = 0; +}; + +//------------------------------------------------------------------------ +// LinkDest +//------------------------------------------------------------------------ + +enum LinkDestKind { + destXYZ, + destFit, + destFitH, + destFitV, + destFitR, + destFitB, + destFitBH, + destFitBV +}; + +class LinkDest { +public: + + // Build a LinkDest from the array. If is true, the + // page is specified by an object reference; otherwise the page is + // specified by a (zero-relative) page number. + LinkDest(Array *a, GBool pageIsRef1); + + // Copy a LinkDest. + LinkDest *copy() { return new LinkDest(this); } + + // Was the LinkDest created successfully? + GBool isOk() { return ok; } + + // Accessors. + LinkDestKind getKind() { return kind; } + GBool isPageRef() { return pageIsRef; } + int getPageNum() { return pageNum; } + Ref getPageRef() { return pageRef; } + double getLeft() { return left; } + double getBottom() { return bottom; } + double getRight() { return right; } + double getTop() { return top; } + double getZoom() { return zoom; } + GBool getChangeLeft() { return changeLeft; } + GBool getChangeTop() { return changeTop; } + GBool getChangeZoom() { return changeZoom; } + +private: + + LinkDestKind kind; // destination type + GBool pageIsRef; // is the page a reference or number? + union { + Ref pageRef; // reference to page + int pageNum; // one-relative page number + }; + double left, bottom; // position + double right, top; + double zoom; // zoom factor + GBool changeLeft, changeTop; // for destXYZ links, which position + GBool changeZoom; // components to change + GBool ok; // set if created successfully + + LinkDest(LinkDest *dest); +}; + +//------------------------------------------------------------------------ +// LinkGoTo +//------------------------------------------------------------------------ + +class LinkGoTo: public LinkAction { +public: + + // Build a LinkGoTo from a destination (dictionary, name, or string). + LinkGoTo(Object *destObj); + + // Destructor. + virtual ~LinkGoTo(); + + // Was the LinkGoTo created successfully? + virtual GBool isOk() { return dest || namedDest; } + + // Accessors. + virtual LinkActionKind getKind() { return actionGoTo; } + LinkDest *getDest() { return dest; } + GString *getNamedDest() { return namedDest; } + +private: + + LinkDest *dest; // regular destination (NULL for remote + // link with bad destination) + GString *namedDest; // named destination (only one of dest and + // and namedDest may be non-NULL) +}; + +//------------------------------------------------------------------------ +// LinkGoToR +//------------------------------------------------------------------------ + +class LinkGoToR: public LinkAction { +public: + + // Build a LinkGoToR from a file spec (dictionary) and destination + // (dictionary, name, or string). + LinkGoToR(Object *fileSpecObj, Object *destObj); + + // Destructor. + virtual ~LinkGoToR(); + + // Was the LinkGoToR created successfully? + virtual GBool isOk() { return fileName && (dest || namedDest); } + + // Accessors. + virtual LinkActionKind getKind() { return actionGoToR; } + GString *getFileName() { return fileName; } + LinkDest *getDest() { return dest; } + GString *getNamedDest() { return namedDest; } + +private: + + GString *fileName; // file name + LinkDest *dest; // regular destination (NULL for remote + // link with bad destination) + GString *namedDest; // named destination (only one of dest and + // and namedDest may be non-NULL) +}; + +//------------------------------------------------------------------------ +// LinkLaunch +//------------------------------------------------------------------------ + +class LinkLaunch: public LinkAction { +public: + + // Build a LinkLaunch from an action dictionary. + LinkLaunch(Object *actionObj); + + // Destructor. + virtual ~LinkLaunch(); + + // Was the LinkLaunch created successfully? + virtual GBool isOk() { return fileName != NULL; } + + // Accessors. + virtual LinkActionKind getKind() { return actionLaunch; } + GString *getFileName() { return fileName; } + GString *getParams() { return params; } + +private: + + GString *fileName; // file name + GString *params; // parameters +}; + +//------------------------------------------------------------------------ +// LinkURI +//------------------------------------------------------------------------ + +class LinkURI: public LinkAction { +public: + + // Build a LinkURI given the URI (string) and base URI. + LinkURI(Object *uriObj, GString *baseURI); + + // Destructor. + virtual ~LinkURI(); + + // Was the LinkURI created successfully? + virtual GBool isOk() { return uri != NULL; } + + // Accessors. + virtual LinkActionKind getKind() { return actionURI; } + GString *getURI() { return uri; } + +private: + + GString *uri; // the URI +}; + +//------------------------------------------------------------------------ +// LinkUnknown +//------------------------------------------------------------------------ + +class LinkUnknown: public LinkAction { +public: + + // Build a LinkUnknown with the specified action type. + LinkUnknown(char *action1); + + // Destructor. + virtual ~LinkUnknown(); + + // Was the LinkUnknown create successfully? + virtual GBool isOk() { return action != NULL; } + + // Accessors. + virtual LinkActionKind getKind() { return actionUnknown; } + GString *getAction() { return action; } + +private: + + GString *action; // action subtype +}; + +//------------------------------------------------------------------------ +// Link +//------------------------------------------------------------------------ + +class Link { +public: + + // Construct a link, given its dictionary. + Link(Dict *dict, GString *baseURI); + + // Destructor. + ~Link(); + + // Was the link created successfully? + GBool isOk() { return ok; } + + // Check if point is inside the link rectangle. + GBool inRect(double x, double y) + { return x1 <= x && x <= x2 && y1 <= y && y <= y2; } + + // Get action. + LinkAction *getAction() { return action; } + + // Get border corners and width. + void getBorder(double *xa1, double *ya1, double *xa2, double *ya2, + double *wa) + { *xa1 = x1; *ya1 = y1; *xa2 = x2; *ya2 = y2; *wa = borderW; } + +private: + + double x1, y1; // lower left corner + double x2, y2; // upper right corner + double borderW; // border width + LinkAction *action; // action + GBool ok; // is link valid? +}; + +//------------------------------------------------------------------------ +// Links +//------------------------------------------------------------------------ + +class Links { +public: + + // Extract links from array of annotations. + Links(Object *annots, GString *baseURI); + + // Destructor. + ~Links(); + + // Iterate through list of links. + int getNumLinks() { return numLinks; } + Link *getLink(int i) { return links[i]; } + + // If point , is in a link, return the associated action; + // else return NULL. + LinkAction *find(double x, double y); + + // Return true if , is in a link. + GBool onLink(double x, double y); + +private: + + Link **links; + int numLinks; +}; + +#endif diff --git a/pdftops/Makefile b/pdftops/Makefile new file mode 100644 index 0000000000..b06bcf0516 --- /dev/null +++ b/pdftops/Makefile @@ -0,0 +1,128 @@ +# +# "$Id$" +# +# pdftops filter Makefile for the Common UNIX Printing System (CUPS). +# +# CUPS filter changes Copyright 2000 by Easy Software Products. +# Xpdf code Copyright 1996-1999 by Derek B. Noonburg +# + + +include ../Makedefs + +# +# Object files... +# + +LIBOBJS = GString.o gfile.o gmempp.o gmem.o parseargs.o \ + Array.o Catalog.o Dict.o Error.o FontEncoding.o \ + FontFile.o Gfx.o GfxFont.o GfxState.o Lexer.o Link.o \ + Object.o OutputDev.o Page.o Params.o Parser.o PDFDoc.o \ + PSOutputDev.o Stream.o XRef.o +OBJS = pdftops.o $(LIBOBJS) + +# +# Make everything... +# + +all: pdftops + + +# +# Clean all object files... +# + +clean: + $(RM) $(OBJS) + $(RM) pdftops + + +# +# Install the filter... +# + +install: + $(MKDIR) $(SERVERBIN)/filter + $(CHMOD) ugo+rx $(SERVERBIN) + $(CHMOD) ugo+rx $(SERVERBIN)/filter + $(RM) $(SERVERBIN)/filter/pdftops + $(INSTALL_BIN) pdftops $(SERVERBIN)/filter + + +# +# pdftops +# + +pdftops: libxpdf.a pdftops.o ../cups/$(LIBCUPS) + echo Linking $@... + $(CXX) $(LDFLAGS) -o $@ pdftops.o libxpdf.a $(LIBS) -lm + +pdftops.o: parseargs.h gtypes.h GString.h gmem.h Object.h Array.h \ + Dict.h Stream.h XRef.h Catalog.h Page.h PDFDoc.h Link.h \ + PSOutputDev.h config.h OutputDev.h Params.h Error.h + + +# +# libxpdf.a +# + +libxpdf.a: $(LIBOBJS) + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + +GString.o: GString.h +gmempp.o: gmem.h +gfile.o: GString.h gfile.h gtypes.h +gmem.o: gmem.h +parseargs.o: parseargs.h gtypes.h +Array.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h +Catalog.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h \ + Page.h Error.h config.h Link.h Catalog.h +Dict.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h \ + XRef.h +Error.o: gtypes.h Params.h Error.h config.h +FontEncoding.o: gmem.h FontEncoding.h gtypes.h +FontFile.o: gmem.h Error.h config.h FontFile.h gtypes.h GString.h \ + FontEncoding.h StdFontInfo.h CompactFontInfo.h +Gfx.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h \ + Lexer.h Parser.h GfxFont.h FontEncoding.h GfxState.h \ + OutputDev.h Params.h Error.h config.h Gfx.h +GfxFont.o: GString.h gmem.h gfile.h gtypes.h config.h Object.h Array.h \ + Dict.h Stream.h Error.h Params.h FontFile.h FontEncoding.h \ + GfxFont.h FontInfo.h +GfxState.o: gmem.h Error.h config.h Object.h gtypes.h GString.h Array.h \ + Dict.h Stream.h GfxState.h +ImageOutputDev.o: gmem.h config.h Error.h GfxState.h gtypes.h Object.h \ + GString.h Array.h Dict.h Stream.h ImageOutputDev.h OutputDev.h +Lexer.o: Lexer.h Object.h gtypes.h gmem.h GString.h Array.h Dict.h \ + Stream.h Error.h config.h +Link.o: gmem.h GString.h Error.h config.h Object.h gtypes.h Array.h \ + Dict.h Stream.h Link.h +Object.o: Object.h gtypes.h gmem.h GString.h Array.h Dict.h Stream.h \ + Error.h config.h XRef.h +OutputDev.o: Object.h gtypes.h gmem.h GString.h Array.h Dict.h Stream.h \ + GfxState.h OutputDev.h +Page.o: Object.h gtypes.h gmem.h GString.h Array.h Dict.h Stream.h \ + XRef.h OutputDev.h Gfx.h Error.h config.h Params.h Page.h +Params.o: gtypes.h gmem.h GString.h gfile.h Params.h +Parser.o: Object.h gtypes.h gmem.h GString.h Array.h Dict.h Stream.h \ + Parser.h Lexer.h Error.h config.h +PDFDoc.o: GString.h config.h Page.h Object.h gtypes.h gmem.h Array.h \ + Dict.h Stream.h Catalog.h XRef.h Link.h OutputDev.h Params.h \ + Error.h PDFDoc.h +PSOutputDev.o: GString.h config.h Object.h gtypes.h gmem.h Array.h Dict.h \ + Stream.h Error.h GfxState.h GfxFont.h FontEncoding.h \ + FontFile.h Catalog.h Page.h PSOutputDev.h OutputDev.h +Stream.o: gmem.h config.h Error.h Object.h gtypes.h GString.h Array.h \ + Dict.h Stream.h Stream-CCITT.h +XRef.o: gmem.h Object.h gtypes.h GString.h Array.h Dict.h Stream.h \ + Lexer.h Parser.h Error.h config.h XRef.h + + +$(OBJS): ../config.h ../Makedefs + +# +# End of "$Id$". +# diff --git a/pdftops/Object.cxx b/pdftops/Object.cxx new file mode 100644 index 0000000000..f9c10674d8 --- /dev/null +++ b/pdftops/Object.cxx @@ -0,0 +1,220 @@ +//======================================================================== +// +// Object.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Error.h" +#include "Stream.h" +#include "XRef.h" + +//------------------------------------------------------------------------ +// Object +//------------------------------------------------------------------------ + +char *objTypeNames[numObjTypes] = { + "boolean", + "integer", + "real", + "string", + "name", + "null", + "array", + "dictionary", + "stream", + "ref", + "cmd", + "error", + "eof", + "none" +}; + +#ifdef DEBUG_MEM +int Object::numAlloc[numObjTypes] = + {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; +#endif + +Object *Object::initArray() { + initObj(objArray); + array = new Array(); + return this; +} + +Object *Object::initDict() { + initObj(objDict); + dict = new Dict(); + return this; +} + +Object *Object::initStream(Stream *stream1) { + initObj(objStream); + stream = stream1; + return this; +} + +Object *Object::copy(Object *obj) { + *obj = *this; + switch (type) { + case objString: + obj->string = string->copy(); + break; + case objName: + obj->name = copyString(name); + break; + case objArray: + array->incRef(); + break; + case objDict: + dict->incRef(); + break; + case objStream: + stream->incRef(); + break; + case objCmd: + obj->cmd = copyString(cmd); + break; + default: + break; + } +#ifdef DEBUG_MEM + ++numAlloc[type]; +#endif + return obj; +} + +Object *Object::fetch(Object *obj) { + return (type == objRef && xref) ? + xref->fetch(ref.num, ref.gen, obj) : copy(obj); +} + +void Object::free() { + switch (type) { + case objString: + delete string; + break; + case objName: + gfree(name); + break; + case objArray: + if (!array->decRef()) { + delete array; + } + break; + case objDict: + if (!dict->decRef()) { + delete dict; + } + break; + case objStream: + if (!stream->decRef()) { + delete stream; + } + break; + case objCmd: + gfree(cmd); + break; + default: + break; + } +#ifdef DEBUG_MEM + --numAlloc[type]; +#endif + type = objNone; +} + +char *Object::getTypeName() { + return objTypeNames[type]; +} + +void Object::print(FILE *f) { + Object obj; + int i; + + switch (type) { + case objBool: + fprintf(f, "%s", booln ? "true" : "false"); + break; + case objInt: + fprintf(f, "%d", intg); + break; + case objReal: + fprintf(f, "%g", real); + break; + case objString: + fprintf(f, "(%s)", string->getCString()); + break; + case objName: + fprintf(f, "/%s", name); + break; + case objNull: + fprintf(f, "null"); + break; + case objArray: + fprintf(f, "["); + for (i = 0; i < arrayGetLength(); ++i) { + if (i > 0) + fprintf(f, " "); + arrayGetNF(i, &obj); + obj.print(f); + obj.free(); + } + fprintf(f, "]"); + break; + case objDict: + fprintf(f, "<<"); + for (i = 0; i < dictGetLength(); ++i) { + fprintf(f, " /%s ", dictGetKey(i)); + dictGetValNF(i, &obj); + obj.print(f); + obj.free(); + } + fprintf(f, " >>"); + break; + case objStream: + fprintf(f, ""); + break; + case objRef: + fprintf(f, "%d %d R", ref.num, ref.gen); + break; + case objCmd: + fprintf(f, "%s", cmd); + break; + case objError: + fprintf(f, ""); + break; + case objEOF: + fprintf(f, ""); + break; + case objNone: + fprintf(f, ""); + break; + } +} + +void Object::memCheck(FILE *f) { +#ifdef DEBUG_MEM + int i; + int t; + + t = 0; + for (i = 0; i < numObjTypes; ++i) + t += numAlloc[i]; + if (t > 0) { + fprintf(f, "Allocated objects:\n"); + for (i = 0; i < numObjTypes; ++i) { + if (numAlloc[i] > 0) + fprintf(f, " %-20s: %6d\n", objTypeNames[i], numAlloc[i]); + } + } +#endif +} diff --git a/pdftops/Object.h b/pdftops/Object.h new file mode 100644 index 0000000000..395096fb00 --- /dev/null +++ b/pdftops/Object.h @@ -0,0 +1,299 @@ +//======================================================================== +// +// Object.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef OBJECT_H +#define OBJECT_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include +#include +#include "gtypes.h" +#include "gmem.h" +#include "GString.h" + +class Array; +class Dict; +class Stream; + +//------------------------------------------------------------------------ +// Ref +//------------------------------------------------------------------------ + +struct Ref { + int num; // object number + int gen; // generation number +}; + +//------------------------------------------------------------------------ +// object types +//------------------------------------------------------------------------ + +enum ObjType { + // simple objects + objBool, // boolean + objInt, // integer + objReal, // real + objString, // string + objName, // name + objNull, // null + + // complex objects + objArray, // array + objDict, // dictionary + objStream, // stream + objRef, // indirect reference + + // special objects + objCmd, // command name + objError, // error return from Lexer + objEOF, // end of file return from Lexer + objNone // uninitialized object +}; + +#define numObjTypes 14 // total number of object types + +//------------------------------------------------------------------------ +// Object +//------------------------------------------------------------------------ + +#ifdef DEBUG_MEM +#define initObj(t) ++numAlloc[type = t] +#else +#define initObj(t) type = t +#endif + +class Object { +public: + + // Default constructor. + Object(): + type(objNone) {} + + // Initialize an object. + Object *initBool(GBool booln1) + { initObj(objBool); booln = booln1; return this; } + Object *initInt(int intg1) + { initObj(objInt); intg = intg1; return this; } + Object *initReal(double real1) + { initObj(objReal); real = real1; return this; } + Object *initString(GString *string1) + { initObj(objString); string = string1; return this; } + Object *initName(char *name1) + { initObj(objName); name = copyString(name1); return this; } + Object *initNull() + { initObj(objNull); return this; } + Object *initArray(); + Object *initDict(); + Object *initDict(Dict *dict1) + { initObj(objDict); dict = dict1; return this; } + Object *initStream(Stream *stream1); + Object *initRef(int num1, int gen1) + { initObj(objRef); ref.num = num1; ref.gen = gen1; return this; } + Object *initCmd(char *cmd1) + { initObj(objCmd); cmd = copyString(cmd1); return this; } + Object *initError() + { initObj(objError); return this; } + Object *initEOF() + { initObj(objEOF); return this; } + + // Copy an object. + Object *copy(Object *obj); + + // If object is a Ref, fetch and return the referenced object. + // Otherwise, return a copy of the object. + Object *fetch(Object *obj); + + // Free object contents. + void free(); + + // Type checking. + GBool isBool() { return type == objBool; } + GBool isInt() { return type == objInt; } + GBool isReal() { return type == objReal; } + GBool isNum() { return type == objInt || type == objReal; } + GBool isString() { return type == objString; } + GBool isName() { return type == objName; } + GBool isNull() { return type == objNull; } + GBool isArray() { return type == objArray; } + GBool isDict() { return type == objDict; } + GBool isStream() { return type == objStream; } + GBool isRef() { return type == objRef; } + GBool isCmd() { return type == objCmd; } + GBool isError() { return type == objError; } + GBool isEOF() { return type == objEOF; } + GBool isNone() { return type == objNone; } + + // Special type checking. + GBool isName(char *name1) + { return type == objName && !strcmp(name, name1); } + GBool isDict(char *dictType); + GBool isStream(char *dictType); + GBool isCmd(char *cmd1) + { return type == objCmd && !strcmp(cmd, cmd1); } + + // Accessors. NB: these assume object is of correct type. + GBool getBool() { return booln; } + int getInt() { return intg; } + double getReal() { return real; } + double getNum() { return type == objInt ? (double)intg : real; } + GString *getString() { return string; } + char *getName() { return name; } + Array *getArray() { return array; } + Dict *getDict() { return dict; } + Stream *getStream() { return stream; } + Ref getRef() { return ref; } + int getRefNum() { return ref.num; } + int getRefGen() { return ref.gen; } + + // Array accessors. + int arrayGetLength(); + void arrayAdd(Object *elem); + Object *arrayGet(int i, Object *obj); + Object *arrayGetNF(int i, Object *obj); + + // Dict accessors. + int dictGetLength(); + void dictAdd(char *key, Object *val); + GBool dictIs(char *dictType); + Object *dictLookup(char *key, Object *obj); + Object *dictLookupNF(char *key, Object *obj); + char *dictGetKey(int i); + Object *dictGetVal(int i, Object *obj); + Object *dictGetValNF(int i, Object *obj); + + // Stream accessors. + GBool streamIs(char *dictType); + void streamReset(); + int streamGetChar(); + int streamLookChar(); + char *streamGetLine(char *buf, int size); + int streamGetPos(); + void streamSetPos(int pos); + FILE *streamGetFile(); + Dict *streamGetDict(); + + // Output. + char *getTypeName(); + void print(FILE *f = stdout); + + // Memory testing. + static void memCheck(FILE *f); + +private: + + ObjType type; // object type + union { // value for each type: + GBool booln; // boolean + int intg; // integer + double real; // real + GString *string; // string + char *name; // name + Array *array; // array + Dict *dict; // dictionary + Stream *stream; // stream + Ref ref; // indirect reference + char *cmd; // command + }; + +#ifdef DEBUG_MEM + static int // number of each type of object + numAlloc[numObjTypes]; // currently allocated +#endif +}; + +//------------------------------------------------------------------------ +// Array accessors. +//------------------------------------------------------------------------ + +#include "Array.h" + +inline int Object::arrayGetLength() + { return array->getLength(); } + +inline void Object::arrayAdd(Object *elem) + { array->add(elem); } + +inline Object *Object::arrayGet(int i, Object *obj) + { return array->get(i, obj); } + +inline Object *Object::arrayGetNF(int i, Object *obj) + { return array->getNF(i, obj); } + +//------------------------------------------------------------------------ +// Dict accessors. +//------------------------------------------------------------------------ + +#include "Dict.h" + +inline int Object::dictGetLength() + { return dict->getLength(); } + +inline void Object::dictAdd(char *key, Object *val) + { dict->add(key, val); } + +inline GBool Object::dictIs(char *dictType) + { return dict->is(dictType); } + +inline GBool Object::isDict(char *dictType) + { return type == objDict && dictIs(dictType); } + +inline Object *Object::dictLookup(char *key, Object *obj) + { return dict->lookup(key, obj); } + +inline Object *Object::dictLookupNF(char *key, Object *obj) + { return dict->lookupNF(key, obj); } + +inline char *Object::dictGetKey(int i) + { return dict->getKey(i); } + +inline Object *Object::dictGetVal(int i, Object *obj) + { return dict->getVal(i, obj); } + +inline Object *Object::dictGetValNF(int i, Object *obj) + { return dict->getValNF(i, obj); } + +//------------------------------------------------------------------------ +// Stream accessors. +//------------------------------------------------------------------------ + +#include "Stream.h" + +inline GBool Object::streamIs(char *dictType) + { return stream->getDict()->is(dictType); } + +inline GBool Object::isStream(char *dictType) + { return type == objStream && streamIs(dictType); } + +inline void Object::streamReset() + { stream->reset(); } + +inline int Object::streamGetChar() + { return stream->getChar(); } + +inline int Object::streamLookChar() + { return stream->lookChar(); } + +inline char *Object::streamGetLine(char *buf, int size) + { return stream->getLine(buf, size); } + +inline int Object::streamGetPos() + { return stream->getPos(); } + +inline void Object::streamSetPos(int pos) + { stream->setPos(pos); } + +inline FILE *Object::streamGetFile() + { return stream->getFile(); } + +inline Dict *Object::streamGetDict() + { return stream->getDict(); } + +#endif diff --git a/pdftops/OutputDev.cxx b/pdftops/OutputDev.cxx new file mode 100644 index 0000000000..95c5628e21 --- /dev/null +++ b/pdftops/OutputDev.cxx @@ -0,0 +1,85 @@ +//======================================================================== +// +// OutputDev.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include "Object.h" +#include "Stream.h" +#include "GfxState.h" +#include "OutputDev.h" + +//------------------------------------------------------------------------ +// OutputDev +//------------------------------------------------------------------------ + +void OutputDev::setDefaultCTM(double *ctm1) { + int i; + double det; + + for (i = 0; i < 6; ++i) + ctm[i] = ctm1[i]; + det = 1 / (ctm[0] * ctm[3] - ctm[1] * ctm[2]); + ictm[0] = ctm[3] * det; + ictm[1] = -ctm[1] * det; + ictm[2] = -ctm[2] * det; + ictm[3] = ctm[0] * det; + ictm[4] = (ctm[2] * ctm[5] - ctm[3] * ctm[4]) * det; + ictm[5] = (ctm[1] * ctm[4] - ctm[0] * ctm[5]) * det; +} + +void OutputDev::cvtDevToUser(int dx, int dy, double *ux, double *uy) { + *ux = ictm[0] * dx + ictm[2] * dy + ictm[4]; + *uy = ictm[1] * dx + ictm[3] * dy + ictm[5]; +} + +void OutputDev::cvtUserToDev(double ux, double uy, int *dx, int *dy) { + *dx = (int)(ctm[0] * ux + ctm[2] * uy + ctm[4] + 0.5); + *dy = (int)(ctm[1] * ux + ctm[3] * uy + ctm[5] + 0.5); +} + +void OutputDev::updateAll(GfxState *state) { + updateLineDash(state); + updateFlatness(state); + updateLineJoin(state); + updateLineCap(state); + updateMiterLimit(state); + updateLineWidth(state); + updateFillColor(state); + updateStrokeColor(state); + updateFont(state); +} + +void OutputDev::drawImageMask(GfxState *state, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) { + int i, j; + + if (inlineImg) { + str->reset(); + j = height * ((width + 7) / 8); + for (i = 0; i < j; ++i) + str->getChar(); + } +} + +void OutputDev::drawImage(GfxState *state, Stream *str, int width, + int height, GfxImageColorMap *colorMap, + GBool inlineImg) { + int i, j; + + if (inlineImg) { + str->reset(); + j = height * ((width * colorMap->getNumPixelComps() * + colorMap->getBits() + 7) / 8); + for (i = 0; i < j; ++i) + str->getChar(); + } +} diff --git a/pdftops/OutputDev.h b/pdftops/OutputDev.h new file mode 100644 index 0000000000..98afaff64c --- /dev/null +++ b/pdftops/OutputDev.h @@ -0,0 +1,131 @@ +//======================================================================== +// +// OutputDev.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef OUTPUTDEV_H +#define OUTPUTDEV_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "gtypes.h" + +class GString; +class GfxState; +class GfxColorSpace; +class GfxImageColorMap; +class Stream; + +//------------------------------------------------------------------------ +// OutputDev +//------------------------------------------------------------------------ + +class OutputDev { +public: + + // Constructor. + OutputDev() {} + + // Destructor. + virtual ~OutputDev() {} + + //----- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() = 0; + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() = 0; + + //----- initialization and control + + // Set default transform matrix. + virtual void setDefaultCTM(double *ctm1); + + // Start a page. + virtual void startPage(int pageNum, GfxState *state) {} + + // End a page. + virtual void endPage() {} + + // Dump page contents to display. + virtual void dump() {} + + //----- coordinate conversion + + // Convert between device and user coordinates. + virtual void cvtDevToUser(int dx, int dy, double *ux, double *uy); + virtual void cvtUserToDev(double ux, double uy, int *dx, int *dy); + + //----- link borders + virtual void drawLinkBorder(double x1, double y1, double x2, double y2, + double w) {} + + //----- save/restore graphics state + virtual void saveState(GfxState *state) {} + virtual void restoreState(GfxState *state) {} + + //----- update graphics state + virtual void updateAll(GfxState *state); + virtual void updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, double m31, double m32) {} + virtual void updateLineDash(GfxState *state) {} + virtual void updateFlatness(GfxState *state) {} + virtual void updateLineJoin(GfxState *state) {} + virtual void updateLineCap(GfxState *state) {} + virtual void updateMiterLimit(GfxState *state) {} + virtual void updateLineWidth(GfxState *state) {} + virtual void updateFillColor(GfxState *state) {} + virtual void updateStrokeColor(GfxState *state) {} + + //----- update text state + virtual void updateFont(GfxState *state) {} + virtual void updateTextMat(GfxState *state) {} + virtual void updateCharSpace(GfxState *state) {} + virtual void updateRender(GfxState *state) {} + virtual void updateRise(GfxState *state) {} + virtual void updateWordSpace(GfxState *state) {} + virtual void updateHorizScaling(GfxState *state) {} + virtual void updateTextPos(GfxState *state) {} + virtual void updateTextShift(GfxState *state, double shift) {} + + //----- path painting + virtual void stroke(GfxState *state) {} + virtual void fill(GfxState *state) {} + virtual void eoFill(GfxState *state) {} + + //----- path clipping + virtual void clip(GfxState *state) {} + virtual void eoClip(GfxState *state) {} + + //----- text drawing + virtual void beginString(GfxState *state, GString *s) {} + virtual void endString(GfxState *state) {} + virtual void drawChar(GfxState *state, double x, double y, + double dx, double dy, Guchar c) {} + virtual void drawChar16(GfxState *state, double x, double y, + double dx, double dy, int c) {} + virtual void drawString(GfxState *state, GString *s) {} + virtual void drawString16(GfxState *state, GString *s) {} + + //----- image drawing + virtual void drawImageMask(GfxState *state, Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Stream *str, int width, + int height, GfxImageColorMap *colorMap, + GBool inlineImg); + +private: + + double ctm[6]; // coordinate transform matrix + double ictm[6]; // inverse CTM +}; + +#endif diff --git a/pdftops/PDFDoc.cxx b/pdftops/PDFDoc.cxx new file mode 100644 index 0000000000..1537c6a322 --- /dev/null +++ b/pdftops/PDFDoc.cxx @@ -0,0 +1,169 @@ +//======================================================================== +// +// PDFDoc.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include "GString.h" +#include "config.h" +#include "Page.h" +#include "Catalog.h" +#include "XRef.h" +#include "Link.h" +#include "OutputDev.h" +#include "Params.h" +#include "Error.h" +#include "PDFDoc.h" + +//------------------------------------------------------------------------ +// PDFDoc +//------------------------------------------------------------------------ + +PDFDoc::PDFDoc(GString *fileName1) { + FileStream *str; + Object catObj; + Object obj; + GString *fileName2; + + // setup + ok = gFalse; + catalog = NULL; + xref = NULL; + file = NULL; + links = NULL; + + // try to open file + fileName = fileName1; + fileName2 = NULL; +#ifdef VMS + if (!(file = fopen(fileName->getCString(), "rb", "ctx=stm"))) { + error(-1, "Couldn't open file '%s'", fileName->getCString()); + return; + } +#else + if (!(file = fopen(fileName->getCString(), "rb"))) { + fileName2 = fileName->copy(); + fileName2->lowerCase(); + if (!(file = fopen(fileName2->getCString(), "rb"))) { + fileName2->upperCase(); + if (!(file = fopen(fileName2->getCString(), "rb"))) { + error(-1, "Couldn't open file '%s'", fileName->getCString()); + delete fileName2; + return; + } + } + delete fileName2; + } +#endif + + // create stream + obj.initNull(); + str = new FileStream(file, 0, -1, &obj); + + // check header + str->checkHeader(); + + // read xref table + xref = new XRef(str); + delete str; + if (!xref->isOk()) { + error(-1, "Couldn't read xref table"); + return; + } + + // read catalog + catalog = new Catalog(xref->getCatalog(&catObj)); + catObj.free(); + if (!catalog->isOk()) { + error(-1, "Couldn't read page catalog"); + return; + } + + // done + ok = gTrue; + return; +} + +PDFDoc::~PDFDoc() { + if (catalog) + delete catalog; + if (xref) + delete xref; + if (file) + fclose(file); + if (fileName) + delete fileName; + if (links) + delete links; +} + +void PDFDoc::displayPage(OutputDev *out, int page, int zoom, int rotate, + GBool doLinks) { + Link *link; + double x1, y1, x2, y2; + double w; + int i; + + if (printCommands) + printf("***** page %d *****\n", page); + catalog->getPage(page)->display(out, zoom, rotate); + if (doLinks) { + if (links) + delete links; + getLinks(page); + for (i = 0; i < links->getNumLinks(); ++i) { + link = links->getLink(i); + link->getBorder(&x1, &y1, &x2, &y2, &w); + if (w > 0) + out->drawLinkBorder(x1, y1, x2, y2, w); + } + out->dump(); + } +} + +void PDFDoc::displayPages(OutputDev *out, int firstPage, int lastPage, + int zoom, int rotate) { + Page *p; + int page; + + for (page = firstPage; page <= lastPage; ++page) { + if (printCommands) + printf("***** page %d *****\n", page); + p = catalog->getPage(page); + p->display(out, zoom, rotate); + } +} + +GBool PDFDoc::saveAs(GString *name) { + FILE *f; + char buf[4096]; + int n; + + if (!(f = fopen(name->getCString(), "wb"))) { + error(-1, "Couldn't open file '%s'", name->getCString()); + return gFalse; + } + rewind(file); + while ((n = fread(buf, 1, sizeof(buf), file)) > 0) + fwrite(buf, 1, n, f); + fclose(f); + return gTrue; +} + +void PDFDoc::getLinks(int page) { + Object obj; + + links = new Links(catalog->getPage(page)->getAnnots(&obj), + catalog->getBaseURI()); + obj.free(); +} diff --git a/pdftops/PDFDoc.h b/pdftops/PDFDoc.h new file mode 100644 index 0000000000..5e28962eda --- /dev/null +++ b/pdftops/PDFDoc.h @@ -0,0 +1,107 @@ +//======================================================================== +// +// PDFDoc.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef PDFDOC_H +#define PDFDOC_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include +#include "Link.h" + +class GString; +class XRef; +class Catalog; +class OutputDev; +class Links; +class LinkAction; +class LinkDest; + +//------------------------------------------------------------------------ +// PDFDoc +//------------------------------------------------------------------------ + +class PDFDoc { +public: + + PDFDoc(GString *fileName1); + ~PDFDoc(); + + // Was PDF document successfully opened? + GBool isOk() { return ok; } + + // Get file name. + GString *getFileName() { return fileName; } + + // Get catalog. + Catalog *getCatalog() { return catalog; } + + // Get page parameters. + double getPageWidth(int page) + { return catalog->getPage(page)->getWidth(); } + double getPageHeight(int page) + { return catalog->getPage(page)->getHeight(); } + int getPageRotate(int page) + { return catalog->getPage(page)->getRotate(); } + + // Get number of pages. + int getNumPages() { return catalog->getNumPages(); } + + // Display a page. + void displayPage(OutputDev *out, int page, int zoom, int rotate, + GBool doLinks); + + // Display a range of pages. + void displayPages(OutputDev *out, int firstPage, int lastPage, + int zoom, int rotate); + + // Find a page, given its object ID. Returns page number, or 0 if + // not found. + int findPage(int num, int gen) { return catalog->findPage(num, gen); } + + // If point , is in a link, return the associated action; + // else return NULL. + LinkAction *findLink(double x, double y) { return links->find(x, y); } + + // Return true if , is in a link. + GBool onLink(double x, double y) { return links->onLink(x, y); } + + // Find a named destination. Returns the link destination, or + // NULL if is not a destination. + LinkDest *findDest(GString *name) + { return catalog->findDest(name); } + + // Is the file encrypted? + GBool isEncrypted() { return xref->isEncrypted(); } + + // Are printing and copying allowed? If not, print an error message. + GBool okToPrint() { return xref->okToPrint(); } + GBool okToCopy() { return xref->okToCopy(); } + + // Return the document's Info dictionary (if any). + Object *getDocInfo(Object *obj) { return xref->getDocInfo(obj); } + + // Save this file with another name. + GBool saveAs(GString *name); + +private: + + void getLinks(int page); + + GString *fileName; + FILE *file; + XRef *xref; + Catalog *catalog; + Links *links; + + GBool ok; +}; + +#endif diff --git a/pdftops/PSOutputDev.cxx b/pdftops/PSOutputDev.cxx new file mode 100644 index 0000000000..d3b36d80aa --- /dev/null +++ b/pdftops/PSOutputDev.cxx @@ -0,0 +1,1177 @@ +//======================================================================== +// +// PSOutputDev.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include +#include "GString.h" +#include "config.h" +#include "Object.h" +#include "Error.h" +#include "GfxState.h" +#include "GfxFont.h" +#include "FontFile.h" +#include "Catalog.h" +#include "Page.h" +#include "Stream.h" +#include "PSOutputDev.h" + +//------------------------------------------------------------------------ +// Parameters +//------------------------------------------------------------------------ + +// Generate Level 1 PostScript? +GBool psOutLevel1 = gFalse; + +int paperWidth = 612; +int paperHeight = 792; + +//------------------------------------------------------------------------ +// PostScript prolog and setup +//------------------------------------------------------------------------ + +static char *prolog[] = { + "/xpdf 75 dict def xpdf begin", + "% PDF special state", + "/pdfDictSize 14 def", +#if 0 // Not used for CUPS - the pstops filter handles this... + "/pdfSetup {", + " 2 array astore", + " /setpagedevice where {", + " pop 3 dict dup begin", + " exch /PageSize exch def", + " /ImagingBBox null def", + " /Policies 1 dict dup begin /PageSize 3 def end def", + " end setpagedevice", + " } {", + " pop", + " } ifelse", + "} def", +#endif // 0 + "/pdfStartPage {", + " pdfDictSize dict begin", + " /pdfFill [0] def", + " /pdfStroke [0] def", + " /pdfLastFill false def", + " /pdfLastStroke false def", + " /pdfTextMat [1 0 0 1 0 0] def", + " /pdfFontSize 0 def", + " /pdfCharSpacing 0 def", + " /pdfTextRender 0 def", + " /pdfTextRise 0 def", + " /pdfWordSpacing 0 def", + " /pdfHorizScaling 1 def", + "} def", + "/pdfEndPage { end } def", + "/sCol { pdfLastStroke not {", + " pdfStroke aload length", + " 1 eq { setgray } { setrgbcolor} ifelse", + " /pdfLastStroke true def /pdfLastFill false def", + " } if } def", + "/fCol { pdfLastFill not {", + " pdfFill aload length", + " 1 eq { setgray } { setrgbcolor } ifelse", + " /pdfLastFill true def /pdfLastStroke false def", + " } if } def", + "% build a font", + "/pdfMakeFont {", + " 3 2 roll findfont", + " 3 2 roll 1 matrix scale makefont", + " dup length dict begin", + " { 1 index /FID ne { def } { pop pop } ifelse } forall", + " /Encoding exch def", + " currentdict", + " end", + " definefont pop", + "} def", + "% graphics state operators", + "/q { gsave pdfDictSize dict begin } def", + "/Q { end grestore } def", + "/cm { concat } def", + "/d { setdash } def", + "/i { setflat } def", + "/j { setlinejoin } def", + "/J { setlinecap } def", + "/M { setmiterlimit } def", + "/w { setlinewidth } def", + "% color operators", + "/g { dup 1 array astore /pdfFill exch def setgray", + " /pdfLastFill true def /pdfLastStroke false def } def", + "/G { dup 1 array astore /pdfStroke exch def setgray", + " /pdfLastStroke true def /pdfLastFill false def } def", + "/rg { 3 copy 3 array astore /pdfFill exch def setrgbcolor", + " /pdfLastFill true def /pdfLastStroke false def } def", + "/RG { 3 copy 3 array astore /pdfStroke exch def setrgbcolor", + " /pdfLastStroke true def /pdfLastFill false def } def", + "% path segment operators", + "/m { moveto } def", + "/l { lineto } def", + "/c { curveto } def", + "/re { 4 2 roll moveto 1 index 0 rlineto 0 exch rlineto", + " neg 0 rlineto closepath } def", + "% path painting operators", + "/S { sCol stroke } def", + "/f { fCol fill } def", + "/f* { fCol eofill } def", + "% clipping operators", + "/W { clip newpath } def", + "/W* { eoclip newpath } def", + "% text state operators", + "/Tc { /pdfCharSpacing exch def } def", + "/Tf { dup /pdfFontSize exch def", + " dup pdfHorizScaling mul exch matrix scale", + " pdfTextMat matrix concatmatrix dup 4 0 put dup 5 0 put", + " exch findfont exch makefont setfont } def", + "/Tr { /pdfTextRender exch def } def", + "/Ts { /pdfTextRise exch def } def", + "/Tw { /pdfWordSpacing exch def } def", + "/Tz { /pdfHorizScaling exch def } def", + "% text positioning operators", + "/Td { pdfTextMat transform moveto } def", + "/Tm { /pdfTextMat exch def } def", + "% text string operators", + "/Tj { pdfTextRender 1 and 0 eq { fCol } { sCol } ifelse", + " 0 pdfTextRise pdfTextMat dtransform rmoveto", + " pdfFontSize mul pdfHorizScaling mul", + " 1 index stringwidth pdfTextMat idtransform pop", + " sub 1 index length dup 0 ne { div } { pop pop 0 } ifelse", + " pdfWordSpacing 0 pdfTextMat dtransform 32", + " 4 3 roll pdfCharSpacing add 0 pdfTextMat dtransform", + " 6 5 roll awidthshow", + " 0 pdfTextRise neg pdfTextMat dtransform rmoveto } def", + "/TJm { pdfFontSize 0.001 mul mul neg 0", + " pdfTextMat dtransform rmoveto } def", + "% Level 1 image operators", + "/pdfIm1 {", + " /pdfImBuf1 4 index string def", + " { currentfile pdfImBuf1 readhexstring pop } image", + "} def", + "/pdfImM1 {", + " /pdfImBuf1 4 index 7 add 8 idiv string def", + " { currentfile pdfImBuf1 readhexstring pop } imagemask", + "} def", + "% Level 2 image operators", + "/pdfImBuf 100 string def", + "/pdfIm {", + " image", + " { currentfile pdfImBuf readline", + " not { pop exit } if", + " (%-EOD-) eq { exit } if } loop", + "} def", + "/pdfImM {", + " fCol imagemask", + " { currentfile pdfImBuf readline", + " not { pop exit } if", + " (%-EOD-) eq { exit } if } loop", + "} def", + "end", + NULL +}; + +//------------------------------------------------------------------------ +// Fonts +//------------------------------------------------------------------------ + +struct PSFont { + char *name; // PDF name + char *psName; // PostScript name +}; + +struct PSSubstFont { + char *psName; // PostScript name + double mWidth; // width of 'm' character +}; + +static PSFont psFonts[] = { + {"Courier", "Courier"}, + {"Courier-Bold", "Courier-Bold"}, + {"Courier-Oblique", "Courier-Bold"}, + {"Courier-BoldOblique", "Courier-BoldOblique"}, + {"Helvetica", "Helvetica"}, + {"Helvetica-Bold", "Helvetica-Bold"}, + {"Helvetica-Oblique", "Helvetica-Oblique"}, + {"Helvetica-BoldOblique", "Helvetica-BoldOblique"}, + {"Symbol", "Symbol"}, + {"Times-Roman", "Times-Roman"}, + {"Times-Bold", "Times-Bold"}, + {"Times-Italic", "Times-Italic"}, + {"Times-BoldItalic", "Times-BoldItalic"}, + {"ZapfDingbats", "ZapfDingbats"}, + {NULL} +}; + +static PSSubstFont psSubstFonts[] = { + {"Helvetica", 0.833}, + {"Helvetica-Oblique", 0.833}, + {"Helvetica-Bold", 0.889}, + {"Helvetica-BoldOblique", 0.889}, + {"Times-Roman", 0.788}, + {"Times-Italic", 0.722}, + {"Times-Bold", 0.833}, + {"Times-BoldItalic", 0.778}, + {"Courier", 0.600}, + {"Courier-Oblique", 0.600}, + {"Courier-Bold", 0.600}, + {"Courier-BoldOblique", 0.600} +}; + +//------------------------------------------------------------------------ +// PSOutputDev +//------------------------------------------------------------------------ + +PSOutputDev::PSOutputDev(char *fileName, Catalog *catalog, + int firstPage, int lastPage, + GBool embedType11, GBool doForm1) { + Page *page; + Dict *resDict; + char **p; + int pg; + + // initialize + embedType1 = embedType11; + doForm = doForm1; + fontIDs = NULL; + fontFileIDs = NULL; + fontFileNames = NULL; + f = NULL; + if (doForm) + lastPage = firstPage; + + // open file or pipe + ok = gTrue; + if (!strcmp(fileName, "-")) { + fileType = psStdout; + f = stdout; + } else if (fileName[0] == '|') { + fileType = psPipe; +#ifdef HAVE_POPEN +#ifndef WIN32 + signal(SIGPIPE, (void (*)(int))SIG_IGN); +#endif + if (!(f = popen(fileName + 1, "w"))) { + error(-1, "Couldn't run print command '%s'", fileName); + ok = gFalse; + return; + } +#else + error(-1, "Print commands are not supported ('%s')", fileName); + ok = gFalse; + return; +#endif + } else { + fileType = psFile; + if (!(f = fopen(fileName, "w"))) { + error(-1, "Couldn't open PostScript file '%s'", fileName); + ok = gFalse; + return; + } + } + + // initialize fontIDs, fontFileIDs, and fontFileNames lists + fontIDSize = 64; + fontIDLen = 0; + fontIDs = (Ref *)gmalloc(fontIDSize * sizeof(Ref)); + fontFileIDSize = 64; + fontFileIDLen = 0; + fontFileIDs = (Ref *)gmalloc(fontFileIDSize * sizeof(Ref)); + fontFileNameSize = 64; + fontFileNameLen = 0; + fontFileNames = (char **)gmalloc(fontFileNameSize * sizeof(char *)); + + // write header + if (doForm) { + writePS("%%!PS-Adobe-3.0 Resource-Form\n"); + writePS("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); + writePS("%%%%EndComments\n"); + } else { + writePS("%%!PS-Adobe-3.0\n"); + writePS("%%%%Creator: xpdf/pdftops %s\n", xpdfVersion); + writePS("%%%%Pages: %d\n", lastPage - firstPage + 1); + writePS("%%%%EndComments\n"); + } + + // write prolog + if (!doForm) + writePS("%%%%BeginProlog\n"); + writePS("%%%%BeginResource: xpdf %s\n", xpdfVersion); + for (p = prolog; *p; ++p) + writePS("%s\n", *p); + writePS("%%%%EndResource\n"); + if (!doForm) + writePS("%%%%EndProlog\n"); + + // set up fonts + if (!doForm) + writePS("%%%%BeginSetup\n"); + writePS("xpdf begin\n"); + for (pg = firstPage; pg <= lastPage; ++pg) { + if ((resDict = catalog->getPage(pg)->getResourceDict())) + setupFonts(resDict); + } + if (doForm) { + writePS("end\n"); + } else { +// pdfSetup not used for CUPS filter... +// writePS("%d %d pdfSetup\n", paperWidth, paperHeight); + writePS("%%%%EndSetup\n"); + } + + // write form header + if (doForm) { + page = catalog->getPage(firstPage); + writePS("4 dict dup begin\n"); + writePS("/BBox [%d %d %d %d] def\n", + (int)page->getX1(), (int)page->getY1(), + (int)page->getX2(), (int)page->getY2()); + writePS("/FormType 1 def\n"); + writePS("/Matrix [1 0 0 1 0 0] def\n"); + } + + // initialize sequential page number + seqPage = 1; +} + +PSOutputDev::~PSOutputDev() { + if (f) { + if (doForm) { + writePS("end\n"); + writePS("/Foo exch /Form defineresource pop\n"); + } else { + writePS("%%%%Trailer\n"); + writePS("end\n"); + writePS("%%%%EOF\n"); + } + if (fileType == psFile) { + fclose(f); + } +#ifdef HAVE_POPEN + else if (fileType == psPipe) { + pclose(f); +#ifndef WIN32 + signal(SIGPIPE, (void (*)(int))SIG_DFL); +#endif + } +#endif + } + if (fontIDs) + gfree(fontIDs); + if (fontFileIDs) + gfree(fontFileIDs); + if (fontFileNames) + gfree(fontFileNames); +} + +void PSOutputDev::setupFonts(Dict *resDict) { + Object fontDict, xObjDict, xObj, resObj; + GfxFontDict *gfxFontDict; + GfxFont *font; + int i; + + resDict->lookup("Font", &fontDict); + if (fontDict.isDict()) { + gfxFontDict = new GfxFontDict(fontDict.getDict()); + for (i = 0; i < gfxFontDict->getNumFonts(); ++i) { + font = gfxFontDict->getFont(i); + setupFont(font); + } + delete gfxFontDict; + } + fontDict.free(); + + resDict->lookup("XObject", &xObjDict); + if (xObjDict.isDict()) { + for (i = 0; i < xObjDict.dictGetLength(); ++i) { + xObjDict.dictGetVal(i, &xObj); + if (xObj.isStream()) { + xObj.streamGetDict()->lookup("Resources", &resObj); + if (resObj.isDict()) + setupFonts(resObj.getDict()); + resObj.free(); + } + xObj.free(); + } + } + xObjDict.free(); +} + +void PSOutputDev::setupFont(GfxFont *font) { + Ref fontFileID; + GString *name; + char *psName; + char *charName; + double scale; + int i, j; + + // check if font is already set up + for (i = 0; i < fontIDLen; ++i) { + if (fontIDs[i].num == font->getID().num && + fontIDs[i].gen == font->getID().gen) + return; + } + + // add entry to fontIDs list + if (fontIDLen >= fontIDSize) { + fontIDSize += 64; + fontIDs = (Ref *)grealloc(fontIDs, fontIDSize * sizeof(Ref)); + } + fontIDs[fontIDLen++] = font->getID(); + + // check for embedded Type 1 font + if (embedType1 && font->getType() == fontType1 && + font->getEmbeddedFontID(&fontFileID)) { + setupEmbeddedType1Font(&fontFileID); + psName = font->getEmbeddedFontName(); + scale = 1; + + // check for external Type 1 font file + } else if (embedType1 && font->getType() == fontType1 && + font->getExtFontFile()) { + setupEmbeddedType1Font(font->getExtFontFile()); + // this assumes that the PS font name matches the PDF font name + psName = font->getName()->getCString(); + scale = 1; + + // check for embedded Type 1C font + } else if (embedType1 && font->getType() == fontType1C && + font->getEmbeddedFontID(&fontFileID)) { + setupEmbeddedType1CFont(font, &fontFileID); + psName = font->getEmbeddedFontName(); + scale = 1; + + // do font substitution + } else { + name = font->getName(); + psName = NULL; + scale = 1.0; + if (name) { + for (i = 0; psFonts[i].name; ++i) { + if (name->cmp(psFonts[i].name) == 0) { + psName = psFonts[i].psName; + break; + } + } + } + if (!psName) { + if (font->isFixedWidth()) + i = 8; + else if (font->isSerif()) + i = 4; + else + i = 0; + if (font->isBold()) + i += 2; + if (font->isItalic()) + i += 1; + psName = psSubstFonts[i].psName; + scale = font->getWidth('m') / psSubstFonts[i].mWidth; + if (scale < 0.1) + scale = 1; + } + } + + // generate PostScript code to set up the font + writePS("/F%d_%d /%s %g\n", + font->getID().num, font->getID().gen, psName, scale); + for (i = 0; i < 256; i += 8) { + writePS((i == 0) ? "[ " : " "); + for (j = 0; j < 8; ++j) { + charName = font->getCharName(i+j); + writePS("/%s", charName ? charName : ".notdef"); + } + writePS((i == 256-8) ? "]\n" : "\n"); + } + writePS("pdfMakeFont\n"); +} + +void PSOutputDev::setupEmbeddedType1Font(Ref *id) { + static char hexChar[17] = "0123456789abcdef"; + Object refObj, strObj, obj1, obj2; + Dict *dict; + int length1, length2; + int c; + int start[4]; + GBool binMode; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileIDLen; ++i) { + if (fontFileIDs[i].num == id->num && + fontFileIDs[i].gen == id->gen) + return; + } + + // add entry to fontFileIDs list + if (fontFileIDLen >= fontFileIDSize) { + fontFileIDSize += 64; + fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref)); + } + fontFileIDs[fontFileIDLen++] = *id; + + // get the font stream and info + refObj.initRef(id->num, id->gen); + refObj.fetch(&strObj); + refObj.free(); + if (!strObj.isStream()) { + error(-1, "Embedded font file object is not a stream"); + goto err1; + } + if (!(dict = strObj.streamGetDict())) { + error(-1, "Embedded font stream is missing its dictionary"); + goto err1; + } + dict->lookup("Length1", &obj1); + dict->lookup("Length2", &obj2); + if (!obj1.isInt() || !obj2.isInt()) { + error(-1, "Missing length fields in embedded font stream dictionary"); + obj1.free(); + obj2.free(); + goto err1; + } + length1 = obj1.getInt(); + length2 = obj2.getInt(); + obj1.free(); + obj2.free(); + + // copy ASCII portion of font + strObj.streamReset(); + for (i = 0; i < length1 && (c = strObj.streamGetChar()) != EOF; ++i) + fputc(c, f); + + // figure out if encrypted portion is binary or ASCII + binMode = gFalse; + for (i = 0; i < 4; ++i) { + start[i] = strObj.streamGetChar(); + if (start[i] == EOF) { + error(-1, "Unexpected end of file in embedded font stream"); + goto err1; + } + if (!((start[i] >= '0' && start[i] <= '9') || + (start[i] >= 'A' && start[i] <= 'F') || + (start[i] >= 'a' && start[i] <= 'f'))) + binMode = gTrue; + } + + // convert binary data to ASCII + if (binMode) { + for (i = 0; i < 4; ++i) { + fputc(hexChar[(start[i] >> 4) & 0x0f], f); + fputc(hexChar[start[i] & 0x0f], f); + } + while (i < length2) { + if ((c = strObj.streamGetChar()) == EOF) + break; + fputc(hexChar[(c >> 4) & 0x0f], f); + fputc(hexChar[c & 0x0f], f); + if (++i % 32 == 0) + fputc('\n', f); + } + if (i % 32 > 0) + fputc('\n', f); + + // already in ASCII format -- just copy it + } else { + for (i = 0; i < 4; ++i) + fputc(start[i], f); + for (i = 4; i < length2; ++i) { + if ((c = strObj.streamGetChar()) == EOF) + break; + fputc(c, f); + } + } + + // write padding and "cleartomark" + for (i = 0; i < 8; ++i) + writePS("00000000000000000000000000000000" + "00000000000000000000000000000000\n"); + writePS("cleartomark\n"); + + err1: + strObj.free(); +} + +//~ This doesn't handle .pfb files or binary eexec data (which only +//~ happens in pfb files?). +void PSOutputDev::setupEmbeddedType1Font(char *fileName) { + FILE *fontFile; + int c; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileNameLen; ++i) { + if (!strcmp(fontFileNames[i], fileName)) + return; + } + + // add entry to fontFileNames list + if (fontFileNameLen >= fontFileNameSize) { + fontFileNameSize += 64; + fontFileNames = (char **)grealloc(fontFileNames, + fontFileNameSize * sizeof(char *)); + } + fontFileNames[fontFileNameLen++] = fileName; + + // copy the font file + if (!(fontFile = fopen(fileName, "rb"))) { + error(-1, "Couldn't open external font file"); + return; + } + while ((c = fgetc(fontFile)) != EOF) + fputc(c, f); + fclose(fontFile); +} + +void PSOutputDev::setupEmbeddedType1CFont(GfxFont *font, Ref *id) { + char *fontBuf; + int fontLen; + Type1CFontConverter *cvt; + int i; + + // check if font is already embedded + for (i = 0; i < fontFileIDLen; ++i) { + if (fontFileIDs[i].num == id->num && + fontFileIDs[i].gen == id->gen) + return; + } + + // add entry to fontFileIDs list + if (fontFileIDLen >= fontFileIDSize) { + fontFileIDSize += 64; + fontFileIDs = (Ref *)grealloc(fontFileIDs, fontFileIDSize * sizeof(Ref)); + } + fontFileIDs[fontFileIDLen++] = *id; + + // convert it to a Type 1 font + fontBuf = font->readEmbFontFile(&fontLen); + cvt = new Type1CFontConverter(fontBuf, fontLen, f); + cvt->convert(); + delete cvt; + gfree(fontBuf); +} + +void PSOutputDev::startPage(int pageNum, GfxState *state) { + int x1, y1, x2, y2, width, height, t; + double xScale, yScale; + + if (doForm) { + + writePS("/PaintProc {\n"); + writePS("begin xpdf begin\n"); + writePS("pdfSetup\n"); + + } else { + + writePS("%%%%Page: %d %d\n", pageNum, seqPage); + writePS("%%%%BeginPageSetup\n"); + + // rotate, translate, and scale page + x1 = (int)(state->getX1() + 0.5); + y1 = (int)(state->getY1() + 0.5); + x2 = (int)(state->getX2() + 0.5); + y2 = (int)(state->getY2() + 0.5); + width = x2 - x1; + height = y2 - y1; + if (width > height) { + writePS("%%%%PageOrientation: Landscape\n"); + writePS("pdfStartPage\n"); + writePS("90 rotate\n"); + writePS("%d %d translate\n", -x1, -(y1 + paperWidth)); + t = width; + width = height; + height = t; + } else { + writePS("%%%%PageOrientation: Portrait\n"); + writePS("pdfStartPage\n"); + if (x1 != 0 || y1 != 0) + writePS("%d %d translate\n", -x1, -y1); + } + if (width > paperWidth || height > paperHeight) { + xScale = (double)paperWidth / (double)width; + yScale = (double)paperHeight / (double)height; + if (yScale < xScale) + xScale = yScale; + writePS("%0.4f %0.4f scale\n", xScale, xScale); + } + + writePS("%%%%EndPageSetup\n"); + ++seqPage; + } +} + +void PSOutputDev::endPage() { + if (doForm) { + writePS("pdfEndPage\n"); + writePS("end end\n"); + writePS("} def\n"); + } else { + writePS("showpage\n"); + writePS("%%%%PageTrailer\n"); + writePS("pdfEndPage\n"); + } +} + +void PSOutputDev::saveState(GfxState *state) { + writePS("q\n"); +} + +void PSOutputDev::restoreState(GfxState *state) { + writePS("Q\n"); +} + +void PSOutputDev::updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, double m31, double m32) { + writePS("[%g %g %g %g %g %g] cm\n", m11, m12, m21, m22, m31, m32); +} + +void PSOutputDev::updateLineDash(GfxState *state) { + double *dash; + double start; + int length, i; + + state->getLineDash(&dash, &length, &start); + writePS("["); + for (i = 0; i < length; ++i) + writePS("%g%s", dash[i], (i == length-1) ? "" : " "); + writePS("] %g d\n", start); +} + +void PSOutputDev::updateFlatness(GfxState *state) { + writePS("%d i\n", state->getFlatness()); +} + +void PSOutputDev::updateLineJoin(GfxState *state) { + writePS("%d j\n", state->getLineJoin()); +} + +void PSOutputDev::updateLineCap(GfxState *state) { + writePS("%d J\n", state->getLineCap()); +} + +void PSOutputDev::updateMiterLimit(GfxState *state) { + writePS("%g M\n", state->getMiterLimit()); +} + +void PSOutputDev::updateLineWidth(GfxState *state) { + writePS("%g w\n", state->getLineWidth()); +} + +void PSOutputDev::updateFillColor(GfxState *state) { + GfxColor *color; + double r, g, b; + + color = state->getFillColor(); + r = color->getR(); + g = color->getG(); + b = color->getB(); + if (r == g && g == b) + writePS("%g g\n", r); + else + writePS("%g %g %g rg\n", r, g, b); +} + +void PSOutputDev::updateStrokeColor(GfxState *state) { + GfxColor *color; + double r, g, b; + + color = state->getStrokeColor(); + r = color->getR(); + g = color->getG(); + b = color->getB(); + if (r == g && g == b) + writePS("%g G\n", r); + else + writePS("%g %g %g RG\n", r, g, b); +} + +void PSOutputDev::updateFont(GfxState *state) { + if (state->getFont()) { + writePS("/F%d_%d %g Tf\n", + state->getFont()->getID().num, state->getFont()->getID().gen, + state->getFontSize()); + } +} + +void PSOutputDev::updateTextMat(GfxState *state) { + double *mat; + + mat = state->getTextMat(); + writePS("[%g %g %g %g %g %g] Tm\n", + mat[0], mat[1], mat[2], mat[3], mat[4], mat[5]); +} + +void PSOutputDev::updateCharSpace(GfxState *state) { + writePS("%g Tc\n", state->getCharSpace()); +} + +void PSOutputDev::updateRender(GfxState *state) { + writePS("%d Tr\n", state->getRender()); +} + +void PSOutputDev::updateRise(GfxState *state) { + writePS("%g Ts\n", state->getRise()); +} + +void PSOutputDev::updateWordSpace(GfxState *state) { + writePS("%g Tw\n", state->getWordSpace()); +} + +void PSOutputDev::updateHorizScaling(GfxState *state) { + writePS("%g Tz\n", state->getHorizScaling()); +} + +void PSOutputDev::updateTextPos(GfxState *state) { + writePS("%g %g Td\n", state->getLineX(), state->getLineY()); +} + +void PSOutputDev::updateTextShift(GfxState *state, double shift) { + writePS("%g TJm\n", shift); +} + +void PSOutputDev::stroke(GfxState *state) { + doPath(state->getPath()); + writePS("S\n"); +} + +void PSOutputDev::fill(GfxState *state) { + doPath(state->getPath()); + writePS("f\n"); +} + +void PSOutputDev::eoFill(GfxState *state) { + doPath(state->getPath()); + writePS("f*\n"); +} + +void PSOutputDev::clip(GfxState *state) { + doPath(state->getPath()); + writePS("W\n"); +} + +void PSOutputDev::eoClip(GfxState *state) { + doPath(state->getPath()); + writePS("W*\n"); +} + +void PSOutputDev::doPath(GfxPath *path) { + GfxSubpath *subpath; + double x0, y0, x1, y1, x2, y2, x3, y3, x4, y4; + int n, m, i, j; + + n = path->getNumSubpaths(); + + if (n == 1 && path->getSubpath(0)->getNumPoints() == 5) { + subpath = path->getSubpath(0); + x0 = subpath->getX(0); + y0 = subpath->getY(0); + x4 = subpath->getX(4); + y4 = subpath->getY(4); + if (x4 == x0 && y4 == y0) { + x1 = subpath->getX(1); + y1 = subpath->getY(1); + x2 = subpath->getX(2); + y2 = subpath->getY(2); + x3 = subpath->getX(3); + y3 = subpath->getY(3); + if (x0 == x1 && x2 == x3 && y0 == y3 && y1 == y2) { + writePS("%g %g %g %g re\n", + x0 < x2 ? x0 : x2, y0 < y1 ? y0 : y1, + fabs(x2 - x0), fabs(y1 - y0)); + return; + } else if (x0 == x3 && x1 == x2 && y0 == y1 && y2 == y3) { + writePS("%g %g %g %g re\n", + x0 < x1 ? x0 : x1, y0 < y2 ? y0 : y2, + fabs(x1 - x0), fabs(y2 - y0)); + return; + } + } + } + + for (i = 0; i < n; ++i) { + subpath = path->getSubpath(i); + m = subpath->getNumPoints(); + writePS("%g %g m\n", subpath->getX(0), subpath->getY(0)); + j = 1; + while (j < m) { + if (subpath->getCurve(j)) { + writePS("%g %g %g %g %g %g c\n", subpath->getX(j), subpath->getY(j), + subpath->getX(j+1), subpath->getY(j+1), + subpath->getX(j+2), subpath->getY(j+2)); + j += 3; + } else { + writePS("%g %g l\n", subpath->getX(j), subpath->getY(j)); + ++j; + } + } + } +} + +void PSOutputDev::drawString(GfxState *state, GString *s) { + // check for invisible text -- this is used by Acrobat Capture + if ((state->getRender() & 3) == 3) + return; + + writePSString(s); + writePS(" %g Tj\n", state->getFont()->getWidth(s)); +} + +void PSOutputDev::drawImageMask(GfxState *state, Stream *str, + int width, int height, GBool invert, + GBool inlineImg) { + int len; + + len = height * ((width + 7) / 8); + if (psOutLevel1) + doImageL1(NULL, invert, inlineImg, str, width, height, len); + else + doImage(NULL, invert, inlineImg, str, width, height, len); +} + +void PSOutputDev::drawImage(GfxState *state, Stream *str, int width, + int height, GfxImageColorMap *colorMap, + GBool inlineImg) { + int len; + + len = height * ((width * colorMap->getNumPixelComps() * + colorMap->getBits() + 7) / 8); + if (psOutLevel1) + doImageL1(colorMap, gFalse, inlineImg, str, width, height, len); + else + doImage(colorMap, gFalse, inlineImg, str, width, height, len); +} + +void PSOutputDev::doImageL1(GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len) { + ImageStream *imgStr; + Guchar pixBuf[4]; + GfxColor color; + int x, y, i; + + // width, height, matrix, bits per component + if (colorMap) { + writePS("%d %d 8 [%d 0 0 %d 0 %d] pdfIm1\n", + width, height, + width, -height, height); + } else { + writePS("%d %d %s [%d 0 0 %d 0 %d] pdfImM1\n", + width, height, invert ? "true" : "false", + width, -height, height); + } + + // image + if (colorMap) { + + // set up to process the data stream + imgStr = new ImageStream(str, width, colorMap->getNumPixelComps(), + colorMap->getBits()); + imgStr->reset(); + + // process the data stream + i = 0; + for (y = 0; y < height; ++y) { + + // write the line + for (x = 0; x < width; ++x) { + imgStr->getPixel(pixBuf); + colorMap->getColor(pixBuf, &color); + fprintf(f, "%02x", (int)(color.getGray() * 255 + 0.5)); + if (++i == 32) { + fputc('\n', f); + i = 0; + } + } + } + if (i != 0) + fputc('\n', f); + delete imgStr; + + // imagemask + } else { + str->reset(); + i = 0; + for (y = 0; y < height; ++y) { + for (x = 0; x < width; x += 8) { + fprintf(f, "%02x", str->getChar() & 0xff); + if (++i == 32) { + fputc('\n', f); + i = 0; + } + } + } + if (i != 0) + fputc('\n', f); + } +} + +void PSOutputDev::doImage(GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len) { + GfxColorSpace *colorSpace; + GString *s; + int n, numComps; + Guchar *color; + GBool useRLE, useA85; + int c; + int i, j, k; + + // color space + if (colorMap) { + colorSpace = colorMap->getColorSpace(); + if (colorSpace->isIndexed()) + writePS("[/Indexed "); + switch (colorSpace->getMode()) { + case colorGray: + writePS("/DeviceGray "); + break; + case colorCMYK: + writePS("/DeviceCMYK "); + break; + case colorRGB: + writePS("/DeviceRGB "); + break; + } + if (colorSpace->isIndexed()) { + n = colorSpace->getIndexHigh(); + numComps = colorSpace->getNumColorComps(); + writePS("%d <\n", n); + for (i = 0; i <= n; i += 8) { + writePS(" "); + for (j = i; j < i+8 && j <= n; ++j) { + color = colorSpace->getLookupVal(j); + for (k = 0; k < numComps; ++k) + writePS("%02x", color[k]); + } + writePS("\n"); + } + writePS("> ] setcolorspace\n"); + } else { + writePS("setcolorspace\n"); + } + } + + // image dictionary + writePS("<<\n /ImageType 1\n"); + + // width, height, matrix, bits per component + writePS(" /Width %d\n", width); + writePS(" /Height %d\n", height); + writePS(" /ImageMatrix [%d 0 0 %d 0 %d]\n", width, -height, height); + writePS(" /BitsPerComponent %d\n", + colorMap ? colorMap->getBits() : 1); + + // decode + if (colorMap) { + writePS(" /Decode ["); + numComps = colorMap->getNumPixelComps(); + for (i = 0; i < numComps; ++i) { + if (i > 0) + writePS(" "); + writePS("%g %g", colorMap->getDecodeLow(i), colorMap->getDecodeHigh(i)); + } + writePS("]\n"); + } else { + writePS(" /Decode [%d %d]\n", invert ? 1 : 0, invert ? 0 : 1); + } + + if (doForm) { + + // data source + writePS(" /DataSource <~\n"); + + // write image data stream, using ASCII85 encode filter + str = new ASCII85Encoder(str); + str->reset(); + while ((c = str->getChar()) != EOF) + fputc(c, f); + fputc('\n', f); + delete str; + + // end of image dictionary + writePS(">>\n%s\n", colorMap ? "image" : "imagemask"); + + } else { + + // data source + writePS(" /DataSource currentfile\n"); + s = str->getPSFilter(" "); + if (inlineImg || !s) { + useRLE = gTrue; + useA85 = gTrue; + } else { + useRLE = gFalse; + useA85 = str->isBinary(); + } + if (useA85) + writePS(" /ASCII85Decode filter\n"); + if (useRLE) + writePS(" /RunLengthDecode filter\n"); + else + writePS("%s", s->getCString()); + if (s) + delete s; + + // end of image dictionary + writePS(">>\n%s\n", colorMap ? "pdfIm" : "pdfImM"); + + // write image data stream + + // cut off inline image streams at appropriate length + if (inlineImg) + str = new FixedLengthEncoder(str, len); + else if (!useRLE) + str = str->getBaseStream(); + + // add RunLengthEncode and ASCII85 encode filters + if (useRLE) + str = new RunLengthEncoder(str); + if (useA85) + str = new ASCII85Encoder(str); + + // copy the stream data + str->reset(); + while ((c = str->getChar()) != EOF) + fputc(c, f); + + // add newline and trailer to the end + fputc('\n', f); + fputs("%-EOD-\n", f); + + // delete encoders + if (useRLE || useA85) + delete str; + } +} + +void PSOutputDev::writePS(const char *fmt, ...) { + va_list args; + + va_start(args, fmt); + vfprintf(f, fmt, args); + va_end(args); +} + +void PSOutputDev::writePSString(GString *s) { + Guchar *p; + int n; + + fputc('(', f); + for (p = (Guchar *)s->getCString(), n = s->getLength(); n; ++p, --n) { + if (*p == '(' || *p == ')' || *p == '\\') + fprintf(f, "\\%c", *p); + else if (*p < 0x20 || *p >= 0x80) + fprintf(f, "\\%03o", *p); + else + fputc(*p, f); + } + fputc(')', f); +} diff --git a/pdftops/PSOutputDev.h b/pdftops/PSOutputDev.h new file mode 100644 index 0000000000..beee9fcf27 --- /dev/null +++ b/pdftops/PSOutputDev.h @@ -0,0 +1,160 @@ +//======================================================================== +// +// PSOutputDev.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef PSOUTPUTDEV_H +#define PSOUTPUTDEV_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include +#include "config.h" +#include "Object.h" +#include "OutputDev.h" + +class GfxPath; +class GfxFont; + +//------------------------------------------------------------------------ +// Parameters +//------------------------------------------------------------------------ + +// Generate Level 1 PostScript? +extern GBool psOutLevel1; + +// Paper size. +extern int paperWidth; +extern int paperHeight; + +//------------------------------------------------------------------------ +// PSOutputDev +//------------------------------------------------------------------------ + +enum PSFileType { + psFile, // write to file + psPipe, // write to pipe + psStdout // write to stdout +}; + +class PSOutputDev: public OutputDev { +public: + + // Open a PostScript output file, and write the prolog. + PSOutputDev(char *fileName, Catalog *catalog, + int firstPage, int lastPage, + GBool embedType11, GBool doForm1); + + // Destructor -- writes the trailer and closes the file. + virtual ~PSOutputDev(); + + // Check if file was successfully created. + virtual GBool isOk() { return ok; } + + //---- get info about output device + + // Does this device use upside-down coordinates? + // (Upside-down means (0,0) is the top left corner of the page.) + virtual GBool upsideDown() { return gFalse; } + + // Does this device use drawChar() or drawString()? + virtual GBool useDrawChar() { return gFalse; } + + //----- initialization and control + + // Start a page. + virtual void startPage(int pageNum, GfxState *state); + + // End a page. + virtual void endPage(); + + //----- save/restore graphics state + virtual void saveState(GfxState *state); + virtual void restoreState(GfxState *state); + + //----- update graphics state + virtual void updateCTM(GfxState *state, double m11, double m12, + double m21, double m22, double m31, double m32); + virtual void updateLineDash(GfxState *state); + virtual void updateFlatness(GfxState *state); + virtual void updateLineJoin(GfxState *state); + virtual void updateLineCap(GfxState *state); + virtual void updateMiterLimit(GfxState *state); + virtual void updateLineWidth(GfxState *state); + virtual void updateFillColor(GfxState *state); + virtual void updateStrokeColor(GfxState *state); + + //----- update text state + virtual void updateFont(GfxState *state); + virtual void updateTextMat(GfxState *state); + virtual void updateCharSpace(GfxState *state); + virtual void updateRender(GfxState *state); + virtual void updateRise(GfxState *state); + virtual void updateWordSpace(GfxState *state); + virtual void updateHorizScaling(GfxState *state); + virtual void updateTextPos(GfxState *state); + virtual void updateTextShift(GfxState *state, double shift); + + //----- path painting + virtual void stroke(GfxState *state); + virtual void fill(GfxState *state); + virtual void eoFill(GfxState *state); + + //----- path clipping + virtual void clip(GfxState *state); + virtual void eoClip(GfxState *state); + + //----- text drawing + virtual void drawString(GfxState *state, GString *s); + + //----- image drawing + virtual void drawImageMask(GfxState *state, Stream *str, + int width, int height, GBool invert, + GBool inlineImg); + virtual void drawImage(GfxState *state, Stream *str, int width, + int height, GfxImageColorMap *colorMap, + GBool inlineImg); + +private: + + void setupFonts(Dict *resDict); + void setupFont(GfxFont *font); + void setupEmbeddedType1Font(Ref *id); + void setupEmbeddedType1Font(char *fileName); + void setupEmbeddedType1CFont(GfxFont *font, Ref *id); + void doPath(GfxPath *path); + void doImageL1(GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len); + void doImage(GfxImageColorMap *colorMap, + GBool invert, GBool inlineImg, + Stream *str, int width, int height, int len); + void writePS(const char *fmt, ...); + void writePSString(GString *s); + + GBool embedType1; // embed Type 1 fonts? + GBool doForm; // generate a form? + + FILE *f; // PostScript file + PSFileType fileType; // file / pipe / stdout + int seqPage; // current sequential page number + + Ref *fontIDs; // list of object IDs of all used fonts + int fontIDLen; // number of entries in fontIDs array + int fontIDSize; // size of fontIDs array + Ref *fontFileIDs; // list of object IDs of all embedded fonts + int fontFileIDLen; // number of entries in fontFileIDs array + int fontFileIDSize; // size of fontFileIDs array + char **fontFileNames; // list of names of all embedded external fonts + int fontFileNameLen; // number of entries in fontFileNames array + int fontFileNameSize; // size of fontFileNames array + + GBool ok; // set up ok? +}; + +#endif diff --git a/pdftops/Page.cxx b/pdftops/Page.cxx new file mode 100644 index 0000000000..7a5ee4bb1b --- /dev/null +++ b/pdftops/Page.cxx @@ -0,0 +1,211 @@ +//======================================================================== +// +// Page.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "XRef.h" +#include "OutputDev.h" +#ifndef PDF_PARSER_ONLY +#include "Gfx.h" +#endif +#include "Error.h" + +#include "Params.h" +#include "Page.h" + +//------------------------------------------------------------------------ +// PageAttrs +//------------------------------------------------------------------------ + +PageAttrs::PageAttrs(PageAttrs *attrs, Dict *dict) { + Object obj1, obj2; + double w, h; + + // get old/default values + if (attrs) { + x1 = attrs->x1; + y1 = attrs->y1; + x2 = attrs->x2; + y2 = attrs->y2; + cropX1 = attrs->cropX1; + cropY1 = attrs->cropY1; + cropX2 = attrs->cropX2; + cropY2 = attrs->cropY2; + rotate = attrs->rotate; + attrs->resources.copy(&resources); + } else { + // set default MediaBox to 8.5" x 11" -- this shouldn't be necessary + // but some (non-compliant) PDF files don't specify a MediaBox + x1 = 0; + y1 = 0; + x2 = 612; + y2 = 792; + cropX1 = cropY1 = cropX2 = cropY2 = 0; + rotate = 0; + resources.initNull(); + } + + // media box + dict->lookup("MediaBox", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 4) { + obj1.arrayGet(0, &obj2); + if (obj2.isNum()) + x1 = obj2.getNum(); + obj2.free(); + obj1.arrayGet(1, &obj2); + if (obj2.isNum()) + y1 = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2, &obj2); + if (obj2.isNum()) + x2 = obj2.getNum(); + obj2.free(); + obj1.arrayGet(3, &obj2); + if (obj2.isNum()) + y2 = obj2.getNum(); + obj2.free(); + } + obj1.free(); + + // crop box + dict->lookup("CropBox", &obj1); + if (obj1.isArray() && obj1.arrayGetLength() == 4) { + obj1.arrayGet(0, &obj2); + if (obj2.isNum()) + cropX1 = obj2.getNum(); + obj2.free(); + obj1.arrayGet(1, &obj2); + if (obj2.isNum()) + cropY1 = obj2.getNum(); + obj2.free(); + obj1.arrayGet(2, &obj2); + if (obj2.isNum()) + cropX2 = obj2.getNum(); + obj2.free(); + obj1.arrayGet(3, &obj2); + if (obj2.isNum()) + cropY2 = obj2.getNum(); + obj2.free(); + } + obj1.free(); + + // if the MediaBox is excessively larger than the CropBox, + // just use the CropBox + limitToCropBox = gFalse; + w = 0.25 * (cropX2 - cropX1); + h = 0.25 * (cropY2 - cropY1); + if (cropX2 > cropX1 && + (cropX1 - x1 > w || x2 - cropX2 > w || + cropY1 - y1 > h || y2 - cropY2 > h)) { + limitToCropBox = gTrue; + } + + // rotate + dict->lookup("Rotate", &obj1); + if (obj1.isInt()) + rotate = obj1.getInt(); + obj1.free(); + while (rotate < 0) + rotate += 360; + while (rotate >= 360) + rotate -= 360; + + // resource dictionary + dict->lookup("Resources", &obj1); + if (obj1.isDict()) { + resources.free(); + obj1.copy(&resources); + } + obj1.free(); +} + +PageAttrs::~PageAttrs() { + resources.free(); +} + +//------------------------------------------------------------------------ +// Page +//------------------------------------------------------------------------ + +Page::Page(int num1, Dict *pageDict, PageAttrs *attrs1) { + + ok = gTrue; + num = num1; + + // get attributes + attrs = attrs1; + + // annotations + pageDict->lookupNF("Annots", &annots); + if (!(annots.isRef() || annots.isArray() || annots.isNull())) { + error(-1, "Page annotations object (page %d) is wrong type (%s)", + num, annots.getTypeName()); + annots.free(); + goto err2; + } + + // contents + pageDict->lookupNF("Contents", &contents); + if (!(contents.isRef() || contents.isArray() || + contents.isNull())) { + error(-1, "Page contents object (page %d) is wrong type (%s)", + num, contents.getTypeName()); + contents.free(); + goto err1; + } + + return; + + err2: + annots.initNull(); + err1: + contents.initNull(); + ok = gFalse; +} + +Page::~Page() { + delete attrs; + annots.free(); + contents.free(); +} + +void Page::display(OutputDev *out, int dpi, int rotate) { +#ifndef PDF_PARSER_ONLY + Gfx *gfx; + Object obj; + + if (printCommands) { + printf("***** MediaBox = ll:%g,%g ur:%g,%g\n", + getX1(), getY1(), getX2(), getY2()); + if (isCropped()) { + printf("***** CropBox = ll:%g,%g ur:%g,%g\n", + getCropX1(), getCropY1(), getCropX2(), getCropY2()); + } + printf("***** Rotate = %d\n", attrs->getRotate()); + } + rotate += getRotate(); + if (rotate >= 360) + rotate -= 360; + else if (rotate < 0) + rotate += 360; + gfx = new Gfx(out, num, attrs->getResourceDict(), + dpi, getX1(), getY1(), getX2(), getY2(), isCropped(), + getCropX1(), getCropY1(), getCropX2(), getCropY2(), rotate); + contents.fetch(&obj); + if (!obj.isNull()) + gfx->display(&obj); + obj.free(); + delete gfx; +#endif +} diff --git a/pdftops/Page.h b/pdftops/Page.h new file mode 100644 index 0000000000..6c020c7dc0 --- /dev/null +++ b/pdftops/Page.h @@ -0,0 +1,111 @@ +//======================================================================== +// +// Page.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef PAGE_H +#define PAGE_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "Object.h" + +class Dict; +class XRef; +class OutputDev; + +//------------------------------------------------------------------------ +// PageAttrs +//------------------------------------------------------------------------ + +class PageAttrs { +public: + + // Construct a new PageAttrs object by merging a dictionary + // (of type Pages or Page) into another PageAttrs object. If + // is NULL, uses defaults. + PageAttrs(PageAttrs *attrs, Dict *dict); + + // Destructor. + ~PageAttrs(); + + // Accessors. + double getX1() { return limitToCropBox ? cropX1 : x1; } + double getY1() { return limitToCropBox ? cropY1 : y1; } + double getX2() { return limitToCropBox ? cropX2 : x2; } + double getY2() { return limitToCropBox ? cropY2 : y2; } + GBool isCropped() { return cropX2 > cropX1; } + double getCropX1() { return cropX1; } + double getCropY1() { return cropY1; } + double getCropX2() { return cropX2; } + double getCropY2() { return cropY2; } + int getRotate() { return rotate; } + Dict *getResourceDict() + { return resources.isDict() ? resources.getDict() : (Dict *)NULL; } + +private: + + double x1, y1, x2, y2; + double cropX1, cropY1, cropX2, cropY2; + GBool limitToCropBox; + int rotate; + Object resources; +}; + +//------------------------------------------------------------------------ +// Page +//------------------------------------------------------------------------ + +class Page { +public: + + // Constructor. + Page(int num1, Dict *pageDict, PageAttrs *attrs1); + + // Destructor. + ~Page(); + + // Is page valid? + GBool isOk() { return ok; } + + // Get page parameters. + double getX1() { return attrs->getX1(); } + double getY1() { return attrs->getY1(); } + double getX2() { return attrs->getX2(); } + double getY2() { return attrs->getY2(); } + GBool isCropped() { return attrs->isCropped(); } + double getCropX1() { return attrs->getCropX1(); } + double getCropY1() { return attrs->getCropY1(); } + double getCropX2() { return attrs->getCropX2(); } + double getCropY2() { return attrs->getCropY2(); } + double getWidth() { return attrs->getX2() - attrs->getX1(); } + double getHeight() { return attrs->getY2() - attrs->getY1(); } + int getRotate() { return attrs->getRotate(); } + + // Get resource + Dict *getResourceDict() { return attrs->getResourceDict(); } + + // Get annotations array. + Object *getAnnots(Object *obj) { return annots.fetch(obj); } + + // Get contents. + Object *getContents(Object *obj) { return contents.fetch(obj); } + + // Display a page. + void display(OutputDev *out, int dpi, int rotate); + +private: + + int num; // page number + PageAttrs *attrs; // page attributes + Object annots; // annotations array + Object contents; // page contents + GBool ok; // true if page is valid +}; + +#endif diff --git a/pdftops/Params.cxx b/pdftops/Params.cxx new file mode 100644 index 0000000000..35adfdfe00 --- /dev/null +++ b/pdftops/Params.cxx @@ -0,0 +1,87 @@ +//======================================================================== +// +// Params.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#include +#include +#include +#include +#include "gtypes.h" +#include "gmem.h" +#include "GString.h" +#include "gfile.h" +#include "Params.h" + +char **fontPath = NULL; +static int fontPathLen, fontPathSize; + +DevFontMapEntry *devFontMap = NULL; +static int devFontMapLen, devFontMapSize; + +void initParams(char *configFile) { + GString *fileName; + FILE *f; + char buf[256]; + char *p, *q; + + // initialize font path and font map + fontPath = (char **)gmalloc((fontPathSize = 8) * sizeof(char *)); + fontPath[fontPathLen = 0] = NULL; + devFontMap = (DevFontMapEntry *)gmalloc((devFontMapSize = 8) * + sizeof(DevFontMapEntry)); + devFontMap[devFontMapLen = 0].pdfFont = NULL; + + // read config file + fileName = appendToPath(getHomeDir(), configFile); + if ((f = fopen(fileName->getCString(), "r"))) { + while (fgets(buf, sizeof(buf)-1, f)) { + buf[sizeof(buf)-1] = '\0'; + p = strtok(buf, " \t\n\r"); + if (p && !strcmp(p, "fontpath")) { + if (fontPathLen+1 >= fontPathSize) + fontPath = (char **) + grealloc(fontPath, (fontPathSize += 8) * sizeof(char *)); + p = strtok(NULL, " \t\n\r"); + fontPath[fontPathLen++] = copyString(p); + } else if (p && !strcmp(p, "fontmap")) { + if (devFontMapLen+1 >= devFontMapSize) + devFontMap = (DevFontMapEntry *) + grealloc(devFontMap, + (devFontMapSize += 8) * sizeof(DevFontMapEntry)); + p = strtok(NULL, " \t\n\r"); + devFontMap[devFontMapLen].pdfFont = copyString(p); + p = strtok(NULL, "\t\n\r"); + while (*p == ' ') + ++p; + for (q = p + strlen(p) - 1; q >= p && *q == ' '; --q) ; + q[1] = '\0'; + devFontMap[devFontMapLen++].devFont = copyString(p); + } + } + fclose(f); + fontPath[fontPathLen] = NULL; + devFontMap[devFontMapLen].pdfFont = NULL; + } + delete fileName; +} + +void freeParams() { + int i; + + if (fontPath) { + for (i = 0; i < fontPathLen; ++i) + gfree(fontPath[i]); + gfree(fontPath); + } + if (devFontMap) { + for (i = 0; i < devFontMapLen; ++i) { + gfree(devFontMap[i].pdfFont); + gfree(devFontMap[i].devFont); + } + gfree(devFontMap); + } +} diff --git a/pdftops/Params.h b/pdftops/Params.h new file mode 100644 index 0000000000..4b5cc9fb47 --- /dev/null +++ b/pdftops/Params.h @@ -0,0 +1,40 @@ +//======================================================================== +// +// Params.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef PARAMS_H +#define PARAMS_H + +// Print commands as they're executed. +extern GBool printCommands; + +// Send error messages to /dev/tty instead of stderr. +extern GBool errorsToTTY; + +// If this is set, error messages will be silently discarded. +extern GBool errQuiet; + +// Font search path. +extern char **fontPath; + +// Mapping from PDF font name to device font name. +struct DevFontMapEntry { + char *pdfFont; + char *devFont; +}; +extern DevFontMapEntry *devFontMap; + +//------------------------------------------------------------------------ + +// Initialize font path and font map, and read configuration file, +// if present. +extern void initParams(char *configFile); + +// Free memory used for font path and font map. +extern void freeParams(); + +#endif diff --git a/pdftops/Parser.cxx b/pdftops/Parser.cxx new file mode 100644 index 0000000000..49968f3256 --- /dev/null +++ b/pdftops/Parser.cxx @@ -0,0 +1,161 @@ +//======================================================================== +// +// Parser.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include "Object.h" +#include "Array.h" +#include "Dict.h" +#include "Parser.h" +#include "Error.h" + +Parser::Parser(Lexer *lexer1) { + lexer = lexer1; + inlineImg = 0; + lexer->getObj(&buf1); + lexer->getObj(&buf2); +} + +Parser::~Parser() { + buf1.free(); + buf2.free(); + delete lexer; +} + +Object *Parser::getObj(Object *obj) { + char *key; + Stream *str; + Object obj2; + int num; + + // refill buffer after inline image data + if (inlineImg == 2) { + buf1.free(); + buf2.free(); + lexer->getObj(&buf1); + lexer->getObj(&buf2); + inlineImg = 0; + } + + // array + if (buf1.isCmd("[")) { + shift(); + obj->initArray(); + while (!buf1.isCmd("]") && !buf1.isEOF()) + obj->arrayAdd(getObj(&obj2)); + if (buf1.isEOF()) + error(getPos(), "End of file inside array"); + shift(); + + // dictionary or stream + } else if (buf1.isCmd("<<")) { + shift(); + obj->initDict(); + while (!buf1.isCmd(">>") && !buf1.isEOF()) { + if (!buf1.isName()) { + error(getPos(), "Dictionary key must be a name object"); + shift(); + } else { + key = copyString(buf1.getName()); + shift(); + if (buf1.isEOF() || buf1.isError()) + break; + obj->dictAdd(key, getObj(&obj2)); + } + } + if (buf1.isEOF()) + error(getPos(), "End of file inside dictionary"); + if (buf2.isCmd("stream")) { + if ((str = makeStream(obj))) { + obj->initStream(str); + } else { + obj->free(); + obj->initError(); + } + } else { + shift(); + } + + // indirect reference or integer + } else if (buf1.isInt()) { + num = buf1.getInt(); + shift(); + if (buf1.isInt() && buf2.isCmd("R")) { + obj->initRef(num, buf1.getInt()); + shift(); + shift(); + } else { + obj->initInt(num); + } + + // simple object + } else { + buf1.copy(obj); + shift(); + } + + return obj; +} + +Stream *Parser::makeStream(Object *dict) { + Object obj; + Stream *str; + int pos, length; + + // get stream start position + lexer->skipToNextLine(); + pos = lexer->getPos(); + + // get length + dict->dictLookup("Length", &obj); + if (obj.isInt()) { + length = obj.getInt(); + obj.free(); + } else { + error(getPos(), "Bad 'Length' attribute in stream"); + obj.free(); + return NULL; + } + + // make base stream + str = new FileStream(lexer->getStream()->getFile(), pos, length, dict); + + // get filters + str = str->addFilters(dict); + + // skip over stream data + lexer->setPos(pos + length); + + // refill token buffers and check for 'endstream' + shift(); // kill '>>' + shift(); // kill 'stream' + if (buf1.isCmd("endstream")) + shift(); + else + error(getPos(), "Missing 'endstream'"); + + return str; +} + +void Parser::shift() { + if (inlineImg > 0) { + ++inlineImg; + } else if (buf2.isCmd("ID")) { + lexer->skipChar(); // skip char after 'ID' command + inlineImg = 1; + } + buf1.free(); + buf1 = buf2; + if (inlineImg > 0) // don't buffer inline image data + buf2.initNull(); + else + lexer->getObj(&buf2); +} diff --git a/pdftops/Parser.h b/pdftops/Parser.h new file mode 100644 index 0000000000..1e2c117785 --- /dev/null +++ b/pdftops/Parser.h @@ -0,0 +1,51 @@ +//======================================================================== +// +// Parser.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef PARSER_H +#define PARSER_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include "Lexer.h" + +//------------------------------------------------------------------------ +// Parser +//------------------------------------------------------------------------ + +class Parser { +public: + + // Constructor. + Parser(Lexer *lexer1); + + // Destructor. + ~Parser(); + + // Get the next object from the input stream. + Object *getObj(Object *obj); + + // Get stream. + Stream *getStream() { return lexer->getStream(); } + + // Get current position in file. + int getPos() { return lexer->getPos(); } + +private: + + Lexer *lexer; // input stream + Object buf1, buf2; // next two tokens + int inlineImg; // set when inline image data is encountered + + Stream *makeStream(Object *dict); + void shift(); +}; + +#endif + diff --git a/pdftops/README b/pdftops/README new file mode 100644 index 0000000000..f6bc9ebee0 --- /dev/null +++ b/pdftops/README @@ -0,0 +1,348 @@ +xpdf +==== + +version 0.90 +99-aug-02 + +The xpdf software and documentation are +copyright 1996-1999 Derek B. Noonburg. + +Email: derekn@foolabs.com +WWW: http://www.foolabs.com/xpdf/ + +The PDF data structures, operators, and specification are +copyright 1995 Adobe Systems Inc. + + +What is xpdf? +------------- + +Xpdf is a viewer for Portable Document Format (PDF) files. (These are +also sometimes also called 'Acrobat' files, from the name of Adobe's +PDF software.) Xpdf runs under the X Window System on UNIX, VMS, and +OS/2. The non-X components of the package (pdftops, pdftotext, etc.) +also run on Win32 systems and should run on pretty much any system +with a decent C++ compiler. + +Xpdf is designed to be small and efficient. It does not use the Motif +or Xt libraries. It can use standard X fonts. + + +Distribution +------------ + +Xpdf is licensed under the GNU General Public License (GPL), version +2. In my opinion, the GPL is a convoluted, confusing, ambiguous mess. +But it's also pervasive, and I'm sick of arguing. And even if it is +confusing, the basic idea is good. + +In order to cut down on the confusion a little bit, here are some +informal clarifications: + +- I don't mind if you redistribute xpdf in source and/or binary form, + as long as you include all of the documentation: README, man pages + (or help files), and COPYING. (Note that the README file contains a + pointer to a web page with the source code.) + +- Selling a CD-ROM that contains xpdf is fine with me, as long as it + includes the documentation. I wouldn't mind receiving a sample + copy, but it's not necessary. + +- If you make useful changes to xpdf, please make the source code + available -- post it on a web site, email it to me, whatever. + +If you're interested in commercial licensing, please contact me by +email: derekn@foolabs.com . + + +Compatibility +------------- + +Xpdf is developed and tested on a Linux 2.0 x86 system. + +In addition, it has been compiled by others on Solaris, AIX, HP-UX, +SCO UnixWare, Digital Unix, Irix, and numerous other Unix +implementations, as well as VMS and OS/2. It should work on pretty +much any system which runs X11 and has Unix-like libraries. You'll +need ANSI C++ and C compilers to compile it. + +The non-X components of xpdf (pdftops, pdftotext, pdfinfo, pdfimages) +can also be compiled on Win32 systems. See the xpdf web page for +details. + +If you compiled xpdf for a system not listed on the web page, please +let me know. If you're willing to make your binary available by ftp +or on the web, I'll be happy to add a link from the xpdf web page. I +have decided not to host any binaries I didn't compile myself (for +disk space and support reasons). + +If you can't get xpdf to compile on your system, send me email and +I'll try to help. + +Xpdf has been ported to the Acorn, Amiga, and BeOS. See the xpdf web +page for links. + + +Getting xpdf +------------ + +The latest version is available from: + + http://www.foolabs.com/xpdf/ + +or: + + ftp://ftp.foolabs.com/pub/xpdf/ + +Source code and several precompiled executables are available. + +Announcements of new versions are posted to several newsgroups +(comp.text.pdf, comp.os.linux.announce, and others) and emailed to a +list of people. If you'd like to receive email notification of new +versions, just let me know. + + +Running xpdf +------------ + +To run xpdf, simply type: + + xpdf file.pdf + +To generate a PostScript file, hit the "print" button in xpdf, or run +pdftops: + + pdftops file.pdf + +To generate a plain text file, run pdftotext: + + pdftotext file.pdf + +There are three additional utilities (which are fully described in +their man pages): + + pdfinfo -- dumps a PDF file's Info dictionary (plus some other + useful information) + pdftopbm -- converts a PDF file to a series of PBM-format bitmaps + pdfimages -- extracts the images from a PDF file + +Command line options and many other details are described in the man +pages (xpdf.1, etc.) and the VMS help files (xpdf.hlp, etc.). + + +Fonts +----- + +Xpdf uses X server fonts. It requires the following fonts: + +* Courier: medium-r, bold-r, medium-o, and bold-o +* Helvetica: medium-r, bold-r, medium-o, and bold-o +* Times: medium-r, bold-r, medium-i, and bold-i +* Symbol: medium-r +* Zapf Dingbats: medium-r + +Most X installations should already have all of these fonts, except +Zapf Dingbats. You can install a Type 1 Zapf Dingbats font -- see the +mkfontdir(1) man page for details. Use this font descriptor in your +fonts.scale file: + + -itc-zapfdingbats-medium-r-normal--0-0-0-0-p-0-adobe-fontspecific + +You can get a Type 1 font file from the ghostscript 4.x distribution +(look for d050000l.pfb). + +X servers, starting at R5, support font scaling. Xpdf will +automatically take advantage of this. There are two types of scaling. +The first type uses standard bitmap fonts: if a font doesn't exist in +the requested size, the server will scale the bitmapped characters. +This is reasonably fast, and the results are readable but not very +pretty. X servers can also handle true scalable, e.g., Type 1, fonts. +(See the mkfontdir(1) man page for details on setting these up.) +Scalable fonts are slower, especially since PDF documents tend to use +lots of fonts, but they look much nicer. + +Some X servers also support font rotation. Xpdf will use this feature +if available. + +For Japanese support, you will need a Japanese font of the form: + + -*-fixed-medium-r-normal-*-NN-*-*-*-*-*-jisx0208.1983-0 + +and an X server that can handle 16-bit fonts. + +If compiled with t1lib support, xpdf will use t1lib to render embedded +Type 1 and Type 1C fonts. In addition, xpdf can be configured to use +t1lib for the base 14 fonts and for substituted fonts. To enable this +feature, you must set an X resource for each Type 1 font file. For +example: + + xpdf.t1TimesRoman: /usr/local/fonts/Times-Roman.pfa + xpdf.t1TimesItalic: /usr/local/fonts/Times-Italic.pfa + xpdf.t1TimesBold: /usr/local/fonts/Times-Bold.pfa + xpdf.t1TimesBoldItalic: /usr/local/fonts/Times-BoldItalic.pfa + xpdf.t1Helvetica: /usr/local/fonts/Helvetica.pfa + xpdf.t1HelveticaOblique: /usr/local/fonts/Helvetica-Oblique.pfa + xpdf.t1HelveticaBold: /usr/local/fonts/Helvetica-Bold.pfa + xpdf.t1HelveticaBoldOblique: /usr/local/fonts/Helvetica-BoldOblique.pfa + xpdf.t1Courier: /usr/local/fonts/Courier.pfa + xpdf.t1CourierOblique: /usr/local/fonts/Courier-Oblique.pfa + xpdf.t1CourierBold: /usr/local/fonts/Courier-Bold.pfa + xpdf.t1CourierBoldOblique: /usr/local/fonts/Courier-BoldOblique.pfa + xpdf.t1Symbol: /usr/local/fonts/Symbol.pfa + xpdf.t1ZapfDingbats: /usr/local/fonts/ZapfDingbats.pfa + + +The Unisys LZW Patent +--------------------- + +Nearly all PDF files include data which has been compressed with the +LZW compression algorithm. Unfortunately, LZW is covered by a +software patent which is owned by Unisys Corporation. Unisys refuses +to license this patent for PDF-related use in software such as xpdf +which is released for free and which may be freely redistributed. +(This is same algorithm which is used by GIF. However, Unisys is not +doing licensing for free PDF viwers in the same way as for free GIF +viewers.) + +As a workaround, xpdf converts PDF-format LZW data to compress-format +LZW data. (The standard UNIX compress utility also uses LZW, but with +a slightly different file format.) This conversion does *not* +decompress the data; it simply converts it to a different file format. +Xpdf then calls uncompress to actually decompress the data. + +I have been told by several notable people that the LZW patent covers +compression only, and does not cover decompression. This seems pretty +fuzzy to me, so I'm going to stick with my workaround, at least for +now. + +For Unisys's slant on things (mostly regarding GIF), see + and +. These pages mention +an email address for feedback. + + +Compiling xpdf +-------------- + +See the separate file, INSTALL. + + +Bugs +---- + +This release of xpdf should improve the situation with embedded +fonts. However, Type 3 and TrueType fonts are still not handled. + +If you find a bug in xpdf, i.e., if it prints an error message, +crashes, or incorrectly displays a document, and you don't see that +bug listed here, please send me email, with a pointer (URL, ftp site, +etc.) to the PDF file. + + +Acknowledgments +--------------- + +Thanks to: + +* Patrick Voigt for help with the remote server code. +* Patrick Moreau and Martin P.J. Zinser for the VMS port. +* David Boldt and Rick Rodgers for sample man pages. +* Brendan Miller for the icon idea. +* Olly Betts for help testing pdftotext. +* Peter Ganten for the OS/2 port. +* Michael Richmond for the Win32 port of pdftops and pdftotext. +* Frank M. Siegert for improvements in the PostScript code. +* Leo Smiers for the decryption patches. +* Rainer Menzner for creating t1lib, and for helping me adapt it to + xpdf. + + +References +---------- + +Adobe Systems Inc., _Portable Document Format Reference Manual_. +Addison-Wesley, 1993, ISBN 0-201-62628-4. +[The printed manual for PDF version 1.0.] + +Adobe Systems Inc., _Portable Document Format Reference Manual_, +Version 1.3. March 11, 1999. +http://partners.adobe.com/asn/developer/PDFS/TN/PDFSPEC.PDF +[Updated manual for PDF 1.3.] + +Adobe Systems Inc., _PostScript Language Reference Manual_, 2nd ed. +Addison-Wesley, 1990, ISBN 0-201-18127-4. +[The official PostScript manual.] + +Adobe Systems, Inc., _Adobe CMap and CIDFont Files Specification_, +Adobe Developer Support Technical Specification #5014. 1995. +http://www.adobe.com/supportservice/devrelations/PDFS/TN/5014.CIDFont_Spec.pdf +[CMap file format needed for Japanese font support.] + +Adobe Systems, Inc., _Adobe-Japan1-2 Character Collection for +CID-Keyed Fonts_ (Bitmap Character Image Version), Adobe Developer +Support Technical Note #5078-b. 1994. +http://www.adobe.com/supportservice/devrelations/PDFS/TN/5078b.pdf +[The complete Adobe Japanese character set.] + +Adobe Systems Inc., _Supporting the DCT Filters in PostScript Level +2_, Adobe Developer Support Technical Note #5116. 1992. +http://www.adobe.com/supportservice/devrelations/PDFS/TN/5116.PS2_DCT.PDF +[Description of the DCTDecode filter parameters.] + +Anonymous, RC4 source code. +ftp://ftp.ox.ac.uk/pub/crypto/misc/rc4.tar.gz +ftp://idea.sec.dsi.unimi.it/pub/crypt/code/rc4.tar.gz +[This is the algorithm used to encrypt PDF files.] + +CCITT, _Blue Book_, Volume VII Fascicle 3: "Terminal Equipment and +Protocols for Telematic Services", Recommendations T.4 and T.6. +ftp://ftp.uu.net/doc/standards/ccitt/1988/7_3_01.ps +ftp://ftp.uu.net/doc/standards/ccitt/1988/7_3_02.ps +[The official Group 3 and 4 fax standards. The online copies are +unfortunately misformatted.] + +L. Peter Deutsch, "ZLIB Compressed Data Format Specification version +3.3". RFC 1950. +[Information on the general format used in FlateDecode streams.] + +L. Peter Deutsch, "DEFLATE Compressed Data Format Specification +version 1.3". RFC 1951. +[The definition of the compression algorithm used in FlateDecode +streams.] + +Jim Flowers, "X Logical Font Description Conventions", Version 1.5, X +Consortium Standard, X Version 11, Release 6.1. +ftp://ftp.x.org/pub/R6.1/xc/doc/hardcopy/XLFD/xlfd.PS.Z +[The official specification of X font descriptors, including font +transformation matrices.] + +Foley, van Dam, Feiner, and Hughes, _Computer Graphics: Principles and +Practice_, 2nd ed. Addison-Wesley, 1990, ISBN 0-201-12110-7. +[Colorspace conversion functions, Bezier spline math.] + +Robert L. Hummel, _Programmer's Technical Reference: Data and Fax +Communications_. Ziff-Davis Press, 1993, ISBN 1-56276-077-7. +[CCITT Group 3 and 4 fax decoding.] + +Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz, "Practical +Fast 1-D DCT Algorithms with 11 Multiplications". IEEE Intl. Conf. on +Acoustics, Speech & Signal Processing, 1989, 988-991. +[The fast IDCT algorithm used in the DCTDecode filter.] + +R. Rivest, "The MD5 Message-Digest Algorithm". RFC 1321. +[MD5 is used in PDF document encryption.] + +Gregory K. Wallace, "The JPEG Still Picture Compression Standard". +ftp://ftp.uu.net/graphics/jpeg/wallace.ps.gz +[Good description of the JPEG standard. Also published in CACM, April +1991, and submitted to IEEE Transactions on Consumer Electronics.] + +W3C Recommendation, "PNG (Portable Network Graphics) Specification +Version 1.0". +http://www.w3.org/Graphics/PNG/ +[Defines the PNG image predictor.] + +"ISO 8859-2 (Latin 2) Resources". +http://sizif.mf.uni-lj.si/linux/cee/iso8859-2.html +[This is a web page with all sorts of useful Latin-2 character set and +font information.] diff --git a/pdftops/StdFontInfo.h b/pdftops/StdFontInfo.h new file mode 100644 index 0000000000..0db033f6bd --- /dev/null +++ b/pdftops/StdFontInfo.h @@ -0,0 +1,546 @@ +//======================================================================== +// +// StdFontInfo.h +// +// This file was automatically generated by makeFontInfo. +// +// Copyright 1999 Derek B. Noonburg +// +//======================================================================== + +#ifndef STDFONTINFO_H +#define STDFONTINFO_H + +//------------------------------------------------------------------------ +// type1StdEncoding -- Adobe Type 1 StandardEncoding +//------------------------------------------------------------------------ + +#define type1StdEncodingSize 256 +static char *type1StdEncodingNames[type1StdEncodingSize] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclam", + "quotedbl", + "numbersign", + "dollar", + "percent", + "ampersand", + "quoteright", + "parenleft", + "parenright", + "asterisk", + "plus", + "comma", + "hyphen", + "period", + "slash", + "zero", + "one", + "two", + "three", + "four", + "five", + "six", + "seven", + "eight", + "nine", + "colon", + "semicolon", + "less", + "equal", + "greater", + "question", + "at", + "A", + "B", + "C", + "D", + "E", + "F", + "G", + "H", + "I", + "J", + "K", + "L", + "M", + "N", + "O", + "P", + "Q", + "R", + "S", + "T", + "U", + "V", + "W", + "X", + "Y", + "Z", + "bracketleft", + "backslash", + "bracketright", + "asciicircum", + "underscore", + "quoteleft", + "a", + "b", + "c", + "d", + "e", + "f", + "g", + "h", + "i", + "j", + "k", + "l", + "m", + "n", + "o", + "p", + "q", + "r", + "s", + "t", + "u", + "v", + "w", + "x", + "y", + "z", + "braceleft", + "bar", + "braceright", + "asciitilde", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "exclamdown", + "cent", + "sterling", + "fraction", + "yen", + "florin", + "section", + "currency", + "quotesingle", + "quotedblleft", + "guillemotleft", + "guilsinglleft", + "guilsinglright", + "fi", + "fl", + NULL, + "endash", + "dagger", + "daggerdbl", + "periodcentered", + NULL, + "paragraph", + "bullet", + "quotesinglbase", + "quotedblbase", + "quotedblright", + "guillemotright", + "ellipsis", + "perthousand", + NULL, + "questiondown", + NULL, + "grave", + "acute", + "circumflex", + "tilde", + "macron", + "breve", + "dotaccent", + "dieresis", + NULL, + "ring", + "cedilla", + NULL, + "hungarumlaut", + "ogonek", + "caron", + "emdash", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "AE", + NULL, + "ordfeminine", + NULL, + NULL, + NULL, + NULL, + "Lslash", + "Oslash", + "OE", + "ordmasculine", + NULL, + NULL, + NULL, + NULL, + NULL, + "ae", + NULL, + NULL, + NULL, + "dotlessi", + NULL, + NULL, + "lslash", + "oslash", + "oe", + "germandbls", + NULL, + NULL, + NULL, + NULL +}; +static FontEncoding type1StdEncoding(type1StdEncodingNames, + type1StdEncodingSize); + +//------------------------------------------------------------------------ +// type1ExpertEncoding -- Adobe Type 1 ExpertEncoding +//------------------------------------------------------------------------ + +#define type1ExpertEncodingSize 256 +static char *type1ExpertEncodingNames[type1ExpertEncodingSize] = { + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "space", + "exclamsmall", + "Hungarumlautsmall", + NULL, + "dollaroldstyle", + "dollarsuperior", + "ampersandsmall", + "Acutesmall", + "parenleftsuperior", + "parenrightsuperior", + "twodotenleader", + "onedotenleader", + "comma", + "hyphen", + "period", + "fraction", + "zerooldstyle", + "oneoldstyle", + "twooldstyle", + "threeoldstyle", + "fouroldstyle", + "fiveoldstyle", + "sixoldstyle", + "sevenoldstyle", + "eightoldstyle", + "nineoldstyle", + "colon", + "semicolon", + "commasuperior", + "threequartersemdash", + "periodsuperior", + "questionsmall", + NULL, + "asuperior", + "bsuperior", + "centsuperior", + "dsuperior", + "esuperior", + NULL, + NULL, + NULL, + "isuperior", + NULL, + NULL, + "lsuperior", + "msuperior", + "nsuperior", + "osuperior", + NULL, + NULL, + "rsuperior", + "ssuperior", + "tsuperior", + NULL, + "ff", + "fi", + "fl", + "ffi", + "ffl", + "parenleftinferior", + NULL, + "parenrightinferior", + "Circumflexsmall", + "hyphensuperior", + "Gravesmall", + "Asmall", + "Bsmall", + "Csmall", + "Dsmall", + "Esmall", + "Fsmall", + "Gsmall", + "Hsmall", + "Ismall", + "Jsmall", + "Ksmall", + "Lsmall", + "Msmall", + "Nsmall", + "Osmall", + "Psmall", + "Qsmall", + "Rsmall", + "Ssmall", + "Tsmall", + "Usmall", + "Vsmall", + "Wsmall", + "Xsmall", + "Ysmall", + "Zsmall", + "colonmonetary", + "onefitted", + "rupiah", + "Tildesmall", + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + NULL, + "exclamdownsmall", + "centoldstyle", + "Lslashsmall", + NULL, + NULL, + "Scaronsmall", + "Zcaronsmall", + "Dieresissmall", + "Brevesmall", + "Caronsmall", + NULL, + "Dotaccentsmall", + NULL, + NULL, + "Macronsmall", + NULL, + NULL, + "figuredash", + "hypheninferior", + NULL, + NULL, + "Ogoneksmall", + "Ringsmall", + "Cedillasmall", + NULL, + NULL, + NULL, + "onequarter", + "onehalf", + "threequarters", + "questiondownsmall", + "oneeighth", + "threeeighths", + "fiveeighths", + "seveneighths", + "onethird", + "twothirds", + NULL, + NULL, + "zerosuperior", + "onesuperior", + "twosuperior", + "threesuperior", + "foursuperior", + "fivesuperior", + "sixsuperior", + "sevensuperior", + "eightsuperior", + "ninesuperior", + "zeroinferior", + "oneinferior", + "twoinferior", + "threeinferior", + "fourinferior", + "fiveinferior", + "sixinferior", + "seveninferior", + "eightinferior", + "nineinferior", + "centinferior", + "dollarinferior", + "periodinferior", + "commainferior", + "Agravesmall", + "Aacutesmall", + "Acircumflexsmall", + "Atildesmall", + "Adieresissmall", + "Aringsmall", + "AEsmall", + "Ccedillasmall", + "Egravesmall", + "Eacutesmall", + "Ecircumflexsmall", + "Edieresissmall", + "Igravesmall", + "Iacutesmall", + "Icircumflexsmall", + "Idieresissmall", + "Ethsmall", + "Ntildesmall", + "Ogravesmall", + "Oacutesmall", + "Ocircumflexsmall", + "Otildesmall", + "Odieresissmall", + "OEsmall", + "Oslashsmall", + "Ugravesmall", + "Uacutesmall", + "Ucircumflexsmall", + "Udieresissmall", + "Yacutesmall", + "Thornsmall", + "Ydieresissmall" +}; +static FontEncoding type1ExpertEncoding(type1ExpertEncodingNames, + type1ExpertEncodingSize); + +#endif diff --git a/pdftops/Stream-CCITT.h b/pdftops/Stream-CCITT.h new file mode 100644 index 0000000000..1af874225d --- /dev/null +++ b/pdftops/Stream-CCITT.h @@ -0,0 +1,459 @@ +//======================================================================== +// +// Stream-CCITT.h +// +// Tables for CCITT Fax decoding. +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +struct CCITTCode { + short bits; + short n; +}; + +#define ccittEOL -2 + +//------------------------------------------------------------------------ +// 2D codes +//------------------------------------------------------------------------ + +#define twoDimPass 0 +#define twoDimHoriz 1 +#define twoDimVert0 2 +#define twoDimVertR1 3 +#define twoDimVertL1 4 +#define twoDimVertR2 5 +#define twoDimVertL2 6 +#define twoDimVertR3 7 +#define twoDimVertL3 8 + +// 1-7 bit codes +static CCITTCode twoDimTab1[128] = { + {-1, -1}, {-1, -1}, // 000000x + {7, twoDimVertL3}, // 0000010 + {7, twoDimVertR3}, // 0000011 + {6, twoDimVertL2}, {6, twoDimVertL2}, // 000010x + {6, twoDimVertR2}, {6, twoDimVertR2}, // 000011x + {4, twoDimPass}, {4, twoDimPass}, // 0001xxx + {4, twoDimPass}, {4, twoDimPass}, + {4, twoDimPass}, {4, twoDimPass}, + {4, twoDimPass}, {4, twoDimPass}, + {3, twoDimHoriz}, {3, twoDimHoriz}, // 001xxxx + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimHoriz}, {3, twoDimHoriz}, + {3, twoDimVertL1}, {3, twoDimVertL1}, // 010xxxx + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertL1}, {3, twoDimVertL1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, // 011xxxx + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {3, twoDimVertR1}, {3, twoDimVertR1}, + {1, twoDimVert0}, {1, twoDimVert0}, // 1xxxxxx + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0}, + {1, twoDimVert0}, {1, twoDimVert0} +}; + +//------------------------------------------------------------------------ +// white run lengths +//------------------------------------------------------------------------ + +// 11-12 bit codes (upper 7 bits are 0) +static CCITTCode whiteTab1[32] = { + {-1, -1}, // 00000 + {12, ccittEOL}, // 00001 + {-1, -1}, {-1, -1}, // 0001x + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 001xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 010xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 011xx + {11, 1792}, {11, 1792}, // 1000x + {12, 1984}, // 10010 + {12, 2048}, // 10011 + {12, 2112}, // 10100 + {12, 2176}, // 10101 + {12, 2240}, // 10110 + {12, 2304}, // 10111 + {11, 1856}, {11, 1856}, // 1100x + {11, 1920}, {11, 1920}, // 1101x + {12, 2368}, // 11100 + {12, 2432}, // 11101 + {12, 2496}, // 11110 + {12, 2560} // 11111 +}; + +// 1-9 bit codes +static CCITTCode whiteTab2[512] = { + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 0000000xx + {8, 29}, {8, 29}, // 00000010x + {8, 30}, {8, 30}, // 00000011x + {8, 45}, {8, 45}, // 00000100x + {8, 46}, {8, 46}, // 00000101x + {7, 22}, {7, 22}, {7, 22}, {7, 22}, // 0000011xx + {7, 23}, {7, 23}, {7, 23}, {7, 23}, // 0000100xx + {8, 47}, {8, 47}, // 00001010x + {8, 48}, {8, 48}, // 00001011x + {6, 13}, {6, 13}, {6, 13}, {6, 13}, // 000011xxx + {6, 13}, {6, 13}, {6, 13}, {6, 13}, + {7, 20}, {7, 20}, {7, 20}, {7, 20}, // 0001000xx + {8, 33}, {8, 33}, // 00010010x + {8, 34}, {8, 34}, // 00010011x + {8, 35}, {8, 35}, // 00010100x + {8, 36}, {8, 36}, // 00010101x + {8, 37}, {8, 37}, // 00010110x + {8, 38}, {8, 38}, // 00010111x + {7, 19}, {7, 19}, {7, 19}, {7, 19}, // 0001100xx + {8, 31}, {8, 31}, // 00011010x + {8, 32}, {8, 32}, // 00011011x + {6, 1}, {6, 1}, {6, 1}, {6, 1}, // 000111xxx + {6, 1}, {6, 1}, {6, 1}, {6, 1}, + {6, 12}, {6, 12}, {6, 12}, {6, 12}, // 001000xxx + {6, 12}, {6, 12}, {6, 12}, {6, 12}, + {8, 53}, {8, 53}, // 00100100x + {8, 54}, {8, 54}, // 00100101x + {7, 26}, {7, 26}, {7, 26}, {7, 26}, // 0010011xx + {8, 39}, {8, 39}, // 00101000x + {8, 40}, {8, 40}, // 00101001x + {8, 41}, {8, 41}, // 00101010x + {8, 42}, {8, 42}, // 00101011x + {8, 43}, {8, 43}, // 00101100x + {8, 44}, {8, 44}, // 00101101x + {7, 21}, {7, 21}, {7, 21}, {7, 21}, // 0010111xx + {7, 28}, {7, 28}, {7, 28}, {7, 28}, // 0011000xx + {8, 61}, {8, 61}, // 00110010x + {8, 62}, {8, 62}, // 00110011x + {8, 63}, {8, 63}, // 00110100x + {8, 0}, {8, 0}, // 00110101x + {8, 320}, {8, 320}, // 00110110x + {8, 384}, {8, 384}, // 00110111x + {5, 10}, {5, 10}, {5, 10}, {5, 10}, // 00111xxxx + {5, 10}, {5, 10}, {5, 10}, {5, 10}, + {5, 10}, {5, 10}, {5, 10}, {5, 10}, + {5, 10}, {5, 10}, {5, 10}, {5, 10}, + {5, 11}, {5, 11}, {5, 11}, {5, 11}, // 01000xxxx + {5, 11}, {5, 11}, {5, 11}, {5, 11}, + {5, 11}, {5, 11}, {5, 11}, {5, 11}, + {5, 11}, {5, 11}, {5, 11}, {5, 11}, + {7, 27}, {7, 27}, {7, 27}, {7, 27}, // 0100100xx + {8, 59}, {8, 59}, // 01001010x + {8, 60}, {8, 60}, // 01001011x + {9, 1472}, // 010011000 + {9, 1536}, // 010011001 + {9, 1600}, // 010011010 + {9, 1728}, // 010011011 + {7, 18}, {7, 18}, {7, 18}, {7, 18}, // 0100111xx + {7, 24}, {7, 24}, {7, 24}, {7, 24}, // 0101000xx + {8, 49}, {8, 49}, // 01010010x + {8, 50}, {8, 50}, // 01010011x + {8, 51}, {8, 51}, // 01010100x + {8, 52}, {8, 52}, // 01010101x + {7, 25}, {7, 25}, {7, 25}, {7, 25}, // 0101011xx + {8, 55}, {8, 55}, // 01011000x + {8, 56}, {8, 56}, // 01011001x + {8, 57}, {8, 57}, // 01011010x + {8, 58}, {8, 58}, // 01011011x + {6, 192}, {6, 192}, {6, 192}, {6, 192}, // 010111xxx + {6, 192}, {6, 192}, {6, 192}, {6, 192}, + {6, 1664}, {6, 1664}, {6, 1664}, {6, 1664}, // 011000xxx + {6, 1664}, {6, 1664}, {6, 1664}, {6, 1664}, + {8, 448}, {8, 448}, // 01100100x + {8, 512}, {8, 512}, // 01100101x + {9, 704}, // 011001100 + {9, 768}, // 011001101 + {8, 640}, {8, 640}, // 01100111x + {8, 576}, {8, 576}, // 01101000x + {9, 832}, // 011010010 + {9, 896}, // 011010011 + {9, 960}, // 011010100 + {9, 1024}, // 011010101 + {9, 1088}, // 011010110 + {9, 1152}, // 011010111 + {9, 1216}, // 011011000 + {9, 1280}, // 011011001 + {9, 1344}, // 011011010 + {9, 1408}, // 011011011 + {7, 256}, {7, 256}, {7, 256}, {7, 256}, // 0110111xx + {4, 2}, {4, 2}, {4, 2}, {4, 2}, // 0111xxxxx + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 2}, {4, 2}, {4, 2}, {4, 2}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, // 1000xxxxx + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {4, 3}, {4, 3}, {4, 3}, {4, 3}, + {5, 128}, {5, 128}, {5, 128}, {5, 128}, // 10010xxxx + {5, 128}, {5, 128}, {5, 128}, {5, 128}, + {5, 128}, {5, 128}, {5, 128}, {5, 128}, + {5, 128}, {5, 128}, {5, 128}, {5, 128}, + {5, 8}, {5, 8}, {5, 8}, {5, 8}, // 10011xxxx + {5, 8}, {5, 8}, {5, 8}, {5, 8}, + {5, 8}, {5, 8}, {5, 8}, {5, 8}, + {5, 8}, {5, 8}, {5, 8}, {5, 8}, + {5, 9}, {5, 9}, {5, 9}, {5, 9}, // 10100xxxx + {5, 9}, {5, 9}, {5, 9}, {5, 9}, + {5, 9}, {5, 9}, {5, 9}, {5, 9}, + {5, 9}, {5, 9}, {5, 9}, {5, 9}, + {6, 16}, {6, 16}, {6, 16}, {6, 16}, // 101010xxx + {6, 16}, {6, 16}, {6, 16}, {6, 16}, + {6, 17}, {6, 17}, {6, 17}, {6, 17}, // 101011xxx + {6, 17}, {6, 17}, {6, 17}, {6, 17}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, // 1011xxxxx + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 4}, {4, 4}, {4, 4}, {4, 4}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, // 1100xxxxx + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {4, 5}, {4, 5}, {4, 5}, {4, 5}, + {6, 14}, {6, 14}, {6, 14}, {6, 14}, // 110100xxx + {6, 14}, {6, 14}, {6, 14}, {6, 14}, + {6, 15}, {6, 15}, {6, 15}, {6, 15}, // 110101xxx + {6, 15}, {6, 15}, {6, 15}, {6, 15}, + {5, 64}, {5, 64}, {5, 64}, {5, 64}, // 11011xxxx + {5, 64}, {5, 64}, {5, 64}, {5, 64}, + {5, 64}, {5, 64}, {5, 64}, {5, 64}, + {5, 64}, {5, 64}, {5, 64}, {5, 64}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, // 1110xxxxx + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 6}, {4, 6}, {4, 6}, {4, 6}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, // 1111xxxxx + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7}, + {4, 7}, {4, 7}, {4, 7}, {4, 7} +}; + +//------------------------------------------------------------------------ +// black run lengths +//------------------------------------------------------------------------ + +// 10-13 bit codes (upper 6 bits are 0) +static CCITTCode blackTab1[128] = { + {-1, -1}, {-1, -1}, // 000000000000x + {12, ccittEOL}, {12, ccittEOL}, // 000000000001x + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000001xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000010xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000011xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000100xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000101xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000110xx + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 00000000111xx + {11, 1792}, {11, 1792}, {11, 1792}, {11, 1792}, // 00000001000xx + {12, 1984}, {12, 1984}, // 000000010010x + {12, 2048}, {12, 2048}, // 000000010011x + {12, 2112}, {12, 2112}, // 000000010100x + {12, 2176}, {12, 2176}, // 000000010101x + {12, 2240}, {12, 2240}, // 000000010110x + {12, 2304}, {12, 2304}, // 000000010111x + {11, 1856}, {11, 1856}, {11, 1856}, {11, 1856}, // 00000001100xx + {11, 1920}, {11, 1920}, {11, 1920}, {11, 1920}, // 00000001101xx + {12, 2368}, {12, 2368}, // 000000011100x + {12, 2432}, {12, 2432}, // 000000011101x + {12, 2496}, {12, 2496}, // 000000011110x + {12, 2560}, {12, 2560}, // 000000011111x + {10, 18}, {10, 18}, {10, 18}, {10, 18}, // 0000001000xxx + {10, 18}, {10, 18}, {10, 18}, {10, 18}, + {12, 52}, {12, 52}, // 000000100100x + {13, 640}, // 0000001001010 + {13, 704}, // 0000001001011 + {13, 768}, // 0000001001100 + {13, 832}, // 0000001001101 + {12, 55}, {12, 55}, // 000000100111x + {12, 56}, {12, 56}, // 000000101000x + {13, 1280}, // 0000001010010 + {13, 1344}, // 0000001010011 + {13, 1408}, // 0000001010100 + {13, 1472}, // 0000001010101 + {12, 59}, {12, 59}, // 000000101011x + {12, 60}, {12, 60}, // 000000101100x + {13, 1536}, // 0000001011010 + {13, 1600}, // 0000001011011 + {11, 24}, {11, 24}, {11, 24}, {11, 24}, // 00000010111xx + {11, 25}, {11, 25}, {11, 25}, {11, 25}, // 00000011000xx + {13, 1664}, // 0000001100100 + {13, 1728}, // 0000001100101 + {12, 320}, {12, 320}, // 000000110011x + {12, 384}, {12, 384}, // 000000110100x + {12, 448}, {12, 448}, // 000000110101x + {13, 512}, // 0000001101100 + {13, 576}, // 0000001101101 + {12, 53}, {12, 53}, // 000000110111x + {12, 54}, {12, 54}, // 000000111000x + {13, 896}, // 0000001110010 + {13, 960}, // 0000001110011 + {13, 1024}, // 0000001110100 + {13, 1088}, // 0000001110101 + {13, 1152}, // 0000001110110 + {13, 1216}, // 0000001110111 + {10, 64}, {10, 64}, {10, 64}, {10, 64}, // 0000001111xxx + {10, 64}, {10, 64}, {10, 64}, {10, 64} +}; + +// 7-12 bit codes (upper 4 bits are 0) +static CCITTCode blackTab2[192] = { + {8, 13}, {8, 13}, {8, 13}, {8, 13}, // 00000100xxxx + {8, 13}, {8, 13}, {8, 13}, {8, 13}, + {8, 13}, {8, 13}, {8, 13}, {8, 13}, + {8, 13}, {8, 13}, {8, 13}, {8, 13}, + {11, 23}, {11, 23}, // 00000101000x + {12, 50}, // 000001010010 + {12, 51}, // 000001010011 + {12, 44}, // 000001010100 + {12, 45}, // 000001010101 + {12, 46}, // 000001010110 + {12, 47}, // 000001010111 + {12, 57}, // 000001011000 + {12, 58}, // 000001011001 + {12, 61}, // 000001011010 + {12, 256}, // 000001011011 + {10, 16}, {10, 16}, {10, 16}, {10, 16}, // 0000010111xx + {10, 17}, {10, 17}, {10, 17}, {10, 17}, // 0000011000xx + {12, 48}, // 000001100100 + {12, 49}, // 000001100101 + {12, 62}, // 000001100110 + {12, 63}, // 000001100111 + {12, 30}, // 000001101000 + {12, 31}, // 000001101001 + {12, 32}, // 000001101010 + {12, 33}, // 000001101011 + {12, 40}, // 000001101100 + {12, 41}, // 000001101101 + {11, 22}, {11, 22}, // 00000110111x + {8, 14}, {8, 14}, {8, 14}, {8, 14}, // 00000111xxxx + {8, 14}, {8, 14}, {8, 14}, {8, 14}, + {8, 14}, {8, 14}, {8, 14}, {8, 14}, + {8, 14}, {8, 14}, {8, 14}, {8, 14}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, // 0000100xxxxx + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 10}, {7, 10}, {7, 10}, {7, 10}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, // 0000101xxxxx + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {7, 11}, {7, 11}, {7, 11}, {7, 11}, + {9, 15}, {9, 15}, {9, 15}, {9, 15}, // 000011000xxx + {9, 15}, {9, 15}, {9, 15}, {9, 15}, + {12, 128}, // 000011001000 + {12, 192}, // 000011001001 + {12, 26}, // 000011001010 + {12, 27}, // 000011001011 + {12, 28}, // 000011001100 + {12, 29}, // 000011001101 + {11, 19}, {11, 19}, // 00001100111x + {11, 20}, {11, 20}, // 00001101000x + {12, 34}, // 000011010010 + {12, 35}, // 000011010011 + {12, 36}, // 000011010100 + {12, 37}, // 000011010101 + {12, 38}, // 000011010110 + {12, 39}, // 000011010111 + {11, 21}, {11, 21}, // 00001101100x + {12, 42}, // 000011011010 + {12, 43}, // 000011011011 + {10, 0}, {10, 0}, {10, 0}, {10, 0}, // 0000110111xx + {7, 12}, {7, 12}, {7, 12}, {7, 12}, // 0000111xxxxx + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12}, + {7, 12}, {7, 12}, {7, 12}, {7, 12} +}; + +// 2-6 bit codes +static CCITTCode blackTab3[64] = { + {-1, -1}, {-1, -1}, {-1, -1}, {-1, -1}, // 0000xx + {6, 9}, // 000100 + {6, 8}, // 000101 + {5, 7}, {5, 7}, // 00011x + {4, 6}, {4, 6}, {4, 6}, {4, 6}, // 0010xx + {4, 5}, {4, 5}, {4, 5}, {4, 5}, // 0011xx + {3, 1}, {3, 1}, {3, 1}, {3, 1}, // 010xxx + {3, 1}, {3, 1}, {3, 1}, {3, 1}, + {3, 4}, {3, 4}, {3, 4}, {3, 4}, // 011xxx + {3, 4}, {3, 4}, {3, 4}, {3, 4}, + {2, 3}, {2, 3}, {2, 3}, {2, 3}, // 10xxxx + {2, 3}, {2, 3}, {2, 3}, {2, 3}, + {2, 3}, {2, 3}, {2, 3}, {2, 3}, + {2, 3}, {2, 3}, {2, 3}, {2, 3}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, // 11xxxx + {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2}, + {2, 2}, {2, 2}, {2, 2}, {2, 2} +}; diff --git a/pdftops/Stream.cxx b/pdftops/Stream.cxx new file mode 100644 index 0000000000..667d07c8ca --- /dev/null +++ b/pdftops/Stream.cxx @@ -0,0 +1,3332 @@ +//======================================================================== +// +// Stream.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#ifndef WIN32 +#include +#endif +#include +#include +#include "gmem.h" +#include "config.h" +#include "Error.h" +#include "Object.h" +#include "Stream.h" +#include "Stream-CCITT.h" + +#ifdef _MSC_VER +#define popen _popen +#define pclose _pclose +#endif + +#ifdef __DJGPP__ +static GBool setDJSYSFLAGS = gFalse; +#endif + +#ifdef VMS +#if (__VMS_VER < 70000000) +extern "C" int unlink(char *filename); +#endif +#ifdef __GNUC__ +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif +#endif + +//------------------------------------------------------------------------ + +#define headerSearchSize 1024 // read this many bytes at beginning of + // file to look for '%PDF' + +//------------------------------------------------------------------------ +// Stream (base class) +//------------------------------------------------------------------------ + +Stream::Stream() { + ref = 1; +} + +Stream::~Stream() { +} + +int Stream::getRawChar() { + error(-1, "Internal: called getRawChar() on non-predictor stream"); + return EOF; +} + +char *Stream::getLine(char *buf, int size) { + int i; + int c; + + if (lookChar() == EOF) + return NULL; + for (i = 0; i < size - 1; ++i) { + c = getChar(); + if (c == EOF || c == '\n') + break; + if (c == '\r') { + if ((c = lookChar()) == '\n') + getChar(); + break; + } + buf[i] = c; + } + buf[i] = '\0'; + return buf; +} + +void Stream::setPos(int pos) { + error(-1, "Internal: called setPos() on non-FileStream"); +} + +GString *Stream::getPSFilter(char *indent) { + return new GString(); +} + +Stream *Stream::addFilters(Object *dict) { + Object obj, obj2; + Object params, params2; + Stream *str; + int i; + + str = this; + dict->dictLookup("Filter", &obj); + if (obj.isNull()) { + obj.free(); + dict->dictLookup("F", &obj); + } + dict->dictLookup("DecodeParms", ¶ms); + if (params.isNull()) { + params.free(); + dict->dictLookup("DP", ¶ms); + } + if (obj.isName()) { + str = makeFilter(obj.getName(), str, ¶ms); + } else if (obj.isArray()) { + for (i = 0; i < obj.arrayGetLength(); ++i) { + obj.arrayGet(i, &obj2); + if (params.isArray()) + params.arrayGet(i, ¶ms2); + else + params2.initNull(); + if (obj2.isName()) { + str = makeFilter(obj2.getName(), str, ¶ms2); + } else { + error(getPos(), "Bad filter name"); + str = new EOFStream(str); + } + obj2.free(); + params2.free(); + } + } else if (!obj.isNull()) { + error(getPos(), "Bad 'Filter' attribute in stream"); + } + obj.free(); + params.free(); + + return str; +} + +Stream *Stream::makeFilter(char *name, Stream *str, Object *params) { + int pred; // parameters + int colors; + int bits; + int early; + int encoding; + GBool endOfLine, byteAlign, endOfBlock, black; + int columns, rows; + Object obj; + + if (!strcmp(name, "ASCIIHexDecode") || !strcmp(name, "AHx")) { + str = new ASCIIHexStream(str); + } else if (!strcmp(name, "ASCII85Decode") || !strcmp(name, "A85")) { + str = new ASCII85Stream(str); + } else if (!strcmp(name, "LZWDecode") || !strcmp(name, "LZW")) { + pred = 1; + columns = 1; + colors = 1; + bits = 8; + early = 1; + if (params->isDict()) { + params->dictLookup("Predictor", &obj); + if (obj.isInt()) + pred = obj.getInt(); + obj.free(); + params->dictLookup("Columns", &obj); + if (obj.isInt()) + columns = obj.getInt(); + obj.free(); + params->dictLookup("Colors", &obj); + if (obj.isInt()) + colors = obj.getInt(); + obj.free(); + params->dictLookup("BitsPerComponent", &obj); + if (obj.isInt()) + bits = obj.getInt(); + obj.free(); + params->dictLookup("EarlyChange", &obj); + if (obj.isInt()) + early = obj.getInt(); + obj.free(); + } + str = new LZWStream(str, pred, columns, colors, bits, early); + } else if (!strcmp(name, "RunLengthDecode") || !strcmp(name, "RL")) { + str = new RunLengthStream(str); + } else if (!strcmp(name, "CCITTFaxDecode") || !strcmp(name, "CCF")) { + encoding = 0; + endOfLine = gFalse; + byteAlign = gFalse; + columns = 1728; + rows = 0; + endOfBlock = gTrue; + black = gFalse; + if (params->isDict()) { + params->dictLookup("K", &obj); + if (obj.isInt()) { + encoding = obj.getInt(); + } + obj.free(); + params->dictLookup("EndOfLine", &obj); + if (obj.isBool()) { + endOfLine = obj.getBool(); + } + obj.free(); + params->dictLookup("EncodedByteAlign", &obj); + if (obj.isBool()) { + byteAlign = obj.getBool(); + } + obj.free(); + params->dictLookup("Columns", &obj); + if (obj.isInt()) { + columns = obj.getInt(); + } + obj.free(); + params->dictLookup("Rows", &obj); + if (obj.isInt()) { + rows = obj.getInt(); + } + obj.free(); + params->dictLookup("EndOfBlock", &obj); + if (obj.isBool()) { + endOfBlock = obj.getBool(); + } + obj.free(); + params->dictLookup("BlackIs1", &obj); + if (obj.isBool()) { + black = obj.getBool(); + } + obj.free(); + } + str = new CCITTFaxStream(str, encoding, endOfLine, byteAlign, + columns, rows, endOfBlock, black); + } else if (!strcmp(name, "DCTDecode") || !strcmp(name, "DCT")) { + str = new DCTStream(str); + } else if (!strcmp(name, "FlateDecode") || !strcmp(name, "Fl")) { + pred = 1; + columns = 1; + colors = 1; + bits = 8; + if (params->isDict()) { + params->dictLookup("Predictor", &obj); + if (obj.isInt()) + pred = obj.getInt(); + obj.free(); + params->dictLookup("Columns", &obj); + if (obj.isInt()) + columns = obj.getInt(); + obj.free(); + params->dictLookup("Colors", &obj); + if (obj.isInt()) + colors = obj.getInt(); + obj.free(); + params->dictLookup("BitsPerComponent", &obj); + if (obj.isInt()) + bits = obj.getInt(); + obj.free(); + } + str = new FlateStream(str, pred, columns, colors, bits); + } else { + error(getPos(), "Unknown filter '%s'", name); + str = new EOFStream(str); + } + return str; +} + +//------------------------------------------------------------------------ +// ImageStream +//------------------------------------------------------------------------ + +ImageStream::ImageStream(Stream *str, int width, int nComps, int nBits) { + int imgLineSize; + + this->str = str; + this->width = width; + this->nComps = nComps; + this->nBits = nBits; + + nVals = width * nComps; + if (nBits == 1) { + imgLineSize = (nVals + 7) & ~7; + } else { + imgLineSize = nVals; + } + imgLine = (Guchar *)gmalloc(imgLineSize * sizeof(Guchar)); + imgIdx = nVals; +} + +ImageStream::~ImageStream() { + gfree(imgLine); +} + +void ImageStream::reset() { + str->reset(); +} + +GBool ImageStream::getPixel(Guchar *pix) { + Gulong buf, bitMask; + int bits; + int c; + int i; + + if (imgIdx >= nVals) { + + // read one line of image pixels + if (nBits == 1) { + for (i = 0; i < nVals; i += 8) { + c = str->getChar(); + imgLine[i+0] = (Guchar)((c >> 7) & 1); + imgLine[i+1] = (Guchar)((c >> 6) & 1); + imgLine[i+2] = (Guchar)((c >> 5) & 1); + imgLine[i+3] = (Guchar)((c >> 4) & 1); + imgLine[i+4] = (Guchar)((c >> 3) & 1); + imgLine[i+5] = (Guchar)((c >> 2) & 1); + imgLine[i+6] = (Guchar)((c >> 1) & 1); + imgLine[i+7] = (Guchar)(c & 1); + } + } else if (nBits == 8) { + for (i = 0; i < nVals; ++i) { + imgLine[i] = str->getChar(); + } + } else { + bitMask = (1 << nBits) - 1; + buf = 0; + bits = 0; + for (i = 0; i < nVals; ++i) { + if (bits < nBits) { + buf = (buf << 8) | (str->getChar() & 0xff); + bits += 8; + } + imgLine[i] = (Guchar)((buf >> (bits - nBits)) & bitMask); + bits -= nBits; + } + } + + // reset to start of line + imgIdx = 0; + } + + for (i = 0; i < nComps; ++i) + pix[i] = imgLine[imgIdx++]; + return gTrue; +} + +void ImageStream::skipLine() { + int n, i; + + n = (nVals * nBits + 7) >> 3; + for (i = 0; i < n; ++i) { + str->getChar(); + } +} + +//------------------------------------------------------------------------ +// StreamPredictor +//------------------------------------------------------------------------ + +StreamPredictor::StreamPredictor(Stream *str, int predictor, + int width, int nComps, int nBits) { + this->str = str; + this->predictor = predictor; + this->width = width; + this->nComps = nComps; + this->nBits = nBits; + + nVals = width * nComps; + pixBytes = (nComps * nBits + 7) >> 3; + rowBytes = ((nVals * nBits + 7) >> 3) + pixBytes; + predLine = (Guchar *)gmalloc(rowBytes); + memset(predLine, 0, rowBytes); + predIdx = rowBytes; +} + +StreamPredictor::~StreamPredictor() { + gfree(predLine); +} + +int StreamPredictor::lookChar() { + if (predIdx >= rowBytes) { + if (!getNextLine()) { + return EOF; + } + } + return predLine[predIdx]; +} + +int StreamPredictor::getChar() { + if (predIdx >= rowBytes) { + if (!getNextLine()) { + return EOF; + } + } + return predLine[predIdx++]; +} + +GBool StreamPredictor::getNextLine() { + int curPred; + Guchar upLeftBuf[4]; + int left, up, upLeft, p, pa, pb, pc; + int c; + Gulong inBuf, outBuf, bitMask; + int inBits, outBits; + int i, j, k; + + // get PNG optimum predictor number + if (predictor == 15) { + if ((curPred = str->getRawChar()) == EOF) { + return gFalse; + } + curPred += 10; + } else { + curPred = predictor; + } + + // read the raw line, apply PNG (byte) predictor + upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0; + for (i = pixBytes; i < rowBytes; ++i) { + upLeftBuf[3] = upLeftBuf[2]; + upLeftBuf[2] = upLeftBuf[1]; + upLeftBuf[1] = upLeftBuf[0]; + upLeftBuf[0] = predLine[i]; + if ((c = str->getRawChar()) == EOF) { + break; + } + switch (curPred) { + case 11: // PNG sub + predLine[i] = predLine[i - pixBytes] + (Guchar)c; + break; + case 12: // PNG up + predLine[i] = predLine[i] + (Guchar)c; + break; + case 13: // PNG average + predLine[i] = ((predLine[i - pixBytes] + predLine[i]) >> 1) + + (Guchar)c; + break; + case 14: // PNG Paeth + left = predLine[i - pixBytes]; + up = predLine[i]; + upLeft = upLeftBuf[pixBytes]; + p = left + up - upLeft; + if ((pa = p - left) < 0) + pa = -pa; + if ((pb = p - up) < 0) + pb = -pb; + if ((pc = p - upLeft) < 0) + pc = -pc; + if (pa <= pb && pa <= pc) + predLine[i] = pa + (Guchar)c; + else if (pb <= pc) + predLine[i] = pb + (Guchar)c; + else + predLine[i] = pc + (Guchar)c; + break; + case 10: // PNG none + default: // no predictor or TIFF predictor + predLine[i] = (Guchar)c; + break; + } + } + + // apply TIFF (component) predictor + //~ this is completely untested + if (predictor == 2) { + if (nBits == 1) { + inBuf = predLine[pixBytes - 1]; + for (i = pixBytes; i < rowBytes; i += 8) { + // 1-bit add is just xor + inBuf = (inBuf << 8) | predLine[i]; + predLine[i] ^= inBuf >> nComps; + } + } else if (nBits == 8) { + for (i = pixBytes; i < rowBytes; ++i) { + predLine[i] += predLine[i - nComps]; + } + } else { + upLeftBuf[0] = upLeftBuf[1] = upLeftBuf[2] = upLeftBuf[3] = 0; + bitMask = (1 << nBits) - 1; + inBuf = outBuf = 0; + inBits = outBits = 0; + j = k = pixBytes; + for (i = 0; i < nVals; ++i) { + if (inBits < nBits) { + inBuf = (inBuf << 8) | (predLine[j++] & 0xff); + inBits += 8; + } + upLeftBuf[3] = upLeftBuf[2]; + upLeftBuf[2] = upLeftBuf[1]; + upLeftBuf[1] = upLeftBuf[0]; + upLeftBuf[0] = (upLeftBuf[nComps] + + (inBuf >> (inBits - nBits))) & bitMask; + outBuf = (outBuf << nBits) | upLeftBuf[0]; + inBits -= nBits; + outBits += nBits; + if (outBits > 8) { + predLine[k++] = (Guchar)(outBuf >> (outBits - 8)); + } + } + if (outBits > 0) { + predLine[k++] = (Guchar)(outBuf << (8 - outBits)); + } + } + } + + // reset to start of line + predIdx = pixBytes; + + return gTrue; +} + +//------------------------------------------------------------------------ +// FileStream +//------------------------------------------------------------------------ + +FileStream::FileStream(FILE *f1, int start1, int length1, Object *dict1) { + f = f1; + start = start1; + length = length1; + bufPtr = bufEnd = buf; + bufPos = start; + savePos = -1; + dict = *dict1; +} + +FileStream::~FileStream() { + if (savePos >= 0) + fseek(f, savePos, SEEK_SET); + dict.free(); +} + +void FileStream::reset() { + savePos = (int)ftell(f); + fseek(f, start, SEEK_SET); + bufPtr = bufEnd = buf; + bufPos = start; +} + +GBool FileStream::fillBuf() { + int n; + + bufPos += bufEnd - buf; + bufPtr = bufEnd = buf; + if (length >= 0 && bufPos >= start + length) + return gFalse; + if (length >= 0 && bufPos + 256 > start + length) + n = start + length - bufPos; + else + n = 256; + n = fread(buf, 1, n, f); + bufEnd = buf + n; + if (bufPtr >= bufEnd) + return gFalse; + return gTrue; +} + +void FileStream::setPos(int pos1) { + long size; + + if (pos1 >= 0) { + fseek(f, pos1, SEEK_SET); + bufPos = pos1; + } else { + fseek(f, 0, SEEK_END); + size = ftell(f); + if (pos1 < -size) + pos1 = (int)(-size); + fseek(f, pos1, SEEK_END); + bufPos = (int)ftell(f); + } + bufPtr = bufEnd = buf; +} + +GBool FileStream::checkHeader() { + char hdrBuf[headerSearchSize+1]; + char *p; + double version; + int i; + + for (i = 0; i < headerSearchSize; ++i) + hdrBuf[i] = getChar(); + hdrBuf[headerSearchSize] = '\0'; + for (i = 0; i < headerSearchSize - 5; ++i) { + if (!strncmp(&hdrBuf[i], "%PDF-", 5)) + break; + } + if (i >= headerSearchSize - 5) { + error(-1, "May not be a PDF file (continuing anyway)"); + return gFalse; + } + start += i; + p = strtok(&hdrBuf[i+5], " \t\n\r"); + version = atof(p); + if (!(hdrBuf[i+5] >= '0' && hdrBuf[i+5] <= '9') || + version > pdfVersionNum + 0.0001) { + error(getPos(), "PDF version %s -- xpdf supports version %s" + " (continuing anyway)", p, pdfVersion); + return gFalse; + } + return gTrue; +} + +//------------------------------------------------------------------------ +// SubStream +//------------------------------------------------------------------------ + +SubStream::SubStream(Stream *str1, Object *dict1) { + str = str1; + dict = *dict1; +} + +SubStream::~SubStream() { + dict.free(); +} + +//------------------------------------------------------------------------ +// ASCIIHexStream +//------------------------------------------------------------------------ + +ASCIIHexStream::ASCIIHexStream(Stream *str1) { + str = str1; + buf = EOF; + eof = gFalse; +} + +ASCIIHexStream::~ASCIIHexStream() { + delete str; +} + +void ASCIIHexStream::reset() { + str->reset(); + buf = EOF; + eof = gFalse; +} + +int ASCIIHexStream::lookChar() { + int c1, c2, x; + + if (buf != EOF) + return buf; + if (eof) { + buf = EOF; + return EOF; + } + do { + c1 = str->getChar(); + } while (isspace(c1)); + if (c1 == '>') { + eof = gTrue; + buf = EOF; + return buf; + } + do { + c2 = str->getChar(); + } while (isspace(c2)); + if (c2 == '>') { + eof = gTrue; + c2 = '0'; + } + if (c1 >= '0' && c1 <= '9') { + x = (c1 - '0') << 4; + } else if (c1 >= 'A' && c1 <= 'F') { + x = (c1 - 'A' + 10) << 4; + } else if (c1 >= 'a' && c1 <= 'f') { + x = (c1 - 'a' + 10) << 4; + } else if (c1 == EOF) { + eof = gTrue; + x = 0; + } else { + error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c1); + x = 0; + } + if (c2 >= '0' && c2 <= '9') { + x += c2 - '0'; + } else if (c2 >= 'A' && c2 <= 'F') { + x += c2 - 'A' + 10; + } else if (c2 >= 'a' && c2 <= 'f') { + x += c2 - 'a' + 10; + } else if (c2 == EOF) { + eof = gTrue; + x = 0; + } else { + error(getPos(), "Illegal character <%02x> in ASCIIHex stream", c2); + } + buf = x & 0xff; + return buf; +} + +GString *ASCIIHexStream::getPSFilter(char *indent) { + GString *s; + + s = str->getPSFilter(indent); + s->append(indent)->append("/ASCIIHexDecode filter\n"); + return s; +} + +GBool ASCIIHexStream::isBinary(GBool last) { + return str->isBinary(gFalse); +} + +//------------------------------------------------------------------------ +// ASCII85Stream +//------------------------------------------------------------------------ + +ASCII85Stream::ASCII85Stream(Stream *str1) { + str = str1; + index = n = 0; + eof = gFalse; +} + +ASCII85Stream::~ASCII85Stream() { + delete str; +} + +void ASCII85Stream::reset() { + str->reset(); + index = n = 0; + eof = gFalse; +} + +int ASCII85Stream::lookChar() { + int k; + Gulong t; + + if (index >= n) { + if (eof) + return EOF; + index = 0; + do { + c[0] = str->getChar(); + } while (c[0] == '\n' || c[0] == '\r'); + if (c[0] == '~' || c[0] == EOF) { + eof = gTrue; + n = 0; + return EOF; + } else if (c[0] == 'z') { + b[0] = b[1] = b[2] = b[3] = 0; + n = 4; + } else { + for (k = 1; k < 5; ++k) { + do { + c[k] = str->getChar(); + } while (c[k] == '\n' || c[k] == '\r'); + if (c[k] == '~' || c[k] == EOF) + break; + } + n = k - 1; + if (k < 5 && (c[k] == '~' || c[k] == EOF)) { + for (++k; k < 5; ++k) + c[k] = 0x21 + 84; + eof = gTrue; + } + t = 0; + for (k = 0; k < 5; ++k) + t = t * 85 + (c[k] - 0x21); + for (k = 3; k >= 0; --k) { + b[k] = (int)(t & 0xff); + t >>= 8; + } + } + } + return b[index]; +} + +GString *ASCII85Stream::getPSFilter(char *indent) { + GString *s; + + s = str->getPSFilter(indent); + s->append(indent)->append("/ASCII85Decode filter\n"); + return s; +} + +GBool ASCII85Stream::isBinary(GBool last) { + return str->isBinary(gFalse); +} + +//------------------------------------------------------------------------ +// LZWStream +//------------------------------------------------------------------------ + +LZWStream::LZWStream(Stream *str1, int predictor1, int columns1, int colors1, + int bits1, int early1) { + str = str1; + if (predictor1 != 1) { + pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1); + } else { + pred = NULL; + } + early = early1; + zPipe = NULL; + bufPtr = bufEnd = buf; +} + +LZWStream::~LZWStream() { + if (zPipe) { +#ifdef HAVE_POPEN + pclose(zPipe); +#else + fclose(zPipe); +#endif + zPipe = NULL; + unlink(zName); + } + if (pred) { + delete pred; + } + delete str; +} + +int LZWStream::getChar() { + if (pred) { + return pred->getChar(); + } + return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); +} + +int LZWStream::lookChar() { + if (pred) { + return pred->lookChar(); + } + return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); +} + +int LZWStream::getRawChar() { + return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); +} + +void LZWStream::reset() { + FILE *f; + + str->reset(); + bufPtr = bufEnd = buf; + if (zPipe) { +#ifdef HAVE_POPEN + pclose(zPipe); +#else + fclose(zPipe); +#endif + zPipe = NULL; + unlink(zName); + } +#if __DJGPP__ + if (!setDJSYSFLAGS) { + setenv("DJSYSFLAGS", "0x0002", 0); + setDJSYSFLAGS = gTrue; + } +#endif + strcpy(zCmd, uncompressCmd); + strcat(zCmd, " "); + zName = zCmd + strlen(zCmd); + tmpnam(zName); +#ifdef _MSC_VER + zName[strlen(zName) - 2] = '\0'; +#endif + strcat(zName, ".Z"); + if (!(f = fopen(zName, "wb"))) { + error(getPos(), "Couldn't open temporary file '%s'", zName); + return; + } + dumpFile(f); + fclose(f); +#ifdef HAVE_POPEN + if (!(zPipe = popen(zCmd, "r"))) { + error(getPos(), "Couldn't popen '%s'", zCmd); + unlink(zName); + return; + } +#else +#ifdef VMS + if (!system(zCmd)) { +#else + if (system(zCmd)) { +#endif + error(getPos(), "Couldn't execute '%s'", zCmd); + unlink(zName); + return; + } + zName[strlen(zName) - 2] = '\0'; + if (!(zPipe = fopen(zName, "rb"))) { + error(getPos(), "Couldn't open uncompress file '%s'", zName); + unlink(zName); + return; + } +#endif +} + +void LZWStream::dumpFile(FILE *f) { + int outCodeBits; // size of output code + int outBits; // max output code + int outBuf[8]; // output buffer + int outData; // temporary output buffer + int inCode, outCode; // input and output codes + int nextCode; // next code index + GBool eof; // set when EOF is reached + GBool clear; // set if table needs to be cleared + GBool first; // indicates first code word after clear + int i, j; + + // magic number + fputc(0x1f, f); + fputc(0x9d, f); + + // max code length, block mode flag + fputc(0x8c, f); + + // init input side + inCodeBits = 9; + inputBuf = 0; + inputBits = 0; + eof = gFalse; + + // init output side + outCodeBits = 9; + + // clear table + first = gTrue; + nextCode = 258; + + clear = gFalse; + do { + for (i = 0; i < 8; ++i) { + // check for table overflow + if (nextCode + early > 0x1001) { + inCode = 256; + + // read input code + } else { + do { + inCode = getCode(); + if (inCode == EOF) { + eof = gTrue; + inCode = 0; + } + } while (first && inCode == 256); + } + + // compute output code + if (inCode < 256) { + outCode = inCode; + } else if (inCode == 256) { + outCode = 256; + clear = gTrue; + } else if (inCode == 257) { + outCode = 0; + eof = gTrue; + } else { + outCode = inCode - 1; + } + outBuf[i] = outCode; + + // next code index + if (first) + first = gFalse; + else + ++nextCode; + + // check input code size + if (nextCode + early == 0x200) + inCodeBits = 10; + else if (nextCode + early == 0x400) { + inCodeBits = 11; + } else if (nextCode + early == 0x800) { + inCodeBits = 12; + } + + // check for eof/clear + if (eof) + break; + if (clear) { + i = 8; + break; + } + } + + // write output block + outData = 0; + outBits = 0; + j = 0; + while (j < i || outBits > 0) { + if (outBits < 8 && j < i) { + outData = outData | (outBuf[j++] << outBits); + outBits += outCodeBits; + } + fputc(outData & 0xff, f); + outData >>= 8; + outBits -= 8; + } + + // check output code size + if (nextCode - 1 == 512 || + nextCode - 1 == 1024 || + nextCode - 1 == 2048 || + nextCode - 1 == 4096) { + outCodeBits = inCodeBits; + } + + // clear table if necessary + if (clear) { + inCodeBits = 9; + outCodeBits = 9; + first = gTrue; + nextCode = 258; + clear = gFalse; + } + } while (!eof); +} + +int LZWStream::getCode() { + int c; + int code; + + while (inputBits < inCodeBits) { + if ((c = str->getChar()) == EOF) + return EOF; + inputBuf = (inputBuf << 8) | (c & 0xff); + inputBits += 8; + } + code = (inputBuf >> (inputBits - inCodeBits)) & ((1 << inCodeBits) - 1); + inputBits -= inCodeBits; + return code; +} + +GBool LZWStream::fillBuf() { + int n; + + if (!zPipe) + return gFalse; + if ((n = fread(buf, 1, 256, zPipe)) < 256) { +#ifdef HAVE_POPEN + pclose(zPipe); +#else + fclose(zPipe); +#endif + zPipe = NULL; + unlink(zName); + } + bufPtr = buf; + bufEnd = buf + n; + return n > 0; +} + +GString *LZWStream::getPSFilter(char *indent) { + GString *s; + + if (pred) { + return NULL; + } + s = str->getPSFilter(indent); + s->append(indent)->append("/LZWDecode filter\n"); + return s; +} + +GBool LZWStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +//------------------------------------------------------------------------ +// RunLengthStream +//------------------------------------------------------------------------ + +RunLengthStream::RunLengthStream(Stream *str1) { + str = str1; + bufPtr = bufEnd = buf; + eof = gFalse; +} + +RunLengthStream::~RunLengthStream() { + delete str; +} + +void RunLengthStream::reset() { + str->reset(); + bufPtr = bufEnd = buf; + eof = gFalse; +} + +GString *RunLengthStream::getPSFilter(char *indent) { + GString *s; + + s = str->getPSFilter(indent); + s->append(indent)->append("/RunLengthDecode filter\n"); + return s; +} + +GBool RunLengthStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +GBool RunLengthStream::fillBuf() { + int c; + int n, i; + + if (eof) + return gFalse; + c = str->getChar(); + if (c == 0x80 || c == EOF) { + eof = gTrue; + return gFalse; + } + if (c < 0x80) { + n = c + 1; + for (i = 0; i < n; ++i) + buf[i] = (char)str->getChar(); + } else { + n = 0x101 - c; + c = str->getChar(); + for (i = 0; i < n; ++i) + buf[i] = (char)c; + } + bufPtr = buf; + bufEnd = buf + n; + return gTrue; +} + +//------------------------------------------------------------------------ +// CCITTFaxStream +//------------------------------------------------------------------------ + +CCITTFaxStream::CCITTFaxStream(Stream *str, int encoding, GBool endOfLine, + GBool byteAlign, int columns, int rows, + GBool endOfBlock, GBool black) { + this->str = str; + this->encoding = encoding; + this->endOfLine = endOfLine; + this->byteAlign = byteAlign; + this->columns = columns; + this->rows = rows; + this->endOfBlock = endOfBlock; + this->black = black; + refLine = (short *)gmalloc((columns + 2) * sizeof(short)); + codingLine = (short *)gmalloc((columns + 2) * sizeof(short)); + + eof = gFalse; + row = 0; + nextLine2D = encoding < 0; + inputBits = 0; + codingLine[0] = 0; + codingLine[1] = refLine[2] = columns; + a0 = 1; + + buf = EOF; +} + +CCITTFaxStream::~CCITTFaxStream() { + delete str; + gfree(refLine); + gfree(codingLine); +} + +void CCITTFaxStream::reset() { + int n; + + str->reset(); + eof = gFalse; + row = 0; + nextLine2D = encoding < 0; + inputBits = 0; + codingLine[0] = 0; + codingLine[1] = refLine[2] = columns; + a0 = 1; + buf = EOF; + + // get initial end-of-line marker and 2D encoding tag + if (endOfBlock) { + if (lookBits(12) == 0x001) { + eatBits(12); + } + } else { + for (n = 0; n < 11 && lookBits(n) == 0; ++n) ; + if (n == 11 && lookBits(12) == 0x001) { + eatBits(12); + } + } + if (encoding > 0) { + nextLine2D = !lookBits(1); + eatBits(1); + } +} + +int CCITTFaxStream::lookChar() { + short code1, code2, code3; + int a0New; +#if 0 //~ + GBool err; +#endif + int ret; + int bits, i, n; + + // if at eof just return EOF + if (eof && codingLine[a0] >= columns) { + return EOF; + } + + // read the next row +#if 0 //~ + err = gFalse; +#endif + if (codingLine[a0] >= columns) { + + // 2-D encoding + if (nextLine2D) { + for (i = 0; codingLine[i] < columns; ++i) + refLine[i] = codingLine[i]; + refLine[i] = refLine[i + 1] = columns; + b1 = 1; + a0New = codingLine[a0 = 0] = 0; + do { + code1 = getTwoDimCode(); + switch (code1) { + case twoDimPass: + if (refLine[b1] < columns) { + a0New = refLine[b1 + 1]; + b1 += 2; + } + break; + case twoDimHoriz: + if ((a0 & 1) == 0) { + code1 = code2 = 0; + do { + code1 += code3 = getWhiteCode(); + } while (code3 >= 64); + do { + code2 += code3 = getBlackCode(); + } while (code3 >= 64); + } else { + code1 = code2 = 0; + do { + code1 += code3 = getBlackCode(); + } while (code3 >= 64); + do { + code2 += code3 = getWhiteCode(); + } while (code3 >= 64); + } + codingLine[a0 + 1] = a0New + code1; + ++a0; + a0New = codingLine[a0 + 1] = codingLine[a0] + code2; + ++a0; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + break; + case twoDimVert0: + a0New = codingLine[++a0] = refLine[b1]; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertR1: + a0New = codingLine[++a0] = refLine[b1] + 1; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertL1: + a0New = codingLine[++a0] = refLine[b1] - 1; + --b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + break; + case twoDimVertR2: + a0New = codingLine[++a0] = refLine[b1] + 2; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertL2: + a0New = codingLine[++a0] = refLine[b1] - 2; + --b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + break; + case twoDimVertR3: + a0New = codingLine[++a0] = refLine[b1] + 3; + if (refLine[b1] < columns) { + ++b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + } + break; + case twoDimVertL3: + a0New = codingLine[++a0] = refLine[b1] - 3; + --b1; + while (refLine[b1] <= codingLine[a0] && refLine[b1] < columns) + b1 += 2; + break; + case EOF: + eof = gTrue; + codingLine[a0 = 0] = columns; + return EOF; + default: + error(getPos(), "Bad 2D code %04x in CCITTFax stream", code1); +#if 0 //~ + err = gTrue; + break; +#else + eof = gTrue; + return EOF; +#endif + } + } while (codingLine[a0] < columns); + + // 1-D encoding + } else { + codingLine[a0 = 0] = 0; + while (1) { + code1 = 0; + do { + code1 += code3 = getWhiteCode(); + } while (code3 >= 64); + codingLine[a0+1] = codingLine[a0] + code1; + ++a0; + if (codingLine[a0] >= columns) + break; + code2 = 0; + do { + code2 += code3 = getBlackCode(); + } while (code3 >= 64); + codingLine[a0+1] = codingLine[a0] + code2; + ++a0; + if (codingLine[a0] >= columns) + break; + } + } + + if (codingLine[a0] != columns) { + error(getPos(), "CCITTFax row is wrong length (%d)", codingLine[a0]); +#if 0 //~ + err = gTrue; +#endif + } + + // byte-align the row + if (byteAlign) { + inputBits &= ~7; + } + + // check for end-of-line marker, end-of-block marker, and + // 2D encoding tag + if (endOfBlock) { + code1 = lookBits(12); + if (code1 == EOF) { + eof = gTrue; + } else if (code1 == 0x001) { + eatBits(12); + if (encoding > 0) { + nextLine2D = !lookBits(1); + eatBits(1); + } + code1 = lookBits(12); + if (code1 == 0x001) { + eatBits(12); + if (encoding > 0) { + lookBits(1); + eatBits(1); + } + if (encoding >= 0) { + for (i = 0; i < 4; ++i) { + code1 = lookBits(12); + if (code1 != 0x001) { + error(getPos(), "Bad RTC code in CCITTFax stream"); + } + eatBits(12); + if (encoding > 0) { + lookBits(1); + eatBits(1); + } + } + } + eof = gTrue; + } + } else { + if (encoding > 0) { + nextLine2D = !lookBits(1); + eatBits(1); + } + } + } else { + if (row == rows - 1) { + eof = gTrue; + } else { + for (n = 0; n < 11 && lookBits(n) == 0; ++n) ; + if (n == 11 && lookBits(12) == 0x001) { + eatBits(12); + } + if (encoding > 0) { + nextLine2D = !lookBits(1); + eatBits(1); + } + } + } + +#if 0 //~ + // This looks for an end-of-line marker after an error, however + // some (most?) CCITT streams in PDF files don't use end-of-line + // markers, and the just-plow-on technique works better in those + // cases. + else if (err) { + do { + if (code1 == EOF) { + eof = gTrue; + return EOF; + } + eatBits(1); + code1 = look13Bits(); + } while ((code1 >> 1) != 0x001); + eatBits(12); + codingLine[++a0] = columns; + if (encoding > 0) { + eatBits(1); + nextLine2D = !(code1 & 1); + } + } +#endif + + a0 = 0; + outputBits = codingLine[1] - codingLine[0]; + if (outputBits == 0) { + a0 = 1; + outputBits = codingLine[2] - codingLine[1]; + } + + ++row; + } + + // get a byte + if (outputBits >= 8) { + ret = ((a0 & 1) == 0) ? 0xff : 0x00; + if ((outputBits -= 8) == 0) { + ++a0; + if (codingLine[a0] < columns) { + outputBits = codingLine[a0 + 1] - codingLine[a0]; + } + } + } else { + bits = 8; + ret = 0; + do { + if (outputBits > bits) { + i = bits; + bits = 0; + if ((a0 & 1) == 0) { + ret |= 0xff >> (8 - i); + } + outputBits -= i; + } else { + i = outputBits; + bits -= outputBits; + if ((a0 & 1) == 0) { + ret |= (0xff >> (8 - i)) << bits; + } + outputBits = 0; + ++a0; + if (codingLine[a0] < columns) { + outputBits = codingLine[a0 + 1] - codingLine[a0]; + } + } + } while (bits > 0 && codingLine[a0] < columns); + } + buf = black ? (ret ^ 0xff) : ret; + return buf; +} + +short CCITTFaxStream::getTwoDimCode() { + short code; + CCITTCode *p; + int n; + + code = 0; // make gcc happy + if (endOfBlock) { + code = lookBits(7); + p = &twoDimTab1[code]; + if (p->bits > 0) { + eatBits(p->bits); + return p->n; + } + } else { + for (n = 1; n <= 7; ++n) { + code = lookBits(n); + if (n < 7) { + code <<= 7 - n; + } + p = &twoDimTab1[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + } + error(getPos(), "Bad two dim code (%04x) in CCITTFax stream", code); + return EOF; +} + +short CCITTFaxStream::getWhiteCode() { + short code; + CCITTCode *p; + int n; + + code = 0; // make gcc happy + if (endOfBlock) { + code = lookBits(12); + if ((code >> 5) == 0) + p = &whiteTab1[code]; + else + p = &whiteTab2[code >> 3]; + if (p->bits > 0) { + eatBits(p->bits); + return p->n; + } + } else { + for (n = 1; n <= 9; ++n) { + code = lookBits(n); + if (n < 9) { + code <<= 9 - n; + } + p = &whiteTab2[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + for (n = 11; n <= 12; ++n) { + code = lookBits(n); + if (n < 12) { + code <<= 12 - n; + } + p = &whiteTab1[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + } + error(getPos(), "Bad white code (%04x) in CCITTFax stream", code); + return EOF; +} + +short CCITTFaxStream::getBlackCode() { + short code; + CCITTCode *p; + int n; + + code = 0; // make gcc happy + if (endOfBlock) { + code = lookBits(13); + if ((code >> 7) == 0) + p = &blackTab1[code]; + else if ((code >> 9) == 0) + p = &blackTab2[(code >> 1) - 64]; + else + p = &blackTab3[code >> 7]; + if (p->bits > 0) { + eatBits(p->bits); + return p->n; + } + } else { + for (n = 2; n <= 6; ++n) { + code = lookBits(n); + if (n < 6) { + code <<= 6 - n; + } + p = &blackTab3[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + for (n = 7; n <= 12; ++n) { + code = lookBits(n); + if (n < 12) { + code <<= 12 - n; + } + if (code >= 64) { + p = &blackTab2[code - 64]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + } + for (n = 10; n <= 13; ++n) { + code = lookBits(n); + if (n < 13) { + code <<= 13 - n; + } + p = &blackTab1[code]; + if (p->bits == n) { + eatBits(n); + return p->n; + } + } + } + error(getPos(), "Bad black code (%04x) in CCITTFax stream", code); + return EOF; +} + +short CCITTFaxStream::lookBits(int n) { + int c; + + while (inputBits < n) { + if ((c = str->getChar()) == EOF) { + if (inputBits == 0) + return EOF; + c = 0; + } + inputBuf = (inputBuf << 8) + c; + inputBits += 8; + } + return (inputBuf >> (inputBits - n)) & (0xffff >> (16 - n)); +} + +GString *CCITTFaxStream::getPSFilter(char *indent) { + GString *s; + char s1[50]; + + s = str->getPSFilter(indent); + s->append(indent)->append("<< "); + if (encoding != 0) { + sprintf(s1, "/K %d ", encoding); + s->append(s1); + } + if (endOfLine) { + s->append("/EndOfLine true "); + } + if (byteAlign) { + s->append("/EncodedByteAlign true "); + } + sprintf(s1, "/Columns %d ", columns); + s->append(s1); + if (rows != 0) { + sprintf(s1, "/Rows %d ", rows); + s->append(s1); + } + if (!endOfBlock) { + s->append("/EndOfBlock false "); + } + if (black) { + s->append("/BlackIs1 true "); + } + s->append(">> /CCITTFaxDecode filter\n"); + return s; +} + +GBool CCITTFaxStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +//------------------------------------------------------------------------ +// DCTStream +//------------------------------------------------------------------------ + +// IDCT constants (20.12 fixed point format) +#ifndef FP_IDCT +#define dctCos1 4017 // cos(pi/16) +#define dctSin1 799 // sin(pi/16) +#define dctCos3 3406 // cos(3*pi/16) +#define dctSin3 2276 // sin(3*pi/16) +#define dctCos6 1567 // cos(6*pi/16) +#define dctSin6 3784 // sin(6*pi/16) +#define dctSqrt2 5793 // sqrt(2) +#define dctSqrt1d2 2896 // sqrt(2) / 2 +#endif + +// IDCT constants +#ifdef FP_IDCT +#define dctCos1 0.98078528 // cos(pi/16) +#define dctSin1 0.19509032 // sin(pi/16) +#define dctCos3 0.83146961 // cos(3*pi/16) +#define dctSin3 0.55557023 // sin(3*pi/16) +#define dctCos6 0.38268343 // cos(6*pi/16) +#define dctSin6 0.92387953 // sin(6*pi/16) +#define dctSqrt2 1.41421356 // sqrt(2) +#define dctSqrt1d2 0.70710678 // sqrt(2) / 2 +#endif + +// color conversion parameters (16.16 fixed point format) +#define dctCrToR 91881 // 1.4020 +#define dctCbToG -22553 // -0.3441363 +#define dctCrToG -46802 // -0.71413636 +#define dctCbToB 116130 // 1.772 + +// clip [-256,511] --> [0,255] +#define dctClipOffset 256 +static Guchar dctClip[768]; +static int dctClipInit = 0; + +// zig zag decode map +static int dctZigZag[64] = { + 0, + 1, 8, + 16, 9, 2, + 3, 10, 17, 24, + 32, 25, 18, 11, 4, + 5, 12, 19, 26, 33, 40, + 48, 41, 34, 27, 20, 13, 6, + 7, 14, 21, 28, 35, 42, 49, 56, + 57, 50, 43, 36, 29, 22, 15, + 23, 30, 37, 44, 51, 58, + 59, 52, 45, 38, 31, + 39, 46, 53, 60, + 61, 54, 47, + 55, 62, + 63 +}; + +DCTStream::DCTStream(Stream *str1) { + int i, j; + + str = str1; + width = height = 0; + mcuWidth = mcuHeight = 0; + numComps = 0; + comp = 0; + x = y = dy = 0; + for (i = 0; i < 4; ++i) + for (j = 0; j < 32; ++j) + rowBuf[i][j] = NULL; + + if (!dctClipInit) { + for (i = -256; i < 0; ++i) + dctClip[dctClipOffset + i] = 0; + for (i = 0; i < 256; ++i) + dctClip[dctClipOffset + i] = i; + for (i = 256; i < 512; ++i) + dctClip[dctClipOffset + i] = 255; + dctClipInit = 1; + } +} + +DCTStream::~DCTStream() { + int i, j; + + delete str; + for (i = 0; i < numComps; ++i) + for (j = 0; j < mcuHeight; ++j) + gfree(rowBuf[i][j]); +} + +void DCTStream::reset() { + str->reset(); + if (!readHeader()) { + y = height; + return; + } + restartMarker = 0xd0; + restart(); +} + +int DCTStream::getChar() { + int c; + + c = lookChar(); + if (c == EOF) + return EOF; + if (++comp == numComps) { + comp = 0; + if (++x == width) { + x = 0; + ++y; + ++dy; + } + } + if (y == height) + readTrailer(); + return c; +} + +int DCTStream::lookChar() { + if (y >= height) + return EOF; + if (dy >= mcuHeight) { + if (!readMCURow()) { + y = height; + return EOF; + } + comp = 0; + x = 0; + dy = 0; + } + return rowBuf[comp][dy][x]; +} + +void DCTStream::restart() { + int i; + + inputBits = 0; + restartCtr = restartInterval; + for (i = 0; i < numComps; ++i) + compInfo[i].prevDC = 0; +} + +GBool DCTStream::readMCURow() { + Guchar data[64]; + Guchar *p1, *p2; + int pY, pCb, pCr, pR, pG, pB; + int h, v, horiz, vert, hSub, vSub; + int x1, x2, y2, x3, y3, x4, y4, x5, y5, cc, i; + int c; + + for (x1 = 0; x1 < width; x1 += mcuWidth) { + + // deal with restart marker + if (restartInterval > 0 && restartCtr == 0) { + c = readMarker(); + if (c != restartMarker) { + error(getPos(), "Bad DCT data: incorrect restart marker"); + return gFalse; + } + if (++restartMarker == 0xd8) + restartMarker = 0xd0; + restart(); + } + + // read one MCU + for (cc = 0; cc < numComps; ++cc) { + h = compInfo[cc].hSample; + v = compInfo[cc].vSample; + horiz = mcuWidth / h; + vert = mcuHeight / v; + hSub = horiz / 8; + vSub = vert / 8; + for (y2 = 0; y2 < mcuHeight; y2 += vert) { + for (x2 = 0; x2 < mcuWidth; x2 += horiz) { + if (!readDataUnit(&dcHuffTables[compInfo[cc].dcHuffTable], + &acHuffTables[compInfo[cc].acHuffTable], + quantTables[compInfo[cc].quantTable], + &compInfo[cc].prevDC, + data)) + return gFalse; + if (hSub == 1 && vSub == 1) { + for (y3 = 0, i = 0; y3 < 8; ++y3, i += 8) { + p1 = &rowBuf[cc][y2+y3][x1+x2]; + p1[0] = data[i]; + p1[1] = data[i+1]; + p1[2] = data[i+2]; + p1[3] = data[i+3]; + p1[4] = data[i+4]; + p1[5] = data[i+5]; + p1[6] = data[i+6]; + p1[7] = data[i+7]; + } + } else if (hSub == 2 && vSub == 2) { + for (y3 = 0, i = 0; y3 < 16; y3 += 2, i += 8) { + p1 = &rowBuf[cc][y2+y3][x1+x2]; + p2 = &rowBuf[cc][y2+y3+1][x1+x2]; + p1[0] = p1[1] = p2[0] = p2[1] = data[i]; + p1[2] = p1[3] = p2[2] = p2[3] = data[i+1]; + p1[4] = p1[5] = p2[4] = p2[5] = data[i+2]; + p1[6] = p1[7] = p2[6] = p2[7] = data[i+3]; + p1[8] = p1[9] = p2[8] = p2[9] = data[i+4]; + p1[10] = p1[11] = p2[10] = p2[11] = data[i+5]; + p1[12] = p1[13] = p2[12] = p2[13] = data[i+6]; + p1[14] = p1[15] = p2[14] = p2[15] = data[i+7]; + } + } else { + i = 0; + for (y3 = 0, y4 = 0; y3 < 8; ++y3, y4 += vSub) { + for (x3 = 0, x4 = 0; x3 < 8; ++x3, x4 += hSub) { + for (y5 = 0; y5 < vSub; ++y5) + for (x5 = 0; x5 < hSub; ++x5) + rowBuf[cc][y2+y4+y5][x1+x2+x4+x5] = data[i]; + ++i; + } + } + } + } + } + } + --restartCtr; + + // color space conversion + if (colorXform) { + // convert YCbCr to RGB + if (numComps == 3) { + for (y2 = 0; y2 < mcuHeight; ++y2) { + for (x2 = 0; x2 < mcuWidth; ++x2) { + pY = rowBuf[0][y2][x1+x2]; + pCb = rowBuf[1][y2][x1+x2] - 128; + pCr = rowBuf[2][y2][x1+x2] - 128; + pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16; + rowBuf[0][y2][x1+x2] = dctClip[dctClipOffset + pR]; + pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32768) >> 16; + rowBuf[1][y2][x1+x2] = dctClip[dctClipOffset + pG]; + pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16; + rowBuf[2][y2][x1+x2] = dctClip[dctClipOffset + pB]; + } + } + // convert YCbCrK to CMYK (K is passed through unchanged) + } else if (numComps == 4) { + for (y2 = 0; y2 < mcuHeight; ++y2) { + for (x2 = 0; x2 < mcuWidth; ++x2) { + pY = rowBuf[0][y2][x1+x2]; + pCb = rowBuf[1][y2][x1+x2] - 128; + pCr = rowBuf[2][y2][x1+x2] - 128; + pR = ((pY << 16) + dctCrToR * pCr + 32768) >> 16; + rowBuf[0][y2][x1+x2] = 255 - dctClip[dctClipOffset + pR]; + pG = ((pY << 16) + dctCbToG * pCb + dctCrToG * pCr + 32678) >> 16; + rowBuf[1][y2][x1+x2] = 255 - dctClip[dctClipOffset + pG]; + pB = ((pY << 16) + dctCbToB * pCb + 32768) >> 16; + rowBuf[2][y2][x1+x2] = 255 - dctClip[dctClipOffset + pB]; + } + } + } + } + } + return gTrue; +} + +// This IDCT algorithm is taken from: +// Christoph Loeffler, Adriaan Ligtenberg, George S. Moschytz, +// "Practical Fast 1-D DCT Algorithms with 11 Multiplications", +// IEEE Intl. Conf. on Acoustics, Speech & Signal Processing, 1989, +// 988-991. +// The stage numbers mentioned in the comments refer to Figure 1 in this +// paper. +#ifndef FP_IDCT +GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable, + DCTHuffTable *acHuffTable, + Guchar quantTable[64], int *prevDC, + Guchar data[64]) { + int tmp1[64]; + int v0, v1, v2, v3, v4, v5, v6, v7, t; + int run, size, amp; + int c; + int i, j; + + // Huffman decode and dequantize + size = readHuffSym(dcHuffTable); + if (size == 9999) + return gFalse; + if (size > 0) { + amp = readAmp(size); + if (amp == 9999) + return gFalse; + } else { + amp = 0; + } + tmp1[0] = (*prevDC += amp) * quantTable[0]; + for (i = 1; i < 64; ++i) + tmp1[i] = 0; + i = 1; + while (i < 64) { + run = 0; + while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) + run += 0x10; + if (c == 9999) + return gFalse; + if (c == 0x00) { + break; + } else { + run += (c >> 4) & 0x0f; + size = c & 0x0f; + amp = readAmp(size); + if (amp == 9999) + return gFalse; + i += run; + j = dctZigZag[i++]; + tmp1[j] = amp * quantTable[j]; + } + } + + // inverse DCT on rows + for (i = 0; i < 64; i += 8) { + + // stage 4 + v0 = (dctSqrt2 * tmp1[i+0] + 128) >> 8; + v1 = (dctSqrt2 * tmp1[i+4] + 128) >> 8; + v2 = tmp1[i+2]; + v3 = tmp1[i+6]; + v4 = (dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]) + 128) >> 8; + v7 = (dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]) + 128) >> 8; + v5 = tmp1[i+3] << 4; + v6 = tmp1[i+5] << 4; + + // stage 3 + t = (v0 - v1+ 1) >> 1; + v0 = (v0 + v1 + 1) >> 1; + v1 = t; + t = (v2 * dctSin6 + v3 * dctCos6 + 128) >> 8; + v2 = (v2 * dctCos6 - v3 * dctSin6 + 128) >> 8; + v3 = t; + t = (v4 - v6 + 1) >> 1; + v4 = (v4 + v6 + 1) >> 1; + v6 = t; + t = (v7 + v5 + 1) >> 1; + v5 = (v7 - v5 + 1) >> 1; + v7 = t; + + // stage 2 + t = (v0 - v3 + 1) >> 1; + v0 = (v0 + v3 + 1) >> 1; + v3 = t; + t = (v1 - v2 + 1) >> 1; + v1 = (v1 + v2 + 1) >> 1; + v2 = t; + t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12; + v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12; + v7 = t; + t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12; + v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12; + v6 = t; + + // stage 1 + tmp1[i+0] = v0 + v7; + tmp1[i+7] = v0 - v7; + tmp1[i+1] = v1 + v6; + tmp1[i+6] = v1 - v6; + tmp1[i+2] = v2 + v5; + tmp1[i+5] = v2 - v5; + tmp1[i+3] = v3 + v4; + tmp1[i+4] = v3 - v4; + } + + // inverse DCT on columns + for (i = 0; i < 8; ++i) { + + // stage 4 + v0 = (dctSqrt2 * tmp1[0*8+i] + 2048) >> 12; + v1 = (dctSqrt2 * tmp1[4*8+i] + 2048) >> 12; + v2 = tmp1[2*8+i]; + v3 = tmp1[6*8+i]; + v4 = (dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]) + 2048) >> 12; + v7 = (dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]) + 2048) >> 12; + v5 = tmp1[3*8+i]; + v6 = tmp1[5*8+i]; + + // stage 3 + t = (v0 - v1 + 1) >> 1; + v0 = (v0 + v1 + 1) >> 1; + v1 = t; + t = (v2 * dctSin6 + v3 * dctCos6 + 2048) >> 12; + v2 = (v2 * dctCos6 - v3 * dctSin6 + 2048) >> 12; + v3 = t; + t = (v4 - v6 + 1) >> 1; + v4 = (v4 + v6 + 1) >> 1; + v6 = t; + t = (v7 + v5 + 1) >> 1; + v5 = (v7 - v5 + 1) >> 1; + v7 = t; + + // stage 2 + t = (v0 - v3 + 1) >> 1; + v0 = (v0 + v3 + 1) >> 1; + v3 = t; + t = (v1 - v2 + 1) >> 1; + v1 = (v1 + v2 + 1) >> 1; + v2 = t; + t = (v4 * dctSin3 + v7 * dctCos3 + 2048) >> 12; + v4 = (v4 * dctCos3 - v7 * dctSin3 + 2048) >> 12; + v7 = t; + t = (v5 * dctSin1 + v6 * dctCos1 + 2048) >> 12; + v5 = (v5 * dctCos1 - v6 * dctSin1 + 2048) >> 12; + v6 = t; + + // stage 1 + tmp1[0*8+i] = v0 + v7; + tmp1[7*8+i] = v0 - v7; + tmp1[1*8+i] = v1 + v6; + tmp1[6*8+i] = v1 - v6; + tmp1[2*8+i] = v2 + v5; + tmp1[5*8+i] = v2 - v5; + tmp1[3*8+i] = v3 + v4; + tmp1[4*8+i] = v3 - v4; + } + + // convert to 8-bit integers + for (i = 0; i < 64; ++i) + data[i] = dctClip[dctClipOffset + 128 + ((tmp1[i] + 8) >> 4)]; + + return gTrue; +} +#endif + +#ifdef FP_IDCT +GBool DCTStream::readDataUnit(DCTHuffTable *dcHuffTable, + DCTHuffTable *acHuffTable, + Guchar quantTable[64], int *prevDC, + Guchar data[64]) { + double tmp1[64]; + double v0, v1, v2, v3, v4, v5, v6, v7, t; + int run, size, amp; + int c; + int i, j; + + // Huffman decode and dequantize + size = readHuffSym(dcHuffTable); + if (size == 9999) + return gFalse; + if (size > 0) { + amp = readAmp(size); + if (amp == 9999) + return gFalse; + } else { + amp = 0; + } + tmp1[0] = (*prevDC += amp) * quantTable[0]; + for (i = 1; i < 64; ++i) + tmp1[i] = 0; + i = 1; + while (i < 64) { + run = 0; + while ((c = readHuffSym(acHuffTable)) == 0xf0 && run < 0x30) + run += 0x10; + if (c == 9999) + return gFalse; + if (c == 0x00) { + break; + } else { + run += (c >> 4) & 0x0f; + size = c & 0x0f; + amp = readAmp(size); + if (amp == 9999) + return gFalse; + i += run; + j = dctZigZag[i++]; + tmp1[j] = amp * quantTable[j]; + } + } + + // inverse DCT on rows + for (i = 0; i < 64; i += 8) { + + // stage 4 + v0 = dctSqrt2 * tmp1[i+0]; + v1 = dctSqrt2 * tmp1[i+4]; + v2 = tmp1[i+2]; + v3 = tmp1[i+6]; + v4 = dctSqrt1d2 * (tmp1[i+1] - tmp1[i+7]); + v7 = dctSqrt1d2 * (tmp1[i+1] + tmp1[i+7]); + v5 = tmp1[i+3]; + v6 = tmp1[i+5]; + + // stage 3 + t = 0.5 * (v0 - v1); + v0 = 0.5 * (v0 + v1); + v1 = t; + t = v2 * dctSin6 + v3 * dctCos6; + v2 = v2 * dctCos6 - v3 * dctSin6; + v3 = t; + t = 0.5 * (v4 - v6); + v4 = 0.5 * (v4 + v6); + v6 = t; + t = 0.5 * (v7 + v5); + v5 = 0.5 * (v7 - v5); + v7 = t; + + // stage 2 + t = 0.5 * (v0 - v3); + v0 = 0.5 * (v0 + v3); + v3 = t; + t = 0.5 * (v1 - v2); + v1 = 0.5 * (v1 + v2); + v2 = t; + t = v4 * dctSin3 + v7 * dctCos3; + v4 = v4 * dctCos3 - v7 * dctSin3; + v7 = t; + t = v5 * dctSin1 + v6 * dctCos1; + v5 = v5 * dctCos1 - v6 * dctSin1; + v6 = t; + + // stage 1 + tmp1[i+0] = v0 + v7; + tmp1[i+7] = v0 - v7; + tmp1[i+1] = v1 + v6; + tmp1[i+6] = v1 - v6; + tmp1[i+2] = v2 + v5; + tmp1[i+5] = v2 - v5; + tmp1[i+3] = v3 + v4; + tmp1[i+4] = v3 - v4; + } + + // inverse DCT on columns + for (i = 0; i < 8; ++i) { + + // stage 4 + v0 = dctSqrt2 * tmp1[0*8+i]; + v1 = dctSqrt2 * tmp1[4*8+i]; + v2 = tmp1[2*8+i]; + v3 = tmp1[6*8+i]; + v4 = dctSqrt1d2 * (tmp1[1*8+i] - tmp1[7*8+i]); + v7 = dctSqrt1d2 * (tmp1[1*8+i] + tmp1[7*8+i]); + v5 = tmp1[3*8+i]; + v6 = tmp1[5*8+i]; + + // stage 3 + t = 0.5 * (v0 - v1); + v0 = 0.5 * (v0 + v1); + v1 = t; + t = v2 * dctSin6 + v3 * dctCos6; + v2 = v2 * dctCos6 - v3 * dctSin6; + v3 = t; + t = 0.5 * (v4 - v6); + v4 = 0.5 * (v4 + v6); + v6 = t; + t = 0.5 * (v7 + v5); + v5 = 0.5 * (v7 - v5); + v7 = t; + + // stage 2 + t = 0.5 * (v0 - v3); + v0 = 0.5 * (v0 + v3); + v3 = t; + t = 0.5 * (v1 - v2); + v1 = 0.5 * (v1 + v2); + v2 = t; + t = v4 * dctSin3 + v7 * dctCos3; + v4 = v4 * dctCos3 - v7 * dctSin3; + v7 = t; + t = v5 * dctSin1 + v6 * dctCos1; + v5 = v5 * dctCos1 - v6 * dctSin1; + v6 = t; + + // stage 1 + tmp1[0*8+i] = v0 + v7; + tmp1[7*8+i] = v0 - v7; + tmp1[1*8+i] = v1 + v6; + tmp1[6*8+i] = v1 - v6; + tmp1[2*8+i] = v2 + v5; + tmp1[5*8+i] = v2 - v5; + tmp1[3*8+i] = v3 + v4; + tmp1[4*8+i] = v3 - v4; + } + + // convert to 8-bit integers + for (i = 0; i < 64; ++i) + data[i] = dctClip[dctClipOffset + (int)(tmp1[i] + 128.5)]; + + return gTrue; +} +#endif + +int DCTStream::readHuffSym(DCTHuffTable *table) { + Gushort code; + int bit; + int codeBits; + + code = 0; + codeBits = 0; + do { + // add a bit to the code + if ((bit = readBit()) == EOF) + return 9999; + code = (code << 1) + bit; + ++codeBits; + + // look up code + if (code - table->firstCode[codeBits] < table->numCodes[codeBits]) { + code -= table->firstCode[codeBits]; + return table->sym[table->firstSym[codeBits] + code]; + } + } while (codeBits < 16); + + error(getPos(), "Bad Huffman code in DCT stream"); + return 9999; +} + +int DCTStream::readAmp(int size) { + int amp, bit; + int bits; + + amp = 0; + for (bits = 0; bits < size; ++bits) { + if ((bit = readBit()) == EOF) + return 9999; + amp = (amp << 1) + bit; + } + if (amp < (1 << (size - 1))) + amp -= (1 << size) - 1; + return amp; +} + +int DCTStream::readBit() { + int bit; + int c, c2; + + if (inputBits == 0) { + if ((c = str->getChar()) == EOF) + return EOF; + if (c == 0xff) { + do { + c2 = str->getChar(); + } while (c2 == 0xff); + if (c2 != 0x00) { + error(getPos(), "Bad DCT data: missing 00 after ff"); + return EOF; + } + } + inputBuf = c; + inputBits = 8; + } + bit = (inputBuf >> (inputBits - 1)) & 1; + --inputBits; + return bit; +} + +GBool DCTStream::readHeader() { + GBool doScan; + int minHSample, minVSample; + int bufWidth; + int n; + int c = 0; + int i, j; + + width = height = 0; + numComps = 0; + numQuantTables = 0; + numDCHuffTables = 0; + numACHuffTables = 0; + colorXform = 0; + gotAdobeMarker = gFalse; + restartInterval = 0; + + // read headers + doScan = gFalse; + while (!doScan) { + c = readMarker(); + switch (c) { + case 0xc0: // SOF0 + if (!readFrameInfo()) + return gFalse; + break; + case 0xc4: // DHT + if (!readHuffmanTables()) + return gFalse; + break; + case 0xd8: // SOI + break; + case 0xda: // SOS + if (!readScanInfo()) + return gFalse; + doScan = gTrue; + break; + case 0xdb: // DQT + if (!readQuantTables()) + return gFalse; + break; + case 0xdd: // DRI + if (!readRestartInterval()) + return gFalse; + break; + case 0xee: // APP14 + if (!readAdobeMarker()) + return gFalse; + break; + case EOF: + error(getPos(), "Bad DCT header"); + return gFalse; + default: + // skip APPn / COM / etc. + if (c >= 0xe0) { + n = read16() - 2; + for (i = 0; i < n; ++i) + str->getChar(); + } else { + error(getPos(), "Unknown DCT marker <%02x>", c); + return gFalse; + } + break; + } + } + + // compute MCU size + mcuWidth = minHSample = compInfo[0].hSample; + mcuHeight = minVSample = compInfo[0].vSample; + for (i = 1; i < numComps; ++i) { + if (compInfo[i].hSample < minHSample) + minHSample = compInfo[i].hSample; + if (compInfo[i].vSample < minVSample) + minVSample = compInfo[i].vSample; + if (compInfo[i].hSample > mcuWidth) + mcuWidth = compInfo[i].hSample; + if (compInfo[i].vSample > mcuHeight) + mcuHeight = compInfo[i].vSample; + } + for (i = 0; i < numComps; ++i) { + compInfo[i].hSample /= minHSample; + compInfo[i].vSample /= minVSample; + } + mcuWidth = (mcuWidth / minHSample) * 8; + mcuHeight = (mcuHeight / minVSample) * 8; + + // allocate buffers + bufWidth = ((width + mcuWidth - 1) / mcuWidth) * mcuWidth; + for (i = 0; i < numComps; ++i) + for (j = 0; j < mcuHeight; ++j) + rowBuf[i][j] = (Guchar *)gmalloc(bufWidth * sizeof(Guchar)); + + // figure out color transform + if (!gotAdobeMarker && numComps == 3) { + if (compInfo[0].id == 1 && compInfo[1].id == 2 && compInfo[2].id == 3) { + colorXform = 1; + } + } + + // initialize counters + comp = 0; + x = 0; + y = 0; + dy = mcuHeight; + + return gTrue; +} + +GBool DCTStream::readFrameInfo() { + int length; + int prec; + int i; + int c; + + length = read16() - 2; + prec = str->getChar(); + height = read16(); + width = read16(); + numComps = str->getChar(); + length -= 6; + if (prec != 8) { + error(getPos(), "Bad DCT precision %d", prec); + return gFalse; + } + for (i = 0; i < numComps; ++i) { + compInfo[i].id = str->getChar(); + compInfo[i].inScan = gFalse; + c = str->getChar(); + compInfo[i].hSample = (c >> 4) & 0x0f; + compInfo[i].vSample = c & 0x0f; + compInfo[i].quantTable = str->getChar(); + compInfo[i].dcHuffTable = 0; + compInfo[i].acHuffTable = 0; + } + return gTrue; +} + +GBool DCTStream::readScanInfo() { + int length; + int scanComps, id, c; + int i, j; + + length = read16() - 2; + scanComps = str->getChar(); + --length; + if (length != 2 * scanComps + 3) { + error(getPos(), "Bad DCT scan info block"); + return gFalse; + } + for (i = 0; i < scanComps; ++i) { + id = str->getChar(); + for (j = 0; j < numComps; ++j) { + if (id == compInfo[j].id) + break; + } + if (j == numComps) { + error(getPos(), "Bad DCT component ID in scan info block"); + return gFalse; + } + compInfo[j].inScan = gTrue; + c = str->getChar(); + compInfo[j].dcHuffTable = (c >> 4) & 0x0f; + compInfo[j].acHuffTable = c & 0x0f; + } + str->getChar(); + str->getChar(); + str->getChar(); + return gTrue; +} + +GBool DCTStream::readQuantTables() { + int length; + int i; + int index; + + length = read16() - 2; + while (length > 0) { + index = str->getChar(); + if ((index & 0xf0) || index >= 4) { + error(getPos(), "Bad DCT quantization table"); + return gFalse; + } + if (index == numQuantTables) + numQuantTables = index + 1; + for (i = 0; i < 64; ++i) + quantTables[index][dctZigZag[i]] = str->getChar(); + length -= 65; + } + return gTrue; +} + +GBool DCTStream::readHuffmanTables() { + DCTHuffTable *tbl; + int length; + int index; + Gushort code; + Guchar sym; + int i; + int c; + + length = read16() - 2; + while (length > 0) { + index = str->getChar(); + --length; + if ((index & 0x0f) >= 4) { + error(getPos(), "Bad DCT Huffman table"); + return gFalse; + } + if (index & 0x10) { + index &= 0x0f; + if (index >= numACHuffTables) + numACHuffTables = index+1; + tbl = &acHuffTables[index]; + } else { + if (index >= numDCHuffTables) + numDCHuffTables = index+1; + tbl = &dcHuffTables[index]; + } + sym = 0; + code = 0; + for (i = 1; i <= 16; ++i) { + c = str->getChar(); + tbl->firstSym[i] = sym; + tbl->firstCode[i] = code; + tbl->numCodes[i] = c; + sym += c; + code = (code + c) << 1; + } + length -= 16; + for (i = 0; i < sym; ++i) + tbl->sym[i] = str->getChar(); + length -= sym; + } + return gTrue; +} + +GBool DCTStream::readRestartInterval() { + int length; + + length = read16(); + if (length != 4) { + error(getPos(), "Bad DCT restart interval"); + return gFalse; + } + restartInterval = read16(); + return gTrue; +} + +GBool DCTStream::readAdobeMarker() { + int length, i; + char buf[12]; + int c; + + length = read16(); + if (length != 14) + goto err; + for (i = 0; i < 12; ++i) { + if ((c = str->getChar()) == EOF) + goto err; + buf[i] = c; + } + if (strncmp(buf, "Adobe", 5)) + goto err; + colorXform = buf[11]; + gotAdobeMarker = gTrue; + return gTrue; + + err: + error(getPos(), "Bad DCT Adobe APP14 marker"); + return gFalse; +} + +GBool DCTStream::readTrailer() { + int c; + + c = readMarker(); + if (c != 0xd9) { // EOI + error(getPos(), "Bad DCT trailer"); + return gFalse; + } + return gTrue; +} + +int DCTStream::readMarker() { + int c; + + do { + do { + c = str->getChar(); + } while (c != 0xff); + do { + c = str->getChar(); + } while (c == 0xff); + } while (c == 0x00); + return c; +} + +int DCTStream::read16() { + int c1, c2; + + if ((c1 = str->getChar()) == EOF) + return EOF; + if ((c2 = str->getChar()) == EOF) + return EOF; + return (c1 << 8) + c2; +} + +GString *DCTStream::getPSFilter(char *indent) { + GString *s; + + s = str->getPSFilter(indent); + s->append(indent)->append("<< >> /DCTDecode filter\n"); + return s; +} + +GBool DCTStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +//------------------------------------------------------------------------ +// FlateStream +//------------------------------------------------------------------------ + +int FlateStream::codeLenCodeMap[flateMaxCodeLenCodes] = { + 16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15 +}; + +FlateDecode FlateStream::lengthDecode[flateMaxLitCodes-257] = { + {0, 3}, + {0, 4}, + {0, 5}, + {0, 6}, + {0, 7}, + {0, 8}, + {0, 9}, + {0, 10}, + {1, 11}, + {1, 13}, + {1, 15}, + {1, 17}, + {2, 19}, + {2, 23}, + {2, 27}, + {2, 31}, + {3, 35}, + {3, 43}, + {3, 51}, + {3, 59}, + {4, 67}, + {4, 83}, + {4, 99}, + {4, 115}, + {5, 131}, + {5, 163}, + {5, 195}, + {5, 227}, + {0, 258} +}; + +FlateDecode FlateStream::distDecode[flateMaxDistCodes] = { + { 0, 1}, + { 0, 2}, + { 0, 3}, + { 0, 4}, + { 1, 5}, + { 1, 7}, + { 2, 9}, + { 2, 13}, + { 3, 17}, + { 3, 25}, + { 4, 33}, + { 4, 49}, + { 5, 65}, + { 5, 97}, + { 6, 129}, + { 6, 193}, + { 7, 257}, + { 7, 385}, + { 8, 513}, + { 8, 769}, + { 9, 1025}, + { 9, 1537}, + {10, 2049}, + {10, 3073}, + {11, 4097}, + {11, 6145}, + {12, 8193}, + {12, 12289}, + {13, 16385}, + {13, 24577} +}; + +FlateStream::FlateStream(Stream *str1, int predictor1, int columns1, + int colors1, int bits1) { + str = str1; + if (predictor1 != 1) { + pred = new StreamPredictor(this, predictor1, columns1, colors1, bits1); + } else { + pred = NULL; + } +} + +FlateStream::~FlateStream() { + if (pred) { + delete pred; + } + delete str; +} + +void FlateStream::reset() { + int cmf, flg; + + str->reset(); + + // read header + //~ need to look at window size? + endOfBlock = eof = gTrue; + cmf = str->getChar(); + flg = str->getChar(); + if (cmf == EOF || flg == EOF) + return; + if ((cmf & 0x0f) != 0x08) { + error(getPos(), "Unknown compression method in flate stream"); + return; + } + if ((((cmf << 8) + flg) % 31) != 0) { + error(getPos(), "Bad FCHECK in flate stream"); + return; + } + if (flg & 0x20) { + error(getPos(), "FDICT bit set in flate stream"); + return; + } + + // initialize + index = 0; + remain = 0; + codeBuf = 0; + codeSize = 0; + compressedBlock = gFalse; + endOfBlock = gTrue; + eof = gFalse; +} + +int FlateStream::getChar() { + int c; + + if (pred) { + return pred->getChar(); + } + while (remain == 0) { + if (endOfBlock && eof) + return EOF; + readSome(); + } + c = buf[index]; + index = (index + 1) & flateMask; + --remain; + return c; +} + +int FlateStream::lookChar() { + int c; + + if (pred) { + return pred->lookChar(); + } + while (remain == 0) { + if (endOfBlock && eof) + return EOF; + readSome(); + } + c = buf[index]; + return c; +} + +int FlateStream::getRawChar() { + int c; + + while (remain == 0) { + if (endOfBlock && eof) + return EOF; + readSome(); + } + c = buf[index]; + index = (index + 1) & flateMask; + --remain; + return c; +} + +GString *FlateStream::getPSFilter(char *indent) { + return NULL; +} + +GBool FlateStream::isBinary(GBool last) { + return str->isBinary(gTrue); +} + +void FlateStream::readSome() { + int code1, code2; + int len, dist; + int i, j, k; + int c; + + if (endOfBlock) { + if (!startBlock()) + return; + } + + if (compressedBlock) { + if ((code1 = getHuffmanCodeWord(&litCodeTab)) == EOF) + goto err; + if (code1 < 256) { + buf[index] = code1; + remain = 1; + } else if (code1 == 256) { + endOfBlock = gTrue; + remain = 0; + } else { + code1 -= 257; + code2 = lengthDecode[code1].bits; + if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF) + goto err; + len = lengthDecode[code1].first + code2; + if ((code1 = getHuffmanCodeWord(&distCodeTab)) == EOF) + goto err; + code2 = distDecode[code1].bits; + if (code2 > 0 && (code2 = getCodeWord(code2)) == EOF) + goto err; + dist = distDecode[code1].first + code2; + i = index; + j = (index - dist) & flateMask; + for (k = 0; k < len; ++k) { + buf[i] = buf[j]; + i = (i + 1) & flateMask; + j = (j + 1) & flateMask; + } + remain = len; + } + + } else { + len = (blockLen < flateWindow) ? blockLen : flateWindow; + for (i = 0, j = index; i < len; ++i, j = (j + 1) & flateMask) { + if ((c = str->getChar()) == EOF) { + endOfBlock = eof = gTrue; + break; + } + buf[j] = c & 0xff; + } + remain = i; + blockLen -= len; + if (blockLen == 0) + endOfBlock = gTrue; + } + + return; + +err: + error(getPos(), "Unexpected end of file in flate stream"); + endOfBlock = eof = gTrue; + remain = 0; +} + +GBool FlateStream::startBlock() { + int blockHdr; + int c; + int check; + + // read block header + blockHdr = getCodeWord(3); + if (blockHdr & 1) + eof = gTrue; + blockHdr >>= 1; + + // uncompressed block + if (blockHdr == 0) { + compressedBlock = gFalse; + if ((c = str->getChar()) == EOF) + goto err; + blockLen = c & 0xff; + if ((c = str->getChar()) == EOF) + goto err; + blockLen |= (c & 0xff) << 8; + if ((c = str->getChar()) == EOF) + goto err; + check = c & 0xff; + if ((c = str->getChar()) == EOF) + goto err; + check |= (c & 0xff) << 8; + if (check != (~blockLen & 0xffff)) + error(getPos(), "Bad uncompressed block length in flate stream"); + codeBuf = 0; + codeSize = 0; + + // compressed block with fixed codes + } else if (blockHdr == 1) { + compressedBlock = gTrue; + loadFixedCodes(); + + // compressed block with dynamic codes + } else if (blockHdr == 2) { + compressedBlock = gTrue; + if (!readDynamicCodes()) + goto err; + + // unknown block type + } else { + goto err; + } + + endOfBlock = gFalse; + return gTrue; + +err: + error(getPos(), "Bad block header in flate stream"); + endOfBlock = eof = gTrue; + return gFalse; +} + +void FlateStream::loadFixedCodes() { + int i; + + // set up code arrays + litCodeTab.codes = allCodes; + distCodeTab.codes = allCodes + flateMaxLitCodes; + + // initialize literal code table + for (i = 0; i <= 143; ++i) + litCodeTab.codes[i].len = 8; + for (i = 144; i <= 255; ++i) + litCodeTab.codes[i].len = 9; + for (i = 256; i <= 279; ++i) + litCodeTab.codes[i].len = 7; + for (i = 280; i <= 287; ++i) + litCodeTab.codes[i].len = 8; + compHuffmanCodes(&litCodeTab, flateMaxLitCodes); + + // initialize distance code table + for (i = 0; i < 5; ++i) + distCodeTab.start[i] = 0; + distCodeTab.start[5] = 0; + for (i = 6; i <= flateMaxHuffman+1; ++i) + distCodeTab.start[6] = flateMaxDistCodes; + for (i = 0; i < flateMaxDistCodes; ++i) { + distCodeTab.codes[i].len = 5; + distCodeTab.codes[i].code = i; + distCodeTab.codes[i].val = i; + } +} + +GBool FlateStream::readDynamicCodes() { + int numCodeLenCodes; + int numLitCodes; + int numDistCodes; + FlateCode codeLenCodes[flateMaxCodeLenCodes]; + FlateHuffmanTab codeLenCodeTab; + int len, repeat, code; + int i; + + // read lengths + if ((numLitCodes = getCodeWord(5)) == EOF) + goto err; + numLitCodes += 257; + if ((numDistCodes = getCodeWord(5)) == EOF) + goto err; + numDistCodes += 1; + if ((numCodeLenCodes = getCodeWord(4)) == EOF) + goto err; + numCodeLenCodes += 4; + if (numLitCodes > flateMaxLitCodes || + numDistCodes > flateMaxDistCodes || + numCodeLenCodes > flateMaxCodeLenCodes) + goto err; + + // read code length code table + codeLenCodeTab.codes = codeLenCodes; + for (i = 0; i < flateMaxCodeLenCodes; ++i) + codeLenCodes[i].len = 0; + for (i = 0; i < numCodeLenCodes; ++i) { + if ((codeLenCodes[codeLenCodeMap[i]].len = getCodeWord(3)) == -1) + goto err; + } + compHuffmanCodes(&codeLenCodeTab, flateMaxCodeLenCodes); + + // set up code arrays + litCodeTab.codes = allCodes; + distCodeTab.codes = allCodes + numLitCodes; + + // read literal and distance code tables + len = 0; + repeat = 0; + i = 0; + while (i < numLitCodes + numDistCodes) { + if ((code = getHuffmanCodeWord(&codeLenCodeTab)) == EOF) + goto err; + if (code == 16) { + if ((repeat = getCodeWord(2)) == EOF) + goto err; + for (repeat += 3; repeat > 0; --repeat) + allCodes[i++].len = len; + } else if (code == 17) { + if ((repeat = getCodeWord(3)) == EOF) + goto err; + len = 0; + for (repeat += 3; repeat > 0; --repeat) + allCodes[i++].len = 0; + } else if (code == 18) { + if ((repeat = getCodeWord(7)) == EOF) + goto err; + len = 0; + for (repeat += 11; repeat > 0; --repeat) + allCodes[i++].len = 0; + } else { + allCodes[i++].len = len = code; + } + } + compHuffmanCodes(&litCodeTab, numLitCodes); + compHuffmanCodes(&distCodeTab, numDistCodes); + + return gTrue; + +err: + error(getPos(), "Bad dynamic code table in flate stream"); + return gFalse; +} + +// On entry, the codes> array contains the lengths of each code, +// stored in code value order. This function computes the code words. +// The result is sorted in order of (1) code length and (2) code word. +// The length values are no longer valid. The start> array is +// filled with the indexes of the first code of each length. +void FlateStream::compHuffmanCodes(FlateHuffmanTab *tab, int n) { + int numLengths[flateMaxHuffman+1]; + int nextCode[flateMaxHuffman+1]; + int nextIndex[flateMaxHuffman+2]; + int code; + int i, j; + + // count number of codes for each code length + for (i = 0; i <= flateMaxHuffman; ++i) + numLengths[i] = 0; + for (i = 0; i < n; ++i) + ++numLengths[tab->codes[i].len]; + + // compute first index for each length + tab->start[0] = nextIndex[0] = 0; + for (i = 1; i <= flateMaxHuffman + 1; ++i) + tab->start[i] = nextIndex[i] = tab->start[i-1] + numLengths[i-1]; + + // compute first code for each length + code = 0; + numLengths[0] = 0; + for (i = 1; i <= flateMaxHuffman; ++i) { + code = (code + numLengths[i-1]) << 1; + nextCode[i] = code; + } + + // compute the codes -- this permutes the codes array from value + // order to length/code order + for (i = 0; i < n; ++i) { + j = nextIndex[tab->codes[i].len]++; + if (tab->codes[i].len == 0) + tab->codes[j].code = 0; + else + tab->codes[j].code = nextCode[tab->codes[i].len]++; + tab->codes[j].val = i; + } +} + +int FlateStream::getHuffmanCodeWord(FlateHuffmanTab *tab) { + int len; + int code; + int c; + int i, j; + + code = 0; + for (len = 1; len <= flateMaxHuffman; ++len) { + + // add a bit to the code + if (codeSize == 0) { + if ((c = str->getChar()) == EOF) + return EOF; + codeBuf = c & 0xff; + codeSize = 8; + } + code = (code << 1) | (codeBuf & 1); + codeBuf >>= 1; + --codeSize; + + // look for code + i = tab->start[len]; + j = tab->start[len + 1]; + if (i < j && code >= tab->codes[i].code && code <= tab->codes[j-1].code) { + i += code - tab->codes[i].code; + return tab->codes[i].val; + } + } + + // not found + error(getPos(), "Bad code (%04x) in flate stream", code); + return EOF; +} + +int FlateStream::getCodeWord(int bits) { + int c; + + while (codeSize < bits) { + if ((c = str->getChar()) == EOF) + return EOF; + codeBuf |= (c & 0xff) << codeSize; + codeSize += 8; + } + c = codeBuf & ((1 << bits) - 1); + codeBuf >>= bits; + codeSize -= bits; + return c; +} + +//------------------------------------------------------------------------ +// EOFStream +//------------------------------------------------------------------------ + +EOFStream::EOFStream(Stream *str1) { + str = str1; +} + +EOFStream::~EOFStream() { + delete str; +} + +//------------------------------------------------------------------------ +// FixedLengthEncoder +//------------------------------------------------------------------------ + +FixedLengthEncoder::FixedLengthEncoder(Stream *str1, int length1) { + str = str1; + length = length1; + count = 0; +} + +FixedLengthEncoder::~FixedLengthEncoder() { + if (str->isEncoder()) + delete str; +} + +void FixedLengthEncoder::reset() { + str->reset(); + count = 0; +} + +int FixedLengthEncoder::getChar() { + if (length >= 0 && count >= length) + return EOF; + ++count; + return str->getChar(); +} + +int FixedLengthEncoder::lookChar() { + if (length >= 0 && count >= length) + return EOF; + return str->getChar(); +} + +//------------------------------------------------------------------------ +// ASCII85Encoder +//------------------------------------------------------------------------ + +ASCII85Encoder::ASCII85Encoder(Stream *str1) { + str = str1; + bufPtr = bufEnd = buf; + lineLen = 0; + eof = gFalse; +} + +ASCII85Encoder::~ASCII85Encoder() { + if (str->isEncoder()) + delete str; +} + +void ASCII85Encoder::reset() { + str->reset(); + bufPtr = bufEnd = buf; + lineLen = 0; + eof = gFalse; +} + +GBool ASCII85Encoder::fillBuf() { + Gulong t; + char buf1[5]; + int c; + int n, i; + + if (eof) + return gFalse; + t = 0; + for (n = 0; n < 4; ++n) { + if ((c = str->getChar()) == EOF) + break; + t = (t << 8) + c; + } + bufPtr = bufEnd = buf; + if (n > 0) { + if (n == 4 && t == 0) { + *bufEnd++ = 'z'; + if (++lineLen == 65) { + *bufEnd++ = '\n'; + lineLen = 0; + } + } else { + if (n < 4) + t <<= 8 * (4 - n); + for (i = 4; i >= 0; --i) { + buf1[i] = (char)(t % 85 + 0x21); + t /= 85; + } + for (i = 0; i <= n; ++i) { + *bufEnd++ = buf1[i]; + if (++lineLen == 65) { + *bufEnd++ = '\n'; + lineLen = 0; + } + } + } + } + if (n < 4) { + *bufEnd++ = '~'; + *bufEnd++ = '>'; + eof = gTrue; + } + return bufPtr < bufEnd; +} + +//------------------------------------------------------------------------ +// RunLengthEncoder +//------------------------------------------------------------------------ + +RunLengthEncoder::RunLengthEncoder(Stream *str1) { + str = str1; + bufPtr = bufEnd = nextEnd = buf; + eof = gFalse; +} + +RunLengthEncoder::~RunLengthEncoder() { + if (str->isEncoder()) + delete str; +} + +void RunLengthEncoder::reset() { + str->reset(); + bufPtr = bufEnd = nextEnd = buf; + eof = gFalse; +} + +// +// When fillBuf finishes, buf[] looks like this: +// +-----+--------------+-----------------+-- +// + tag | ... data ... | next 0, 1, or 2 | +// +-----+--------------+-----------------+-- +// ^ ^ ^ +// bufPtr bufEnd nextEnd +// +GBool RunLengthEncoder::fillBuf() { + int c, c1, c2; + int n; + + // already hit EOF? + if (eof) + return gFalse; + + // grab two bytes + if (nextEnd < bufEnd + 1) { + if ((c1 = str->getChar()) == EOF) { + eof = gTrue; + return gFalse; + } + } else { + c1 = bufEnd[0] & 0xff; + } + if (nextEnd < bufEnd + 2) { + if ((c2 = str->getChar()) == EOF) { + eof = gTrue; + buf[0] = 0; + buf[1] = c1; + bufPtr = buf; + bufEnd = &buf[2]; + return gTrue; + } + } else { + c2 = bufEnd[1] & 0xff; + } + + // check for repeat + if (c1 == c2) { + n = 2; + while (n < 128 && (c = str->getChar()) == c1) + ++n; + buf[0] = (char)(257 - n); + buf[1] = c1; + bufEnd = &buf[2]; + if (c == EOF) { + eof = gTrue; + } else if (n < 128) { + buf[2] = c; + nextEnd = &buf[3]; + } else { + nextEnd = bufEnd; + } + + // get up to 128 chars + } else { + buf[1] = c1; + buf[2] = c2; + n = 2; + while (n < 128) { + if ((c = str->getChar()) == EOF) { + eof = gTrue; + break; + } + ++n; + buf[n] = c; + if (buf[n] == buf[n-1]) + break; + } + if (buf[n] == buf[n-1]) { + buf[0] = (char)(n-2-1); + bufEnd = &buf[n-1]; + nextEnd = &buf[n+1]; + } else { + buf[0] = (char)(n-1); + bufEnd = nextEnd = &buf[n+1]; + } + } + bufPtr = buf; + return gTrue; +} diff --git a/pdftops/Stream.h b/pdftops/Stream.h new file mode 100644 index 0000000000..3eb8160b61 --- /dev/null +++ b/pdftops/Stream.h @@ -0,0 +1,715 @@ +//======================================================================== +// +// Stream.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef STREAM_H +#define STREAM_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include +#include "gtypes.h" +#include "Object.h" + +//------------------------------------------------------------------------ + +enum StreamKind { + strFile, + strASCIIHex, + strASCII85, + strLZW, + strRunLength, + strCCITTFax, + strDCT, + strFlate, + strWeird // internal-use stream types +}; + +//------------------------------------------------------------------------ +// Stream (base class) +//------------------------------------------------------------------------ + +class Stream { +public: + + // Constructor. + Stream(); + + // Destructor. + virtual ~Stream(); + + // Reference counting. + int incRef() { return ++ref; } + int decRef() { return --ref; } + + // Get kind of stream. + virtual StreamKind getKind() = 0; + + // Reset stream to beginning. + virtual void reset() = 0; + + // Get next char from stream. + virtual int getChar() = 0; + + // Peek at next char in stream. + virtual int lookChar() = 0; + + // Get next char from stream without using the predictor. + // This is only used by StreamPredictor. + virtual int getRawChar(); + + // Get next line from stream. + virtual char *getLine(char *buf, int size); + + // Get current position in file. + virtual int getPos() = 0; + + // Go to a position in the stream. + virtual void setPos(int pos1); + + // Get PostScript command for the filter(s). + virtual GString *getPSFilter(char *indent); + + // Does this stream type potentially contain non-printable chars? + virtual GBool isBinary(GBool last = gTrue) = 0; + + // Get the base FileStream or SubStream of this stream. + virtual Stream *getBaseStream() = 0; + + // Get the base file of this stream. + virtual FILE *getFile() = 0; + + // Get the dictionary associated with this stream. + virtual Dict *getDict() = 0; + + // Is this an encoding filter? + virtual GBool isEncoder() { return gFalse; } + + // Add filters to this stream according to the parameters in . + // Returns the new stream. + Stream *addFilters(Object *dict); + +private: + + Stream *makeFilter(char *name, Stream *str, Object *params); + + int ref; // reference count +}; + +//------------------------------------------------------------------------ +// ImageStream +//------------------------------------------------------------------------ + +class ImageStream { +public: + + // Create an image stream object for an image with the specified + // parameters. Note that these are the actual image parameters, + // which may be different from the predictor parameters. + ImageStream(Stream *str, int width, int nComps, int nBits); + + ~ImageStream(); + + // Reset the stream. + void reset(); + + // Gets the next pixel from the stream. should be able to hold + // at least nComps elements. Returns false at end of file. + GBool getPixel(Guchar *pix); + + // Skip an entire line from the image. + void skipLine(); + +private: + + Stream *str; // base stream + int width; // pixels per line + int nComps; // components per pixel + int nBits; // bits per component + int nVals; // components per line + Guchar *imgLine; // line buffer + int imgIdx; // current index in imgLine +}; + +//------------------------------------------------------------------------ +// StreamPredictor +//------------------------------------------------------------------------ + +class StreamPredictor { +public: + + // Create a predictor object. Note that the parameters are for the + // predictor, and may not match the actual image parameters. + StreamPredictor(Stream *str, int predictor, + int width, int nComps, int nBits); + + ~StreamPredictor(); + + int lookChar(); + int getChar(); + +private: + + GBool getNextLine(); + + Stream *str; // base stream + int predictor; // predictor + int width; // pixels per line + int nComps; // components per pixel + int nBits; // bits per component + int nVals; // components per line + int pixBytes; // bytes per pixel + int rowBytes; // bytes per line + Guchar *predLine; // line buffer + int predIdx; // current index in predLine +}; + +//------------------------------------------------------------------------ +// FileStream +//------------------------------------------------------------------------ + +class FileStream: public Stream { +public: + + FileStream(FILE *f1, int start1, int length1, Object *dict1); + virtual ~FileStream(); + virtual StreamKind getKind() { return strFile; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual int getPos() { return bufPos + (bufPtr - buf); } + virtual void setPos(int pos1); + virtual GBool isBinary(GBool last = gTrue) { return last; } + virtual Stream *getBaseStream() { return this; } + virtual FILE *getFile() { return f; } + virtual Dict *getDict() { return dict.getDict(); } + + // Check for a PDF header on this stream. Skip past some garbage + // if necessary. + GBool checkHeader(); + + // Get position of first byte of stream within the file. + int getStart() { return start; } + +private: + + GBool fillBuf(); + + FILE *f; + int start; + int length; + char buf[256]; + char *bufPtr; + char *bufEnd; + int bufPos; + int savePos; + Object dict; +}; + +//------------------------------------------------------------------------ +// SubStream +//------------------------------------------------------------------------ + +class SubStream: public Stream { +public: + + SubStream(Stream *str1, Object *dict1); + virtual ~SubStream(); + virtual StreamKind getKind() { return str->getKind(); } + virtual void reset() {} + virtual int getChar() { return str->getChar(); } + virtual int lookChar() { return str->lookChar(); } + virtual int getPos() { return str->getPos(); } + virtual GBool isBinary(GBool last = gTrue) { return last; } + virtual Stream *getBaseStream() { return this; } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return dict.getDict(); } + +private: + + Stream *str; + Object dict; +}; + +//------------------------------------------------------------------------ +// ASCIIHexStream +//------------------------------------------------------------------------ + +class ASCIIHexStream: public Stream { +public: + + ASCIIHexStream(Stream *str1); + virtual ~ASCIIHexStream(); + virtual StreamKind getKind() { return strASCIIHex; } + virtual void reset(); + virtual int getChar() + { int c = lookChar(); buf = EOF; return c; } + virtual int lookChar(); + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent); + virtual GBool isBinary(GBool last = gTrue); + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + +private: + + Stream *str; + int buf; + GBool eof; +}; + +//------------------------------------------------------------------------ +// ASCII85Stream +//------------------------------------------------------------------------ + +class ASCII85Stream: public Stream { +public: + + ASCII85Stream(Stream *str1); + virtual ~ASCII85Stream(); + virtual StreamKind getKind() { return strASCII85; } + virtual void reset(); + virtual int getChar() + { int ch = lookChar(); ++index; return ch; } + virtual int lookChar(); + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent); + virtual GBool isBinary(GBool last = gTrue); + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + +private: + + Stream *str; + int c[5]; + int b[4]; + int index, n; + GBool eof; +}; + +//------------------------------------------------------------------------ +// LZWStream +//------------------------------------------------------------------------ + +class LZWStream: public Stream { +public: + + LZWStream(Stream *str1, int predictor1, int columns1, int colors1, + int bits1, int early1); + virtual ~LZWStream(); + virtual StreamKind getKind() { return strLZW; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual int getRawChar(); + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent); + virtual GBool isBinary(GBool last = gTrue); + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + +private: + + Stream *str; // stream + StreamPredictor *pred; // predictor + int early; // early parameter + char zCmd[256]; // uncompress command + FILE *zPipe; // uncompress pipe + char *zName; // .Z file name (in zCmd) + int inputBuf; // input buffer + int inputBits; // number of bits in input buffer + int inCodeBits; // size of input code + char buf[256]; // buffer + char *bufPtr; // next char to read + char *bufEnd; // end of buffer + + void dumpFile(FILE *f); + int getCode(); + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// RunLengthStream +//------------------------------------------------------------------------ + +class RunLengthStream: public Stream { +public: + + RunLengthStream(Stream *str1); + virtual ~RunLengthStream(); + virtual StreamKind getKind() { return strRunLength; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent); + virtual GBool isBinary(GBool last = gTrue); + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + +private: + + Stream *str; + char buf[128]; // buffer + char *bufPtr; // next char to read + char *bufEnd; // end of buffer + GBool eof; + + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// CCITTFaxStream +//------------------------------------------------------------------------ + +struct CCITTCodeTable; + +class CCITTFaxStream: public Stream { +public: + + CCITTFaxStream(Stream *str, int encoding, GBool endOfLine, + GBool byteAlign, int columns, int rows, + GBool endOfBlock, GBool black); + virtual ~CCITTFaxStream(); + virtual StreamKind getKind() { return strCCITTFax; } + virtual void reset(); + virtual int getChar() + { int c = lookChar(); buf = EOF; return c; } + virtual int lookChar(); + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent); + virtual GBool isBinary(GBool last = gTrue); + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + +private: + + Stream *str; // stream + int encoding; // 'K' parameter + GBool endOfLine; // 'EndOfLine' parameter + GBool byteAlign; // 'EncodedByteAlign' parameter + int columns; // 'Columns' parameter + int rows; // 'Rows' parameter + GBool endOfBlock; // 'EndOfBlock' parameter + GBool black; // 'BlackIs1' parameter + GBool eof; // true if at eof + GBool nextLine2D; // true if next line uses 2D encoding + int row; // current row + int inputBuf; // input buffer + int inputBits; // number of bits in input buffer + short *refLine; // reference line changing elements + int b1; // index into refLine + short *codingLine; // coding line changing elements + int a0; // index into codingLine + int outputBits; // remaining ouput bits + int buf; // character buffer + + short getTwoDimCode(); + short getWhiteCode(); + short getBlackCode(); + short lookBits(int n); + void eatBits(int n) { inputBits -= n; } +}; + +//------------------------------------------------------------------------ +// DCTStream +//------------------------------------------------------------------------ + +// DCT component info +struct DCTCompInfo { + int id; // component ID + GBool inScan; // is this component in the current scan? + int hSample, vSample; // horiz/vert sampling resolutions + int quantTable; // quantization table number + int dcHuffTable, acHuffTable; // Huffman table numbers + int prevDC; // DC coefficient accumulator +}; + +// DCT Huffman decoding table +struct DCTHuffTable { + Guchar firstSym[17]; // first symbol for this bit length + Gushort firstCode[17]; // first code for this bit length + Gushort numCodes[17]; // number of codes of this bit length + Guchar sym[256]; // symbols +}; + +class DCTStream: public Stream { +public: + + DCTStream(Stream *str1); + virtual ~DCTStream(); + virtual StreamKind getKind() { return strDCT; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent); + virtual GBool isBinary(GBool last = gTrue); + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + Stream *getRawStream() { return str; } + +private: + + Stream *str; // stream + int width, height; // image size + int mcuWidth, mcuHeight; // size of min coding unit, in data units + DCTCompInfo compInfo[4]; // info for each component + int numComps; // number of components in image + int colorXform; // need YCbCr-to-RGB transform? + GBool gotAdobeMarker; // set if APP14 Adobe marker was present + int restartInterval; // restart interval, in MCUs + Guchar quantTables[4][64]; // quantization tables + int numQuantTables; // number of quantization tables + DCTHuffTable dcHuffTables[4]; // DC Huffman tables + DCTHuffTable acHuffTables[4]; // AC Huffman tables + int numDCHuffTables; // number of DC Huffman tables + int numACHuffTables; // number of AC Huffman tables + Guchar *rowBuf[4][32]; // buffer for one MCU + int comp, x, y, dy; // current position within image/MCU + int restartCtr; // MCUs left until restart + int restartMarker; // next restart marker + int inputBuf; // input buffer for variable length codes + int inputBits; // number of valid bits in input buffer + + void restart(); + GBool readMCURow(); + GBool readDataUnit(DCTHuffTable *dcHuffTable, DCTHuffTable *acHuffTable, + Guchar quantTable[64], int *prevDC, Guchar data[64]); + int readHuffSym(DCTHuffTable *table); + int readAmp(int size); + int readBit(); + GBool readHeader(); + GBool readFrameInfo(); + GBool readScanInfo(); + GBool readQuantTables(); + GBool readHuffmanTables(); + GBool readRestartInterval(); + GBool readAdobeMarker(); + GBool readTrailer(); + int readMarker(); + int read16(); +}; + +//------------------------------------------------------------------------ +// FlateStream +//------------------------------------------------------------------------ + +#define flateWindow 32768 // buffer size +#define flateMask (flateWindow-1) +#define flateMaxHuffman 15 // max Huffman code length +#define flateMaxCodeLenCodes 19 // max # code length codes +#define flateMaxLitCodes 288 // max # literal codes +#define flateMaxDistCodes 30 // max # distance codes + +// Huffman code table entry +struct FlateCode { + int len; // code length in bits + int code; // code word + int val; // value represented by this code +}; + +// Huffman code table +struct FlateHuffmanTab { + int start[flateMaxHuffman+2]; // indexes of first code of each length + FlateCode *codes; // codes, sorted by length and code word +}; + +// Decoding info for length and distance code words +struct FlateDecode { + int bits; // # extra bits + int first; // first length/distance +}; + +class FlateStream: public Stream { +public: + + FlateStream(Stream *str1, int predictor1, int columns1, + int colors1, int bits1); + virtual ~FlateStream(); + virtual StreamKind getKind() { return strFlate; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual int getRawChar(); + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent); + virtual GBool isBinary(GBool last = gTrue); + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + +private: + + Stream *str; // stream + StreamPredictor *pred; // predictor + Guchar buf[flateWindow]; // output data buffer + int index; // current index into output buffer + int remain; // number valid bytes in output buffer + int codeBuf; // input buffer + int codeSize; // number of bits in input buffer + FlateCode // literal and distance codes + allCodes[flateMaxLitCodes + flateMaxDistCodes]; + FlateHuffmanTab litCodeTab; // literal code table + FlateHuffmanTab distCodeTab; // distance code table + GBool compressedBlock; // set if reading a compressed block + int blockLen; // remaining length of uncompressed block + GBool endOfBlock; // set when end of block is reached + GBool eof; // set when end of stream is reached + + static int // code length code reordering + codeLenCodeMap[flateMaxCodeLenCodes]; + static FlateDecode // length decoding info + lengthDecode[flateMaxLitCodes-257]; + static FlateDecode // distance decoding info + distDecode[flateMaxDistCodes]; + + void readSome(); + GBool startBlock(); + void loadFixedCodes(); + GBool readDynamicCodes(); + void compHuffmanCodes(FlateHuffmanTab *tab, int n); + int getHuffmanCodeWord(FlateHuffmanTab *tab); + int getCodeWord(int bits); +}; + +//------------------------------------------------------------------------ +// EOFStream +//------------------------------------------------------------------------ + +class EOFStream: public Stream { +public: + + EOFStream(Stream *str1); + virtual ~EOFStream(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset() {} + virtual int getChar() { return EOF; } + virtual int lookChar() { return EOF; } + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + +private: + + Stream *str; +}; + +//------------------------------------------------------------------------ +// FixedLengthEncoder +//------------------------------------------------------------------------ + +class FixedLengthEncoder: public Stream { +public: + + FixedLengthEncoder(Stream *str1, int length1); + ~FixedLengthEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar(); + virtual int lookChar(); + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + virtual GBool isEncoder() { return gTrue; } + +private: + + Stream *str; + int length; + int count; +}; + +//------------------------------------------------------------------------ +// ASCII85Encoder +//------------------------------------------------------------------------ + +class ASCII85Encoder: public Stream { +public: + + ASCII85Encoder(Stream *str1); + virtual ~ASCII85Encoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + virtual GBool isEncoder() { return gTrue; } + +private: + + Stream *str; + char buf[8]; + char *bufPtr; + char *bufEnd; + int lineLen; + GBool eof; + + GBool fillBuf(); +}; + +//------------------------------------------------------------------------ +// RunLengthEncoder +//------------------------------------------------------------------------ + +class RunLengthEncoder: public Stream { +public: + + RunLengthEncoder(Stream *str1); + virtual ~RunLengthEncoder(); + virtual StreamKind getKind() { return strWeird; } + virtual void reset(); + virtual int getChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr++ & 0xff); } + virtual int lookChar() + { return (bufPtr >= bufEnd && !fillBuf()) ? EOF : (*bufPtr & 0xff); } + virtual int getPos() { return str->getPos(); } + virtual GString *getPSFilter(char *indent) { return NULL; } + virtual GBool isBinary(GBool last = gTrue) { return gFalse; } + virtual Stream *getBaseStream() { return str->getBaseStream(); } + virtual FILE *getFile() { return str->getFile(); } + virtual Dict *getDict() { return str->getDict(); } + virtual GBool isEncoder() { return gTrue; } + +private: + + Stream *str; + char buf[131]; + char *bufPtr; + char *bufEnd; + char *nextEnd; + GBool eof; + + GBool fillBuf(); +}; + +#endif diff --git a/pdftops/XRef.cxx b/pdftops/XRef.cxx new file mode 100644 index 0000000000..cc9bee8040 --- /dev/null +++ b/pdftops/XRef.cxx @@ -0,0 +1,443 @@ +//======================================================================== +// +// XRef.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef __GNUC__ +#pragma implementation +#endif + +#include +#include +#include +#include +#include "gmem.h" +#include "Object.h" +#include "Stream.h" +#include "Lexer.h" +#include "Parser.h" +#include "Dict.h" +#include "Error.h" +#include "XRef.h" + +//------------------------------------------------------------------------ + +#define xrefSearchSize 1024 // read this many bytes at end of file + // to look for 'startxref' + +//------------------------------------------------------------------------ +// The global xref table +//------------------------------------------------------------------------ + +XRef *xref = NULL; + +//------------------------------------------------------------------------ +// XRef +//------------------------------------------------------------------------ + +XRef::XRef(FileStream *str) { + XRef *oldXref; + int pos; + int i; + + ok = gTrue; + size = 0; + entries = NULL; + + // get rid of old xref (otherwise it will try to fetch the Root object + // in the new document, using the old xref) + oldXref = xref; + xref = NULL; + + // read the trailer + file = str->getFile(); + start = str->getStart(); + pos = readTrailer(str); + + // if there was a problem with the trailer, + // try to reconstruct the xref table + if (pos == 0) { + if (!(ok = constructXRef(str))) { + xref = oldXref; + return; + } + + // trailer is ok - read the xref table + } else { + entries = (XRefEntry *)gmalloc(size * sizeof(XRefEntry)); + for (i = 0; i < size; ++i) { + entries[i].offset = -1; + entries[i].used = gFalse; + } + while (readXRef(str, &pos)) ; + + // if there was a problem with the xref table, + // try to reconstruct it + if (!ok) { + gfree(entries); + size = 0; + entries = NULL; + if (!(ok = constructXRef(str))) { + xref = oldXref; + return; + } + } + } + + // set up new xref table + xref = this; + + // check for encryption + if (checkEncrypted()) { + ok = gFalse; + xref = oldXref; + return; + } +} + +XRef::~XRef() { + gfree(entries); + trailerDict.free(); +} + +// Read startxref position, xref table size, and root. Returns +// first xref position. +int XRef::readTrailer(FileStream *str) { + Parser *parser; + Object obj; + char buf[xrefSearchSize+1]; + int n, pos, pos1; + char *p; + int c; + int i; + + // read last xrefSearchSize bytes + str->setPos(-xrefSearchSize); + for (n = 0; n < xrefSearchSize; ++n) { + if ((c = str->getChar()) == EOF) + break; + buf[n] = c; + } + buf[n] = '\0'; + + // find startxref + for (i = n - 9; i >= 0; --i) { + if (!strncmp(&buf[i], "startxref", 9)) + break; + } + if (i < 0) + return 0; + for (p = &buf[i+9]; isspace(*p); ++p) ; + pos = atoi(p); + + // find trailer dict by looking after first xref table + // (NB: we can't just use the trailer dict at the end of the file -- + // this won't work for linearized files.) + str->setPos(start + pos); + for (i = 0; i < 4; ++i) + buf[i] = str->getChar(); + if (strncmp(buf, "xref", 4)) + return 0; + pos1 = pos + 4; + while (1) { + str->setPos(start + pos1); + for (i = 0; i < 35; ++i) { + if ((c = str->getChar()) == EOF) + return 0; + buf[i] = c; + } + if (!strncmp(buf, "trailer", 7)) + break; + p = buf; + while (isspace(*p)) ++p; + while ('0' <= *p && *p <= '9') ++p; + while (isspace(*p)) ++p; + n = atoi(p); + while ('0' <= *p && *p <= '9') ++p; + while (isspace(*p)) ++p; + if (p == buf) + return 0; + pos1 += (p - buf) + n * 20; + } + pos1 += 7; + + // read trailer dict + obj.initNull(); + parser = new Parser(new Lexer(new FileStream(file, start + pos1, -1, &obj))); + parser->getObj(&trailerDict); + if (trailerDict.isDict()) { + trailerDict.dictLookupNF("Size", &obj); + if (obj.isInt()) + size = obj.getInt(); + else + pos = 0; + obj.free(); + trailerDict.dictLookupNF("Root", &obj); + if (obj.isRef()) { + rootNum = obj.getRefNum(); + rootGen = obj.getRefGen(); + } else { + pos = 0; + } + obj.free(); + } else { + pos = 0; + } + delete parser; + + // return first xref position + return pos; +} + +// Read an xref table and the prev pointer from the trailer. +GBool XRef::readXRef(FileStream *str, int *pos) { + Parser *parser; + Object obj, obj2; + char s[20]; + GBool more; + int first, n, i, j; + int c; + + // seek to xref in stream + str->setPos(start + *pos); + + // make sure it's an xref table + while ((c = str->getChar()) != EOF && isspace(c)) ; + s[0] = (char)c; + s[1] = (char)str->getChar(); + s[2] = (char)str->getChar(); + s[3] = (char)str->getChar(); + if (!(s[0] == 'x' && s[1] == 'r' && s[2] == 'e' && s[3] == 'f')) + goto err2; + + // read xref + while (1) { + while ((c = str->lookChar()) != EOF && isspace(c)) + str->getChar(); + if (c == 't') + break; + for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) + s[i] = (char)c; + if (i == 0) + goto err2; + s[i] = '\0'; + first = atoi(s); + while ((c = str->lookChar()) != EOF && isspace(c)) + str->getChar(); + for (i = 0; (c = str->getChar()) != EOF && isdigit(c) && i < 20; ++i) + s[i] = (char)c; + if (i == 0) + goto err2; + s[i] = '\0'; + n = atoi(s); + while ((c = str->lookChar()) != EOF && isspace(c)) + str->getChar(); + for (i = first; i < first + n; ++i) { + for (j = 0; j < 20; ++j) { + if ((c = str->getChar()) == EOF) + goto err2; + s[j] = (char)c; + } + if (entries[i].offset < 0) { + s[10] = '\0'; + entries[i].offset = atoi(s); + s[16] = '\0'; + entries[i].gen = atoi(&s[11]); + if (s[17] == 'n') + entries[i].used = gTrue; + else if (s[17] == 'f') + entries[i].used = gFalse; + else + goto err2; + } + } + } + + // read prev pointer from trailer dictionary + obj.initNull(); + parser = new Parser(new Lexer( + new FileStream(file, str->getPos(), -1, &obj))); + parser->getObj(&obj); + if (!obj.isCmd("trailer")) + goto err1; + obj.free(); + parser->getObj(&obj); + if (!obj.isDict()) + goto err1; + obj.getDict()->lookupNF("Prev", &obj2); + if (obj2.isInt()) { + *pos = obj2.getInt(); + more = gTrue; + } else { + more = gFalse; + } + obj.free(); + obj2.free(); + + delete parser; + return more; + + err1: + obj.free(); + err2: + ok = gFalse; + return gFalse; +} + +// Attempt to construct an xref table for a damaged file. +GBool XRef::constructXRef(FileStream *str) { + Parser *parser; + Object obj; + char buf[256]; + int pos; + int num, gen; + int newSize; + char *p; + int i; + GBool gotRoot; + + error(0, "PDF file is damaged - attempting to reconstruct xref table..."); + gotRoot = gFalse; + + str->reset(); + while (1) { + pos = str->getPos(); + if (!str->getLine(buf, 256)) + break; + p = buf; + + // got trailer dictionary + if (!strncmp(p, "trailer", 7)) { + obj.initNull(); + parser = new Parser(new Lexer( + new FileStream(file, start + pos + 8, -1, &obj))); + if (!trailerDict.isNone()) + trailerDict.free(); + parser->getObj(&trailerDict); + if (trailerDict.isDict()) { + trailerDict.dictLookupNF("Root", &obj); + if (obj.isRef()) { + rootNum = obj.getRefNum(); + rootGen = obj.getRefGen(); + gotRoot = gTrue; + } + obj.free(); + } else { + pos = 0; + } + delete parser; + + // look for object + } else if (isdigit(*p)) { + num = atoi(p); + do { + ++p; + } while (*p && isdigit(*p)); + if (isspace(*p)) { + do { + ++p; + } while (*p && isspace(*p)); + if (isdigit(*p)) { + gen = atoi(p); + do { + ++p; + } while (*p && isdigit(*p)); + if (isspace(*p)) { + do { + ++p; + } while (*p && isspace(*p)); + if (!strncmp(p, "obj", 3)) { + if (num >= size) { + newSize = (num + 1 + 255) & ~255; + entries = (XRefEntry *) + grealloc(entries, newSize * sizeof(XRefEntry)); + for (i = size; i < newSize; ++i) { + entries[i].offset = -1; + entries[i].used = gFalse; + } + size = newSize; + } + if (!entries[num].used || gen >= entries[num].gen) { + entries[num].offset = pos - start; + entries[num].gen = gen; + entries[num].used = gTrue; + } + } + } + } + } + } + } + + if (gotRoot) + return gTrue; + + error(-1, "Couldn't find trailer dictionary"); + return gFalse; +} + +GBool XRef::checkEncrypted() { + Object obj; + GBool encrypted; + + trailerDict.dictLookup("Encrypt", &obj); + if ((encrypted = !obj.isNull())) { + error(-1, "PDF file is encrypted and cannot be displayed"); + error(-1, "* Decryption support is currently not included in xpdf"); + error(-1, "* due to legal restrictions: the U.S.A. still has bogus"); + error(-1, "* export controls on cryptography software."); + } + obj.free(); + return encrypted; +} + +GBool XRef::okToPrint() { + return gTrue; +} + +GBool XRef::okToCopy() { + return gTrue; +} + +Object *XRef::fetch(int num, int gen, Object *obj) { + XRefEntry *e; + Parser *parser; + Object obj1, obj2, obj3; + + // check for bogus ref - this can happen in corrupted PDF files + if (num < 0 || num >= size) { + obj->initNull(); + return obj; + } + + e = &entries[num]; + if (e->gen == gen && e->offset >= 0) { + obj1.initNull(); + parser = new Parser(new Lexer( + new FileStream(file, start + e->offset, -1, &obj1))); + parser->getObj(&obj1); + parser->getObj(&obj2); + parser->getObj(&obj3); + if (obj1.isInt() && obj1.getInt() == num && + obj2.isInt() && obj2.getInt() == gen && + obj3.isCmd("obj")) { + parser->getObj(obj); + } else { + obj->initNull(); + } + obj1.free(); + obj2.free(); + obj3.free(); + delete parser; + } else { + obj->initNull(); + } + return obj; +} + +Object *XRef::getDocInfo(Object *obj) { + return trailerDict.dictLookup("Info", obj); +} diff --git a/pdftops/XRef.h b/pdftops/XRef.h new file mode 100644 index 0000000000..b843ea28dc --- /dev/null +++ b/pdftops/XRef.h @@ -0,0 +1,84 @@ +//======================================================================== +// +// XRef.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef XREF_H +#define XREF_H + +#ifdef __GNUC__ +#pragma interface +#endif + +#include +#include "gtypes.h" +#include "Object.h" + +class Dict; +class FileStream; + +//------------------------------------------------------------------------ +// XRef +//------------------------------------------------------------------------ + +struct XRefEntry { + int offset; + int gen; + GBool used; +}; + +class XRef { +public: + + // Constructor. Read xref table from stream. + XRef(FileStream *str); + + // Destructor. + ~XRef(); + + // Is xref table valid? + GBool isOk() { return ok; } + + // Is the file encrypted? + GBool isEncrypted() { return gFalse; } + + // Are printing and copying allowed? If not, print an error message. + GBool okToPrint(); + GBool okToCopy(); + + // Get catalog object. + Object *getCatalog(Object *obj) { return fetch(rootNum, rootGen, obj); } + + // Fetch an indirect reference. + Object *fetch(int num, int gen, Object *obj); + + // Return the document's Info dictionary (if any). + Object *getDocInfo(Object *obj); + +private: + + FILE *file; // input file + int start; // offset in file (to allow for garbage + // at beginning of file) + XRefEntry *entries; // xref entries + int size; // size of array + int rootNum, rootGen; // catalog dict + GBool ok; // true if xref table is valid + Object trailerDict; // trailer dictionary + + int readTrailer(FileStream *str); + GBool readXRef(FileStream *str, int *pos); + GBool constructXRef(FileStream *str); + GBool checkEncrypted(); +}; + +//------------------------------------------------------------------------ +// The global xref table +//------------------------------------------------------------------------ + +extern XRef *xref; + +#endif diff --git a/pdftops/config.h b/pdftops/config.h new file mode 100644 index 0000000000..e84bbb2f68 --- /dev/null +++ b/pdftops/config.h @@ -0,0 +1,46 @@ +//======================================================================== +// +// config.h +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef CONFIG_H +#define CONFIG_H + +//------------------------------------------------------------------------ +// general constants +//------------------------------------------------------------------------ + +// xpdf version +#define xpdfVersion "0.90" + +// supported PDF version +#define pdfVersion "1.3" +#define pdfVersionNum 1.3 + +// copyright notice +#define xpdfCopyright "Copyright 1996-1999 Derek B. Noonburg" + +//------------------------------------------------------------------------ +// uncompress program +//------------------------------------------------------------------------ + +#define HAVE_POPEN +#define uncompressCmd "uncompress -c" + +//------------------------------------------------------------------------ +// Win32 stuff +//------------------------------------------------------------------------ + +#ifdef WIN32 +#ifdef CDECL +#undef CDECL +#endif +#define CDECL __cdecl +#else +#define CDECL +#endif + +#endif diff --git a/pdftops/configure.in b/pdftops/configure.in new file mode 100644 index 0000000000..8ba7984758 --- /dev/null +++ b/pdftops/configure.in @@ -0,0 +1,203 @@ +dnl Process this file with autoconf to produce a configure script. +AC_INIT(xpdf/xpdf.cc) + +dnl ##### Optional features. +OPTIONS="" +AC_ARG_ENABLE(a4-paper, +[ --enable-a4-paper use A4 paper size instead of Letter for + PostScript output], +OPTIONS="$OPTIONS -DA4_PAPER") +AC_ARG_ENABLE(japanese, +[ --enable-japanese enable Japanese font support], +OPTIONS="$OPTIONS -DJAPANESE_SUPPORT") +AC_ARG_ENABLE(no-text-select, +[ --enable-no-text-select do not allow text selection], +OPTIONS="$OPTIONS -DNO_TEXT_SELECT") +AC_ARG_WITH(gzip, +[ --with-gzip use gzip instead of uncompress], +OPTIONS="$OPTIONS -DUSE_GZIP") +AC_SUBST(OPTIONS) + +dnl ##### Checks for programs. +AC_PROG_CC +AC_ISC_POSIX +AM_PROG_CC_STDC +#if test -z "$CXX" -a "$CC" = "gcc"; then +# CXX="gcc" +#fi +AC_PROG_CXX +AC_PROG_INSTALL +AC_PROG_RANLIB + +dnl ##### Default values for Unix. +EXE="" +LIBPREFIX="lib" +AR="ar rc" +UP_DIR="" + +dnl ##### Check for OS/2. +AC_CACHE_CHECK([for OS/2 (with EMX)], +xpdf_cv_sys_os2, +[AC_TRY_COMPILE([], +[__EMX__], +xpdf_cv_sys_os2=yes, xpdf_cv_sys_os2=no)]) +if test "$xpdf_cv_sys_os2" = yes; then + EXE=".exe" + LIBPREFIX="" + AR="ar -rc" +fi + +dnl ##### Check for DOS (with DJGPP). +AC_CACHE_CHECK([for DOS (with DJGPP)], +xpdf_cv_sys_dos, +[AC_TRY_COMPILE([], +[__DJGPP__], +xpdf_cv_sys_dos=yes, xpdf_cv_sys_dos=no)]) +if test "$xpdf_cv_sys_dos" = yes; then + EXE=".exe" + LIBPREFIX="lib" + AR="ar -rc" + UP_DIR="../" +fi + +dnl ##### Do substitutions. +AC_SUBST(EXE) +AC_SUBST(LIBPREFIX) +AC_SUBST(AR) +AC_SUBST(UP_DIR) + +dnl ##### Checks for header files. +AC_PATH_XTRA +AC_HEADER_DIRENT + +dnl ##### Look for header that defines fd_set. +AC_MSG_CHECKING([fd_set and sys/select.h or sys/bsdtypes.h]) +AC_TRY_COMPILE([#include ], + [fd_set fds;], xpdf_ok=yes, xpdf_ok=no) +if test $xpdf_ok = yes; then + AC_MSG_RESULT([not needed]) +else + AC_TRY_COMPILE([#include +#include ], + [fd_set fds;], xpdf_ok=yes, xpdf_ok=no) + if test $xpdf_ok = yes; then + AC_DEFINE(HAVE_SYS_SELECT_H) + AC_MSG_RESULT([need sys/select.h]) + else + AC_TRY_COMPILE([#include +#include ], + [fd_set fds;], xpdf_ok=yes, xpdf_ok=no) + if test $xpdf_ok = yes; then + AC_DEFINE(HAVE_SYS_BSDTYPES_H) + AC_MSG_RESULT([need sys/bsdtypes.h]) + else + AC_MSG_RESULT([problem]) + fi + fi +fi + +dnl ##### Look for header that defines FD_ZERO. +AC_MSG_CHECKING([FD_ZERO and strings.h or bstring.h]) +AC_TRY_COMPILE([#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif], +[fd_set fds; FD_ZERO(&fds);], xpdf_ok=yes, xpdf_ok=no) +if test $xpdf_ok = yes; then + AC_MSG_RESULT([not needed]) +else + AC_TRY_COMPILE([#include +#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif], + [fd_set fds; FD_ZERO(&fds);], xpdf_ok=yes, xpdf_ok=no) + if test $xpdf_ok = yes; then + AC_DEFINE(HAVE_STRINGS_H) + AC_MSG_RESULT([need strings.h]) + else + AC_TRY_COMPILE([#include +#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif], + [fd_set fds; FD_ZERO(&fds);], xpdf_ok=yes, xpdf_ok=no) + if test $xpdf_ok = yes; then + AC_DEFINE(HAVE_BSTRING_H) + AC_MSG_RESULT([need bstring.h]) + else + AC_MSG_RESULT([problem]) + fi + fi +fi + +dnl ##### Look for rewinddir. +AC_CHECK_FUNCS(rewinddir) +if test $ac_cv_func_rewinddir = no; then + AC_CHECK_LIB(cposix, rewinddir) +fi + +dnl ##### Checks for library functions. +AC_CHECK_FUNCS(popen) + +dnl ##### Check select argument type: on HP-UX before version 10, select +dnl ##### takes (int *) instead of (fd_set *). +AC_LANG_CPLUSPLUS +AC_CACHE_CHECK([whether select takes fd_set arguments], +xpdf_cv_func_select_arg, +[AC_TRY_COMPILE([#include +#include +#ifdef HAVE_SYS_SELECT_H +#include +#endif], +[fd_set fds; +select(1, &fds, &fds, &fds, 0);], +xpdf_cv_func_select_arg=yes, xpdf_cv_func_select_arg=no)]) +if test "$xpdf_cv_func_select_arg" != yes; then + AC_DEFINE(SELECT_TAKES_INT) +fi +AC_LANG_C + +dnl ##### Check for libXpm. +if test -z "$no_x"; then + smr_CHECK_LIB(Xpm, Xpm, [pixmap library, used only for icon], + XpmCreatePixmapFromData, X11/xpm.h, + $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS, $X_CFLAGS) + AC_SUBST(Xpm_LIBS) + AC_SUBST(Xpm_CFLAGS) +fi + +dnl ##### Check for t1lib. +if test -z "$no_x"; then + smr_CHECK_LIB(t1, t1, [Type 1 font rasterizer], + T1_InitLib, t1lib.h, + $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS -lm, $X_CFLAGS) + AC_SUBST(t1_LIBS) + AC_SUBST(t1_CFLAGS) + smr_CHECK_LIB(t1x, t1x, [Type 1 font rasterizer], + T1_SetX11Params, t1libx.h, + $X_LIBS $X_PRE_LIBS -lX11 $X_EXTRA_LIBS $t1_LIBS -lm, + $X_CFLAGS $t1_CFLAGS) + AC_SUBST(t1x_LIBS) + AC_SUBST(t1x_CFLAGS) +fi + +dnl ##### Disable X-specific stuff in top-level Makefile. +if test -n "$no_x"; then + X="#" + XPDF_TARGET="all-no-x" +else + X="" + XPDF_TARGET="all" +fi +AC_SUBST(X) +AC_SUBST(XPDF_TARGET) + +dnl ##### Write the makefiles. +AC_OUTPUT(Makefile xpdf/Makefile ltk/Makefile goo/Makefile) + +dnl ##### Warn user if X is missing. +if test -n "$no_x"; then + AC_MSG_WARN([Couldn't find X -- you will be able to compile + pdftops, pdftotext, pdfinfo, and pdfimages, but not xpdf]) +fi diff --git a/pdftops/gfile.cxx b/pdftops/gfile.cxx new file mode 100644 index 0000000000..97060ef4bc --- /dev/null +++ b/pdftops/gfile.cxx @@ -0,0 +1,522 @@ +//======================================================================== +// +// gfile.cc +// +// Miscellaneous file and directory name manipulation. +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifdef WIN32 + extern "C" { +# include +# ifndef _MSC_VER +# include +# endif + } +#else // !WIN32 +# ifndef ACORN +# include +# include +# endif +# include +# include +# if !defined(VMS) && !defined(ACORN) +# include +# endif +# if defined(VMS) && (__DECCXX_VER < 50200000) +# include +# endif +#endif // WIN32 +#include "GString.h" +#include "gfile.h" + +// Some systems don't define this, so just make it something reasonably +// large. +#ifndef PATH_MAX +#define PATH_MAX 1024 +#endif + +//------------------------------------------------------------------------ + +GString *getHomeDir() { +#ifdef VMS + //---------- VMS ---------- + return new GString("SYS$LOGIN:"); + +#elif defined(__EMX__) || defined(WIN32) + //---------- OS/2+EMX and Win32 ---------- + char *s; + GString *ret; + + if ((s = getenv("HOME"))) + ret = new GString(s); + else + ret = new GString("."); + return ret; + +#elif defined(ACORN) + //---------- RISCOS ---------- + return new GString("@"); + +#else + //---------- Unix ---------- + char *s; + struct passwd *pw; + GString *ret; + + if ((s = getenv("HOME"))) { + ret = new GString(s); + } else { + if ((s = getenv("USER"))) + pw = getpwnam(s); + else + pw = getpwuid(getuid()); + if (pw) + ret = new GString(pw->pw_dir); + else + ret = new GString("."); + } + return ret; +#endif +} + +GString *getCurrentDir() { + char buf[PATH_MAX+1]; + +#if defined(__EMX__) + if (_getcwd2(buf, sizeof(buf))) +#elif defined(WIN32) + if (GetCurrentDirectory(sizeof(buf), buf)) +#elif defined(ACORN) + if (strcpy(buf, "@")) +#else + if (getcwd(buf, sizeof(buf))) +#endif + return new GString(buf); + return new GString(); +} + +GString *appendToPath(GString *path, char *fileName) { +#if defined(VMS) + //---------- VMS ---------- + //~ this should handle everything necessary for file + //~ requesters, but it's certainly not complete + char *p0, *p1, *p2; + char *q1; + + p0 = path->getCString(); + p1 = p0 + path->getLength() - 1; + if (!strcmp(fileName, "-")) { + if (*p1 == ']') { + for (p2 = p1; p2 > p0 && *p2 != '.' && *p2 != '['; --p2) ; + if (*p2 == '[') + ++p2; + path->del(p2 - p0, p1 - p2); + } else if (*p1 == ':') { + path->append("[-]"); + } else { + path->clear(); + path->append("[-]"); + } + } else if ((q1 = strrchr(fileName, '.')) && !strncmp(q1, ".DIR;", 5)) { + if (*p1 == ']') { + path->insert(p1 - p0, '.'); + path->insert(p1 - p0 + 1, fileName, q1 - fileName); + } else if (*p1 == ':') { + path->append('['); + path->append(']'); + path->append(fileName, q1 - fileName); + } else { + path->clear(); + path->append(fileName, q1 - fileName); + } + } else { + if (*p1 != ']' && *p1 != ':') + path->clear(); + path->append(fileName); + } + return path; + +#elif defined(WIN32) + //---------- Win32 ---------- + GString *tmp; + char buf[256]; + char *fp; + + tmp = new GString(path); + tmp->append('/'); + tmp->append(fileName); + GetFullPathName(tmp->getCString(), sizeof(buf), buf, &fp); + delete tmp; + path->clear(); + path->append(buf); + return path; + +#elif defined(ACORN) + //---------- RISCOS ---------- + char *p; + int i; + + path->append("."); + i = path->getLength(); + path->append(fileName); + for (p = path->getCString() + i; *p; ++p) { + if (*p == '/') { + *p = '.'; + } else if (*p == '.') { + *p = '/'; + } + } + return path; + +#elif defined(__EMX__) + //---------- OS/2+EMX ---------- + int i; + + // appending "." does nothing + if (!strcmp(fileName, ".")) + return path; + + // appending ".." goes up one directory + if (!strcmp(fileName, "..")) { + for (i = path->getLength() - 2; i >= 0; --i) { + if (path->getChar(i) == '/' || path->getChar(i) == '\\' || + path->getChar(i) == ':') + break; + } + if (i <= 0) { + if (path->getChar(0) == '/' || path->getChar(0) == '\\') { + path->del(1, path->getLength() - 1); + } else if (path->getLength() >= 2 && path->getChar(1) == ':') { + path->del(2, path->getLength() - 2); + } else { + path->clear(); + path->append(".."); + } + } else { + if (path->getChar(i-1) == ':') + ++i; + path->del(i, path->getLength() - i); + } + return path; + } + + // otherwise, append "/" and new path component + if (path->getLength() > 0 && + path->getChar(path->getLength() - 1) != '/' && + path->getChar(path->getLength() - 1) != '\\') + path->append('/'); + path->append(fileName); + return path; + +#else + //---------- Unix ---------- + int i; + + // appending "." does nothing + if (!strcmp(fileName, ".")) + return path; + + // appending ".." goes up one directory + if (!strcmp(fileName, "..")) { + for (i = path->getLength() - 2; i >= 0; --i) { + if (path->getChar(i) == '/') + break; + } + if (i <= 0) { + if (path->getChar(0) == '/') { + path->del(1, path->getLength() - 1); + } else { + path->clear(); + path->append(".."); + } + } else { + path->del(i, path->getLength() - i); + } + return path; + } + + // otherwise, append "/" and new path component + if (path->getLength() > 0 && + path->getChar(path->getLength() - 1) != '/') + path->append('/'); + path->append(fileName); + return path; +#endif +} + +GString *grabPath(char *fileName) { +#ifdef VMS + //---------- VMS ---------- + char *p; + + if ((p = strrchr(fileName, ']'))) + return new GString(fileName, p + 1 - fileName); + if ((p = strrchr(fileName, ':'))) + return new GString(fileName, p + 1 - fileName); + return new GString(); + +#elif defined(__EMX__) || defined(WIN32) + //---------- OS/2+EMX and Win32 ---------- + char *p; + + if ((p = strrchr(fileName, '/'))) + return new GString(fileName, p - fileName); + if ((p = strrchr(fileName, '\\'))) + return new GString(fileName, p - fileName); + if ((p = strrchr(fileName, ':'))) + return new GString(fileName, p + 1 - fileName); + return new GString(); + +#elif defined(ACORN) + //---------- RISCOS ---------- + char *p; + + if ((p = strrchr(fileName, '.'))) + return new GString(fileName, p - fileName); + return new GString(); + +#else + //---------- Unix ---------- + char *p; + + if ((p = strrchr(fileName, '/'))) + return new GString(fileName, p - fileName); + return new GString(); +#endif +} + +GBool isAbsolutePath(char *path) { +#ifdef VMS + //---------- VMS ---------- + return strchr(path, ':') || + (path[0] == '[' && path[1] != '.' && path[1] != '-'); + +#elif defined(__EMX__) || defined(WIN32) + //---------- OS/2+EMX and Win32 ---------- + return path[0] == '/' || path[0] == '\\' || path[1] == ':'; + +#elif defined(ACORN) + //---------- RISCOS ---------- + return path[0] == '$'; + +#else + //---------- Unix ---------- + return path[0] == '/'; +#endif +} + +GString *makePathAbsolute(GString *path) { +#ifdef VMS + //---------- VMS ---------- + char buf[PATH_MAX+1]; + + if (!isAbsolutePath(path->getCString())) { + if (getcwd(buf, sizeof(buf))) { + if (path->getChar(0) == '[') { + if (path->getChar(1) != '.') + path->insert(0, '.'); + path->insert(0, buf); + } else { + path->insert(0, '['); + path->insert(1, ']'); + path->insert(1, buf); + } + } + } + return path; + +#elif defined(WIN32) + //---------- Win32 ---------- + char buf[_MAX_PATH]; + char *fp; + + buf[0] = '\0'; + if (!GetFullPathName(path->getCString(), _MAX_PATH, buf, &fp)) { + path->clear(); + return path; + } + path->clear(); + path->append(buf); + return path; + +#elif defined(ACORN) + //---------- RISCOS ---------- + path->insert(0, '@'); + return path; + +#else + //---------- Unix and OS/2+EMX ---------- + struct passwd *pw; + char buf[PATH_MAX+1]; + GString *s; + char *p1, *p2; + int n; + + if (path->getChar(0) == '~') { + if (path->getChar(1) == '/' || +#ifdef __EMX__ + path->getChar(1) == '\\' || +#endif + path->getLength() == 1) { + path->del(0, 1); + s = getHomeDir(); + path->insert(0, s); + delete s; + } else { + p1 = path->getCString() + 1; +#ifdef __EMX__ + for (p2 = p1; *p2 && *p2 != '/' && *p2 != '\\'; ++p2) ; +#else + for (p2 = p1; *p2 && *p2 != '/'; ++p2) ; +#endif + if ((n = p2 - p1) > PATH_MAX) + n = PATH_MAX; + strncpy(buf, p1, n); + buf[n] = '\0'; + if ((pw = getpwnam(buf))) { + path->del(0, p2 - p1 + 1); + path->insert(0, pw->pw_dir); + } + } + } else if (!isAbsolutePath(path->getCString())) { + if (getcwd(buf, sizeof(buf))) { +#ifndef __EMX__ + path->insert(0, '/'); +#endif + path->insert(0, buf); + } + } + return path; +#endif +} + +//------------------------------------------------------------------------ +// GDir and GDirEntry +//------------------------------------------------------------------------ + +GDirEntry::GDirEntry(char *dirPath, char *name1, GBool doStat) { +#ifdef VMS + char *p; +#elif defined(WIN32) + int fa; + GString *s; +#elif defined(ACORN) +#else + struct stat st; + GString *s; +#endif + + name = new GString(name1); + dir = gFalse; + if (doStat) { +#ifdef VMS + if (!strcmp(name1, "-") || + ((p = strrchr(name1, '.')) && !strncmp(p, ".DIR;", 5))) + dir = gTrue; +#elif defined(ACORN) +#else + s = new GString(dirPath); + appendToPath(s, name1); +#ifdef WIN32 + fa = GetFileAttributes(s->getCString()); + dir = (fa != 0xFFFFFFFF && (fa & FILE_ATTRIBUTE_DIRECTORY)); +#else + if (stat(s->getCString(), &st) == 0) + dir = S_ISDIR(st.st_mode); +#endif + delete s; +#endif + } +} + +GDirEntry::~GDirEntry() { + delete name; +} + +GDir::GDir(char *name, GBool doStat1) { + path = new GString(name); + doStat = doStat1; +#if defined(WIN32) + GString *tmp; + + tmp = path->copy(); + tmp->append("/*.*"); + hnd = FindFirstFile(tmp->getCString(), &ffd); + delete tmp; +#elif defined(ACORN) +#else + dir = opendir(name); +#ifdef VMS + needParent = strchr(name, '[') != NULL; +#endif +#endif +} + +GDir::~GDir() { + delete path; +#if defined(WIN32) + if (hnd) { + FindClose(hnd); + hnd = NULL; + } +#elif defined(ACORN) +#else + if (dir) + closedir(dir); +#endif +} + +GDirEntry *GDir::getNextEntry() { + struct dirent *ent; + GDirEntry *e; + + e = NULL; +#if defined(WIN32) + e = new GDirEntry(path->getCString(), ffd.cFileName, doStat); + if (hnd && !FindNextFile(hnd, &ffd)) { + FindClose(hnd); + hnd = NULL; + } +#elif defined(ACORN) +#else + if (dir) { +#ifdef VMS + if (needParent) { + e = new GDirEntry(path->getCString(), "-", doStat); + needParent = gFalse; + return e; + } +#endif + ent = readdir(dir); +#ifndef VMS + if (ent && !strcmp(ent->d_name, ".")) + ent = readdir(dir); +#endif + if (ent) + e = new GDirEntry(path->getCString(), ent->d_name, doStat); + } +#endif + return e; +} + +void GDir::rewind() { +#ifdef WIN32 + GString *tmp; + + if (hnd) + FindClose(hnd); + tmp = path->copy(); + tmp->append("/*.*"); + hnd = FindFirstFile(tmp->getCString(), &ffd); +#elif defined(ACORN) +#else + if (dir) + rewinddir(dir); +#ifdef VMS + needParent = strchr(path->getCString(), '[') != NULL; +#endif +#endif +} diff --git a/pdftops/gfile.h b/pdftops/gfile.h new file mode 100644 index 0000000000..dcd72d88f8 --- /dev/null +++ b/pdftops/gfile.h @@ -0,0 +1,115 @@ +//======================================================================== +// +// gfile.h +// +// Miscellaneous file and directory name manipulation. +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#ifndef GFILE_H +#define GFILE_H + +#include +#include +#include +#if defined(WIN32) +# ifdef _MSC_VER +# include +# else +# include +# endif +#elif defined(ACORN) +#else +# include +# include +# ifdef VMS +# include "vms_dirent.h" +# elif HAVE_DIRENT_H +# include +# define NAMLEN(dirent) strlen((dirent)->d_name) +# else +# define dirent direct +# define NAMLEN(dirent) (dirent)->d_namlen +# if HAVE_SYS_NDIR_H +# include +# endif +# if HAVE_SYS_DIR_H +# include +# endif +# if HAVE_NDIR_H +# include +# endif +# endif +#endif +#include "gtypes.h" + +class GString; + +//------------------------------------------------------------------------ + +// Get home directory path. +extern GString *getHomeDir(); + +// Get current directory. +extern GString *getCurrentDir(); + +// Append a file name to a path string. may be an empty +// string, denoting the current directory). Returns . +extern GString *appendToPath(GString *path, char *fileName); + +// Grab the path from the front of the file name. If there is no +// directory component in , returns an empty string. +extern GString *grabPath(char *fileName); + +// Is this an absolute path or file name? +extern GBool isAbsolutePath(char *path); + +// Make this path absolute by prepending current directory (if path is +// relative) or prepending user's directory (if path starts with '~'). +GString *makePathAbsolute(GString *path); + +//------------------------------------------------------------------------ +// GDir and GDirEntry +//------------------------------------------------------------------------ + +class GDirEntry { +public: + + GDirEntry(char *dirPath, char *name1, GBool doStat); + ~GDirEntry(); + GString *getName() { return name; } + GBool isDir() { return dir; } + +private: + + GString *name; // dir/file name + GBool dir; // is it a directory? +}; + +class GDir { +public: + + GDir(char *name, GBool doStat1 = gTrue); + ~GDir(); + GDirEntry *getNextEntry(); + void rewind(); + +private: + + GString *path; // directory path + GBool doStat; // call stat() for each entry? +#if defined(WIN32) + WIN32_FIND_DATA ffd; + HANDLE hnd; +#elif defined(ACORN) +#else + DIR *dir; // the DIR structure from opendir() +#ifdef VMS + GBool needParent; // need to return an entry for [-] +#endif +#endif +}; + +#endif diff --git a/pdftops/gmem.c b/pdftops/gmem.c new file mode 100644 index 0000000000..cac386bc8a --- /dev/null +++ b/pdftops/gmem.c @@ -0,0 +1,203 @@ +/* + * gmem.c + * + * Memory routines with out-of-memory checking. + * + * Copyright 1996 Derek B. Noonburg + */ + +#include +#include +#include +#include +#include "gmem.h" + +#ifdef DEBUG_MEM + +typedef struct _GMemHdr { + int size; + int index; + struct _GMemHdr *next; +} GMemHdr; + +#define gMemHdrSize ((sizeof(GMemHdr) + 7) & ~7) +#define gMemTrlSize (sizeof(long)) + +#if gmemTrlSize==8 +#define gMemDeadVal 0xdeadbeefdeadbeef +#else +#define gMemDeadVal 0xdeadbeef +#endif + +/* round data size so trailer will be aligned */ +#define gMemDataSize(size) \ + ((((size) + gMemTrlSize - 1) / gMemTrlSize) * gMemTrlSize) + +#define gMemNLists 64 +#define gMemListShift 4 +#define gMemListMask (gMemNLists - 1) +static GMemHdr *gMemList[gMemNLists] = { + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL +}; + +static int gMemIndex = 0; +static int gMemAlloc = 0; + +#endif /* DEBUG_MEM */ + +void *gmalloc(int size) { +#ifdef DEBUG_MEM + int size1; + char *mem; + GMemHdr *hdr; + void *data; + int lst; + long *trl, *p; + + if (size == 0) + return NULL; + size1 = gMemDataSize(size); + if (!(mem = (char *)malloc(size1 + gMemHdrSize + gMemTrlSize))) { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + hdr = (GMemHdr *)mem; + data = (void *)(mem + gMemHdrSize); + trl = (long *)(mem + gMemHdrSize + size1); + hdr->size = size; + hdr->index = gMemIndex++; + lst = ((int)hdr >> gMemListShift) & gMemListMask; + hdr->next = gMemList[lst]; + gMemList[lst] = hdr; + ++gMemAlloc; + for (p = (long *)data; p <= trl; ++p) + *p = gMemDeadVal; + return data; +#else + void *p; + + if (size == 0) + return NULL; + if (!(p = malloc(size))) { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + return p; +#endif +} + +void *grealloc(void *p, int size) { +#ifdef DEBUG_MEM + GMemHdr *hdr; + void *q; + int oldSize; + + if (size == 0) { + if (p) + gfree(p); + return NULL; + } + if (p) { + hdr = (GMemHdr *)((char *)p - gMemHdrSize); + oldSize = hdr->size; + q = gmalloc(size); + memcpy(q, p, size < oldSize ? size : oldSize); + gfree(p); + } else { + q = gmalloc(size); + } + return q; +#else + void *q; + + if (size == 0) { + if (p) + free(p); + return NULL; + } + if (p) + q = realloc(p, size); + else + q = malloc(size); + if (!q) { + fprintf(stderr, "Out of memory\n"); + exit(1); + } + return q; +#endif +} + +void gfree(void *p) { +#ifdef DEBUG_MEM + int size; + GMemHdr *hdr; + GMemHdr *prevHdr, *q; + int lst; + long *trl, *clr; + + if (p) { + hdr = (GMemHdr *)((char *)p - gMemHdrSize); + lst = ((int)hdr >> gMemListShift) & gMemListMask; + for (prevHdr = NULL, q = gMemList[lst]; q; prevHdr = q, q = q->next) { + if (q == hdr) + break; + } + if (q) { + if (prevHdr) + prevHdr->next = hdr->next; + else + gMemList[lst] = hdr->next; + --gMemAlloc; + size = gMemDataSize(hdr->size); + trl = (long *)((char *)hdr + gMemHdrSize + size); + if (*trl != gMemDeadVal) { + fprintf(stderr, "Overwrite past end of block %d at address %p\n", + hdr->index, p); + } + for (clr = (long *)hdr; clr <= trl; ++clr) + *clr = gMemDeadVal; + free(hdr); + } else { + fprintf(stderr, "Attempted to free bad address %p\n", p); + } + } +#else + if (p) + free(p); +#endif +} + +#ifdef DEBUG_MEM +void gMemReport(FILE *f) { + GMemHdr *p; + int lst; + + fprintf(f, "%d memory allocations in all\n", gMemIndex); + if (gMemAlloc > 0) { + fprintf(f, "%d memory blocks left allocated:\n", gMemAlloc); + fprintf(f, " index size\n"); + fprintf(f, "-------- --------\n"); + for (lst = 0; lst < gMemNLists; ++lst) { + for (p = gMemList[lst]; p; p = p->next) + fprintf(f, "%8d %8d\n", p->index, p->size); + } + } else { + fprintf(f, "No memory blocks left allocated\n"); + } +} +#endif + +char *copyString(char *s) { + char *s1; + + s1 = (char *)gmalloc(strlen(s) + 1); + strcpy(s1, s); + return s1; +} diff --git a/pdftops/gmem.h b/pdftops/gmem.h new file mode 100644 index 0000000000..7ab5ddbeb8 --- /dev/null +++ b/pdftops/gmem.h @@ -0,0 +1,53 @@ +/* + * gmem.h + * + * Memory routines with out-of-memory checking. + * + * Copyright 1996 Derek B. Noonburg + */ + +#ifndef GMEM_H +#define GMEM_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +/* + * Same as malloc, but prints error message and exits if malloc() + * returns NULL. + */ +extern void *gmalloc(int size); + +/* + * Same as realloc, but prints error message and exits if realloc() + * returns NULL. If
+ } + ifelse + % Check for PFB file header. + dup (\200\001????*) .stringmatch + { dup length 6 sub 6 exch getinterval } + if + % Check for font file headers. + false .scanfontheaders + { 2 index exch .stringmatch or + } + forall exch pop + { % stack: + % + dup 0 setfileposition .findfontname + { dup Fontmap exch known + { pop pop + } + { exch copystring exch + DEBUG { ( ) print dup =only flush } if + 1 index .definefontmap + .splitfilename pop true .scanfontdict 3 1 roll .growput + % Increment fontcount. + 3 -1 roll 1 add 3 1 roll + } + ifelse + } + { pop + } + ifelse + } + % .findfontname will have done a closefile in the above case. + { dup null eq { pop } { closefile } ifelse pop + } + ifelse + } + ifelse + } + .scan1fontstring filenameforall + QUIET + { pop pop pop } + { ( ) print =only ( files, ) print =only ( scanned, ) print + =only ( new fonts.\n) print flush + } + ifelse + setglobal + } bind def + +%END FONTPATH + +% Create the dictionary that registers the .buildfont procedure (called by +% definefont) for each FontType. +/buildfontdict 20 dict def + +% Register Type 3 fonts, which are always supported, for definefont. +buildfontdict 3 /.buildfont3 cvx put + +% Register Type 0 fonts if they are supported. Strictly speaking, +% we should do this in its own file (gs_type0.ps), but since this is +% the only thing that would be in that file, it's simpler to put it here. +/.buildfont0 where { pop buildfontdict 0 /.buildfont0 cvx put } if + +% Define definefont. This is a procedure built on a set of operators +% that do all the error checking and key insertion. +/.growfontdict + { % Grow the font dictionary, if necessary, to ensure room for an + % added entry, making sure there is at least one slot left for FID. + dup maxlength 1 index length sub 2 lt + { dup dup wcheck + { .growdict } + { .growdictlength dict .copydict } + ifelse + } + { dup wcheck not { dup maxlength dict .copydict } if + } + ifelse + } bind def +/.completefont { + { % Check for disabled platform fonts. + NOPLATFONTS + { % Make sure we leave room for FID. + .growfontdict dup /ExactSize 0 put + } + { % Hack: if the Encoding looks like it might be the + % Symbol or Dingbats encoding, load those now (for the + % benefit of platform font matching) just in case + % the font didn't actually reference them. + % Note that some types of font don't have an Encoding. + dup /Encoding .knownget { + dup length 65 ge { + 64 get + dup /congruent eq { SymbolEncoding pop } if + /a9 eq { DingbatsEncoding pop } if + } { + pop + } ifelse + } if + } + ifelse + true exch + dup /FontType known not { + % This might be a CIDFont. + dup /CIDFontType known { + /.buildcidfont where { + pop exch pop false exch + } if + } if + } if + exch { + dup /FontType get //buildfontdict exch get exec + } { + .buildcidfont + } ifelse + + DISKFONTS + { FontFileDirectory 2 index known + { dup /FontFile FontFileDirectory 4 index get .growput + } + if + } + if + readonly % stack: name fontdict + } stopped { /invalidfont signalerror } if +} bind odef +/definefont + { .completefont + % If the current allocation mode is global, also enter + % the font in LocalFontDirectory. + .currentglobal + { //systemdict /LocalFontDirectory .knownget + { 2 index 2 index .growput } + if + } + if + dup .FontDirectory 4 -2 roll .growput + } odef + +% Define a procedure for defining aliased fonts. +% We use this only for explicitly aliased fonts, not substituted fonts: +% we think this matches the observed behavior of Adobe interpreters. +/.aliasfont % .aliasfont + { .currentglobal 3 1 roll dup .gcheck .setglobal + dup length 2 add dict + dup 3 -1 roll { 1 index /FID eq { pop pop } { put dup } ifelse } forall + % Stack: global fontname newfont newfont. + % We might be defining a global font whose FontName + % is a local string. This is weird, but legal, + % and doesn't cause problems anywhere else: + % to avoid any possible problems in this case, do a cvn. + % We might also be defining (as an alias) a global font + % whose FontName is a local non-string, if someone passed a + % garbage value to findfont. In this case, just don't + % call definefont at all. + 2 index dup type /stringtype eq exch .gcheck or 1 index .gcheck not or + { /FontName 3 index dup type /stringtype eq { cvn } if put + % Don't bind in definefont, since Level 2 redefines it. + /definefont .systemvar exec + } + { .completefont pop exch pop + } + ifelse exch .setglobal + } odef % so findfont will bind it + +% Define .loadfontfile for loading a font. If we recognize Type 1 and/or +% TrueType fonts, gs_type1.ps and/or gs_ttf.ps will redefine this. +/.loadfontfile { + % According to Ed Taft, Adobe interpreters push userdict + % before loading a font, and pop it afterwards. + userdict begin + cvx exec + end +} bind def +/.loadfont + { % Some buggy fonts leave extra junk on the stack, + % so we have to make a closure that records the stack depth + % in a fail-safe way. + /.loadfontfile cvx count 1 sub 2 packedarray cvx exec + count exch sub { pop } repeat + } bind def + +% Find an alternate font to substitute for an unknown one. +% We go to some trouble to parse the font name and extract +% properties from it. Later entries take priority over earlier. +/.substitutefaces [ + % Guess at suitable substitutions for random unknown fonts. + [(Grot) /Times] + [(Roman) /Times] + [(Book) /NewCenturySchlbk] + % If the family name appears in the font name, + % use a font from that family. + [(Arial) /Helvetica] + [(Avant) /AvantGarde] + [(Bookman) /Bookman] + [(Century) /NewCenturySchlbk] + [(Cour) /Courier] + [(Frut) /Helvetica] + [(Geneva) /Helvetica] + [(Helv) /Helvetica] + [(NewYork) /Times] + [(Pala) /Palatino] + [(Sans) /Helvetica] + [(Schlbk) /NewCenturySchlbk] + [(Serif) /Times] + [(Swiss) /Helvetica] + [(Times) /Times] + [(Univers) /Helvetica] + % Substitute for Adobe Multiple Master fonts. + [(Minion) /Times] + [(Myriad) /Helvetica] + [(MyriadPkg) /Helvetica-Narrow] + % Condensed or narrow fonts map to the only narrow family we have. + [(Cond) /Helvetica-Narrow] + [(Narrow) /Helvetica-Narrow] + % If the font wants to be monospace, use Courier. + [(Monospace) /Courier] + [(Typewriter) /Courier] +] readonly def +/.substituteproperties [ + [(It) 1] [(Oblique) 1] + [(Bd) 2] [(Bold) 2] [(bold) 2] [(Demi) 2] [(Heavy) 2] [(Sb) 2] +] readonly def +/.substitutefamilies mark + /AvantGarde + {/AvantGarde-Book /AvantGarde-BookOblique + /AvantGarde-Demi /AvantGarde-DemiOblique} + /Bookman + {/Bookman-Demi /Bookman-DemiItalic /Bookman-Light /Bookman-LightItalic} + /Courier + {/Courier /Courier-Oblique /Courier-Bold /Courier-BoldOblique} + /Helvetica + {/Helvetica /Helvetica-Oblique /Helvetica-Bold /Helvetica-BoldOblique} + /Helvetica-Narrow + {/Helvetica-Narrow /Helvetica-Narrow-Oblique + /Helvetica-Narrow-Bold /Helvetica-Narrow-BoldOblique} + /NewCenturySchlbk + {/NewCenturySchlbk-Roman /NewCenturySchlbk-Italic + /NewCenturySchlbk-Bold /NewCenturySchlbk-BoldItalic} + /Palatino + {/Palatino-Roman /Palatino-Italic /Palatino-Bold /Palatino-BoldItalic} + /Times + {/Times-Roman /Times-Italic /Times-Bold /Times-BoldItalic} +.dicttomark readonly def +/.substitutefont % .substitutefont + { % Look for properties and/or a face name in the font name. + % If we find any, use Helvetica as the base font; + % otherwise, use the default font. + % Note that the "substituted" font name may be the same as + % the requested one; the caller must check this. + dup type dup /stringtype eq exch /nametype eq or + { dup length string cvs } { () } ifelse + {defaultfontname /Helvetica-Oblique /Helvetica-Bold /Helvetica-BoldOblique} + exch 0 exch % stack: fontname facelist properties fontname + % Look for a face name. + .substitutefaces + { 2 copy 0 get search + { pop pop pop 1 get .substitutefamilies exch get + 4 -1 roll pop 3 1 roll + } + { pop pop + } + ifelse + } + forall + .substituteproperties + { 2 copy 0 get search + { pop pop pop 1 get 3 -1 roll or exch } + { pop pop } + ifelse + } + forall pop get exec + % Only accept fonts known in the Fontmap. + Fontmap 1 index known not { pop defaultfontname } if + } bind def + +% If requested, make (and recognize) fake entries in FontDirectory for fonts +% present in Fontmap but not actually loaded. Thanks to Ray Johnston for +% the idea behind this code. +FAKEFONTS not { (%END FAKEFONTS) .skipeof } if + +% We use the presence or absence of the FontMatrix key to indicate whether +% a font is real or fake. We must pop the arguments at the very end, +% so that stack protection will be effective. + +/definefont { % definefont + dup /FontMatrix known { + //definefont + } { + 2 copy /FontName get findfont //definefont exch pop exch pop + } ifelse +} bind odef + +/scalefont { % scalefont + 1 index /FontMatrix known { + //scalefont + } { + 1 index /FontName get findfont 1 index //scalefont + exch pop exch pop + } ifelse +} bind odef + +/makefont { % makefont + 1 index /FontMatrix known { + //makefont + } { + 1 index /FontName get findfont 1 index //makefont + exch pop exch pop + } ifelse +} bind odef + +/setfont { % setfont - + dup /FontMatrix known { + //setfont + } { + dup /FontName get findfont //setfont pop + } ifelse +} bind odef + +%END FAKEFONTS + +% Define findfont so it tries to load a font if it's not found. +% The Red Book requires that findfont be a procedure, not an operator, +% but it still needs to restore the stacks reliably if it fails, +% so we do all the work in an operator. +/.findfont { + mark 1 index + //systemdict begin .dofindfont + % Define any needed aliases. + counttomark 1 sub { .aliasfont } repeat end + exch pop exch pop +} odef +/findfont { + .findfont +} bind def +% Check whether the font name we are about to look for is already on the list +% of aliases we're accumulating; if so, cause an error. +/.checkalias % -mark- ... .checkalias <> + { counttomark 1 sub -1 1 + { index 1 index eq + { pop QUIET not + { (Unable to substitute for font.\n) print flush + } if + /findfont cvx /invalidfont signalerror + } + if + } + for + } bind def +% Get a (non-fake) font if present in a FontDirectory. +/.fontknownget % .fontknownget true + % .fontknownget false + { .knownget + { FAKEFONTS + { dup /FontMatrix known { true } { pop false } ifelse } + { true } + ifelse + } + { false + } + ifelse + } bind def +% Do the work of findfont, including substitution, defaulting, and +% scanning of FONTPATH. +/.dofindfont % .dofindfont + { { .tryfindfont { exit } if + % We didn't find the font. If we haven't scanned + % all the directories in FONTPATH, scan the next one now, + % and look for the font again. + null 0 1 FONTPATH length 1 sub + { FONTPATH 1 index get null ne { exch pop exit } if pop + } + for dup null ne + { dup 0 eq { .scanfontbegin } if + FONTPATH 1 index get .scanfontdir + FONTPATH exch null put + % Start over with an empty alias list. + counttomark 1 sub { pop } repeat + .dofindfont exit + } + if pop + % No luck. Make sure we're not already + % looking for the default font. + dup defaultfontname eq + { QUIET not + { (Unable to load default font ) print + dup =only (! Giving up.\n) print flush + } + if /findfont cvx /invalidfont signalerror + } + if + % Substitute for the font. Don't alias. + /SUBSTFONT where { + pop QUIET not { + (Substituting for font ) print dup =only + (.\n) print flush + } if + cleartomark mark defaultfontname + } { + dup .substitutefont + 2 copy eq { pop defaultfontname } if + .checkalias + QUIET not { + (Substituting font ) print dup =only ( for ) print + 1 index =only (.\n) print flush + } if + % Remove all the accumulated aliases. + counttomark 1 add 1 roll cleartomark mark exch + } ifelse + } + loop + } bind def +% Try to find a font using only the present contents of Fontmap. +/.tryfindfont % .tryfindfont true + % .tryfindfont false + { .FontDirectory 1 index .fontknownget + { % Already loaded + exch pop true + } + { dup Fontmap exch .knownget not + { % Unknown font name. Look for a file with the + % same name as the requested font. + dup dup type /nametype eq { .namestring } if .loadfontloop + } + { % Try each element of the Fontmap in turn. + false exch % (in case we exhaust the list) + % Stack: fontname false fontmaplist + { exch pop + dup type /nametype eq + { % Font alias + .checkalias .tryfindfont exit + } + { dup dup type dup /arraytype eq exch /packedarraytype eq or exch xcheck and + { % Font with a procedural definition + exec % The procedure will load the font. + % Check to make sure this really happened. + .FontDirectory 1 index .knownget + { exch pop true exit } + if + } + { % Font file name + .loadfontloop { true exit } if + } + ifelse + } + ifelse false + } + forall + % Stack: font true -or- fontname false + { true + } + { % None of the Fontmap entries worked. + % Try loading a file with the same name + % as the requested font. + dup dup type /nametype eq { .namestring } if .loadfontloop + } + ifelse + } + ifelse + } + ifelse + } bind def +% Attempt to load a font from a file. +/.loadfontloop % .loadfontloop true + % .loadfontloop false + { % See above regarding the use of 'loop'. + + { + % Is the font name a string? + dup type /stringtype ne + { QUIET not + { (Can't find font with non-string name: ) print dup =only (.\n) print flush + } + if pop false exit + } + if + % Can we open the file? + findlibfile not + { QUIET not + { (Can't find \(or can't open\) font file ) print dup print + (.\n) print flush + } + if pop false exit + } + if + + % Stack: fontname fontfilename fontfile + DISKFONTS + { .currentglobal true .setglobal + 2 index (r) file + FontFileDirectory exch 5 index exch .growput + .setglobal + } + if + QUIET not + { (Loading ) print 2 index =only + ( font from ) print 1 index print (... ) print flush + } + if + % If LOCALFONTS isn't set, load the font into local or global + % VM according to FontType; if LOCALFONTS is set, load the font + % into the current VM, which is what Adobe printers (but not + % DPS or CPSI) do. + LOCALFONTS { false } { /setglobal where } ifelse + { pop /FontType .findfontvalue { 1 eq } { false } ifelse + % .setglobal, like setglobal, aliases FontDirectory to + % GlobalFontDirectory if appropriate. However, we mustn't + % allow the current version of .setglobal to be bound in, + % because it's different depending on language level. + .currentglobal exch /.setglobal .systemvar exec + % Remove the fake definition, if any. + .FontDirectory 3 index .undef + 1 index (r) file .loadfont .FontDirectory exch + /.setglobal .systemvar exec + } + { .loadfont .FontDirectory + } + ifelse + % Stack: fontname fontfilename fontdirectory + QUIET not + { //systemdict /level2dict known + { .currentglobal false .setglobal vmstatus + true .setglobal vmstatus 3 -1 roll pop + 6 -1 roll .setglobal 5 + } + { vmstatus 3 + } + ifelse { =only ( ) print } repeat + (done.\n) print flush + } if + + % Check to make sure the font was actually loaded. + dup 3 index .fontknownget + { 4 1 roll pop pop pop true exit } if + + % Maybe the file had a different FontName. + % See if we can get a FontName from the file, and if so, + % whether a font by that name exists now. + exch (r) file .findfontname + { 2 copy .fontknownget + { % Yes. Stack: origfontname fontdirectory filefontname fontdict + 3 -1 roll pop exch + QUIET + { pop + } + { (Using ) print =only + ( font for ) print 1 index =only + (.\n) print flush + } + ifelse true exit + } + if pop + } + if pop + + % The font definitely did not load correctly. + QUIET not + { (Loading ) print dup =only + ( font failed.\n) print flush + } if + false exit + + } loop % end of loop + + } bind def + +% Define a procedure to load all known fonts. +% This isn't likely to be very useful. +/loadallfonts + { Fontmap { pop findfont pop } forall + } bind def + +% If requested, load all the fonts defined in the Fontmap into FontDirectory +% as "fake" fonts i.e., font dicts with only FontName and FontType defined. +% (We define FontType only for the sake of some questionable code in the +% Apple Printer Utility 2.0 font inquiry code.) +% +% Note that this procedure only creates fake fonts in the FontDirectory +% associated with the current VM. This is because in multi-context systems, +% creating the fake fonts in local VM leads to undesirable complications. +/.definefakefonts + { + } + { + (gs_fonts FAKEFONTS) VMDEBUG + Fontmap { + pop dup type /stringtype eq { cvn } if + .FontDirectory 1 index known not { + 2 dict dup /FontName 3 index put + dup /FontType 1 put + .FontDirectory 3 1 roll put + } { + pop + } ifelse + } forall + } +FAKEFONTS { exch } if pop def % don't bind, .current/setglobal get redefined + +% Install initial fonts from Fontmap. +/.loadinitialfonts + { NOFONTMAP not + { /FONTMAP where + { pop [ FONTMAP .pathlist ] + { dup VMDEBUG findlibfile + { exch pop .loadFontmap } + { /undefinedfilename signalerror } + ifelse + } + } + { LIBPATH + { defaultfontmap 2 copy .filenamedirseparator + exch concatstrings concatstrings dup VMDEBUG + (r) { file } .internalstopped + { pop pop } { .loadFontmap } ifelse + } + } + ifelse forall + } + if + .definefakefonts % current VM is global + } def % don't bind, .current/setglobal get redefined + +% ---------------- Synthetic font support ---------------- % + +% Create a new font by modifying an existing one. paramdict contains +% entries with the same keys as the ones found in a Type 1 font; +% it should also contain enough empty entries to allow adding the +% corresponding non-overridden entries from the original font dictionary, +% including FID. If paramdict includes a FontInfo entry, this will +% also override the original font's FontInfo, entry by entry; +% again, it must contain enough empty entries. + +% Note that this procedure does not perform a definefont. + +/.makemodifiedfont % .makemodifiedfont + { exch + { % Stack: destdict key value + 1 index /FID ne + { 2 index 2 index known + { % Skip fontdict entry supplied in paramdict, but + % handle FontInfo specially. + 1 index /FontInfo eq + { 2 index 2 index get % new FontInfo + 1 index % old FontInfo + { % Stack: destdict key value destinfo key value + 2 index 2 index known + { pop pop } + { 2 index 3 1 roll put } + ifelse + } + forall pop + } + if + } + { % No override, copy the fontdict entry. + 2 index 3 1 roll put + dup dup % to match pop pop below + } + ifelse + } + if + pop pop + } forall + } bind def + +% Make a modified font and define it. Note that unlike definefont, +% this does not leave the font on the operand stack. + +/.definemodifiedfont % .definemodifiedfont - + { .makemodifiedfont + dup /FontName get exch definefont pop + } bind def diff --git a/pstoraster/gs_init.ps b/pstoraster/gs_init.ps new file mode 100644 index 0000000000..6a670b6382 --- /dev/null +++ b/pstoraster/gs_init.ps @@ -0,0 +1,1521 @@ +% Copyright 1993-2000 by Easy Software Products. +% Copyright 1989, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_init.ps 956 2000-03-08 23:15:43Z mike $ +% Initialization file for the interpreter. +% When this is run, systemdict is still writable. + +% Comment lines of the form +% %% Replace +% indicate places where the next lines should be replaced by +% the contents of , when creating a single merged init file. + +% The interpreter can call out to PostScript code. All procedures +% called in this way, and no other procedures defined in these +% initialization files, have names that begin with %, e.g., +% (%Type1BuildChar) cvn. + +% Check the interpreter revision. NOTE: the interpreter code requires +% that the first non-comment token in this file be an integer. +550 +dup revision ne + { (pstoraster: Interpreter revision \() print revision 10 string cvs print + (\) does not match gs_init.ps revision \() print 10 string cvs print + (\).\n) print flush null 1 .quit + } +if pop + +% Acquire userdict, and set its length if necessary. +/userdict where + { pop userdict maxlength 0 eq } + { true } +ifelse +systemdict exch + { % userdict wasn't already set up by iinit.c. + dup /userdict + currentdict dup 200 .setmaxlength % userdict + .forceput % userdict is local, systemdict is global + } +if begin + +% Define dummy local/global operators if needed. +systemdict /.setglobal known + { true .setglobal + } + { /.setglobal { pop } .bind def + /.currentglobal { false } .bind def + /.gcheck { pop false } .bind def + } +ifelse + +% Define .languagelevel if needed. +systemdict /.languagelevel known not { /.languagelevel 1 def } if + +% Optionally choose a default paper size other than U.S. letter. +% (a4) /PAPERSIZE where { pop pop } { /PAPERSIZE exch def } ifelse + +% Turn on array packing for the rest of initialization. +true setpacking + +% Define the old MS-DOS EOF character as a no-op. +% This is a hack to get around the absurd habit of MS-DOS editors +% of adding an EOF character at the end of the file. +<1a> cvn { } def + +% Acquire the debugging flags. +currentdict /DEBUG known /DEBUG exch def + /VMDEBUG + DEBUG {{print mark + systemdict /level2dict known + { .currentglobal dup false .setglobal vmstatus + true .setglobal vmstatus 3 -1 roll pop + 6 -2 roll pop .setglobal + } + { vmstatus 3 -1 roll pop + } + ifelse usertime 16#fffff and counttomark + { ( ) print ( ) cvs print } + repeat pop + ( ) print systemdict length ( ) cvs print + ( ) print countdictstack ( ) cvs print + ( <) print count ( ) cvs print (>\n) print flush + }} + {{pop + }} + ifelse + def + +currentdict /BATCH known /BATCH exch def +currentdict /DELAYBIND known /DELAYBIND exch def +currentdict /DISKFONTS known /DISKFONTS exch def +currentdict /ESTACKPRINT known /ESTACKPRINT exch def +currentdict /FAKEFONTS known /FAKEFONTS exch def +currentdict /FIXEDMEDIA known /FIXEDMEDIA exch def +currentdict /FIXEDRESOLUTION known /FIXEDRESOLUTION exch def +currentdict /LOCALFONTS known /LOCALFONTS exch def +currentdict /NOBIND known /NOBIND exch def +/.bind /bind load def +NOBIND { /bind { } def } if +currentdict /NOCACHE known /NOCACHE exch def +currentdict /NOCIE known /NOCIE exch def +currentdict /NODISPLAY known not /DISPLAYING exch def +currentdict /NOFONTMAP known /NOFONTMAP exch def +currentdict /NOFONTPATH known /NOFONTPATH exch def +currentdict /NOGC known /NOGC exch def +currentdict /NOINTERPOLATE known /NOINTERPOLATE exch def +currentdict /NOPAGEPROMPT known /NOPAGEPROMPT exch def +currentdict /NOPAUSE known /NOPAUSE exch def +currentdict /NOPLATFONTS known /NOPLATFONTS exch def +currentdict /NOPROMPT known /NOPROMPT exch def +% The default value of ORIENT1 is true, not false. +currentdict /ORIENT1 known not { /ORIENT1 true def } if +currentdict /OSTACKPRINT known /OSTACKPRINT exch def +currentdict /OUTPUTFILE known % obsolete + { /OutputFile /OUTPUTFILE load def + currentdict /OUTPUTFILE .undef + } if +currentdict /QUIET known /QUIET exch def +currentdict /SAFER known /SAFER exch def +currentdict /SHORTERRORS known /SHORTERRORS exch def +currentdict /STRICT known /STRICT exch def +currentdict /WRITESYSTEMDICT known /WRITESYSTEMDICT exch def + +% Acquire environment variables. +currentdict /DEVICE known not + { (GS_DEVICE) getenv { /DEVICE exch def } if } if + +(START) VMDEBUG + +% Open the standard files, so they will be open at the outermost save level. +(%stdin) (r) file pop +(%stdout) (w) file pop +(%stderr) (w) file pop + +/.currentuserparams where { + pop mark + % The Adobe implementations appear to have very large maximum + % stack sizes. This turns out to actually make a difference, + % since some badly-behaved files include extremely long procedures, + % or construct huge arrays on the operand stack. + % We reset the stack sizes now so that we don't have to worry + % about overflowing the (rather small) built-in stack sizes + % during initialization. + /MaxDictStack 500 + /MaxExecStack 5000 + /MaxOpStack 50000 + .dicttomark .setuserparams +} if + +% Define a procedure for skipping over an unneeded section of code. +% This avoids allocating space for the skipped procedures. +% We can't use readline, because that imposes a line length limit. +/.skipeof % .skipeof - + { currentfile exch 1 exch .subfiledecode flushfile + } .bind def + +% Define procedures to assist users who don't read the documentation. +userdict begin +/help + { (Enter PostScript commands. '(filename) run' runs a file, 'quit' exits.\n) + print flush + } .bind def +/? /help load def +end + +% Define =string, which is used by some PostScript programs even though +% it isn't documented anywhere. +% Put it in userdict so that each context can have its own copy. +userdict /=string 256 string put + +% Print the greeting. + +/printgreeting + { mark + product (Ghostscript) search + { pop pop pop + (This software comes with NO WARRANTY: see the file COPYING for details.\n) + } + { pop + } + ifelse + (\n) copyright + (\)\n) revisiondate 100 mod (-) + revisiondate 100 idiv 100 mod (-) + revisiondate 10000 idiv ( \() + revision 10 mod + revision 100 mod dup 0 ne { 10 idiv } { pop } ifelse (.) + revision 100 idiv ( ) + product + counttomark + { (%stderr) (w) file exch false .writecvp + } repeat pop + } .bind def + +QUIET not { printgreeting flush } if + +% Define a special version of def for making operator procedures. +/obind { % obind + 1 index exch .makeoperator +} .bind def +/odef { % odef - + 1 index exch .makeoperator def +} .bind def + +% Define a special version of def for storing local objects into global +% dictionaries. Like .forceput, this exists only during initialization. +/.forcedef { % .forcedef - + currentdict 3 1 roll .forceput +} .bind odef + +% Define procedures for accessing variables in systemdict and userdict +% regardless of the contents of the dictionary stack. +/.systemvar { % .systemvar + //systemdict exch get +} .bind odef +/.userdict { % - .userdict + /userdict .systemvar +} .bind odef +/.uservar { % .uservar + .userdict exch get +} .bind odef + +% If we're delaying binding, remember everything that needs to be bound later. +DELAYBIND NOBIND not and + { .currentglobal false .setglobal + systemdict /.delaybind 1500 array .forceput + .setglobal + userdict /.delaycount 0 put + % When we've done the delayed bind, we want to stop saving. + % Detect this by the disappearance of .delaybind. + /bind + { /.delaybind .systemvar dup length 0 ne + { .delaycount 2 index put + .userdict /.delaycount .delaycount 1 add put + } + { pop .bind + } + ifelse + } .bind def + } if + +%**************** BACKWARD COMPATIBILITY +/hwsizedict mark /HWSize null .dicttomark readonly def +/copyscanlines { % copyscanlines + 0 3 1 roll 3 index //hwsizedict .getdeviceparams + exch pop exch pop aload pop 3 2 roll + 0 exch null exch .getbitsrect exch pop +} bind odef +currentdict /hwsizedict .undef +/getdeviceprops + { null .getdeviceparams + } bind odef +/.putdeviceprops + { null true counttomark 1 add 3 roll .putdeviceparams + dup type /booleantype ne + { dup mark eq { /unknown /rangecheck } if + counttomark 4 add 1 roll cleartomark pop pop pop + /.putdeviceprops load exch signalerror + } + if + } bind odef +/max { .max } bind def +/min { .min } bind def +/.currentfilladjust { .currentfilladjust2 pop } bind odef +/.setfilladjust { dup .setfilladjust2 } bind odef +/.writecvs { false .writecvp } bind odef + +% Define predefined procedures substituting for operators, +% in alphabetical order. + +userdict /#copies 1 put +% Adobe implementations don't accept /[ or /], so we don't either. +([) cvn + /mark load def +(]) cvn + {counttomark array astore exch pop} odef +/abs {dup 0 lt {neg} if} odef +% .beginpage is redefined if setpagedevice is present. +/.beginpage { } odef +% In LanguageLevel 3, copypage erases the page. +/copypage { + .languagelevel 3 ge + 1 .endpage { + .currentnumcopies 1 index .outputpage + (>>copypage, press to continue<<\n) .confirm + dup { erasepage } if + } if pop .beginpage +} odef +/currentmatrix { + .currentmatrix 6 index astore pop +} odef +% .currentnumcopies is redefined in Level 2. +/.currentnumcopies { #copies } odef +/setcolorscreen where { pop % not in all Level 1 configurations + /currentcolorscreen + { .currenthalftone + { { 60 exch 0 exch 3 copy 6 copy } % halftone - not possible + { 3 copy 6 copy } % screen + { } % colorscreen + } + exch get exec + } odef +} if +/currentscreen + { .currenthalftone + { { 60 exch 0 exch } % halftone - not possible + { } % screen + { 12 3 roll 9 { pop } repeat } % colorscreen + } + exch get exec + } odef +/.echo /echo load def +userdict /.echo.mode true put +/echo {dup /.echo.mode exch store .echo} odef +/eexec + { 55665 //filterdict /eexecDecode get exec + cvx //systemdict begin exec + % Only pop systemdict if it is still the top element, + % because this is apparently what Adobe interpreters do. + currentdict //systemdict eq { end } if + } odef +% .endpage is redefined if setpagedevice is present. +/.endpage { 2 ne } odef +% erasepage mustn't use gsave/grestore, because we call it before +% the graphics state stack has been fully initialized. +/erasepage + { /currentcolor where + { pop currentcolor currentcolorspace { setcolorspace setcolor } } + { /currentcmykcolor where + { pop currentcmykcolor { setcmykcolor } } + { currentrgbcolor { setrgbcolor } } + ifelse + } + ifelse 1 setgray .fillpage exec + } odef +% To satisfy the Genoa FTS, executive must be a procedure, not an operator. +/executive + { { NOPROMPT not { prompt } if + { (%statementedit) (r) file } stopped + { pop pop $error /errorname get /undefinedfilename eq + { .clearerror exit } if % EOF + handleerror null % ioerror?? + } + if + cvx { .runexec } execute + } loop + } bind def +/filter + { //filterdict 1 index .knownget + { exch pop exec } + { /filter load /undefined signalerror } + ifelse + } odef +/handleerror + { /errordict .systemvar /handleerror get exec } bind def +/identmatrix [1.0 0.0 0.0 1.0 0.0 0.0] readonly def +/identmatrix + { dup 0 //identmatrix putinterval } odef +/languagelevel 1 def % gs_lev2.ps may change this +/makeimagedevice { false makewordimagedevice } odef +/matrix { 6 array identmatrix } odef +/pathbbox + { false .pathbbox + } odef +/prompt { flush flushpage + (GS) print + count 0 ne { (<) print count =only } if + (>) print flush + } bind def +/pstack { 0 1 count 3 sub { index == } for } bind def +/putdeviceprops + { .putdeviceprops { erasepage } if } odef +/quit { /quit load 0 .quit } odef +/run { dup type /filetype ne { (r) file } if + % We must close the file when execution terminates, + % regardless of the state of the stack, + % and then propagate an error, if any. + cvx .runexec + } odef +% Execute a file. +% Level 2 uses 2 .stop to clear the e-stack for a successful startjob: +% we detect that here, since we need to handle this even if we start out +% without job control in effect. +% +% What we push on the e-stack is the following to be executed in this order: +% .runexec1 .runexec2 +/.runexec1 { % .runexec1 - + dup type /filetype ne { cvx exec } if + cvx null 2 .stopped + % If we got back here from a startjob, just keep going. + % startjob replaces the null on the o-stack with a procedure + % to be executed when we get back here. + dup null ne { exec true } { pop false } ifelse +} bind def +/.runexec2 { % .runexec2 - + exch { + .runexec + } { + dup type /filetype ne { cvx exec } if + closefile + } ifelse +} bind def +/.runexec { % .runexec - + cvlit /.runexec1 cvx 1 index /.runexec2 cvx 4 .execn +} bind def +% The following is only for compatibility with Adobe interpreters. +/setdash { + 1 index length 11 gt { /setdash load /limitcheck signalerror } if + //setdash +} odef +/setdevice + { .setdevice { erasepage } if } odef +/setlinecap { + dup 2 gt { /setlinecap load /rangecheck signalerror } if + .setlinecap +} odef +/setlinejoin { + dup 2 gt { /setlinejoin load /rangecheck signalerror } if + .setlinejoin +} odef +/setmatrix { + dup aload pop .setmatrix pop +} odef +/showpage { + 0 .endpage .doneshowpage { + .currentnumcopies true .outputpage + (>>showpage, press to continue<<\n) .confirm + erasepage + } if initgraphics .beginpage +} odef +% Code output by Adobe Illustrator relies on the fact that +% `stack' is a procedure, not an operator!!! +/stack { 0 1 count 3 sub { index = } for } bind def +/start { BATCH { null 0 .quit } { executive } ifelse } def +% Internal uses of stopped that aren't going to do a stop if an error occurs +% should use .internalstopped to avoid setting newerror et al. +/.internalstopped { null 1 .stopped null ne } bind def +/store { % Don't alter operands before completing. + 1 index where { 2 index 2 index put pop pop } { def } ifelse +} odef +% NOTE: the name typenames is known to (initialized by) the interpreter. +/type { + //typenames .type +} odef +% When running in Level 1 mode, this interpreter is supposed to be +% compatible with PostScript "version" 54.0 (I think). +/version (54.0) readonly def + +% internaldict is defined in systemdict, but is allocated in local VM. +% We make a procedure for creating it, since we must create a new one +% for each context with private local VM. +/.makeinternaldict { + .currentglobal false .setglobal + [ /dup .systemvar 1183615869 /eq .systemvar + [ /pop .systemvar 10 dict ] cvx + [ /internaldict /cvx .systemvar /invalidaccess /signalerror cvx ] cvx + /ifelse .systemvar + ] cvx executeonly + exch .setglobal +} odef +systemdict /internaldict dup .makeinternaldict .makeoperator +.forceput % proc is local, systemdict is global +% Move superexec to internaldict if superexec is defined. +currentdict /superexec .knownget { + 1183615869 internaldict /superexec 3 -1 roll put + currentdict /superexec .undef +} if + +% Define some additional built-in procedures (beyond the ones defined by +% the PostScript Language Reference Manual). +% Warning: these are not guaranteed to stay the same from one release +% to the next! +/concatstrings + { exch dup length 2 index length add string % str2 str1 new + dup dup 4 2 roll copy % str2 new new new1 + length 4 -1 roll putinterval + } bind def +/copyarray + { dup length array copy } bind def +% Copy a dictionary per the Level 2 spec even in Level 1. +/.copydict % .copydict + { dup 3 -1 roll { put dup } forall pop } bind def +/copystring + { dup length string copy } bind def +/finddevice + { /devicedict .systemvar exch get + dup 1 get null eq + { % This is the first request for this type of device. + % Create a default instance now. + % Stack: [proto null] + .currentglobal true .setglobal exch + dup dup 0 get copydevice 1 exch put + exch .setglobal + } + if 1 get + } bind def +/.growdictlength % get size for growing a dictionary + { length 3 mul 2 idiv 1 add + } bind def +/.growdict % grow a dictionary + { dup .growdictlength .setmaxlength + } bind def +/.growput % put, grow the dictionary if needed + { 2 index length 3 index maxlength eq + { 3 copy pop known not { 2 index .growdict } if + } if + put + } bind def +/.packtomark + { counttomark packedarray exch pop } bind def +/ppstack + { 0 1 count 3 sub { index === } for } bind def +/runlibfile + { % We don't want to bind 'run' into this procedure, + % since run may get redefined. + findlibfile + { exch pop /run .systemvar exec } + { /undefinedfilename signalerror } + ifelse + } bind def +/selectdevice + { finddevice setdevice .setdefaultscreen } bind def +/signalerror % signalerror - + { /errordict .systemvar exch get exec } bind def + +% Define the =[only] procedures. Also define =print, +% which is used by some PostScript programs even though +% it isn't documented anywhere. +/write=only { + .writecvs +} bind def +/write= { + 1 index exch write=only (\n) writestring +} bind def +%%%% MRS - Send = output to stderr, since stdout is for output. +/=only { (%stderr) (w) file exch write=only } bind def +/= { =only (\n) print } bind def +/=print /=only load def +% Temporarily define == as = for the sake of runlibfile0. +/== /= load def + +% Define procedures for getting and setting the current device resolution. + +/gsgetdeviceprop % gsgetdeviceprop + { 2 copy mark exch null .dicttomark .getdeviceparams + dup mark eq % if true, not found + { pop dup /undefined signalerror } + { 5 1 roll pop pop pop pop } + ifelse + } bind def +/gscurrentresolution % - gscurrentresolution <[xres yres]> + { currentdevice /HWResolution gsgetdeviceprop + } bind def +/gssetresolution % <[xres yres]> gssetresolution - + { 2 array astore mark exch /HWResolution exch + currentdevice copydevice putdeviceprops setdevice + } bind def + +% Define auxiliary procedures needed for the above. +/shellarguments % -> shell_arguments true (or) false + { /ARGUMENTS where + { /ARGUMENTS get dup type /arraytype eq + { aload pop /ARGUMENTS null store true } + { pop false } + ifelse } + { false } ifelse + } bind def +/.confirm + { DISPLAYING NOPAUSE not and + { % Print a message (unless NOPAGEPROMPT or NOPROMPT is true) + % and wait for the user to type something. + % If the user just types a newline, flush it. + NOPAGEPROMPT NOPROMPT or { pop } { print flush } ifelse + .echo.mode false echo + (%stdin) (r) file dup read + { dup (\n) 0 get eq { pop pop } { unread } ifelse } + { pop } + ifelse echo + } + { pop + } + ifelse + } bind def + +% Define the procedure used by .runfile, .runstdin and .runstring +% for executing user input. +% This is called with a procedure or executable file on the operand stack. +/.execute { % .execute + stopped $error /newerror get and + { handleerror flush true } { false } ifelse +} bind def +/execute { % execute - + .execute pop +} odef +% Define an execute analogue of runlibfile0. +/execute0 { % execute0 - + .execute { /execute0 cvx 1 .quit } if +} bind def +% Define the procedure that the C code uses for running files +% named on the command line. +/.runfile { + { runlibfile } execute +} def +% Define the procedure that the C code uses for running piped input. +% We don't use the obvious { (%stdin) run }, because we want the file to be +% reopened if a startjob does a restore. +/.runstdin { + { { (%stdin) (r) file cvx } .runexec } execute0 +} bind def +% Define the procedure that the C code uses for running commands +% given on the command line with -c. We turn the string into a file so that +% .runexec can do the right thing with a startjob. +/.runstring { + .currentglobal exch true .setglobal + 0 () .subfiledecode + exch .setglobal cvx { .runexec } execute +} bind def +% Define the procedure that the C code uses to set up for executing +% a string that may be received in pieces. +/.runstringbegin { + .currentglobal true .setglobal + { .needinput } bind 0 () .subfiledecode + exch .setglobal cvx .runexec +} bind def + +% Define a special version of runlibfile that aborts on errors. +/runlibfile0 + { cvlit dup /.currentfilename exch def + { findlibfile not { stop } if } + stopped + { (Can't find \(or open\) initialization file ) print + .currentfilename == flush /runlibfile0 cvx 1 .quit + } if + exch pop cvx stopped + { (While reading ) print .currentfilename print (:\n) print flush + handleerror /runlibfile0 1 .quit + } if + } bind def +% Temporarily substitute it for the real runlibfile. +/.runlibfile /runlibfile load def +/runlibfile /runlibfile0 load def + +% Create the error handling machinery. +% Define the standard error handlers. +% The interpreter has created the ErrorNames array. +/.unstoppederrorhandler % .unstoppederrorhandler - + { % This is the handler that gets used for recursive errors, + % or errors outside the scope of a 'stopped'. + 2 copy SHORTERRORS + { (%%[ Error: ) print =only flush + (; OffendingCommand: ) print =only ( ]%%\n) print + } + { (Unrecoverable error: ) print =only flush + ( in ) print = flush + count 2 gt + { (Operand stack:\n ) print + 2 1 count 3 sub { ( ) print index =only flush } for + (\n) print flush + } if + } + ifelse + -1 0 1 //ErrorNames length 1 sub + { dup //ErrorNames exch get 3 index eq + { not exch pop exit } { pop } ifelse + } + for exch pop .quit + } bind def +/.errorhandler % .errorhandler - + { % Detect an internal 'stopped'. + 1 .instopped { null eq { pop pop stop } if } if + $error /.inerror get 1 .instopped { pop } { pop true } ifelse + { .unstoppederrorhandler + } if % detect error recursion + $error /globalmode .currentglobal false .setglobal put + $error /.inerror true put + $error /newerror true put + $error exch /errorname exch put + $error exch /command exch put + $error /recordstacks get $error /errorname get /VMerror ne and + { % Attempt to store the stack contents atomically. + count array astore dup $error /ostack 4 -1 roll + countexecstack array execstack $error /estack 3 -1 roll + countdictstack array dictstack $error /dstack 3 -1 roll + put put put aload pop + } + { $error /dstack .undef + $error /estack .undef + $error /ostack .undef + } + ifelse + $error /position currentfile status + { currentfile { fileposition } .internalstopped { pop null } if + } + { % If this was a scanner error, the file is no longer current, + % but the command holds the file, which may still be open. + $error /command get dup type /filetype eq + { { fileposition } .internalstopped { pop null } if } + { pop null } + ifelse + } + ifelse put + % During initialization, we don't reset the allocation + % mode on errors. + $error /globalmode get $error /.nosetlocal get and .setglobal + $error /.inerror false put + stop + } bind def +% Define the standard handleerror. We break out the printing procedure +% (.printerror) so that it can be extended for binary output +% if the Level 2 facilities are present. + /.printerror + { $error begin + /command load errorname SHORTERRORS + { (%%[ Error: ) print =only flush + (; OffendingCommand: ) print =only + currentdict /errorinfo .knownget + { (;\nErrorInfo:) print + dup type /arraytype eq + { { ( ) print =only } forall } + { ( ) print =only } + ifelse + } if + ( ]%%\n) print flush + } + { (Error: ) print ==only flush + ( in ) print ==only flush + currentdict /errorinfo .knownget + { (\nAdditional information: ) print ==only flush + } if + .printerror_long + } + ifelse + .clearerror + end + flush + } bind def + /.printerror_long % long error printout, + % $error is on the dict stack + { % Push the (anonymous) stack printing procedure. + % <==flag> proc + { + currentdict exch .knownget % stackname defined in $error? + { + 4 1 roll % stack: <==flag> + errordict exch .knownget % overridename defined? + { + exch pop exch pop exec % call override with + } + { + exch print exch % print heading. stack <==flag> + 1 index not { (\n) print } if + { 1 index { (\n ) } { ( ) } ifelse print + dup type /dicttype eq + { + (--dict:) print + dup rcheck { + dup length =only (/) print dup maxlength =only + } if + /gcheck where { + pop gcheck { ((G)) } { ((L)) } ifelse print + } { + pop + } ifelse (--) print + } + { + dup type /stringtype eq 2 index or + { ==only } { =only } ifelse + } ifelse + } forall + pop + } + ifelse % overridden + } + { pop pop pop + } + ifelse % stack known + } + + (\nOperand stack:) OSTACKPRINT /.printostack /ostack 4 index exec + (\nExecution stack:) ESTACKPRINT /.printestack /estack 4 index exec + (\nBacktrace:) true /.printbacktrace /backtrace 4 index exec + (\nDictionary stack:) false /.printdstack /dstack 4 index exec + (\n) print + pop % printing procedure + + errorname /VMerror eq + { (VM status:) print mark vmstatus + counttomark { ( ) print counttomark -1 roll dup =only } repeat + cleartomark (\n) print + } if + + .languagelevel 2 ge + { (Current allocation mode is ) print + globalmode { (global\n) } { (local\n) } ifelse print + } if + + .oserrno dup 0 ne + { (Last OS error: ) print + errorname /VMerror ne + { dup .oserrorstring { = pop } { = } ifelse } + { = } + ifelse + } + { pop + } + ifelse + + position null ne + { (Current file position is ) print position = } + if + + } bind def +% Define a procedure for clearing the error indication. +/.clearerror + { $error /newerror false put + $error /errorname null put + $error /errorinfo .undef + 0 .setoserrno + } bind def + +% Define $error. This must be in local VM. +.currentglobal false .setglobal +/$error 40 dict .forcedef % $error is local, systemdict is global + % newerror, errorname, command, errorinfo, + % ostack, estack, dstack, recordstacks, + % binary, globalmode, + % .inerror, .nosetlocal, position, + % plus extra space for badly designed error handers. +$error begin + /newerror false def + /recordstacks true def + /binary false def + /globalmode .currentglobal def + /.inerror false def + /.nosetlocal true def + /position null def +end +% Define errordict similarly. It has one entry per error name, +% plus handleerror. +/errordict ErrorNames length 1 add dict +.forcedef % errordict is local, systemdict is global +.setglobal % contents of errordict are global +errordict begin + ErrorNames + { mark 1 index systemdict /.errorhandler get /exec load .packtomark cvx def + } forall +% The handlers for interrupt and timeout are special; there is no +% 'current object', so they push their own name. + { /interrupt /timeout } + { mark 1 index dup systemdict /.errorhandler get /exec load .packtomark cvx def + } forall +/handleerror + { /.printerror .systemvar exec + } bind def +end + +% Define the [write]==[only] procedures. +/.dict 26 dict dup +begin def + /.cvp {1 index exch .writecvs} bind def + /.nop {exch pop .p} bind def + /.p {1 index exch writestring} bind def + /.p1 {2 index exch writestring} bind def + /.p2 {3 index exch writestring} bind def + /.print + { dup type .dict exch .knownget + { dup type /stringtype eq { .nop } { exec } ifelse } + { (-) .p1 type .cvp (-) .p } + ifelse + } bind def + /.pstring + { { dup dup 32 lt exch 127 ge or + { (\\) .p1 2 copy -6 bitshift 48 add write + 2 copy -3 bitshift 7 and 48 add write + 7 and 48 add + } + { dup dup -2 and 40 eq exch 92 eq or {(\\) .p1} if + } + ifelse 1 index exch write + } + forall + } bind def + /booleantype /.cvp load def + /conditiontype (-condition-) def + /devicetype (-device-) def + /dicttype (-dict-) def + /filetype (-file-) def + /fonttype (-fontID-) def + /gstatetype (-gstate-) def + /integertype /.cvp load def + /locktype (-lock-) def + /marktype (-mark-) def + /nulltype (null) def + /realtype {1 index exch true .writecvp} bind def + /savetype (-save-) def + /nametype + {dup xcheck not {(/) .p1} if + 1 index exch .writecvs} bind def + /arraytype + {dup rcheck + {() exch dup xcheck + {({) .p2 + {exch .p1 + 1 index exch .print pop ( )} forall + (})} + {([) .p2 + {exch .p1 + 1 index exch .print pop ( )} forall + (])} + ifelse exch pop .p} + {(-array-) .nop} + ifelse} bind def + /operatortype + {(--) .p1 .cvp (--) .p} bind def + /packedarraytype + { dup rcheck + { arraytype } + { (-packedarray-) .nop } + ifelse + } bind def + /stringtype + { dup rcheck + { (\() .p1 dup length 200 le + { .pstring } + { 0 200 getinterval .pstring (...) .p } + ifelse (\)) .p + } + { (-string-) .nop + } + ifelse + } bind def +{//.dict begin .print pop end} + bind +end + +/write==only exch def +/write== {1 index exch write==only (\n) writestring} bind def +/==only { (%stderr) (w) file exch write==only } bind def +/== {==only (\n) print} bind def + +% Define [write]===[only], an extension that prints dictionaries +% in readable form and doesn't truncate strings. +/.dict /write==only load 0 get dup length dict .copydict dup +begin def + /dicttype + { dup rcheck + { (<< ) .p1 + { 2 index 3 -1 roll .print pop ( ) .p1 + 1 index exch .print pop ( ) .p + } + forall (>>) .p + } + { (-dict-) .nop + } + ifelse + } bind def + /stringtype + { dup rcheck + { (\() .p1 .pstring (\)) .p } + { (-string-) .nop } + ifelse + } bind def + +{//.dict begin .print pop end} + bind +end + +/write===only exch def +/write=== {1 index exch write===only (\n) writestring} bind def +/===only { (%stderr) (w) file exch write===only } bind def +/=== { ===only (\n) print } bind def + +(END PROCS) VMDEBUG + +% Define the font directory. +/FontDirectory false .setglobal 100 dict true .setglobal +.forcedef % FontDirectory is local, systemdict is global + +% Define the encoding dictionary. +/EncodingDirectory 10 dict def % enough for Level 2 + PDF standard encodings + +% Define .findencoding. (This is redefined in Level 2.) +/.findencoding + { //EncodingDirectory exch get exec + } bind def +/.defineencoding + { //EncodingDirectory 3 1 roll put + } bind def +% If we've got the composite font extensions, define findencoding. +% To satisfy the Genoa FTS, findencoding must be a procedure, not an operator. +/rootfont where { pop /findencoding { .findencoding } def } if + +% Define .registerencoding. +% NOTE: the name registeredencodings is known to (initialized by and shared +% with) the interpreter. +/.registerencoding { % .registerencoding - + % Check that the array is indexable. + % (It might still be a string, but then the .namestring will fail.) + dup 0 0 getinterval pop + % Check that all the elements of the array are names. + dup { .namestring pop } forall + % Do the store. + //registeredencodings 2 index 2 index readonly put pop pop +} bind odef +systemdict /registeredencodings .undef + +% Load StandardEncoding. +%% Replace 1 (gs_std_e.ps) +(gs_std_e.ps) dup runlibfile VMDEBUG + +% Load ISOLatin1Encoding. +%% Replace 1 (gs_iso_e.ps) +(gs_iso_e.ps) dup runlibfile VMDEBUG + +% Define stubs for the Symbol and Dingbats encodings. +% Note that the first element of the procedure must be the file name, +% since gs_lev2.ps extracts it to set up the Encoding resource category. + + /SymbolEncoding { /SymbolEncoding .findencoding } bind def +%% Replace 3 (gs_sym_e.ps) + EncodingDirectory /SymbolEncoding + { (gs_sym_e.ps) //systemdict begin runlibfile SymbolEncoding end } + bind put + + /DingbatsEncoding { /DingbatsEncoding .findencoding } bind def +%% Replace 3 (gs_dbt_e.ps) + EncodingDirectory /DingbatsEncoding + { (gs_dbt_e.ps) //systemdict begin runlibfile DingbatsEncoding end } + bind put + +(END FONTDIR/ENCS) VMDEBUG + +% Construct a dictionary of all available devices. +% These are (read-only) device prototypes that can't be +% installed or have their parameters changed. For this reason, +% the value in the dictionary is actually a 2-element writable array, +% to allow us to create a default instance of the prototype on demand. + + % Loop until the .getdevice gets a rangecheck. +errordict /rangecheck 2 copy get +errordict /rangecheck { pop stop } put % pop the command + 0 { {dup .getdevice exch 1 add} loop} .internalstopped pop + 1 add dict /devicedict 1 index def + begin % 2nd copy of count is on stack + { dup .devicename exch + dup wcheck { dup } { null } ifelse 2 array astore def + } repeat + end +put % errordict /rangecheck +.clearerror +/devicenames devicedict { pop } forall devicedict length packedarray def + +% Determine the default device. +/defaultdevice DISPLAYING + { systemdict /DEVICE .knownget + { devicedict 1 index known not + { (Unknown device: ) print = + flush /defaultdevice cvx 1 .quit + } + if + } + { 0 .getdevice .devicename + } + ifelse + } + { /nullpage + } +ifelse +/.defaultdevicename 1 index def +finddevice % make a copy +def +devicedict /Default devicedict .defaultdevicename get put + +(END DEVS) VMDEBUG + +% Define statusdict, for the benefit of programs +% that think they are running on a LaserWriter or similar printer. +%% Replace 1 (gs_statd.ps) +(gs_statd.ps) runlibfile + +(END STATD) VMDEBUG + +% Load the standard font environment. +%% Replace 1 (gs_fonts.ps) +(gs_fonts.ps) runlibfile + +(END GS_FONTS) VMDEBUG + +% Load the initialization files for optional features. +%% Replace 4 INITFILES +systemdict /INITFILES known + { INITFILES { dup runlibfile VMDEBUG } forall + } +if + +% If Level 2 (or higher) functionality is implemented, enable it now. +/.setlanguagelevel where { + pop 2 .setlanguagelevel + % If the resource machinery is loaded, fix up some things now. + /.fixresources where { pop .fixresources } if +} if +/ll3dict where { + pop 3 .setlanguagelevel +} if + +(END INITFILES) VMDEBUG + +% Create a null font. This is the initial font. +8 dict dup begin + /FontMatrix [ 1 0 0 1 0 0 ] readonly def + /FontType 3 def + /FontName () def + /Encoding StandardEncoding def + /FontBBox { 0 0 0 0 } readonly def % executable is bogus, but customary ... + /BuildChar { pop pop 0 0 setcharwidth } bind def + /PaintType 0 def % shouldn't be needed! +end +/NullFont exch definefont setfont + +% Define NullFont as the font. +/NullFont currentfont def + +% Load initial fonts from FONTPATH directories, Fontmap file, +% and/or .getccfont as appropriate. +.loadinitialfonts + +% Remove NullFont from FontDirectory, so it can't be accessed by mistake. +/undefinefont where { + pop /NullFont undefinefont +} { + FontDirectory /NullFont .undef +} ifelse + +(END FONTS) VMDEBUG + +% Restore the real definition of runlibfile. +/runlibfile /.runlibfile load def +currentdict /.runlibfile .undef + +% Bind all the operators defined as procedures. +/.bindoperators % binds operators in currentdict + { % Temporarily disable the typecheck error. + errordict /typecheck 2 copy get + errordict /typecheck { pop } put % pop the command + currentdict + { dup type /operatortype eq + { % This might be a real operator, so bind might cause a typecheck, + % but we've made the error a no-op temporarily. + .bind % do a real bind even if NOBIND is set + } + if pop pop + } forall + put + } def +NOBIND DELAYBIND or not { .bindoperators } if + +% Establish a default environment. + +defaultdevice +% The following line used to skip setting of page size and resolution if +% NODISPLAY was selected. We think this was only to save time and memory, +% and it is a bad idea because it prevents setting the resolution in this +% situation, which pstoedit (among other programs) relies on. +%DISPLAYING not { setdevice (%END DISPLAYING) .skipeof } if +systemdict /DEVICEWIDTH known +systemdict /DEVICEHEIGHT known or +systemdict /DEVICEWIDTHPOINTS known or +systemdict /DEVICEHEIGHTPOINTS known or +systemdict /DEVICEXRESOLUTION known or +systemdict /DEVICEYRESOLUTION known or +systemdict /PAPERSIZE known or +not { (%END DEVICE) .skipeof } if +% Let DEVICE{WIDTH,HEIGHT}[POINTS] override PAPERSIZE. +systemdict /PAPERSIZE known +systemdict /DEVICEWIDTH known not and +systemdict /DEVICEHEIGHT known not and +systemdict /DEVICEWIDTHPOINTS known not and +systemdict /DEVICEHEIGHTPOINTS known not and + { % Convert the paper size to device dimensions. + true statusdict /.pagetypenames get + { PAPERSIZE eq + { PAPERSIZE load + dup 0 get /DEVICEWIDTHPOINTS exch def + 1 get /DEVICEHEIGHTPOINTS exch def + pop false exit + } + if + } + forall + { (Unknown paper size: ) print PAPERSIZE ==only (.\n) print + } + if + } +if +% Adjust the device parameters per the command line. +% It is possible to specify resolution, pixel size, and page size; +% since any two of these determine the third, conflicts are possible. +% We simply pass them to .setdeviceparams and let it sort things out. + mark /HWResolution null /HWSize null /PageSize null .dicttomark + .getdeviceparams .dicttomark begin + mark + % Check for resolution. + /DEVICEXRESOLUTION where dup + { exch pop HWResolution 0 DEVICEXRESOLUTION put } + if + /DEVICEYRESOLUTION where dup + { exch pop HWResolution 1 DEVICEYRESOLUTION put } + if + or { /HWResolution HWResolution } if + % Check for device sizes specified in pixels. + /DEVICEWIDTH where dup + { exch pop HWSize 0 DEVICEWIDTH put } + if + /DEVICEHEIGHT where dup + { exch pop HWSize 1 DEVICEHEIGHT put } + if + or { /HWSize HWSize } if + % Check for device sizes specified in points. + /DEVICEWIDTHPOINTS where dup + { exch pop PageSize 0 DEVICEWIDTHPOINTS put } + if + /DEVICEHEIGHTPOINTS where dup + { exch pop PageSize 1 DEVICEHEIGHTPOINTS put } + if + or { /PageSize PageSize } if + % Check whether any parameters were set. + dup mark eq { pop } { defaultdevice putdeviceprops } ifelse + end +%END DEVICE +% Set any device properties defined on the command line. +% If BufferSpace is defined but not MaxBitmap, set MaxBitmap to BufferSpace. +systemdict /BufferSpace known +systemdict /MaxBitmap known not and + { systemdict /MaxBitmap BufferSpace put + } if +dup getdeviceprops +counttomark 2 idiv + { systemdict 2 index known + { pop dup load counttomark 2 roll } + { pop pop } + ifelse + } repeat +counttomark dup 0 ne + { 2 add -1 roll putdeviceprops } + { pop pop } +ifelse +setdevice % does an erasepage +% If the media size is fixed, update the current page device dictionary. +FIXEDMEDIA +dup { pop systemdict /.currentpagedevice known } if +dup { pop .currentpagedevice exch pop } if +not { (%END MEDIA) .skipeof } if +currentpagedevice dup length dict .copydict +dup /Policies + % Stack: /Policies +1 index /InputAttributes +2 copy get dup length dict .copydict + % Stack: /Policies + % /InputAttributes +dup 0 2 copy get dup length dict .copydict + % Stack: /Policies + % /InputAttributes 0 +dup /PageSize 7 index /PageSize get +put % PageSize in 0 +put % 0 in InputAttributes +put % InputAttributes in pagedevice +% Also change the page size policy so we don't get an error. + % Stack: /Policies +2 copy get dup length dict .copydict + % Stack: /Policies +dup /PageSize 7 put % PageSize in Policies +put % Policies in pagedevice +.setpagedevice +%END MEDIA +%END DISPLAYING + +(END DEVICE) VMDEBUG + +% Establish a default upper limit in the character cache, +% namely, enough room for a 18-point character at the resolution +% of the default device, or for a character consuming 1% of the +% maximum cache size, whichever is larger. +mark + % Compute limit based on character size. + 18 dup dtransform + exch abs cvi 31 add 32 idiv 4 mul % X raster + exch abs cvi mul % Y + % Compute limit based on allocated space. + cachestatus pop pop pop pop pop exch pop 0.01 mul cvi + .max dup 10 idiv exch +setcacheparams +% Conditionally disable the character cache. +NOCACHE { 0 setcachelimit } if + +(END CONFIG) VMDEBUG + +% Establish an appropriate halftone screen and BG/UCR functions. +% We make this a procedure so we can call it again when switching devices. + +%%%% MRS - Changed default to 16x16 Floyd dither, matching the CUPS +%%%% image RIP. Also, added missing standard transfer function, +%%%% which is needed by output from many apps... + +% Set the default screen and BG/UCR based on the device resolution and +% process color capability. +/.setdefaultbgucr systemdict /setblackgeneration known { { + processcolors 1 eq { { } } { { pop 0.0 } } ifelse + dup setblackgeneration setundercolorremoval +} } { { +} } ifelse bind def +% Set the default screen based on the device resolution. +/.setdefaultscreen +{ + << + /HalftoneType 3 + /Width 16 + /Height 16 + /Thresholds + < 00 80 20 A0 08 88 28 A8 02 82 22 A2 0A 8A 2A AA + C0 40 E0 60 C8 48 E8 68 C2 42 E2 62 CA 4A EA 6A + 30 B0 10 90 38 B8 18 98 32 B2 12 92 3A BA 1A 9A + F0 70 D0 50 F8 78 D8 58 F2 72 D2 52 FA 7A DA 5A + 0C 8C 2C AC 04 84 24 A4 0E 8E 2E AE 06 86 26 A6 + CC 4C EC 6C C4 44 E4 64 CE 4E EE 6E C6 46 E6 66 + 3C BC 1C 9C 34 B4 14 94 3E BE 1E 9E 36 B6 16 96 + FC 7C DC 5C F4 74 D4 54 FE 7E DE 5E F6 76 D6 56 + 03 83 23 A3 0B 8B 2B AB 01 81 21 A1 09 89 29 A9 + C3 43 E3 63 CB 4B EB 6B C1 41 E1 61 C9 49 E9 69 + 33 B3 13 93 3B BB 1B 9B 31 B1 11 91 39 B9 19 99 + F3 73 D3 53 FB 7B DB 5B F1 71 D1 51 F9 79 D9 59 + 0F 8F 2F AF 07 87 27 A7 0D 8D 2D AD 05 85 25 A5 + CF 4F EF 6F C7 47 E7 67 CD 4D ED 6D C5 45 E5 65 + 3F BF 1F 9F 37 B7 17 97 3D BD 1D 9D 35 B5 15 95 + FF 7F DF 5F F7 77 D7 57 FD 7D DD 5D F5 75 D5 55 > + >> sethalftone +} bind def +.setdefaultscreen +% Set a null transfer function... +{} bind settransfer +initgraphics + +% The interpreter relies on there being at least 2 entries +% on the graphics stack. Establish the second one now. +gsave + +% Define some control sequences as no-ops. +% This is a hack to get around problems +% in some common PostScript-generating applications. +<04> cvn { } def % Apple job separator +<0404> cvn { } def % two of the same +<1b> cvn { } def % MS Windows LaserJet 4 prologue + % (UEL = ESC %-12345X) +<1b45> cvn { } def % PJL reset prologue (ESC E) +<1b451b> cvn { } def % PJL reset epilogue (ESC E + UEL) +<041b> cvn { } def % MS Windows LaserJet 4 epilogue (^D + UEL) +(\001M) cvn % TBCP initiator + { currentfile /TBCPDecode filter cvx exec + } bind def +/@PJL % H-P job control + { currentfile //=string readline { pop } if + } bind def + +% If we want a "safer" system, disable some obvious ways to cause havoc. +SAFER not { (%END SAFER) .skipeof } if +/file + { dup (r) eq 2 index (%pipe*) .stringmatch not and + 2 index (%std*) .stringmatch or + { file } + { /invalidfileaccess signalerror } + ifelse + } .bind odef +/renamefile { /invalidfileaccess signalerror } odef +/deletefile { /invalidfileaccess signalerror } odef +/putdeviceprops + { counttomark + dup 2 mod 0 eq { pop /rangecheck signalerror } if + 3 2 3 2 roll + { dup index /OutputFile eq + { -2 roll + dup () ne { /putdeviceprops load /invalidfileaccess signalerror } if + 3 -1 roll + } + { pop + } + ifelse + } for + putdeviceprops + } .bind odef + +%END SAFER + +% If we delayed binding, make it possible to do it later. +/.bindnow { + //systemdict begin .bindoperators end + % Temporarily disable the typecheck error. + errordict /typecheck 2 copy get + errordict /typecheck { pop } put % pop the command + 0 1 .delaycount 1 sub { .delaybind exch get .bind pop } for + //systemdict /.delaybind {} .forceput % reclaim the space + //systemdict /.bindnow .forceundef % ditto + put + //systemdict /.forcedef .forceundef % remove temptation + //systemdict /.forceput .forceundef % ditto + //systemdict /.forceundef .forceundef % ditto +} .bind odef + +% Turn off array packing, since some PostScript code assumes that +% procedures are writable. +false setpacking + +(END INIT) VMDEBUG + +/.currentuserparams where { + pop + % Remove real user params from psuserparams. + mark .currentuserparams counttomark 2 idiv { + pop psuserparams exch undef + } repeat pop + % Update the copy of the user parameters. + mark .currentuserparams counttomark 2 idiv { + userparams 3 1 roll .forceput % userparams is read-only + } repeat pop + % Turn on idiom recognition, if available. + currentuserparams /IdiomRecognition known { + /IdiomRecognition true .definepsuserparam + } if + psuserparams readonly pop + systemdict /.definepsuserparam undef + % Save a copy of userparams for use with save/restore + % (and, if implemented, context switching). + .currentglobal false .setglobal + mark .currentuserparams psuserparams { } forall .dicttomark readonly + /userparams exch .forcedef % systemdict is read-only + .setglobal +} if +/.currentsystemparams where { + pop + % Remove real system params from pssystemparams. + mark .currentsystemparams counttomark 2 idiv { + pop pssystemparams exch .forceundef + } repeat pop +} if + +% Conditionally turn off image interpolation. +NOINTERPOLATE not { (%END NOINTERPOLATE) .skipeof } if +/.nointerpolate { + dup type /dicttype eq { + dup /Interpolate .knownget not { false } if { + dup gcheck .currentglobal exch .setglobal + exch dup length dict copy + dup /Interpolate .undef + exch .setglobal + } if + } if +} bind odef +/image { .nointerpolate image } bind odef +/imagemask { .nointerpolate imagemask } bind odef +%END NOINTERPOLATE + +% Establish local VM as the default. +false /setglobal where { pop setglobal } { .setglobal } ifelse +$error /.nosetlocal false put + +(END GLOBAL) VMDEBUG + +/.savelocalstate where { + % If we might create new contexts, save away copies of all dictionaries + % referenced from systemdict that are stored in local VM, + % and also save a copy of the initial gstate. + pop .savelocalstate +} { + % If we're *not* running in a multi-context system and FAKEFONTS is + % defined, add the fake fonts to LocalFontDirectory. + .definefakefonts % current VM is local +} ifelse + +% Close up systemdict. +currentdict /filterdict .undef % bound in where needed +currentdict /.cidfonttypes .undef % ditto +currentdict /.colorrenderingtypes .undef % ditto +currentdict /.formtypes .undef % ditto +currentdict /.imagetypes .undef % ditto +currentdict /.imagemasktypes .undef % ditto +currentdict /.patterntypes .undef % ditto +currentdict /.shadingtypes .undef % ditto +end + +% Clean up VM, and enable GC. +/vmreclaim where + { pop NOGC not { 2 vmreclaim 0 vmreclaim } if + } if +DELAYBIND not { + systemdict /.forcedef .undef % remove temptation + systemdict /.forceput .undef % ditto + systemdict /.forceundef .undef % ditto +} if +WRITESYSTEMDICT not { systemdict readonly pop } if + +(END GC) VMDEBUG + +% The interpreter will run the initial procedure (start). diff --git a/pstoraster/gs_iso_e.ps b/pstoraster/gs_iso_e.ps new file mode 100644 index 0000000000..607d9714f1 --- /dev/null +++ b/pstoraster/gs_iso_e.ps @@ -0,0 +1,74 @@ +% Copyright (C) 1993, 1994 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_iso_e.ps 956 2000-03-08 23:15:43Z mike $ +% Define the ISO Latin-1 encoding vector. +% The first half is the same as the standard encoding, +% except for minus instead of hyphen at code 055. +/ISOLatin1Encoding +StandardEncoding 0 45 getinterval aload pop + /minus +StandardEncoding 46 82 getinterval aload pop +% NOTE: the following are missing in the Adobe documentation, +% but appear in the displayed table: +% macron at 0225, dieresis at 0230, cedilla at 0233, space at 0240. +% This is an error in the Red Book, corrected in Adobe TN 5085. +% \20x + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /dotlessi /grave /acute /circumflex /tilde /macron /breve /dotaccent + /dieresis /.notdef /ring /cedilla /.notdef /hungarumlaut /ogonek /caron +% \24x + /space /exclamdown /cent /sterling + /currency /yen /brokenbar /section + /dieresis /copyright /ordfeminine /guillemotleft + /logicalnot /minus /registered /macron + /degree /plusminus /twosuperior /threesuperior + /acute /mu /paragraph /periodcentered + /cedilla /onesuperior /ordmasculine /guillemotright + /onequarter /onehalf /threequarters /questiondown +% \30x + /Agrave /Aacute /Acircumflex /Atilde + /Adieresis /Aring /AE /Ccedilla + /Egrave /Eacute /Ecircumflex /Edieresis + /Igrave /Iacute /Icircumflex /Idieresis + /Eth /Ntilde /Ograve /Oacute + /Ocircumflex /Otilde /Odieresis /multiply + /Oslash /Ugrave /Uacute /Ucircumflex + /Udieresis /Yacute /Thorn /germandbls +% \34x + /agrave /aacute /acircumflex /atilde + /adieresis /aring /ae /ccedilla + /egrave /eacute /ecircumflex /edieresis + /igrave /iacute /icircumflex /idieresis + /eth /ntilde /ograve /oacute + /ocircumflex /otilde /odieresis /divide + /oslash /ugrave /uacute /ucircumflex + /udieresis /yacute /thorn /ydieresis +% Make an array on large systems, a packed array on small ones. +256 +vmstatus exch pop exch pop +100000 ge { array astore readonly } { packedarray } ifelse +def +1 ISOLatin1Encoding .registerencoding +/ISOLatin1Encoding ISOLatin1Encoding .defineencoding diff --git a/pstoraster/gs_kanji.ps b/pstoraster/gs_kanji.ps new file mode 100644 index 0000000000..ee4272dd47 --- /dev/null +++ b/pstoraster/gs_kanji.ps @@ -0,0 +1,166 @@ +% Copyright (C) 1994, 1995, 1996 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_kanji.ps 956 2000-03-08 23:15:43Z mike $ +% Scaffolding for Kanji fonts. This is based on the Wadalab free font +% from the University of Tokyo; it may not be appropriate for other +% Kanji fonts. + +/currentglobal where + { pop currentglobal { setglobal } true setglobal } + { { } } +ifelse + +% Define the encoding for the root font. + +/KanjiEncoding +% \x00 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 +% \x20 + 0 1 2 3 4 5 6 7 + 8 0 0 0 0 0 0 0 + 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 +% \x40 + 25 26 27 28 29 30 31 32 + 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 + 49 50 51 52 53 54 55 56 +% \x60 + 57 58 59 60 61 62 63 64 + 65 66 67 68 69 70 71 72 + 73 74 75 76 77 0 0 0 + 0 0 0 0 0 0 0 0 +% \x80 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 +% \xA0 + 0 1 2 3 4 5 6 7 + 8 0 0 0 0 0 0 0 + 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 +% \xC0 + 25 26 27 28 29 30 31 32 + 33 34 35 36 37 38 39 40 + 41 42 43 44 45 46 47 48 + 49 50 51 52 53 54 55 56 +% \xE0 + 57 58 59 60 61 62 63 64 + 65 66 67 68 69 70 71 72 + 73 74 75 76 77 0 0 0 + 0 0 0 0 0 0 0 0 +256 packedarray def + +% Define a stub for the base font encoding. + + /KanjiSubEncoding { /KanjiSubEncoding .findencoding } bind def +%% Replace 3 (gs_ksb_e.ps) + EncodingDirectory /KanjiSubEncoding + { (gs_ksb_e.ps) //systemdict begin runlibfile KanjiSubEncoding end } + bind put + +% Support procedures and data. + +/T1FontInfo 8 dict begin + /version (001.001) readonly def + /FullName (KanjiBase) readonly def + /FamilyName (KanjiBase) readonly def + /Weight (Medium) readonly def + /ItalicAngle 0 def + /isFixedPitch false def + /UnderlinePosition 0 def + /UnderlineThickness 0 def +currentdict end readonly def + +/T1NF % T1NF +{ +20 dict begin + /FontName exch def + /FontType 1 def + /FontInfo T1FontInfo def + /FontMatrix [.001 0 0 .001 0 0] def + /FontBBox [0 0 1000 1000] def + /Encoding KanjiSubEncoding def + /CharStrings 150 dict def + /PaintType 0 def + /Private 2 dict def + Private begin + /BlueValues [] def + /password 5839 def + end +FontName currentdict end definefont +} def + +/T0NF % T0NF +{ +20 dict begin + /FontName exch def + /FDepVector exch def + /FontType 0 def + /FontMatrix [1 0 0 1 0 0] def + /FMapType 2 def + /Encoding KanjiEncoding def +FontName currentdict end definefont +} def + +% Define the composite font and all the base fonts. + +/CompNF % CompNF +{ +/newname1 exch def +newname1 dup length string cvs /str exch def +str length /len exch def +/fdepvector 78 array def +/j 1 def +16#21 1 16#74 { +/i exch def +KanjiEncoding i get 0 gt { +len 4 add string /newstr exch def +newstr 0 str putinterval +newstr len (.r) putinterval +newstr len 2 add i 16 2 string cvrs putinterval +newstr cvn /newlit exch def +newlit T1NF /newfont exch def +fdepvector j newfont put +/j j 1 add def +} if +} for +fdepvector 0 fdepvector 1 get put +/j 0 def +fdepvector newname1 T0NF +} def + +% Define an individual character in a composite font. +/CompD % <(HL)> CompD - + { currentfont /Encoding get 1 index 0 get get % FDepVector index + currentfont /FDepVector get exch get % base font + dup /Encoding get 3 -1 roll 1 get get % base font character name + exch /CharStrings get exch 3 -1 roll put + } bind def + +exec diff --git a/pstoraster/gs_ksb_e.ps b/pstoraster/gs_ksb_e.ps new file mode 100644 index 0000000000..e418ea3aa8 --- /dev/null +++ b/pstoraster/gs_ksb_e.ps @@ -0,0 +1,72 @@ +% Copyright (C) 1994 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_ksb_e.ps 956 2000-03-08 23:15:43Z mike $ +% Define the KanjiSub encoding vector. +/currentglobal where + { pop currentglobal { setglobal } true setglobal } + { { } } +ifelse +/KanjiSubEncoding +%\x00 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%\x20 + /.notdef /c21 /c22 /c23 /c24 /c25 /c26 /c27 + /c28 /c29 /c2A /c2B /c2C /c2D /c2E /c2F + /c30 /c31 /c32 /c33 /c34 /c35 /c36 /c37 + /c38 /c39 /c3A /c3B /c3C /c3D /c3E /c3F +%\x40 + /c40 /c41 /c42 /c43 /c44 /c45 /c46 /c47 + /c48 /c49 /c4A /c4B /c4C /c4D /c4E /c4F + /c50 /c51 /c52 /c53 /c54 /c55 /c56 /c57 + /c58 /c59 /c5A /c5B /c5C /c5D /c5E /c5F +%\x60 + /c60 /c61 /c62 /c63 /c64 /c65 /c66 /c67 + /c68 /c69 /c6A /c6B /c6C /c6D /c6E /c6F + /c70 /c71 /c72 /c73 /c74 /c75 /c76 /c77 + /c78 /c79 /c7A /c7B /c7C /c7D /c7E /.notdef +%\x80 + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef + /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef +%\xA0 + /.notdef /c21 /c22 /c23 /c24 /c25 /c26 /c27 + /c28 /c29 /c2A /c2B /c2C /c2D /c2E /c2F + /c30 /c31 /c32 /c33 /c34 /c35 /c36 /c37 + /c38 /c39 /c3A /c3B /c3C /c3D /c3E /c3F +%\xC0 + /c40 /c41 /c42 /c43 /c44 /c45 /c46 /c47 + /c48 /c49 /c4A /c4B /c4C /c4D /c4E /c4F + /c50 /c51 /c52 /c53 /c54 /c55 /c56 /c57 + /c58 /c59 /c5A /c5B /c5C /c5D /c5E /c5F +%\xE0 + /c60 /c61 /c62 /c63 /c64 /c65 /c66 /c67 + /c68 /c69 /c6A /c6B /c6C /c6D /c6E /c6F + /c70 /c71 /c72 /c73 /c74 /c75 /c76 /c77 + /c78 /c79 /c7A /c7B /c7C /c7D /c7E /.notdef +256 packedarray .defineencoding +exec diff --git a/pstoraster/gs_lev2.ps b/pstoraster/gs_lev2.ps new file mode 100644 index 0000000000..94c490f8db --- /dev/null +++ b/pstoraster/gs_lev2.ps @@ -0,0 +1,717 @@ +% Copyright (C) 1990, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_lev2.ps 956 2000-03-08 23:15:43Z mike $ +% Initialization file for Level 2 functions. +% When this is run, systemdict is still writable, +% but (almost) everything defined here goes into level2dict. + +level2dict begin + +% ------ System and user parameters ------ % + +% User parameters must obey save/restore, and must also be maintained +% per-context. We implement the former, and some of the latter, here +% with PostScript code. NOTE: our implementation assumes that user +% parameters change only as a result of setuserparams -- that there are +% no user parameters that are ever changed dynamically by the interpreter +% (although the interpreter may adjust the value presented to setuserparams) +% +% There are two types of user parameters: those which are actually +% maintained in the interpreter, and those which exist only at the +% PostScript level. We maintain the current state of both types in +% a read-only local dictionary named userparams, defined in systemdict. +% In a multi-context system, each context has its own copy of this +% dictionary. In addition, there is a constant dictionary named +% psuserparams whose keys are the names of user parameters that exist +% only in PostScript and whose values are (currently) arbitrary values +% of the correct datatype: setuserparams uses this for type checking. +% setuserparams updates userparams explicitly, in addition to setting +% any user parameters in the interpreter; thus we can use userparams +% to reset those parameters after a restore or a context switch. +% NOTE: the name userparams is known to the interpreter, and in fact +% the interpreter creates the userparams dictionary. + +% Check parameters that are managed at the PostScript level. +% Currently we allow resetting them iff the new value is of the same type. +/.checksetparams { % + % .checksetparams + 2 index { + % Stack: newdict opname checkdict key newvalue + 3 copy pop .knownget + { type 1 index type ne + { pop pop pop load /typecheck signalerror } + if + dup type /stringtype eq + { dup rcheck not + { pop pop pop load /invalidaccess signalerror } + if + } + if + } + if pop pop + } forall pop pop +} .bind def % not odef, shouldn't reset stacks + +% currentuser/systemparams creates and returns a dictionary in the +% current VM. The easiest way to make this work is to copy any composite +% PostScript-level parameters to global VM. Currently, the only such +% parameters are strings. In fact, we always copy string parameters, +% so that we can be sure the contents won't be changed. +/.copyparam { % .copyparam + dup type /stringtype eq { + .currentglobal true .setglobal + 1 index length string exch .setglobal + copy readonly + } if +} .bind def + +% Some user parameters are managed entirely at the PostScript level. +% We take care of that here. +systemdict begin +/psuserparams 40 dict def +/getuserparam { % getuserparam + /userparams .systemvar 1 index get exch pop +} odef +% Fill in userparams (created by the interpreter) with current values. +mark .currentuserparams +counttomark 2 idiv { + userparams 3 1 roll put +} repeat pop +/.definepsuserparam { % .definepsuserparam - + psuserparams 3 copy pop put + userparams 3 1 roll put +} .bind def +end +/currentuserparams { % - currentuserparams + /userparams .systemvar dup length dict .copydict +} odef +/setuserparams { % setuserparams - + % Check that we will be able to set the PostScript-level + % user parameters. + /setuserparams /psuserparams .systemvar .checksetparams + % Set the C-level user params. If this succeeds, we know that + % the password check succeeded. + dup .setuserparams + % Now set the PostScript-level params. + % The interpreter may have adjusted the values of some of the + % parameters, so we have to read them back. + dup { + /userparams .systemvar 2 index known { + psuserparams 2 index known not { + pop dup .getuserparam + } if + .copyparam + /userparams .systemvar 3 1 roll .forceput % userparams is read-only + } { + pop pop + } ifelse + } forall + % A context switch might have occurred during the above loop, + % causing the interpreter-level parameters to be reset. + % Set them again to the new values. From here on, we are safe, + % since a context switch will consult userparams. + .setuserparams +} .bind odef +% Initialize user parameters managed here. +/JobName () .definepsuserparam + +% Restore must restore the user parameters. +% (Since userparams is in local VM, save takes care of saving them.) +/restore { % restore - + restore /userparams .systemvar .setuserparams +} .bind odef + +% The pssystemparams dictionary holds some system parameters that +% are managed entirely at the PostScript level. +systemdict begin +currentdict /pssystemparams known not { + /pssystemparams 40 dict readonly def +} if +/getsystemparam { % getsystemparam + //pssystemparams 1 index .knownget { exch pop } { .getsystemparam } ifelse +} odef +end +/currentsystemparams { % - currentsystemparams + mark .currentsystemparams //pssystemparams { } forall .dicttomark +} odef +/setsystemparams { % setsystemparams - + % Check that we will be able to set the PostScript-level + % system parameters. + /setsystemparams //pssystemparams .checksetparams + % Set the C-level system params. If this succeeds, we know that + % the password check succeeded. + dup .setsystemparams + % Now set the PostScript-level params. We must copy local strings + % into global VM. + dup + { //pssystemparams 2 index known + { % Stack: key newvalue + .copyparam + //pssystemparams 3 1 roll .forceput % pssystemparams is read-only + } + { pop pop + } + ifelse + } + forall pop +} .bind odef + +% Initialize the passwords. +% NOTE: the names StartJobPassword and SystemParamsPassword are known to +% the interpreter, and must be bound to noaccess strings. +% The length of these strings must be max_password (iutil2.h) + 1. +/StartJobPassword 65 string noaccess def +/SystemParamsPassword 65 string noaccess def + +% Redefine cache parameter setting to interact properly with userparams. +/setcachelimit { + mark /MaxFontItem 2 index .dicttomark setuserparams pop +} .bind odef +/setcacheparams { + % The MaxFontCache parameter is a system parameter, which we might + % not be able to set. Fortunately, this doesn't matter, because + % system parameters don't have to be synchronized between this code + % and the VM. + counttomark 1 add copy setcacheparams + currentcacheparams % mark size lower upper + 3 -1 roll pop + /MinFontCompress 3 1 roll + /MaxFontItem exch + .dicttomark setuserparams + cleartomark +} .bind odef + +% Add bogus user and system parameters to satisfy badly written PostScript +% programs that incorrectly assume the existence of all the parameters +% listed in Appendix C of the Red Book. Note that some of these may become +% real parameters later: code near the end of gs_init.ps takes care of +% removing any such parameters from ps{user,system}params. + +psuserparams begin + /MaxFormItem 100000 def + /MaxPatternItem 20000 def + /MaxScreenItem 48000 def + /MaxUPathItem 5000 def +end + +pssystemparams begin + /CurDisplayList 0 .forcedef + /CurFormCache 0 .forcedef + /CurOutlineCache 0 .forcedef + /CurPatternCache 0 .forcedef + /CurUPathCache 0 .forcedef + /CurScreenStorage 0 .forcedef + /CurSourceList 0 .forcedef + /DoPrintErrors false .forcedef + /MaxDisplayList 140000 .forcedef + /MaxFormCache 100000 .forcedef + /MaxOutlineCache 65000 .forcedef + /MaxPatternCache 100000 .forcedef + /MaxUPathCache 300000 .forcedef + /MaxScreenStorage 84000 .forcedef + /MaxSourceList 25000 .forcedef + /RamSize 4194304 .forcedef +end + +% ------ Miscellaneous ------ % + +(<<) cvn % - << -mark- + /mark load def +(>>) cvn % -mark- ... >> + /.dicttomark load def +/languagelevel 2 def +% When running in Level 2 mode, this interpreter is supposed to be +% compatible with Adobe version 2017. +/version (2017) readonly def + +% If binary tokens are supported by this interpreter, +% set an appropriate default binary object format. +/setobjectformat where + { pop + /RealFormat getsystemparam (IEEE) eq { 1 } { 3 } ifelse + /ByteOrder getsystemparam { 1 add } if + setobjectformat + } if + +% ------ Virtual memory ------ % + +/currentglobal % - currentglobal + /currentshared load def +/gcheck % gcheck + /scheck load def +/setglobal % setglobal - + /setshared load def +% We can make the global dictionaries very small, because they auto-expand. +/globaldict currentdict /shareddict .knownget not { 4 dict } if def +/GlobalFontDirectory SharedFontDirectory def + +% VMReclaim and VMThreshold are user parameters. +/setvmthreshold { % setvmthreshold - + mark /VMThreshold 2 index .dicttomark setuserparams pop +} odef +/vmreclaim { % vmreclaim - + dup 0 gt { + .vmreclaim + } { + mark /VMReclaim 2 index .dicttomark setuserparams pop + } ifelse +} odef +-1 setvmthreshold + +% ------ IODevices ------ % + +/.getdevparams where { + pop /currentdevparams { % currentdevparams + .getdevparams .dicttomark + } odef +} if +/.putdevparams where { + pop /setdevparams { % setdevparams - + mark 1 index { } forall counttomark 2 add index + .putdevparams pop pop + } odef +} if + +% ------ Job control ------ % + +serverdict begin + +% We could protect the job information better, but we aren't attempting +% (currently) to protect ourselves against maliciousness. + +/.jobsave null def % top-level save object +/.jobsavelevel 0 def % save depth of job (0 if .jobsave is null, + % 1 otherwise) +/.adminjob true def % status of current unencapsulated job + +end % serverdict + +% Because there may be objects on the e-stack created since the job save, +% we have to clear the e-stack before doing the end-of-job restore. +% We do this by executing a 2 .stop, which is caught by the 2 .stopped +% in .runexec; we leave on the o-stack a procedure to execute aftewards. +% +%**************** The definition of startjob is not complete yet, since +% it doesn't reset stdin/stdout. +/.startnewjob { % + % .startnewjob - + serverdict /.jobsave get dup null eq { pop } { restore } ifelse + exch { + % Unencapsulated job + serverdict /.jobsave null put + serverdict /.jobsavelevel 0 put + serverdict /.adminjob 3 -1 roll 1 gt put + % The Adobe documentation doesn't say what happens to the + % graphics state stack in this case, but an experiment + % produced results suggesting that a grestoreall occurs. + grestoreall + } { + % Encapsulated job + pop + serverdict /.jobsave save put + serverdict /.jobsavelevel 1 put + .userdict /quit /stop load put + } ifelse + % Reset the interpreter state. + clear cleardictstack + initgraphics + false setglobal +} bind def +/.startjob { % + % .startjob + vmstatus pop pop serverdict /.jobsavelevel get eq + 2 index .checkpassword 0 gt and { + exch .checkpassword exch count 3 roll count 3 sub { pop } repeat + cleardictstack + % Reset the e-stack back to the 2 .stopped in .runexec, + % passing the finish_proc to be executed afterwards. + 2 .stop + } { % Password check failed + pop pop pop false + } ifelse +} odef +/startjob { % startjob + { .startnewjob true } .startjob +} odef + +systemdict begin +/quit { % - quit - + //systemdict begin serverdict /.jobsave get null eq + { end //quit } + { /quit load /invalidaccess /signalerror load end exec } + ifelse +} bind odef +end + +% We would like to define exitserver as a procedure, using the code +% that the Red Book says is equivalent to it. However, since startjob +% resets the exec stack, we can't do this, because control would never +% proceed past the call on startjob if the exitserver is successful. +% Instead, we need to construct exitserver out of pieces of startjob. + +serverdict begin + +/exitserver { % exitserver - + true exch { .startnewjob } .startjob not { + /exitserver /invalidaccess signalerror + } if +} bind def + +end % serverdict + +% ------ Compatibility ------ % + +% In Level 2 mode, the following replace the definitions that gs_statd.ps +% installs in statusdict and serverdict. +% Note that statusdict must be allocated in local VM. +% We don't bother with many of these yet. + +/.dict1 { exch mark 3 1 roll .dicttomark } bind def + +currentglobal false setglobal 25 dict exch setglobal begin +currentsystemparams + +% The following do not depend on the presence of setpagedevice. +/buildtime 1 index /BuildTime get def +/byteorder 1 index /ByteOrder get def +/checkpassword { .checkpassword 0 gt } bind def +dup /DoStartPage known + { /dostartpage { /DoStartPage getsystemparam } bind def + /setdostartpage { /DoStartPage .dict1 setsystemparams } bind def + } if +dup /StartupMode known + { /dosysstart { /StartupMode getsystemparam 0 ne } bind def + /setdosysstart { { 1 } { 0 } ifelse /StartupMode .dict1 setsystemparams } bind def + } if +%****** Setting jobname is supposed to set userparams.JobName, too. +/jobname { /JobName getuserparam } bind def +/jobtimeout { /JobTimeout getuserparam } bind def +/ramsize { /RamSize getsystemparam } bind def +/realformat 1 index /RealFormat get def +dup /PrinterName known + { /setprintername { /PrinterName .dict1 setsystemparams } bind def + } if +/printername + { currentsystemparams /PrinterName .knownget not { () } if exch copy + } bind def +currentuserparams /WaitTimeout known + { /waittimeout { /WaitTimeout getuserparam } bind def + } if + +% The following do require setpagedevice. +/.setpagedevice where { pop } { (%END PAGEDEVICE) .skipeof } ifelse +/defaulttimeouts + { currentsystemparams dup + /JobTimeout .knownget not { 0 } if + exch /WaitTimeout .knownget not { 0 } if + currentpagedevice /ManualFeedTimeout .knownget not { 0 } if + } bind def +/margins + { currentpagedevice /Margins .knownget { exch } { [0 0] } ifelse + } bind def +/pagemargin + { currentpagedevice /PageOffset .knownget { 0 get } { 0 } ifelse + } bind def +/pageparams + { currentpagedevice + dup /Orientation .knownget { 1 and ORIENT1 { 1 xor } if } { 0 } ifelse exch + dup /PageSize get aload pop 3 index 0 ne { exch } if 3 2 roll + /PageOffset .knownget { 0 get } { 0 } ifelse 4 -1 roll + } bind def +/setdefaulttimeouts + { exch mark /ManualFeedTimeout 3 -1 roll + /Policies mark /ManualFeedTimeout 1 .dicttomark + .dicttomark setpagedevice + /WaitTimeout exch mark /JobTimeout 5 2 roll .dicttomark setsystemparams + } bind def +/.setpagesize { 2 array astore /PageSize .dict1 setpagedevice } bind def +/setduplexmode { /Duplex .dict1 setpagedevice } bind def +/setmargins + { exch 2 array astore /Margins .dict1 setpagedevice + } bind def +/setpagemargin { 0 2 array astore /PageOffset .dict1 setpagedevice } bind def +/setpageparams + { mark /PageSize 6 -2 roll + 4 index 1 and ORIENT1 { 1 } { 0 } ifelse ne { exch } if 2 array astore + /Orientation 5 -1 roll ORIENT1 { 1 xor } if + /PageOffset counttomark 2 add -1 roll 0 2 array astore + .dicttomark setpagedevice + } bind def +/setresolution + { dup 2 array astore /HWResolution .dict1 setpagedevice + } bind def +%END PAGEDEVICE + +% The following are not implemented yet. +%manualfeed +%manualfeedtimeout +%pagecount +%pagestackorder +%setpagestackorder + +pop % currentsystemparams + +% Flag the current dictionary so it will be swapped when we +% change language levels. (See zmisc2.c for more information.) +/statusdict currentdict def + +currentdict end +/statusdict exch .forcedef % statusdict is local, systemdict is global + +% ------ Color spaces ------ % + +% Define the setcolorspace procedures: +% proc +/colorspacedict mark + /DeviceGray { pop 0 setgray null } bind + /DeviceRGB { pop 0 0 0 setrgbcolor null } bind + /setcmykcolor where + { pop /DeviceCMYK { pop 0 0 0 1 setcmykcolor null } bind + } if + /.setcieaspace where + { pop /CIEBasedA { NOCIE { pop 0 setgray null } { dup 1 get .setcieaspace } ifelse } bind + } if + /.setcieabcspace where + { pop /CIEBasedABC { NOCIE { pop 0 0 0 setrgbcolor null } { dup 1 get .setcieabcspace } ifelse } bind + } if + /.setciedefspace where + { pop /CIEBasedDEF { NOCIE { pop 0 0 0 setrgbcolor null } { dup 1 get .setciedefspace } ifelse } bind + } if + /.setciedefgspace where + { pop /CIEBasedDEFG { NOCIE { pop 0 0 0 1 setcmykcolor null } { dup 1 get .setciedefgspace } ifelse } bind + } if + /.setseparationspace where + { pop /Separation { dup 2 get setcolorspace dup .setseparationspace } bind + } if + /.setindexedspace where + { pop /Indexed { dup 1 get setcolorspace dup .setindexedspace } bind + } if + /.nullpatternspace [/Pattern] readonly def + /.setpatternspace where + { pop /Pattern + { dup type /nametype eq { pop //.nullpatternspace } if + dup length 1 gt { dup 1 get setcolorspace } if + dup .setpatternspace + } bind + } if + /.setdevicenspace where + { pop /DeviceN { dup 2 get setcolorspace dup .setdevicenspace } bind + } if + /.setdevicepixelspace where + { pop /DevicePixel { dup .setdevicepixelspace } bind + } if + currentdict /.nullpatternspace .undef +.dicttomark def + +/.devcs [ + /DeviceGray /DeviceRGB /DeviceCMYK /DevicePixel +] readonly def +/currentcolorspace { % - currentcolorspace + .currentcolorspace dup type /integertype eq { + //.devcs exch 1 getinterval + } if +} odef +currentdict /.devcs .undef + +/setcolorspace { % setcolorspace - + dup dup dup type /nametype ne { 0 get } if + //colorspacedict exch get exec + dup null eq { pop } { .setcolorspace } ifelse pop +} odef + +% ------ CIE color rendering ------ % + +% Define findcolorrendering and a default ColorRendering ProcSet. + +/findcolorrendering { % findcolorrendering + % + /ColorRendering /ProcSet findresource + 1 index .namestring (.) concatstrings + 1 index /GetPageDeviceName get exec .namestring (.) concatstrings + 2 index /GetHalftoneName get exec .namestring + concatstrings concatstrings + dup /ColorRendering resourcestatus { + pop pop exch pop exch pop true + } { + pop /GetSubstituteCRD get exec false + } ifelse +} odef + +5 dict dup begin + +/GetPageDeviceName { % - GetPageDeviceName + currentpagedevice dup /PageDeviceName .knownget { + exch pop + } { + pop /none + } ifelse +} bind def + +/GetHalftoneName { % - GetHalftoneName + currenthalftone /HalftoneName .knownget not { /none } if +} bind def + +/GetSubstituteCRD { % GetSubstituteCRD + pop /DefaultColorRendering +} bind def + +end +% The resource machinery hasn't been activated, so just save the ProcSet +% and let .fixresources finish the installation process. +/ColorRendering exch def + +% Define setcolorrendering. + +/.colorrenderingtypes 5 dict def + +/setcolorrendering { % setcolorrendering - + dup /ColorRenderingType get //.colorrenderingtypes exch get exec +} odef + +/.setcolorrendering1 where { pop } { (%END CRD) .skipeof } ifelse + +.colorrenderingtypes 1 { + dup .buildcolorrendering1 .setcolorrendering1 +} .bind put + +% Initialize the default CIE rendering dictionary. +% The most common CIE files seem to assume the "calibrated RGB color space" +% described on p. 189 of the PostScript Language Reference Manual, +% 2nd Edition; we simply invert this transformation back to RGB. +mark + /ColorRenderingType 1 +% We must make RangePQR and RangeLMN large enough so that values computed by +% the assumed encoding MatrixLMN don't get clamped. + /RangePQR [0 0.9505 0 1 0 1.0890] readonly + /TransformPQR + [ {exch pop exch pop exch pop exch pop} bind dup dup ] readonly + /RangeLMN [0 0.9505 0 1 0 1.0890] readonly + /MatrixABC + [ 3.24063 -0.96893 0.05571 + -1.53721 1.87576 -0.20402 + -0.49863 0.04152 1.05700 + ] readonly + /EncodeABC [ {0 .max 0.45 exp} bind dup dup] readonly + /WhitePoint [0.9505 1 1.0890] readonly + % Some Genoa tests seem to require the presence of BlackPoint. + /BlackPoint [0 0 0] readonly +.dicttomark setcolorrendering + +%END CRD + +% Initialize a CIEBased color space for sRGB. +/CIEsRGB [ /CIEBasedABC + mark + /DecodeLMN [ { + dup 0.03928 le { 12.92321 div } { 0.055 add 1.055 div 2.4 exp } ifelse + } bind dup dup ] readonly + /MatrixLMN [ + 0.412457 0.212673 0.019334 + 0.357576 0.715152 0.119192 + 0.180437 0.072175 0.950301 + ] readonly + /WhitePoint [0.9505 1.0 1.0890] readonly + .dicttomark readonly +] readonly def + +% ------ Painting ------ % + +% A straightforward definition of execform that doesn't actually +% do any caching. +/.execform1 { + % This is a separate operator so that the stacks will be restored + % properly if an error occurs. + dup /Matrix get concat + dup /BBox get aload pop + exch 3 index sub exch 2 index sub rectclip + dup /PaintProc get + 1 index /Implementation known not { + 1 index dup /Implementation null .forceput readonly pop + } if + exec +} .bind odef % must bind .forceput + +/.formtypes 5 dict + dup 1 /.execform1 load put +def + +/execform { %
execform - + gsave { + dup /FormType get //.formtypes exch get exec + } stopped grestore { stop } if +} odef + +/.patterntypes 5 dict + dup 1 /.buildpattern1 load put +def + +/makepattern { % makepattern + //.patterntypes 2 index /PatternType get get + .currentglobal false .setglobal exch + % Stack: proto matrix global buildproc + 3 index dup length 1 add dict .copydict + 3 index 3 -1 roll exec 3 -1 roll .setglobal + 1 index /Implementation 3 -1 roll put + readonly exch pop exch pop +} odef + +/setpattern { % [ ...] setpattern - + currentcolorspace 0 get /Pattern ne { + [ /Pattern currentcolorspace ] setcolorspace + } if setcolor +} odef + +% Extend image and imagemask to accept dictionaries. +% We must create .imagetypes and .imagemasktypes outside level2dict, +% and leave some extra space because we're still in Level 1 mode. +systemdict begin +/.imagetypes 5 dict + dup 1 /.image1 load put +def +/.imagemasktypes 5 dict + dup 1 /.imagemask1 load put +def +end + +/.image /image load def +/image { + dup type /dicttype eq { + dup /ImageType get //.imagetypes exch get exec + } { + //.image + } ifelse +} odef +currentdict /.image undef + +/.imagemask /imagemask load def +/imagemask { + dup type /dicttype eq { + dup /ImageType get //.imagemasktypes exch get exec + } { + //.imagemask + } ifelse +} odef +currentdict /.imagemask undef + +end % level2dict diff --git a/pstoraster/gs_ll3.ps b/pstoraster/gs_ll3.ps new file mode 100644 index 0000000000..acf701ec67 --- /dev/null +++ b/pstoraster/gs_ll3.ps @@ -0,0 +1,387 @@ +% Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_ll3.ps 956 2000-03-08 23:15:43Z mike $ +% Initialization file for PostScript LanguageLevel 3 functions. +% Essentially all of these are stubs right now. +% This file must be loaded after gs_lev2.ps and gs_res.ps. +% These definitions go into ll3dict or various ProcSets. +% NOTE: the interpreter creates ll3dict. + +ll3dict begin + +% We need LanguageLevel 2 or higher in order to have setuserparams and +% defineresource. +languagelevel dup 2 max .setlanguagelevel + +% ------ Idiom recognition ------ % + +/IdiomRecognition false .definepsuserparam + +% Modify `bind' to apply idiom recognition afterwards. +/.bindscratch 128 string def +% Do the right thing if NOBIND or DELAYBIND is in effect. +% Note also that since this definition of `bind' may get bound in, +% it has to function properly even at lower language levels, +% where IdiomRecognition may not be defined. +/bind load /.bind load ne +/bind { % bind + //.bind currentuserparams /IdiomRecognition + .knownget not { false } if { + (*) { + /IdiomSet findresource + false exch { + % Stack: proc false dummykey [template substitute] + exch pop dup 1 get exch 0 get + % Stack: proc false substitute template + 3 index .eqproc { + 2 index gcheck 1 index gcheck not and { + pop + } { + 3 -1 roll pop exch not exit + } ifelse + } { + pop + } ifelse + } forall { exit } if + } //.bindscratch /IdiomSet resourceforall + } if +} odef +{ /.bind /bind load def + /bind { } def +} if +currentdict /.bindscratch .undef + +% ------ HalftoneTypes 6, 10, 16 ------ % + +% This code depends on one new operator: +% +% .setstriphalftone - +% +% is the dictionary that will be returned by .currenthalftone. +% The operator only looks at the TransferFunction entry. +% Width, Height: as for HalftoneType 3. +% Thresholds: a BigStringEncode filter holding the thresholds, +% Width x Height x BitsPerSample / 8 bytes. +% shift: the amount of X shift per Y repetition of the halftone, +% 0 <= Shift < Width. +% bits: bits per sample, 8 or 16. +% +% Eventually the code below will have to get hooked up to sethalftone +% and currenthalftone.... + +/.copybytes { % .copybytes - + { 1 index read not { /sethalftone load /rangecheck signalerror exit } if + 1 index exch write + } repeat pop pop +} bind def + +/.copythresholds { % .copythresholds - + dup 8 idiv 3 index mul 2 index mul + dup /BigStringEncode filter 3 1 roll + % Stack: dict width height dest bits nbytes + 5 index /Thresholds get 3 index 3 -1 roll .copybytes + 1 index closefile + 0 .setstriphalftone +} bind def + +/.sethalftone6 { % .sethalftone6 - + % Keys: Width, Height, Thresholds, T'Function + dup /Width get 1 index /Height get + 8 .copythresholds +} odef + +/.copythresholds2 { % + % .copythresholds2 - +% The block height B is gcd(Height, Height2). + 3 index 2 index { + 2 copy lt { exch } if dup 1 eq { pop exit } if exch 1 index mod + } loop +% The raster R is (Width * Height + Width2 * Height2) / B * bits/8. + 5 index 5 index mul 4 index 4 index mul add 1 index idiv + 2 index 8 idiv mul +% Currently I don't know how to compute the stride. +% ****** COMPUTE THE STRIDE SOMEHOW ****** +% Push additional arguments onto the stack. + 1 index 1 index mul /BigStringEncode filter 4 1 roll + 9 index /Thresholds get + % Stack: dict width height width2 height2 bits + % dest B R stride source +% For the first rectangle, the number of blocks is Height / B; +% the offset is 0. + 5 copy 14 index 5 1 roll + 14 index 5 index idiv 4 1 roll + 0 exch .copyshifted +% For the second rectangle, the number of blocks is Height2 / B; +% the offset is Width. + 5 copy 12 index 5 1 roll + 12 index 4 index idiv 4 1 roll + 16 index exch .copyshifted + % Stack: dict width height width2 height2 bits + % dest B R stride source + % We want: dict R/(bits/8) B dest bits stride + pop exch 4 index 8 idiv idiv 4 1 roll + % R/(bits/8) dest B stride + exch 3 1 roll 5 -1 roll exch + 9 -4 roll 4 { pop } repeat + .setstriphalftone +} bind def + +% Copy a shifted rectangular threshold array into a BigStringEncode filter. +% Note that the width and shift are in bytes, not samples. +/.copyshifted { % + % .copyshifted - +% Copy N blocks of x B bytes from . +% Row Y (0 <= Y < B) in group G (0 <= G < N) must get copied to byte position +% Y * R + (G * stride + offset) mod R +% in the destination. + 1 index % Stack: ... rowstart + 6 index { % iterate over rows within a block + 5 index { % iterate over blocks + 8 index 1 index setfileposition + 1 index 9 index 9 index .copybytes + 4 index add % + raster + } repeat % end block + 3 index add 4 index mod % + stride, mod raster + } repeat % end row in block + 9 { pop } repeat +} bind def + +/.sethalftone10 { % .sethalftone10 - + % Keys: XSquare, YSquare, Thresholds, T'Function +% ****** DOESN'T HANDLE STRING SOURCE ****** + dup /XSquare get dup 2 index /YSquare get dup + 8 .copythresholds2 +} odef + +/.sethalftone16 { % .sethalftone16 - + % Keys: Width, Height, Width2, Height2, + % Thresholds, T'Function + dup /Width get 1 index /Height get + 2 index /Width2 .knownget { % 2-rectangle case + 3 index /Height2 get + 16 .copythresholds2 + } { % 1-rectangle case + 16 .copythresholds + } ifelse +} odef + +{6 10 16} { dup /HalftoneType defineresource pop } forall + +% ------ ImageTypes 3 and 4 (masked images) ------ % + +.imagetypes + dup 3 /.image3 load put + 4 /.image4 load put + +% ------ Functions ------ % + +% Define the FunctionType resource category. +/Generic /Category findresource dup maxlength 3 add dict .copydict begin + /InstanceType /integertype def +/FunctionType currentdict end /Category defineresource pop + +{0 2 3} { dup /FunctionType defineresource pop } forall + +% ------ Smooth shading ------ % + +% Define the ShadingType resource category. +/Generic /Category findresource dup maxlength 3 add dict .copydict begin + /InstanceType /integertype def +/ShadingType currentdict end /Category defineresource pop + +systemdict /.shadingtypes mark % not ll3dict + 1 /.buildshading1 load + 2 /.buildshading2 load + 3 /.buildshading3 load + 4 /.buildshading4 load + 5 /.buildshading5 load + 6 /.buildshading6 load + 7 /.buildshading7 load +.dicttomark put + +/.buildshading { % .buildshading + % The .buildshading operators use the current color space + % for ColorSpace. + dup /ShadingType get //.shadingtypes exch get + 1 index /ColorSpace get gsave { setcolorspace exec } stopped + grestore { stop } if +} bind def +/.buildpattern2 { %

is NULL, calls malloc instead of realloc(). + */ +extern void *grealloc(void *p, int size); + +/* + * Same as free, but checks for and ignores NULL pointers. + */ +extern void gfree(void *p); + +#ifdef DEBUG_MEM +/* + * Report on unfreed memory. + */ +extern void gMemReport(FILE *f); +#else +#define gMemReport(f) +#endif + +/* + * Allocate memory and copy a string into it. + */ +extern char *copyString(char *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pdftops/gmempp.cxx b/pdftops/gmempp.cxx new file mode 100644 index 0000000000..41dd441cd0 --- /dev/null +++ b/pdftops/gmempp.cxx @@ -0,0 +1,23 @@ +//======================================================================== +// +// gmempp.cc +// +// Use gmalloc/gfree for C++ new/delete operators. +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#include "gmem.h" + +#ifdef DEBUG_MEM +void *operator new(long size) { + return gmalloc((int)size); +} +#endif + +#ifdef DEBUG_MEM +void operator delete(void *p) { + gfree(p); +} +#endif diff --git a/pdftops/gtypes.h b/pdftops/gtypes.h new file mode 100644 index 0000000000..6593267414 --- /dev/null +++ b/pdftops/gtypes.h @@ -0,0 +1,29 @@ +/* + * gtypes.h + * + * Some useful simple types. + * + * Copyright 1996 Derek B. Noonburg + */ + +#ifndef GTYPES_H +#define GTYPES_H + +/* + * These have stupid names to avoid conflicts with some (but not all) + * C++ compilers which define them. + */ +typedef int GBool; +#define gTrue 1 +#define gFalse 0 + +/* + * These have stupid names to avoid conflicts with , + * which on various systems defines some random subset of these. + */ +typedef unsigned char Guchar; +typedef unsigned short Gushort; +typedef unsigned int Guint; +typedef unsigned long Gulong; + +#endif diff --git a/pdftops/parseargs.c b/pdftops/parseargs.c new file mode 100644 index 0000000000..ceba887796 --- /dev/null +++ b/pdftops/parseargs.c @@ -0,0 +1,190 @@ +/* + * parseargs.h + * + * Command line argument parser. + * + * Copyright 1996 Derek B. Noonburg + */ + +#include +#include +#include +#include +#include +#include "parseargs.h" + +static ArgDesc *findArg(ArgDesc *args, char *arg); +static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]); + +GBool parseArgs(ArgDesc *args, int *argc, char *argv[]) { + ArgDesc *arg; + int i, j; + GBool ok; + + ok = gTrue; + i = 1; + while (i < *argc) { + if (!strcmp(argv[i], "--")) { + --*argc; + for (j = i; j < *argc; ++j) + argv[j] = argv[j+1]; + break; + } else if ((arg = findArg(args, argv[i]))) { + if (!grabArg(arg, i, argc, argv)) + ok = gFalse; + } else { + ++i; + } + } + return ok; +} + +void printUsage(char *program, char *otherArgs, ArgDesc *args) { + ArgDesc *arg; + char *typ; + int w, w1; + + w = 0; + for (arg = args; arg->arg; ++arg) { + if ((w1 = strlen(arg->arg)) > w) + w = w1; + } + + fprintf(stderr, "Usage: %s [options]", program); + if (otherArgs) + fprintf(stderr, " %s", otherArgs); + fprintf(stderr, "\n"); + + for (arg = args; arg->arg; ++arg) { + fprintf(stderr, " %s", arg->arg); + w1 = 9 + w - strlen(arg->arg); + switch (arg->kind) { + case argInt: + case argIntDummy: + typ = " "; + break; + case argFP: + case argFPDummy: + typ = " "; + break; + case argString: + case argStringDummy: + typ = " "; + break; + case argFlag: + case argFlagDummy: + default: + typ = ""; + break; + } + fprintf(stderr, "%-*s", w1, typ); + if (arg->usage) + fprintf(stderr, ": %s", arg->usage); + fprintf(stderr, "\n"); + } +} + +static ArgDesc *findArg(ArgDesc *args, char *arg) { + ArgDesc *p; + + for (p = args; p->arg; ++p) { + if (p->kind < argFlagDummy && !strcmp(p->arg, arg)) + return p; + } + return NULL; +} + +static GBool grabArg(ArgDesc *arg, int i, int *argc, char *argv[]) { + int n; + int j; + GBool ok; + + ok = gTrue; + n = 0; + switch (arg->kind) { + case argFlag: + *(GBool *)arg->val = gTrue; + n = 1; + break; + case argInt: + if (i + 1 < *argc && isInt(argv[i+1])) { + *(int *)arg->val = atoi(argv[i+1]); + n = 2; + } else { + ok = gFalse; + n = 1; + } + break; + case argFP: + if (i + 1 < *argc && isFP(argv[i+1])) { + *(double *)arg->val = atof(argv[i+1]); + n = 2; + } else { + ok = gFalse; + n = 1; + } + break; + case argString: + if (i + 1 < *argc) { + strncpy((char *)arg->val, argv[i+1], arg->size - 1); + ((char *)arg->val)[arg->size - 1] = '\0'; + n = 2; + } else { + ok = gFalse; + n = 1; + } + break; + default: + fprintf(stderr, "Internal error in arg table\n"); + n = 1; + break; + } + if (n > 0) { + *argc -= n; + for (j = i; j < *argc; ++j) + argv[j] = argv[j+n]; + } + return ok; +} + +GBool isInt(char *s) { + if (*s == '-' || *s == '+') + ++s; + while (isdigit(*s)) + ++s; + if (*s) + return gFalse; + return gTrue; +} + +GBool isFP(char *s) { + int n; + + if (*s == '-' || *s == '+') + ++s; + n = 0; + while (isdigit(*s)) { + ++s; + ++n; + } + if (*s == '.') + ++s; + while (isdigit(*s)) { + ++s; + ++n; + } + if (n > 0 && (*s == 'e' || *s == 'E')) { + ++s; + if (*s == '-' || *s == '+') + ++s; + n = 0; + if (!isdigit(*s)) + return gFalse; + do { + ++s; + } while (isdigit(*s)); + } + if (*s) + return gFalse; + return gTrue; +} diff --git a/pdftops/parseargs.h b/pdftops/parseargs.h new file mode 100644 index 0000000000..e0aa2be33d --- /dev/null +++ b/pdftops/parseargs.h @@ -0,0 +1,71 @@ +/* + * parseargs.h + * + * Command line argument parser. + * + * Copyright 1996 Derek B. Noonburg + */ + +#ifndef PARSEARGS_H +#define PARSEARGS_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include "gtypes.h" + +/* + * Argument kinds. + */ +typedef enum { + argFlag, /* flag (present / not-present) */ + /* [val: GBool *] */ + argInt, /* integer arg */ + /* [val: int *] */ + argFP, /* floating point arg */ + /* [val: double *] */ + argString, /* string arg */ + /* [val: char *] */ + /* dummy entries -- these show up in the usage listing only; */ + /* useful for X args, for example */ + argFlagDummy, + argIntDummy, + argFPDummy, + argStringDummy +} ArgKind; + +/* + * Argument descriptor. + */ +typedef struct { + char *arg; /* the command line switch */ + ArgKind kind; /* kind of arg */ + void *val; /* place to store value */ + int size; /* for argString: size of string */ + char *usage; /* usage string */ +} ArgDesc; + +/* + * Parse command line. Removes all args which are found in the arg + * descriptor list . Stops parsing if "--" is found (and removes + * it). Returns gFalse if there was an error. + */ +extern GBool parseArgs(ArgDesc *args, int *argc, char *argv[]); + +/* + * Print usage message, based on arg descriptor list. + */ +extern void printUsage(char *program, char *otherArgs, ArgDesc *args); + +/* + * Check if a string is a valid integer or floating point number. + */ +extern GBool isInt(char *s); +extern GBool isFP(char *s); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/pdftops/pdftops.cxx b/pdftops/pdftops.cxx new file mode 100644 index 0000000000..56f7d5c459 --- /dev/null +++ b/pdftops/pdftops.cxx @@ -0,0 +1,144 @@ +//======================================================================== +// +// pdftops.cc +// +// Copyright 1996 Derek B. Noonburg +// +//======================================================================== + +#include +#include +#include +#include +#include +#include "parseargs.h" +#include "GString.h" +#include "gmem.h" +#include "Object.h" +#include "Stream.h" +#include "Array.h" +#include "Dict.h" +#include "XRef.h" +#include "Catalog.h" +#include "Page.h" +#include "PDFDoc.h" +#include "PSOutputDev.h" +#include "Params.h" +#include "Error.h" +#include "config.h" +#include + +GBool printCommands = gFalse; + + +int main(int argc, char *argv[]) { + PDFDoc *doc; + GString *fileName; + PSOutputDev *psOut; + int num_options; + cups_option_t *options; + ppd_file_t *ppd; + ppd_size_t *size; + FILE *fp; + char tempfile[1024]; + char buffer[8192]; + int bytes; + + + // Make sure we have the right number of arguments for CUPS! + if (argc < 6 || argc > 7) + { + fputs("Usage: pdftops job user title copies options [filename]\n", stderr); + return (1); + } + + // Copy stdin if needed... + if (argc == 6) + { + if ((fp = fopen(cupsTempFile(tempfile, sizeof(tempfile)), "w")) == NULL) + { + perror("ERROR: Unable to copy PDF file"); + return (1); + } + + fprintf(stderr, "DEBUG: pdftops - copying to temp print file \"%s\"\n", + tempfile); + + while ((bytes = fread(buffer, 1, sizeof(buffer), stdin)) > 0) + fwrite(buffer, 1, bytes, fp); + fclose(fp); + + fileName = new GString(tempfile); + } + else + { + fileName = new GString(argv[6]); + tempfile[0] = '\0'; + } + + // Get PPD and initialize options as needed... + if ((ppd = ppdOpenFile(getenv("PPD"))) != NULL) + { + fprintf(stderr, "DEBUG: pdftops - opened PPD file \"%s\"...\n", getenv("PPD")); + + ppdMarkDefaults(ppd); + num_options = cupsParseOptions(argv[5], 0, &options); + cupsMarkOptions(ppd, num_options, options); + cupsFreeOptions(num_options, options); + + if ((size = ppdPageSize(ppd, NULL)) != NULL) + { + paperWidth = size->width; + paperHeight = size->length; + } + + psOutLevel1 = ppd->language_level == 1; + + fprintf(stderr, "DEBUG: pstops - psOutLevel1 = %d, paperWidth = %d, paperHeight = %d\n", + psOutLevel1, paperWidth, paperHeight); + + ppdClose(ppd); + } + + // init error file + errorInit(); + + // read config file + initParams(CUPS_SERVERROOT "/xpdf.conf"); + + // open PDF file + xref = NULL; + doc = new PDFDoc(fileName); + if (!doc->isOk()) { + goto err1; + } + + // check for print permission + if (!doc->okToPrint()) { + error(-1, "Printing this document is not allowed."); + goto err2; + } + + // write PostScript file + psOut = new PSOutputDev("-", doc->getCatalog(), 1, doc->getNumPages(), 1, 0); + if (psOut->isOk()) + doc->displayPages(psOut, 1, doc->getNumPages(), 72, 0); + + delete psOut; + + // clean up + err2: + delete doc; + err1: + freeParams(); + + // check for memory leaks + Object::memCheck(stderr); + gMemReport(stderr); + + // Remove temp file if needed... + if (tempfile[0]) + unlink(tempfile); + + return 0; +} diff --git a/ppd/Makefile b/ppd/Makefile new file mode 100644 index 0000000000..d72eb0bca8 --- /dev/null +++ b/ppd/Makefile @@ -0,0 +1,56 @@ +# +# "$Id$" +# +# PPD file makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1993-2000 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# + +include ../Makedefs + +# +# PPD files... +# + +FILES = deskjet.ppd laserjet.ppd stcolor.ppd stphoto.ppd + +# +# Make everything... +# + +all: + +# +# Clean all config and object files... +# + +clean: + +# +# Install files... +# + +install: + -$(MKDIR) $(DATADIR)/model + $(CHMOD) ugo+rx $(DATADIR)/model + $(INSTALL_DATA) $(FILES) $(DATADIR)/model + +# +# End of "$Id$". +# diff --git a/ppd/deskjet.ppd b/ppd/deskjet.ppd new file mode 100644 index 0000000000..ae33eead3f --- /dev/null +++ b/ppd/deskjet.ppd @@ -0,0 +1,196 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Sample HP DeskJet driver PPD file for the Common UNIX Printing +*% System (CUPS). +*% +*% Copyright 1997-2000 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Easy Software Products and are protected by Federal +*% copyright law. Distribution and use rights are outlined in the file +*% "LICENSE.txt" which should have been included with this file. If this +*% file is missing or damaged please contact Easy Software Products +*% at: +*% +*% Attn: CUPS Licensing Information +*% Easy Software Products +*% 44141 Airport View Drive, Suite 204 +*% Hollywood, Maryland 20636-3111 USA +*% +*% Voice: (301) 373-9603 +*% EMail: cups-info@cups.org +*% WWW: http://www.cups.org +*% +*FormatVersion: "4.3" +*FileVersion: "1.1" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "DESKJET.PPD" +*Manufacturer: "ESP" +*Product: "(CUPS v1.1)" +*cupsVersion: 1.1 +*cupsManualCopies: True +*cupsFilter: "application/vnd.cups-raster 0 rastertohp" +*ModelName: "HP DeskJet Series" +*ShortNickName: "HP DeskJet Series" +*NickName: "HP DeskJet Series CUPS v1.1" +*PSVersion: "(3010.000) 550" +*LanguageLevel: "3" +*ColorDevice: True +*DefaultColorSpace: RGB +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*VariablePaperSize: False +*TTRasterizer: Type42 + +*UIConstraints: *PageSize Executive *InputSlot Envelope +*UIConstraints: *PageSize Letter *InputSlot Envelope +*UIConstraints: *PageSize Legal *InputSlot Envelope +*UIConstraints: *PageSize Tabloid *InputSlot Envelope +*UIConstraints: *PageSize A3 *InputSlot Envelope +*UIConstraints: *PageSize A4 *InputSlot Envelope +*UIConstraints: *PageSize A5 *InputSlot Envelope +*UIConstraints: *PageSize B5 *InputSlot Envelope +*UIConstraints: *Resolution 600dpi *ColorModel CMYK + +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: Letter +*PageSize Letter/US Letter: "<>setpagedevice" +*PageSize Legal/US Legal: "<>setpagedevice" +*PageSize Executive/US Executive: "<>setpagedevice" +*PageSize Tabloid/US Tabloid: "<>setpagedevice" +*PageSize A3/A3: "<>setpagedevice" +*PageSize A4/A4: "<>setpagedevice" +*PageSize A5/A5: "<>setpagedevice" +*PageSize B5/B5 (JIS): "<>setpagedevice" +*PageSize EnvISOB5/Envelope B5: "<>setpagedevice" +*PageSize Env10/Envelope #10: "<>setpagedevice" +*PageSize EnvC5/Envelope C5: "<>setpagedevice" +*PageSize EnvDL/Envelope DL: "<>setpagedevice" +*PageSize EnvMonarch/Envelope Monarch: "<>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter/US Letter: "<>setpagedevice" +*PageRegion Legal/US Legal: "<>setpagedevice" +*PageRegion Executive/US Executive: "<>setpagedevice" +*PageRegion Tabloid/US Tabloid: "<>setpagedevice" +*PageRegion A3/A3: "<>setpagedevice" +*PageRegion A4/A4: "<>setpagedevice" +*PageRegion A5/A5: "<>setpagedevice" +*PageRegion B5/B5 (JIS): "<>setpagedevice" +*PageRegion EnvISOB5/Envelope B5: "<>setpagedevice" +*PageRegion Env10/Envelope #10: "<>setpagedevice" +*PageRegion EnvC5/Envelope C5: "<>setpagedevice" +*PageRegion EnvDL/Envelope DL: "<>setpagedevice" +*PageRegion EnvMonarch/Envelope Monarch: "<>setpagedevice" +*CloseUI: *PageRegion + +*DefaultImageableArea: Letter +*ImageableArea Letter/US Letter: "18 36 594 756" +*ImageableArea Legal/US Legal: "18 36 594 972" +*ImageableArea Executive/US Executive: "18 36 504 684" +*ImageableArea Tabloid/US Tabloid: "18 36 774 1188" +*ImageableArea A3/A3: "18 36 824 1155" +*ImageableArea A4/A4: "18 36 577 806" +*ImageableArea A5/A5: "18 36 403 559" +*ImageableArea B5/JIS B5: "18 36 498 693" +*ImageableArea EnvISOB5/B5 (ISO): "18 36 463 673" +*ImageableArea Env10/Com-10: "18 36 279 648" +*ImageableArea EnvC5/EnvC5: "18 36 441 613" +*ImageableArea EnvDL/EnvDL: "18 36 294 588" +*ImageableArea EnvMonarch/Envelope Monarch: "18 36 261 504" + +*DefaultPaperDimension: Letter +*PaperDimension Letter/US Letter: "612 792" +*PaperDimension Legal/US Legal: "612 1008" +*PaperDimension Executive/US Executive: "522 756" +*PaperDimension Tabloid/US Tabloid: "792 1224" +*PaperDimension A3/A3: "842 1191" +*PaperDimension A4/A4: "595 842" +*PaperDimension A5/A5: "421 595" +*PaperDimension B5/B5 (JIS): "516 729" +*PaperDimension EnvISOB5/Envelope B5: "499 709" +*PaperDimension Env10/Envelope #10: "297 684" +*PaperDimension EnvC5/Envelope C5: "459 649" +*PaperDimension EnvDL/Envelope DL: "312 624" +*PaperDimension EnvMonarch/Envelope Monarch: "279 540" + +*OpenUI *MediaType/Media Type: PickOne +*OrderDependency: 10 AnySetup *MediaType +*DefaultMediaType: Plain +*MediaType Plain/Plain Paper: "<>setpagedevice" +*MediaType Bond/Bond Paper: "<>setpagedevice" +*MediaType Special/Special Paper: "<>setpagedevice" +*MediaType Transparency/Transparency: "<>setpagedevice" +*MediaType Glossy/Glossy Paper: "<>setpagedevice" +*CloseUI: *MediaType + +*OpenUI *InputSlot/Media Source: PickOne +*OrderDependency: 10 AnySetup *InputSlot +*DefaultInputSlot: Tray +*InputSlot Tray/Tray: "<>setpagedevice" +*InputSlot Manual/Manual Feed: "<>setpagedevice" +*InputSlot Envelope/Envelope Feed: "<>setpagedevice" +*CloseUI: *InputSlot + +*OpenUI *Resolution/Output Resolution: PickOne +*OrderDependency: 20 AnySetup *Resolution +*DefaultResolution: 300dpi +*Resolution 150dpi/150 DPI: "<>setpagedevice" +*Resolution 300dpi/300 DPI: "<>setpagedevice" +*Resolution 600dpi/600 DPI: "<>setpagedevice" +*CloseUI: *Resolution + +*OpenUI *ColorModel/Output Mode: PickOne +*OrderDependency: 10 AnySetup *ColorModel +*DefaultColorModel: CMYK +*ColorModel CMYK/Color: "<>setpagedevice" +*ColorModel Gray/Grayscale: "<>setpagedevice" +*CloseUI: *ColorModel + +*DefaultFont: Courier +*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM +*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM +*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM +*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM +*Font Bookman-Demi: Standard "(001.004S)" Standard ROM +*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM +*Font Bookman-Light: Standard "(001.004S)" Standard ROM +*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM +*Font Courier: Standard "(002.004S)" Standard ROM +*Font Courier-Bold: Standard "(002.004S)" Standard ROM +*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM +*Font Courier-Oblique: Standard "(002.004S)" Standard ROM +*Font Helvetica: Standard "(001.006S)" Standard ROM +*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM +*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM +*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM +*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM +*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM +*Font Palatino-Bold: Standard "(001.005S)" Standard ROM +*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM +*Font Palatino-Italic: Standard "(001.005S)" Standard ROM +*Font Palatino-Roman: Standard "(001.005S)" Standard ROM +*Font Symbol: Special "(001.007S)" Special ROM +*Font Times-Bold: Standard "(001.007S)" Standard ROM +*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM +*Font Times-Italic: Standard "(001.007S)" Standard ROM +*Font Times-Roman: Standard "(001.007S)" Standard ROM +*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM +*Font ZapfDingbats: Special "(001.004S)" Standard ROM +*% +*% End of "$Id$". +*% diff --git a/ppd/epson24.ppd b/ppd/epson24.ppd new file mode 100644 index 0000000000..4024a22d4f --- /dev/null +++ b/ppd/epson24.ppd @@ -0,0 +1,128 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Sample EPSON 24-Pin driver PPD file for the Common UNIX Printing +*% System (CUPS). +*% +*% Copyright 1997-2000 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Easy Software Products and are protected by Federal +*% copyright law. Distribution and use rights are outlined in the file +*% "LICENSE.txt" which should have been included with this file. If this +*% file is missing or damaged please contact Easy Software Products +*% at: +*% +*% Attn: CUPS Licensing Information +*% Easy Software Products +*% 44141 Airport View Drive, Suite 204 +*% Hollywood, Maryland 20636-3111 USA +*% +*% Voice: (301) 373-9603 +*% EMail: cups-info@cups.org +*% WWW: http://www.cups.org +*% +*FormatVersion: "4.3" +*FileVersion: "1.1" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "EPSON24.PPD" +*Manufacturer: "ESP" +*Product: "(CUPS v1.1)" +*cupsVersion: 1.1 +*cupsManualCopies: True +*cupsModelNumber: 1 +*cupsFilter: "application/vnd.cups-raster 0 rastertoepson" +*ModelName: "EPSON 24-Pin Series" +*ShortNickName: "EPSON 24-Pin Series" +*NickName: "EPSON 24-Pin Series CUPS v1.1" +*PSVersion: "(3010.000) 550" +*LanguageLevel: "3" +*ColorDevice: False +*DefaultColorSpace: Gray +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*VariablePaperSize: False +*TTRasterizer: Type42 + +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: Letter +*PageSize Letter: "<>setpagedevice" +*PageSize Legal: "<>setpagedevice" +*PageSize A4: "<>setpagedevice" +*PageSize FanFoldUS: "<>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter: "<>setpagedevice" +*PageRegion Legal: "<>setpagedevice" +*PageRegion A4: "<>setpagedevice" +*PageRegion FanFoldUS: "<>setpagedevice" +*CloseUI: *PageRegion + +*DefaultImageableArea: Letter +*ImageableArea Letter: "18.0 18.0 594.0 774.0" +*ImageableArea Legal: "18.0 18.0 594.0 990.0" +*ImageableArea A4: "18.0 18.0 577.0 824.0" +*ImageableArea FanFoldUS: "18.0 18.0 1053.0 774.0" + +*DefaultPaperDimension: Letter +*PaperDimension Letter: "612 792" +*PaperDimension Legal: "612 1008" +*PaperDimension A4: "595 842" +*PaperDimension FanFoldUS: "1071 792" + +*OpenUI *Resolution/Output Resolution: PickOne +*OrderDependency: 20 AnySetup *Resolution +*DefaultResolution: 120dpi +*Resolution 60dpi/60 DPI: "<>setpagedevice" +*Resolution 120dpi/120x60 DPI: "<>setpagedevice" +*Resolution 180dpi/180 DPI: "<>setpagedevice" +*Resolution 360x180dpi/360x180 DPI: "<>setpagedevice" +*Resolution 360dpi/360 DPI: "<>setpagedevice" +*CloseUI: *Resolution + +*DefaultFont: Courier +*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM +*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM +*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM +*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM +*Font Bookman-Demi: Standard "(001.004S)" Standard ROM +*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM +*Font Bookman-Light: Standard "(001.004S)" Standard ROM +*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM +*Font Courier: Standard "(002.004S)" Standard ROM +*Font Courier-Bold: Standard "(002.004S)" Standard ROM +*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM +*Font Courier-Oblique: Standard "(002.004S)" Standard ROM +*Font Helvetica: Standard "(001.006S)" Standard ROM +*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM +*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM +*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM +*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM +*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM +*Font Palatino-Bold: Standard "(001.005S)" Standard ROM +*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM +*Font Palatino-Italic: Standard "(001.005S)" Standard ROM +*Font Palatino-Roman: Standard "(001.005S)" Standard ROM +*Font Symbol: Special "(001.007S)" Special ROM +*Font Times-Bold: Standard "(001.007S)" Standard ROM +*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM +*Font Times-Italic: Standard "(001.007S)" Standard ROM +*Font Times-Roman: Standard "(001.007S)" Standard ROM +*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM +*Font ZapfDingbats: Special "(001.004S)" Standard ROM +*% +*% End of "$Id$". +*% diff --git a/ppd/epson9.ppd b/ppd/epson9.ppd new file mode 100644 index 0000000000..7bd9d6ac5c --- /dev/null +++ b/ppd/epson9.ppd @@ -0,0 +1,126 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Sample EPSON 9-Pin driver PPD file for the Common UNIX Printing +*% System (CUPS). +*% +*% Copyright 1997-2000 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Easy Software Products and are protected by Federal +*% copyright law. Distribution and use rights are outlined in the file +*% "LICENSE.txt" which should have been included with this file. If this +*% file is missing or damaged please contact Easy Software Products +*% at: +*% +*% Attn: CUPS Licensing Information +*% Easy Software Products +*% 44141 Airport View Drive, Suite 204 +*% Hollywood, Maryland 20636-3111 USA +*% +*% Voice: (301) 373-9603 +*% EMail: cups-info@cups.org +*% WWW: http://www.cups.org +*% +*FormatVersion: "4.3" +*FileVersion: "1.1" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "EPSON9.PPD" +*Manufacturer: "ESP" +*Product: "(CUPS v1.1)" +*cupsVersion: 1.1 +*cupsManualCopies: True +*cupsModelNumber: 0 +*cupsFilter: "application/vnd.cups-raster 0 rastertoepson" +*ModelName: "EPSON 9-Pin Series" +*ShortNickName: "EPSON 9-Pin Series" +*NickName: "EPSON 9-Pin Series CUPS v1.1" +*PSVersion: "(3010.000) 550" +*LanguageLevel: "3" +*ColorDevice: False +*DefaultColorSpace: Gray +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*VariablePaperSize: False +*TTRasterizer: Type42 + +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: Letter +*PageSize Letter: "<>setpagedevice" +*PageSize Legal: "<>setpagedevice" +*PageSize A4: "<>setpagedevice" +*PageSize FanFoldUS: "<>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter: "<>setpagedevice" +*PageRegion Legal: "<>setpagedevice" +*PageRegion A4: "<>setpagedevice" +*PageRegion FanFoldUS: "<>setpagedevice" +*CloseUI: *PageRegion + +*DefaultImageableArea: Letter +*ImageableArea Letter: "18.0 18.0 594.0 774.0" +*ImageableArea Legal: "18.0 18.0 594.0 990.0" +*ImageableArea A4: "18.0 18.0 577.0 824.0" +*ImageableArea FanFoldUS: "18.0 18.0 1053.0 774.0" + +*DefaultPaperDimension: Letter +*PaperDimension Letter: "612 792" +*PaperDimension Legal: "612 1008" +*PaperDimension A4: "595 842" +*PaperDimension FanFoldUS: "1071 792" + +*OpenUI *Resolution/Output Resolution: PickOne +*OrderDependency: 20 AnySetup *Resolution +*DefaultResolution: 120dpi +*Resolution 60dpi/60x72 DPI: "<>setpagedevice" +*Resolution 120dpi/120x72 DPI: "<>setpagedevice" +*Resolution 240dpi/240x72 DPI: "<>setpagedevice" +*CloseUI: *Resolution + +*DefaultFont: Courier +*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM +*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM +*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM +*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM +*Font Bookman-Demi: Standard "(001.004S)" Standard ROM +*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM +*Font Bookman-Light: Standard "(001.004S)" Standard ROM +*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM +*Font Courier: Standard "(002.004S)" Standard ROM +*Font Courier-Bold: Standard "(002.004S)" Standard ROM +*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM +*Font Courier-Oblique: Standard "(002.004S)" Standard ROM +*Font Helvetica: Standard "(001.006S)" Standard ROM +*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM +*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM +*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM +*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM +*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM +*Font Palatino-Bold: Standard "(001.005S)" Standard ROM +*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM +*Font Palatino-Italic: Standard "(001.005S)" Standard ROM +*Font Palatino-Roman: Standard "(001.005S)" Standard ROM +*Font Symbol: Special "(001.007S)" Special ROM +*Font Times-Bold: Standard "(001.007S)" Standard ROM +*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM +*Font Times-Italic: Standard "(001.007S)" Standard ROM +*Font Times-Roman: Standard "(001.007S)" Standard ROM +*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM +*Font ZapfDingbats: Special "(001.004S)" Standard ROM +*% +*% End of "$Id$". +*% diff --git a/ppd/laserjet.ppd b/ppd/laserjet.ppd new file mode 100644 index 0000000000..8d1d13b3c2 --- /dev/null +++ b/ppd/laserjet.ppd @@ -0,0 +1,199 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Sample HP LaserJet driver PPD file for the Common UNIX Printing +*% System (CUPS). +*% +*% Copyright 1997-2000 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Easy Software Products and are protected by Federal +*% copyright law. Distribution and use rights are outlined in the file +*% "LICENSE.txt" which should have been included with this file. If this +*% file is missing or damaged please contact Easy Software Products +*% at: +*% +*% Attn: CUPS Licensing Information +*% Easy Software Products +*% 44141 Airport View Drive, Suite 204 +*% Hollywood, Maryland 20636-3111 USA +*% +*% Voice: (301) 373-9603 +*% EMail: cups-info@cups.org +*% WWW: http://www.cups.org +*% +*FormatVersion: "4.3" +*FileVersion: "1.1" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "LASERJET.PPD" +*Manufacturer: "ESP" +*Product: "(CUPS v1.1)" +*cupsVersion: 1.1 +*cupsManualCopies: False +*cupsFilter: "application/vnd.cups-raster 0 rastertohp" +*ModelName: "HP LaserJet Series" +*ShortNickName: "HP LaserJet Series" +*NickName: "HP LaserJet Series CUPS v1.1" +*PSVersion: "(3010.000) 550" +*LanguageLevel: "3" +*ColorDevice: False +*DefaultColorSpace: Gray +*FileSystem: False +*Throughput: "8" +*LandscapeOrientation: Plus90 +*VariablePaperSize: False +*TTRasterizer: Type42 + +*UIConstraints: *PageSize Executive *InputSlot Envelope +*UIConstraints: *PageSize Letter *InputSlot Envelope +*UIConstraints: *PageSize Legal *InputSlot Envelope +*UIConstraints: *PageSize Tabloid *InputSlot Envelope +*UIConstraints: *PageSize A3 *InputSlot Envelope +*UIConstraints: *PageSize A4 *InputSlot Envelope +*UIConstraints: *PageSize A5 *InputSlot Envelope +*UIConstraints: *PageSize B5 *InputSlot Envelope +*UIConstraints: *Duplex *Option1 False + +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: Letter +*PageSize Letter/US Letter: "<>setpagedevice" +*PageSize Legal/US Legal: "<>setpagedevice" +*PageSize Executive/US Executive: "<>setpagedevice" +*PageSize Tabloid/US Tabloid: "<>setpagedevice" +*PageSize A3/A3: "<>setpagedevice" +*PageSize A4/A4: "<>setpagedevice" +*PageSize A5/A5: "<>setpagedevice" +*PageSize B5/B5 (JIS): "<>setpagedevice" +*PageSize EnvISOB5/Envelope B5: "<>setpagedevice" +*PageSize Env10/Envelope #10: "<>setpagedevice" +*PageSize EnvC5/Envelope C5: "<>setpagedevice" +*PageSize EnvDL/Envelope DL: "<>setpagedevice" +*PageSize EnvMonarch/Envelope Monarch: "<>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter/US Letter: "<>setpagedevice" +*PageRegion Legal/US Legal: "<>setpagedevice" +*PageRegion Executive/US Executive: "<>setpagedevice" +*PageRegion Tabloid/US Tabloid: "<>setpagedevice" +*PageRegion A3/A3: "<>setpagedevice" +*PageRegion A4/A4: "<>setpagedevice" +*PageRegion A5/A5: "<>setpagedevice" +*PageRegion B5/B5 (JIS): "<>setpagedevice" +*PageRegion EnvISOB5/Envelope B5: "<>setpagedevice" +*PageRegion Env10/Envelope #10: "<>setpagedevice" +*PageRegion EnvC5/Envelope C5: "<>setpagedevice" +*PageRegion EnvDL/Envelope DL: "<>setpagedevice" +*PageRegion EnvMonarch/Envelope Monarch: "<>setpagedevice" +*CloseUI: *PageRegion + +*DefaultImageableArea: Letter +*ImageableArea Letter/US Letter: "18 36 594 756" +*ImageableArea Legal/US Legal: "18 36 594 972" +*ImageableArea Executive/US Executive: "18 36 504 684" +*ImageableArea Tabloid/US Tabloid: "18 36 774 1188" +*ImageableArea A3/A3: "18 36 824 1155" +*ImageableArea A4/A4: "18 36 577 806" +*ImageableArea A5/A5: "18 36 403 559" +*ImageableArea B5/JIS B5: "18 36 498 693" +*ImageableArea EnvISOB5/B5 (ISO): "18 36 463 673" +*ImageableArea Env10/Com-10: "18 36 279 648" +*ImageableArea EnvC5/EnvC5: "18 36 441 613" +*ImageableArea EnvDL/EnvDL: "18 36 294 588" +*ImageableArea EnvMonarch/Envelope Monarch: "18 36 261 504" + +*DefaultPaperDimension: Letter +*PaperDimension Letter/US Letter: "612 792" +*PaperDimension Legal/US Legal: "612 1008" +*PaperDimension Executive/US Executive: "522 756" +*PaperDimension Tabloid/US Tabloid: "792 1224" +*PaperDimension A3/A3: "842 1191" +*PaperDimension A4/A4: "595 842" +*PaperDimension A5/A5: "421 595" +*PaperDimension B5/B5 (JIS): "516 729" +*PaperDimension EnvISOB5/Envelope B5: "499 709" +*PaperDimension Env10/Envelope #10: "297 684" +*PaperDimension EnvC5/Envelope C5: "459 649" +*PaperDimension EnvDL/Envelope DL: "312 624" +*PaperDimension EnvMonarch/Envelope Monarch: "279 540" + +*OpenUI *InputSlot/Media Source: PickOne +*OrderDependency: 10 AnySetup *InputSlot +*DefaultInputSlot: Default +*InputSlot Default/Default: "<>setpagedevice" +*InputSlot Tray1/Tray 1: "<>setpagedevice" +*InputSlot Tray2/Tray 2: "<>setpagedevice" +*InputSlot Tray3/Tray 3: "<>setpagedevice" +*InputSlot Tray4/Tray 4: "<>setpagedevice" +*InputSlot Manual/Manual Feed: "<>setpagedevice" +*InputSlot Envelope/Envelope Feed: "<>setpagedevice" +*CloseUI: *InputSlot + +*OpenUI *Resolution/Output Resolution: PickOne +*OrderDependency: 20 AnySetup *Resolution +*DefaultResolution: 300dpi +*Resolution 150dpi/150 DPI: "<>setpagedevice" +*Resolution 300dpi/300 DPI: "<>setpagedevice" +*Resolution 600dpi/600 DPI: "<>setpagedevice" +*CloseUI: *Resolution + +*OpenUI *Duplex/Double-Sided Printing: PickOne +*OrderDependency: 20 AnySetup *Duplex +*DefaultDuplex: None +*Duplex None/Off: "<>setpagedevice" +*Duplex DuplexNoTumble/Long Edge (Standard): "<>setpagedevice" +*Duplex DuplexTumble/Short Edge (Flip): "<>setpagedevice" +*CloseUI: *Duplex + +*OpenGroup: InstallableOptions +*OpenUI *Option1/Duplexer: Boolean +*DefaultOption1: False +*Option1 True/Installed: "" +*Option1 False/Not Installed: "" +*CloseUI *Option1 +*CloseGroup: InstallableOptions + +*DefaultFont: Courier +*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM +*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM +*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM +*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM +*Font Bookman-Demi: Standard "(001.004S)" Standard ROM +*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM +*Font Bookman-Light: Standard "(001.004S)" Standard ROM +*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM +*Font Courier: Standard "(002.004S)" Standard ROM +*Font Courier-Bold: Standard "(002.004S)" Standard ROM +*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM +*Font Courier-Oblique: Standard "(002.004S)" Standard ROM +*Font Helvetica: Standard "(001.006S)" Standard ROM +*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM +*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM +*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM +*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM +*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM +*Font Palatino-Bold: Standard "(001.005S)" Standard ROM +*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM +*Font Palatino-Italic: Standard "(001.005S)" Standard ROM +*Font Palatino-Roman: Standard "(001.005S)" Standard ROM +*Font Symbol: Special "(001.007S)" Special ROM +*Font Times-Bold: Standard "(001.007S)" Standard ROM +*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM +*Font Times-Italic: Standard "(001.007S)" Standard ROM +*Font Times-Roman: Standard "(001.007S)" Standard ROM +*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM +*Font ZapfDingbats: Special "(001.004S)" Standard ROM +*% +*% End of "$Id$". +*% diff --git a/ppd/stcolor.ppd b/ppd/stcolor.ppd new file mode 100644 index 0000000000..43c68f3970 --- /dev/null +++ b/ppd/stcolor.ppd @@ -0,0 +1,132 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Sample EPSON Stylus Color driver PPD file for the Common UNIX Printing +*% System (CUPS). +*% +*% Copyright 1997-2000 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Easy Software Products and are protected by Federal +*% copyright law. Distribution and use rights are outlined in the file +*% "LICENSE.txt" which should have been included with this file. If this +*% file is missing or damaged please contact Easy Software Products +*% at: +*% +*% Attn: CUPS Licensing Information +*% Easy Software Products +*% 44141 Airport View Drive, Suite 204 +*% Hollywood, Maryland 20636-3111 USA +*% +*% Voice: (301) 373-9603 +*% EMail: cups-info@cups.org +*% WWW: http://www.cups.org +*% +*FormatVersion: "4.3" +*FileVersion: "1.1" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "STCOLOR.PPD" +*Manufacturer: "ESP" +*Product: "(CUPS v1.1)" +*cupsVersion: 1.1 +*cupsManualCopies: True +*cupsModelNumber: 2 +*cupsFilter: "application/vnd.cups-raster 0 rastertoepson" +*cupsColorProfile 180dpi/-: "1.0 1.0 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0" +*cupsColorProfile 360dpi/-: "1.0 1.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0" +*cupsColorProfile 720dpi/-: "1.0 2.5 1.0 0.0 -0.2 -0.4 1.0 0.0 -0.2 0.0 1.0" +*ModelName: "EPSON Stylus Color Series" +*ShortNickName: "EPSON Stylus Color Series" +*NickName: "EPSON Stylus Color Series CUPS v1.1" +*PSVersion: "(3010.000) 550" +*LanguageLevel: "3" +*ColorDevice: True +*DefaultColorSpace: RGB +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*VariablePaperSize: False +*TTRasterizer: Type42 + +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: Letter +*PageSize Letter: "<>setpagedevice" +*PageSize Legal: "<>setpagedevice" +*PageSize A4: "<>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter: "<>setpagedevice" +*PageRegion Legal: "<>setpagedevice" +*PageRegion A4: "<>setpagedevice" +*CloseUI: *PageRegion + +*DefaultImageableArea: Letter +*ImageableArea Letter: "8.60 39.60 603.40 766.49" +*ImageableArea Legal: "8.60 39.60 603.40 982.49" +*ImageableArea A4: "8.60 39.60 586.40 816.49" + +*DefaultPaperDimension: Letter +*PaperDimension Letter: "612 792" +*PaperDimension Legal: "612 1008" +*PaperDimension A4: "595 842" + +*OpenUI *Resolution/Output Resolution: PickOne +*OrderDependency: 20 AnySetup *Resolution +*DefaultResolution: 360dpi +*Resolution 180dpi/180 DPI: "<>setpagedevice" +*Resolution 360dpi/360 DPI: "<>setpagedevice{0.6666 exp}bind settransfer" +*Resolution 720dpi/720 DPI: "<>setpagedevice{0.4 exp}bind settransfer" +*CloseUI: *Resolution + +*OpenUI *ColorModel/Output Mode: PickOne +*OrderDependency: 10 AnySetup *ColorModel +*DefaultColorModel: CMYK +*ColorModel CMYK/Color: "<>setpagedevice" +*ColorModel Gray/Grayscale: "<>setpagedevice" +*CloseUI: *ColorModel + +*DefaultFont: Courier +*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM +*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM +*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM +*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM +*Font Bookman-Demi: Standard "(001.004S)" Standard ROM +*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM +*Font Bookman-Light: Standard "(001.004S)" Standard ROM +*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM +*Font Courier: Standard "(002.004S)" Standard ROM +*Font Courier-Bold: Standard "(002.004S)" Standard ROM +*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM +*Font Courier-Oblique: Standard "(002.004S)" Standard ROM +*Font Helvetica: Standard "(001.006S)" Standard ROM +*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM +*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM +*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM +*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM +*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM +*Font Palatino-Bold: Standard "(001.005S)" Standard ROM +*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM +*Font Palatino-Italic: Standard "(001.005S)" Standard ROM +*Font Palatino-Roman: Standard "(001.005S)" Standard ROM +*Font Symbol: Special "(001.007S)" Special ROM +*Font Times-Bold: Standard "(001.007S)" Standard ROM +*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM +*Font Times-Italic: Standard "(001.007S)" Standard ROM +*Font Times-Roman: Standard "(001.007S)" Standard ROM +*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM +*Font ZapfDingbats: Special "(001.004S)" Standard ROM +*% +*% End of "$Id$". +*% diff --git a/ppd/stphoto.ppd b/ppd/stphoto.ppd new file mode 100644 index 0000000000..ec5c8a0f02 --- /dev/null +++ b/ppd/stphoto.ppd @@ -0,0 +1,132 @@ +*PPD-Adobe: "4.3" +*% +*% "$Id$" +*% +*% Sample EPSON Stylus Photo driver PPD file for the Common UNIX Printing +*% System (CUPS). +*% +*% Copyright 1997-2000 by Easy Software Products. +*% +*% These coded instructions, statements, and computer programs are the +*% property of Easy Software Products and are protected by Federal +*% copyright law. Distribution and use rights are outlined in the file +*% "LICENSE.txt" which should have been included with this file. If this +*% file is missing or damaged please contact Easy Software Products +*% at: +*% +*% Attn: CUPS Licensing Information +*% Easy Software Products +*% 44141 Airport View Drive, Suite 204 +*% Hollywood, Maryland 20636-3111 USA +*% +*% Voice: (301) 373-9603 +*% EMail: cups-info@cups.org +*% WWW: http://www.cups.org +*% +*FormatVersion: "4.3" +*FileVersion: "1.1" +*LanguageVersion: English +*LanguageEncoding: ISOLatin1 +*PCFileName: "STPHOTO.PPD" +*Manufacturer: "ESP" +*Product: "(CUPS v1.1)" +*cupsVersion: 1.1 +*cupsManualCopies: True +*cupsModelNumber: 3 +*cupsFilter: "application/vnd.cups-raster 0 rastertoepson" +*cupsColorProfile 180dpi/-: "1.0 1.0 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0" +*cupsColorProfile 360dpi/-: "1.0 1.5 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0" +*cupsColorProfile 720dpi/-: "1.0 2.5 1.0 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0" +*ModelName: "EPSON Stylus Photo Series" +*ShortNickName: "EPSON Stylus Photo Series" +*NickName: "EPSON Stylus Photo Series CUPS v1.1" +*PSVersion: "(3010.000) 550" +*LanguageLevel: "3" +*ColorDevice: True +*DefaultColorSpace: RGB +*FileSystem: False +*Throughput: "1" +*LandscapeOrientation: Plus90 +*VariablePaperSize: False +*TTRasterizer: Type42 + +*OpenUI *PageSize/Media Size: PickOne +*OrderDependency: 10 AnySetup *PageSize +*DefaultPageSize: Letter +*PageSize Letter: "<>setpagedevice" +*PageSize Legal: "<>setpagedevice" +*PageSize A4: "<>setpagedevice" +*CloseUI: *PageSize + +*OpenUI *PageRegion: PickOne +*OrderDependency: 10 AnySetup *PageRegion +*DefaultPageRegion: Letter +*PageRegion Letter: "<>setpagedevice" +*PageRegion Legal: "<>setpagedevice" +*PageRegion A4: "<>setpagedevice" +*CloseUI: *PageRegion + +*DefaultImageableArea: Letter +*ImageableArea Letter: "8.60 39.60 603.40 766.49" +*ImageableArea Legal: "8.60 39.60 603.40 982.49" +*ImageableArea A4: "8.60 39.60 586.40 816.49" + +*DefaultPaperDimension: Letter +*PaperDimension Letter: "612 792" +*PaperDimension Legal: "612 1008" +*PaperDimension A4: "595 842" + +*OpenUI *Resolution/Output Resolution: PickOne +*OrderDependency: 20 AnySetup *Resolution +*DefaultResolution: 360dpi +*Resolution 180dpi/180 DPI: "<>setpagedevice" +*Resolution 360dpi/360 DPI: "<>setpagedevice{0.6666 exp}bind settransfer" +*Resolution 720dpi/720 DPI: "<>setpagedevice{0.4 exp}bind settransfer" +*CloseUI: *Resolution + +*OpenUI *ColorModel/Output Mode: PickOne +*OrderDependency: 10 AnySetup *ColorModel +*DefaultColorModel: CMYK +*ColorModel CMYK/Color: "<>setpagedevice" +*ColorModel Gray/Grayscale: "<>setpagedevice" +*CloseUI: *ColorModel + +*DefaultFont: Courier +*Font AvantGarde-Book: Standard "(001.006S)" Standard ROM +*Font AvantGarde-BookOblique: Standard "(001.006S)" Standard ROM +*Font AvantGarde-Demi: Standard "(001.007S)" Standard ROM +*Font AvantGarde-DemiOblique: Standard "(001.007S)" Standard ROM +*Font Bookman-Demi: Standard "(001.004S)" Standard ROM +*Font Bookman-DemiItalic: Standard "(001.004S)" Standard ROM +*Font Bookman-Light: Standard "(001.004S)" Standard ROM +*Font Bookman-LightItalic: Standard "(001.004S)" Standard ROM +*Font Courier: Standard "(002.004S)" Standard ROM +*Font Courier-Bold: Standard "(002.004S)" Standard ROM +*Font Courier-BoldOblique: Standard "(002.004S)" Standard ROM +*Font Courier-Oblique: Standard "(002.004S)" Standard ROM +*Font Helvetica: Standard "(001.006S)" Standard ROM +*Font Helvetica-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow: Standard "(001.006S)" Standard ROM +*Font Helvetica-Narrow-Bold: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-BoldOblique: Standard "(001.007S)" Standard ROM +*Font Helvetica-Narrow-Oblique: Standard "(001.006S)" Standard ROM +*Font Helvetica-Oblique: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Bold: Standard "(001.009S)" Standard ROM +*Font NewCenturySchlbk-BoldItalic: Standard "(001.007S)" Standard ROM +*Font NewCenturySchlbk-Italic: Standard "(001.006S)" Standard ROM +*Font NewCenturySchlbk-Roman: Standard "(001.007S)" Standard ROM +*Font Palatino-Bold: Standard "(001.005S)" Standard ROM +*Font Palatino-BoldItalic: Standard "(001.005S)" Standard ROM +*Font Palatino-Italic: Standard "(001.005S)" Standard ROM +*Font Palatino-Roman: Standard "(001.005S)" Standard ROM +*Font Symbol: Special "(001.007S)" Special ROM +*Font Times-Bold: Standard "(001.007S)" Standard ROM +*Font Times-BoldItalic: Standard "(001.009S)" Standard ROM +*Font Times-Italic: Standard "(001.007S)" Standard ROM +*Font Times-Roman: Standard "(001.007S)" Standard ROM +*Font ZapfChancery-MediumItalic: Standard "(001.007S)" Standard ROM +*Font ZapfDingbats: Special "(001.004S)" Standard ROM +*% +*% End of "$Id$". +*% diff --git a/pstoraster/Fontmap b/pstoraster/Fontmap new file mode 100644 index 0000000000..42797fe18d --- /dev/null +++ b/pstoraster/Fontmap @@ -0,0 +1,98 @@ +% +% "$Id: Fontmap 569 1999-07-30 12:57:12Z mike $" +% +% Fontmap file for the Common UNIX Printing System (CUPS). +% +% Copyright 1997-1999 by Easy Software Products, all rights reserved. +% +% These coded instructions, statements, and computer programs are the +% property of Easy Software Products and are protected by Federal +% copyright law. Distribution and use rights are outlined in the file +% "LICENSE.txt" which should have been included with this file. If this +% file is missing or damaged please contact Easy Software Products +% at: +% +% Attn: CUPS Licensing Information +% Easy Software Products +% 44145 Airport View Drive, Suite 204 +% Hollywood, Maryland 20636-3111 USA +% +% Voice: (301) 373-9603 +% EMail: cups-info@cups.org +% WWW: http://www.cups.org +% + +% +% The Fontmap file takes lines in the following formats: +% +% /FontName /RealFontName [for aliases] +% /FontName (FileName) [for actual font files] +% +% All Type1 fonts in the "fonts" directory (usually /usr/share/cups/fonts) +% are automagically added with the names in the font files (that is, the +% font filename doesn't matter, it looks at the file header instead). +% + +% +% The standard fonts included with ESP Print are the free GhostScript fonts, +% which don't use the standard names. These aliases map the standard 39 +% fonts to the free fonts. +% + +/Bookman-Demi /URWBookmanL-DemiBold ; +/Bookman-DemiItalic /URWBookmanL-DemiBoldItal ; +/Bookman-Light /URWBookmanL-Ligh ; +/Bookman-LightItalic /URWBookmanL-LighItal ; + +/Courier /NimbusMonL-Regu ; +/Courier-Oblique /NimbusMonL-ReguObli ; +/Courier-Bold /NimbusMonL-Bold ; +/Courier-BoldOblique /NimbusMonL-BoldObli ; + +/AvantGarde-Book /URWGothicL-Book ; +/AvantGarde-BookOblique /URWGothicL-BookObli ; +/AvantGarde-Demi /URWGothicL-Demi ; +/AvantGarde-DemiOblique /URWGothicL-DemiObli ; + +/Helvetica /NimbusSanL-Regu ; +/Helvetica-Oblique /NimbusSanL-ReguItal ; +/Helvetica-Bold /NimbusSanL-Bold ; +/Helvetica-BoldOblique /NimbusSanL-BoldItal ; + +/Helvetica-Narrow /NimbusSanL-ReguCond ; +/Helvetica-Narrow-Oblique /NimbusSanL-ReguCondItal ; +/Helvetica-Narrow-Bold /NimbusSanL-BoldCond ; +/Helvetica-Narrow-BoldOblique /NimbusSanL-BoldCondItal ; + +/Palatino-Roman /URWPalladioL-Roma ; +/Palatino-Italic /URWPalladioL-Ital ; +/Palatino-Bold /URWPalladioL-Bold ; +/Palatino-BoldItalic /URWPalladioL-BoldItal ; + +/NewCenturySchlbk-Roman /CenturySchL-Roma ; +/NewCenturySchlbk-Italic /CenturySchL-Ital ; +/NewCenturySchlbk-Bold /CenturySchL-Bold ; +/NewCenturySchlbk-BoldItalic /CenturySchL-BoldItal ; + +/Times-Roman /NimbusRomNo9L-Regu ; +/Times-Italic /NimbusRomNo9L-ReguItal ; +/Times-Bold /NimbusRomNo9L-Medi ; +/Times-BoldItalic /NimbusRomNo9L-MediItal ; + +/Symbol /StandardSymL ; + +/ZapfChancery-MediumItalic /URWChanceryL-MediItal ; + +/ZapfDingbats /Dingbats ; + +% +% This alias is for less-intelligent PC programs like Quark and +% Freehand which insist on using "Times" as the name for the +% "Times-Roman" font. Go figure. +% + +/Times /Times-Roman ; + +% +% End of "$Id: Fontmap 569 1999-07-30 12:57:12Z mike $". +% diff --git a/pstoraster/Makefile b/pstoraster/Makefile new file mode 100644 index 0000000000..2377b5fd23 --- /dev/null +++ b/pstoraster/Makefile @@ -0,0 +1,427 @@ +# +# "$Id$" +# +# GNU Ghostscript makefile for the Common UNIX Printing System (CUPS). +# +# Copyright 1993-2000 by Easy Software Products. +# +# These coded instructions, statements, and computer programs are the +# property of Easy Software Products and are protected by Federal +# copyright law. Distribution and use rights are outlined in the file +# "LICENSE.txt" which should have been included with this file. If this +# file is missing or damaged please contact Easy Software Products +# at: +# +# Attn: CUPS Licensing Information +# Easy Software Products +# 44141 Airport View Drive, Suite 204 +# Hollywood, Maryland 20636-3111 USA +# +# Voice: (301) 373-9603 +# EMail: cups-info@cups.org +# WWW: http://www.cups.org +# +# This makefile and any derivative of it may be used and distributed +# freely under the terms of the GNU General Public License when +# used with GNU Ghostscript or its derivatives. Use of the makefile +# (or any derivative of it) with software other than GNU GhostScript +# (or its derivatives) is governed by the CUPS license agreement. +# + +include ../Makedefs + + +# +# Object files... +# + +LIBOBJS = gconfig.o \ + gdevabuf.o \ + gdevbbox.o \ + gdevcups.o \ + gdevdbit.o \ + gdevddrw.o \ + gdevdflt.o \ + gdevdgbr.o \ + gdevhit.o \ + gdevm16.o \ + gdevm1.o \ + gdevm24.o \ + gdevm2.o \ + gdevm32.o \ + gdevm4.o \ + gdevm8.o \ + gdevmem.o \ + gdevmpla.o \ + gdevnfwd.o \ + gdevpipe.o \ + gdevprn.o \ + gp_getnv.o \ + gp_nofb.o \ + gp_nsync.o \ + gp_unifn.o \ + gp_unifs.o \ + gp_unix.o \ + gsalloc.o \ + gsalpha.o \ + gsargs.o \ + gsbitops.o \ + gsbittab.o \ + gscdefs.o \ + gscdevn.o \ + gschar0.o \ + gschar.o \ + gscie.o \ + gsclipsr.o \ + gscolor1.o \ + gscolor2.o \ + gscolor3.o \ + gscolor.o \ + gscoord.o \ + gscparam.o \ + gscpixel.o \ + gscrdp.o \ + gscrd.o \ + gscscie.o \ + gscsepr.o \ + gscspace.o \ + gsdevice.o \ + gsdevmem.o \ + gsdparam.o \ + gsdps1.o \ + gsdsrc.o \ + gsfcmap.o \ + gsfont0.o \ + gsfont.o \ + gsfunc0.o \ + gsfunc3.o \ + gsfunc.o \ + gshsb.o \ + gsht1.o \ + gshtscr.o \ + gsht.o \ + gsimage.o \ + gsimpath.o \ + gsinit.o \ + gsiodev.o \ + gsline.o \ + gsmalloc.o \ + gsmatrix.o \ + gsmemory.o \ + gsmisc.o \ + gsnorop.o \ + gspaint.o \ + gsparams.o \ + gsparam.o \ + gspath1.o \ + gspath.o \ + gspcolor.o \ + gsshade.o \ + gsstate.o \ + gstext.o \ + gstrap.o \ + gstype1.o \ + gstype2.o \ + gstype42.o \ + gsutil.o \ + gxacpath.o \ + gxbcache.o \ + gxccache.o \ + gxccman.o \ + gxcht.o \ + gxclbits.o \ + gxclimag.o \ + gxclip2.o \ + gxclipm.o \ + gxclip.o \ + gxclist.o \ + gxclmem.o \ + gxclpage.o \ + gxclpath.o \ + gxclrast.o \ + gxclread.o \ + gxclrect.o \ + gxclutil.o \ + gxclzlib.o \ + gxcmap.o \ + gxcpath.o \ + gxctable.o \ + gxdcconv.o \ + gxdcolor.o \ + gxdither.o \ + gxfill.o \ + gxhint1.o \ + gxhint2.o \ + gxhint3.o \ + gxht.o \ + gxi12bit.o \ + gxicolor.o \ + gxidata.o \ + gxifast.o \ + gxiinit.o \ + gximage3.o \ + gximage4.o \ + gximono.o \ + gxiscale.o \ + gxmclip.o \ + gxp1fill.o \ + gxpaint.o \ + gxpath2.o \ + gxpath.o \ + gxpcmap.o \ + gxpcopy.o \ + gxpdash.o \ + gxpflat.o \ + gxsample.o \ + gxshade1.o \ + gxshade4.o \ + gxshade6.o \ + gxshade.o \ + gxstroke.o \ + gxtype1.o \ + ialloc.o \ + ibnum.o \ + iccinit0.o \ + iconfig.o \ + icontext.o \ + idebug.o \ + idict.o \ + idparam.o \ + idstack.o \ + igcref.o \ + igcstr.o \ + igc.o \ + iinit.o \ + ilocate.o \ + imainarg.o \ + imain.o \ + iname.o \ + interp.o \ + iparam.o \ + ireclaim.o \ + isave.o \ + iscanbin.o \ + iscannum.o \ + iscan.o \ + istack.o \ + iutil2.o \ + iutil.o \ + sbcp.o \ + sbhc.o \ + sbwbs.o \ + scantab.o \ + scfdtab.o \ + scfd.o \ + scfetab.o \ + scfe.o \ + scfparam.o \ + sdcparam.o \ + sdctc.o \ + sdctd.o \ + sdcte.o \ + sddparam.o \ + sdeparam.o \ + seexec.o \ + sfilter1.o \ + sfilter2.o \ + sfxstdio.o \ + shcgen.o \ + shc.o \ + siscale.o \ + sjpegc.o \ + sjpegd.o \ + sjpegerr.o \ + sjpege.o \ + slzwce.o \ + slzwc.o \ + slzwd.o \ + smtf.o \ + spcxd.o \ + spdiff.o \ + spngp.o \ + srld.o \ + srle.o \ + sstring.o \ + stream.o \ + szlibc.o \ + szlibd.o \ + szlibe.o \ + zarith.o \ + zarray.o \ + zbseq.o \ + zcfont.o \ + zchar1.o \ + zchar2.o \ + zchar32.o \ + zchar42.o \ + zcharout.o \ + zchar.o \ + zcid.o \ + zcie.o \ + zcolor1.o \ + zcolor2.o \ + zcolor.o \ + zcontrol.o \ + zcrd.o \ + zcsdevn.o \ + zcsindex.o \ + zcspixel.o \ + zcssepr.o \ + zdevcal.o \ + zdevice2.o \ + zdevice.o \ + zdict.o \ + zdps1.o \ + zfbcp.o \ + zfcmap.o \ + zfdctd.o \ + zfdcte.o \ + zfdecode.o \ + zfileio.o \ + zfile.o \ + zfilter2.o \ + zfilterx.o \ + zfilter.o \ + zfname.o \ + zfont0.o \ + zfont1.o \ + zfont2.o \ + zfont32.o \ + zfont42.o \ + zfont.o \ + zfproc.o \ + zfreuse.o \ + zfunc0.o \ + zfunc3.o \ + zfunc.o \ + zfzlib.o \ + zgeneric.o \ + zgstate.o \ + zhsb.o \ + zht1.o \ + zht2.o \ + zht.o \ + zimage2.o \ + zimage3.o \ + zimage.o \ + ziodev2.o \ + ziodev.o \ + zmath.o \ + zmatrix.o \ + zmedia2.o \ + zmisc1.o \ + zmisc2.o \ + zmisc3.o \ + zmisc.o \ + zpacked.o \ + zpaint.o \ + zpath1.o \ + zpath.o \ + zpcolor.o \ + zrelbit.o \ + zshade.o \ + zstack.o \ + zstring.o \ + zsysvm.o \ + ztoken.o \ + ztrap.o \ + ztype.o \ + zupath.o \ + zusparam.o \ + zvmem2.o \ + zvmem.o + +OBJS = $(LIBOBJS) genarch.o pstoraster.o + +# +# Data files... +# + +DFILES = Fontmap \ + gs_btokn.ps gs_ccfnt.ps gs_cff.ps gs_cidfn.ps \ + gs_cmap.ps gs_cmdl.ps gs_dbt_e.ps gs_diskf.ps \ + gs_dpnxt.ps gs_dps1.ps gs_dps2.ps gs_dps.ps gs_epsf.ps \ + gs_fform.ps gs_fonts.ps gs_init.ps gs_iso_e.ps \ + gs_kanji.ps gs_ksb_e.ps gs_lev2.ps gs_ll3.ps \ + gs_mex_e.ps gs_mro_e.ps gs_pfile.ps gs_res.ps \ + gs_setpd.ps gs_statd.ps gs_std_e.ps gs_sym_e.ps \ + gs_ttf.ps gs_typ32.ps gs_typ42.ps gs_type1.ps \ + gs_wan_e.ps gs_wl1_e.ps gs_wl2_e.ps gs_wl5_e.ps + + +# +# Targets... +# + +TARGETS = genarch arch.h libgs.a pstoraster + + +# +# Make everything... +# + +all: $(TARGETS) + +# +# Clean all config and object files... +# + +clean: + $(RM) $(TARGETS) + $(RM) $(OBJS) + + +# +# Install files... +# + +install: $(TARGETS) + -$(MKDIR) $(SERVERBIN)/filter + $(CHMOD) ugo+rx $(SERVERBIN) + $(CHMOD) ugo+rx $(SERVERBIN)/filter + $(INSTALL_BIN) pstoraster $(SERVERBIN)/filter + -$(MKDIR) $(DATADIR)/pstoraster + $(CHMOD) ugo+rx $(DATADIR) + $(CHMOD) ugo+rx $(DATADIR)/pstoraster + $(INSTALL_DATA) $(DFILES) $(DATADIR)/pstoraster + + +# +# genarch - generate the architecture configuration file. +# + +genarch: genarch.o + echo Linking $@... + $(CC) $(LDFLAGS) -o genarch genarch.o +arch.h: genarch + echo Generating $@... + ./genarch arch.h + + +# +# libgs.a - GhostScript interpreter library... +# + +libgs.a: $(LIBOBJS) ../Makedefs + echo Archiving $@... + $(RM) $@ + $(AR) $(ARFLAGS) $@ $(LIBOBJS) + $(RANLIB) $@ + +gdevcups.o: ../filter/raster.h +$(LIBOBJS): arch.h ../config.h ../Makedefs + + +# +# pstoraster - PostScript RIP filter. +# + +pstoraster: pstoraster.o libgs.a ../Makedefs ../cups/$(LIBCUPS) + echo Linking $@... + $(CC) $(LDFLAGS) -o pstoraster pstoraster.o libgs.a \ + $(LINKCUPSIMAGE) $(IMGLIBS) $(DSOLIBS) $(LIBS) -lm +pstoraster.o: arch.h ../config.h ../Makedefs + +# +# End of "$Id$". +# diff --git a/pstoraster/bfont.h b/pstoraster/bfont.h new file mode 100644 index 0000000000..7adae17ded --- /dev/null +++ b/pstoraster/bfont.h @@ -0,0 +1,76 @@ +/* Copyright (C) 1992, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Interpreter internal routines and data needed for building fonts */ +/* Requires gxfont.h */ + +#ifndef bfont_INCLUDED +# define bfont_INCLUDED + +#include "ifont.h" + +/* In zfont.c */ +int add_FID(P2(ref * pfdict, gs_font * pfont)); + +font_proc_make_font(zdefault_make_font); +font_proc_make_font(zbase_make_font); +/* The global font directory */ +extern gs_font_dir *ifont_dir; + +/* Structure for passing BuildChar and BuildGlyph procedures. */ +typedef struct build_proc_refs_s { + ref BuildChar; + ref BuildGlyph; +} build_proc_refs; + +/* Options for collecting parameters from a font dictionary. */ +/* The comment indicates where the option is tested. */ +typedef enum { + bf_options_none = 0, + bf_Encoding_optional = 1, /* build_gs_font */ + bf_FontBBox_required = 2, /* build_gs_simple_font */ + bf_UniqueID_ignored = 4, /* build_gs_simple_font */ + bf_CharStrings_optional = 8, /* build_gs_primitive_font */ + bf_notdef_required = 16 /* build_gs_primitive_font */ +} build_font_options_t; + +/* In zfont2.c */ +int build_proc_name_refs(P3(build_proc_refs * pbuild, + const char *bcstr, + const char *bgstr)); +int build_gs_font_procs(P2(os_ptr, build_proc_refs *)); +int build_gs_primitive_font(P6(os_ptr, gs_font_base **, font_type, + gs_memory_type_ptr_t, const build_proc_refs *, + build_font_options_t)); +int build_gs_simple_font(P6(os_ptr, gs_font_base **, font_type, + gs_memory_type_ptr_t, const build_proc_refs *, + build_font_options_t)); +void lookup_gs_simple_font_encoding(P1(gs_font_base *)); +int build_gs_font(P6(os_ptr, gs_font **, font_type, + gs_memory_type_ptr_t, const build_proc_refs *, + build_font_options_t)); +int define_gs_font(P1(gs_font *)); + +#endif /* bfont_INCLUDED */ diff --git a/pstoraster/bseq.h b/pstoraster/bseq.h new file mode 100644 index 0000000000..46dab4a60f --- /dev/null +++ b/pstoraster/bseq.h @@ -0,0 +1,66 @@ +/* Copyright (C) 1990, 1994 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility to + anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer to + the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given to + you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises is not affiliated with the Free Software Foundation or + the GNU Project. GNU Ghostscript, as distributed by Aladdin Enterprises, + does not depend on any other GNU software. +*/ + +/* bseq.h */ +/* Definitions for Level 2 binary object sequences */ + +/* Binary object sequence element types */ +typedef enum { + bs_null = 0, + bs_integer = 1, + bs_real = 2, + bs_name = 3, + bs_boolean = 4, + bs_string = 5, + bs_eval_name = 6, + bs_array = 9, + bs_mark = 10, + /* + * We extend the PostScript language definition by allowing + * dictionaries in binary object sequences. The data for + * a dictionary is like that for an array, with the following + * changes: + * - If the size is an even number, the value is the index of + * the first of a series of alternating keys and values. + * - If the size is 1, the value is the index of another + * object (which must also be a dictionary, and must not have + * size = 1); this object represents the same object as that one. + */ + bs_dictionary = 15 +} bin_seq_type; +#define bs_executable 128 + +/* Definition of an object in a binary object sequence. */ +typedef struct { + byte tx; /* type and executable flag */ + byte unused; + union { + bits16 w; + byte b[2]; + } size; + union { + bits32 w; + float f; + byte b[4]; + } value; +} bin_seq_obj; diff --git a/pstoraster/btoken.h b/pstoraster/btoken.h new file mode 100644 index 0000000000..ac798ef9cf --- /dev/null +++ b/pstoraster/btoken.h @@ -0,0 +1,41 @@ +/* Copyright (C) 1990, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Definitions for Level 2 binary tokens */ + +#ifndef btoken_INCLUDED +# define btoken_INCLUDED + +/* Define accessors for pointers to the system and user name tables. */ +extern ref binary_token_names; /* array of size 2 */ + +#define system_names_p (binary_token_names.value.refs) +#define user_names_p (binary_token_names.value.refs + 1) + +/* Convert an object to its representation in a binary object sequence. */ +int encode_binary_token(P4(const ref * obj, long *ref_offset, long *char_offset, + byte * str)); + +#endif /* btoken_INCLUDED */ diff --git a/pstoraster/ctype_.h b/pstoraster/ctype_.h new file mode 100644 index 0000000000..c120d647fe --- /dev/null +++ b/pstoraster/ctype_.h @@ -0,0 +1,37 @@ +/* Copyright (C) 1993, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Wrapper for ctype.h */ + +#ifndef ctype__INCLUDED +# define ctype__INCLUDED + +/* We must include std.h before any file that includes sys/types.h. */ +#include "std.h" + +/* ... and that's the only reason for having this file at all. */ +#include + +#endif /* ctype__INCLUDED */ diff --git a/pstoraster/dirent_.h b/pstoraster/dirent_.h new file mode 100644 index 0000000000..4248f12cf1 --- /dev/null +++ b/pstoraster/dirent_.h @@ -0,0 +1,60 @@ +/* + Copyright 1993-2000 by Easy Software Products. + Copyright 1993, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Generic substitute for Unix dirent.h */ + +#ifndef dirent__INCLUDED +# define dirent__INCLUDED + +/* We must include std.h before any file that includes sys/types.h. */ +#include "std.h" + +#include + +/* + * Directory entries may be defined in quite a number of different + * header files. The following switches are defined in gconfig_.h. + */ +#ifdef HAVE_DIRENT_H +# include +typedef struct dirent dir_entry; + +#else /* sys/ndir or ndir or sys/dir, i.e., no dirent */ +# ifdef HAVE_SYS_DIR_H +# include +# endif +# ifdef HAVE_SYS_NDIR_H +# include +# endif +# ifdef HAVE_NDIR_H +# include +# endif +typedef struct direct dir_entry; + +#endif /* sys/ndir or ndir or sys/dir */ + +#endif /* dirent__INCLUDED */ diff --git a/pstoraster/dstack.h b/pstoraster/dstack.h new file mode 100644 index 0000000000..a9480a9e98 --- /dev/null +++ b/pstoraster/dstack.h @@ -0,0 +1,236 @@ +/* Copyright (C) 1992, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Definitions for the interpreter's dictionary stack */ + +#ifndef dstack_INCLUDED +# define dstack_INCLUDED + +#include "idstack.h" + +/* Define the (currently static) dictionary stack instance. */ +extern dict_stack_t idict_stack; + +#define d_stack (idict_stack.stack) + +/* Define the interpreter-specific versions of the generic dstack API. */ +#define min_dstack_size (idict_stack.min_size) +#define dstack_userdict_index (idict_stack.userdict_index) +#define dsspace (idict_stack.def_space) +#define dtop_can_store(pvalue) ((int)r_space(pvalue) <= dsspace) +#define dtop_keys (idict_stack.top_keys) +#define dtop_npairs (idict_stack.top_npairs) +#define dtop_values (idict_stack.top_values) +#define dict_set_top() dstack_set_top(&idict_stack); +#define dict_is_permanent_on_dstack(pdict)\ + dstack_dict_is_permanent(&idict_stack, pdict) +#define dicts_gc_cleanup() dstack_gc_cleanup(&idict_stack) +#define systemdict (&idict_stack.system_dict) + +/* Define the dictionary stack pointers. */ +#define dsbot (d_stack.bot) +#define dsp (d_stack.p) +#define dstop (d_stack.top) + +/* Macro to ensure enough room on the dictionary stack */ +#define check_dstack(n)\ + if ( dstop - dsp < (n) )\ + { d_stack.requested = (n); return_error(e_dictstackoverflow); } + +/* + * The dictionary stack is implemented as a linked list of blocks; + * operators that access the entire d-stack must take this into account. + * These are: + * countdictstack dictstack + * In addition, name lookup requires searching the entire stack, not just + * the top block, and the underflow check for the dictionary stack + * (`end' operator) is not just a check for underflowing the top block. + */ + +/* Name lookup */ +#define dict_find_name_by_index(nidx)\ + dstack_find_name_by_index(&idict_stack, nidx) +#define dict_find_name(pnref) dict_find_name_by_index(name_index(pnref)) +#define dict_find_name_by_index_inline(nidx, htemp)\ + dstack_find_name_by_index_inline(&idict_stack, nidx, htemp) +#define if_dict_find_name_by_index_top(nidx, htemp, pvslot)\ + if_dstack_find_name_by_index_top(&idict_stack, nidx, htemp, pvslot) + +/* + Notes on dictionary lookup performance + -------------------------------------- + + We mark heavily used operations with a * below; moderately heavily used + operations with a +. + + The following operations change the dictionary stack: + +begin, +end + readonly (on a dictionary that is on the stack) + noaccess (on a dictionary that is on the stack) + We implement cleardictstack as a series of ends. + + The following operations change the contents of dictionaries: + *def, +put + undef + restore + .setmaxlength + We implement store in PostScript, and copy as a series of puts. Many + other operators also do puts (e.g., ScaleMatrix in makefont, + Implementation in makepattern, ...). Note that put can do an implicit + .setmaxlength (if it has to grow the dictionary). + + The following operations look up keys on the dictionary stack: + *(interpreter name lookup) + load + where + + Current design + -------------- + + Each name has a pointer that has one of 3 states: + - This name has no definitions. + - This name has exactly one definition, in systemdict or userdict. + In this case, the pointer points to the value slot. + - This name has some other status. + + We cache some pointers to the top dictionary on the stack if it is a + readable dictionary with packed keys, which allows us to do fast, + single-probe lookups in this dictionary. We also cache a value that + allows us to do a fast check for stores into the top dictionary + (writability + space check). + + Full shallow binding + -------------------- + + We implement shallow binding with a pointer in each name that points to + the value slot that holds the name's definition. If the name is + undefined, or if we don't know where the slot is, the binding pointer + points to a ref with a special type t__invalid, which cannot occur + anywhere else. "Clearing" the pointer means setting it to point to this + ref. + + We also maintain a pair of pointers that bracket the value region of the + top dictionary on the stack, for fast checking in def. If the top + dictionary is readonly or noaccess, the pointers designate an empty area. + We call this the "def region" cache. + + We implement the above operations as follows: + begin - push the dictionary on the stack; set the pointers of + all name keys to point to the corresponding value slots. + end - pop the stack; clear the pointers of all name keys. + readonly - if the dictionary is the top one on the stack, + reset the def region cache. + noaccess - clear the pointers of all name keys. (This is overly + conservative, but this is a very rare operation.) + Also reset the def region cache if the dictionary is + the top one on the stack. + def - if the key is a name and its pointer points within the cached + def region, store the value through the pointer; otherwise, + look up the key in the top dictionary, store the value, + and if the key is a name, set its pointer to the value slot. + put - if the key is a name and wasn't in the dictionary before, + clear its pointer. (Conservative, but rare.) + undef - if the key is a name, clear its pointer. (Overly + conservative, but rare.) + restore - if either the old or the new value of a change is a name + (possibly in a packed array), clear its pointer. This is + conservative, but easy to detect, and probably not *too* + conservative. + .setmaxlength - clear all the pointers, like noaccess. + (name lookup) - fetch the value through the pointer and dispatch + on its type; if the type is t__invalid, do a full search + and set the pointer. This avoids a separate check for a + clear pointer in the usual case where the pointer is valid. + load - if the pointer is clear, do a search and set the pointer; + then fetch the value. + where - always do a full search and set the pointer. + (Conservative, but rare.) + + One place where shallow binding will result in major new overhead is the + extra push of systemdict for loading fonts. This probably isn't a problem + in real life. + + Adaptive shallow binding + ------------------------ + + We do validity checking for the name value cache using an epoch counter. + For each dictionary D, we keep an on-stack flag F. Each dictionary stack + entry is where D is the actual dictionary, M is a mark vector of + V bits (V is a system constant, probably 64), F is D's former on-stack + flag, and E is the epoch at which the entry was made. For each name K, we + keep a cache where P is a pointer to the dictionary value slot that + holds the current value of K, and E is an epoch value; the cache is valid + if K->E >= dsp->E. Here is what happens for each operation: + + ****** Still need to handle names defined only in systemdict or userdict? + + To initialize: + Epoch = 0 + To clear the cache entry for K: + *K = + begin(D): + *++dsp = F, ++Epoch> + set D->F + value = lookup(K): + if K->E >= dsp->E + value = *K->P + else + do lookup as usual + *K = + set dp->M[i mod V] where dp is the dstack slot of the dictionary + where K was found and i is the index within that dictionary + end: + for each i such that dsp->M[i] is set, + clear the cache entry for dsp->D->keys[i, i+V, ...] + dsp->D->F = dsp->F + --dsp + noaccess(D): + if D->F is set, + clear the cache entries for all name keys of D + readonly(D): + << nothing >> + .setmaxlength(D,N): + same as noaccess + restore: + If either the old or the new value of a change is a name + (possibly in a packed array), clear its cache entry. This is + conservative, but easy to detect, and probably not *too* + conservative. + def(K,V): + if K->P points into dsp->D + *K->P = V + else + put the new value in dsp->D + set *K and dsp->M[i mod V] as for a lookup + put(D,K,V): + if K is already defined in D, do nothing special + otherwise, if D->F isn't set, do nothing special + otherwise, clear K's cache entry + undef(D,K): + if D->F is set, + clear K's cache entry + */ + +#endif /* dstack_INCLUDED */ diff --git a/pstoraster/errno_.h b/pstoraster/errno_.h new file mode 100644 index 0000000000..b2a2ae561b --- /dev/null +++ b/pstoraster/errno_.h @@ -0,0 +1,42 @@ +/* Copyright (C) 1993, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Generic substitute for Unix errno.h */ + +#ifndef errno__INCLUDED +# define errno__INCLUDED + +/* We must include std.h before any file that includes sys/types.h. */ +#include "std.h" + +/* All environments provide errno.h, but in some of them, errno.h */ +/* only defines the error numbers, and doesn't declare errno. */ +#include +#ifndef errno /* in case it was #defined (very implausible!) */ +extern int errno; + +#endif + +#endif /* errno__INCLUDED */ diff --git a/pstoraster/errors.h b/pstoraster/errors.h new file mode 100644 index 0000000000..b5fd1844bc --- /dev/null +++ b/pstoraster/errors.h @@ -0,0 +1,148 @@ +/* Copyright (C) 1989, 1995, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Definition of error codes */ + +#ifndef errors_INCLUDED +# define errors_INCLUDED + +/* + * A procedure that may return an error always returns + * a non-negative value (zero, unless otherwise noted) for success, + * or negative for failure. + * We use ints rather than an enum to avoid a lot of casting. + */ + +/* Define the error name table */ +extern const char *const gs_error_names[]; + + /* ------ PostScript Level 1 errors ------ */ + +#define e_unknownerror (-1) /* unknown error */ +#define e_dictfull (-2) +#define e_dictstackoverflow (-3) +#define e_dictstackunderflow (-4) +#define e_execstackoverflow (-5) +#define e_interrupt (-6) +/* We also need to define gs_error_interrupt, for gpcheck.h. */ +#undef gs_error_interrupt +#define gs_error_interrupt e_interrupt +#define e_invalidaccess (-7) +#define e_invalidexit (-8) +#define e_invalidfileaccess (-9) +#define e_invalidfont (-10) +#define e_invalidrestore (-11) +#define e_ioerror (-12) +#define e_limitcheck (-13) +#define e_nocurrentpoint (-14) +#define e_rangecheck (-15) +#define e_stackoverflow (-16) +#define e_stackunderflow (-17) +#define e_syntaxerror (-18) +#define e_timeout (-19) +#define e_typecheck (-20) +#define e_undefined (-21) +#define e_undefinedfilename (-22) +#define e_undefinedresult (-23) +#define e_unmatchedmark (-24) +#define e_VMerror (-25) + +#define LEVEL1_ERROR_NAMES\ + "unknownerror", "dictfull", "dictstackoverflow", "dictstackunderflow",\ + "execstackoverflow", "interrupt", "invalidaccess", "invalidexit",\ + "invalidfileaccess", "invalidfont", "invalidrestore", "ioerror",\ + "limitcheck", "nocurrentpoint", "rangecheck", "stackoverflow",\ + "stackunderflow", "syntaxerror", "timeout", "typecheck", "undefined",\ + "undefinedfilename", "undefinedresult", "unmatchedmark", "VMerror" + + /* ------ Additional Level 2 and DPS errors ------ */ + +#define e_configurationerror (-26) +#define e_invalidcontext (-27) +#define e_undefinedresource (-28) +#define e_unregistered (-29) +/* invalidid is for the NeXT DPS extension. */ +#define e_invalidid (-30) + +#define LEVEL2_ERROR_NAMES\ + "configurationerror", "invalidcontext", "undefinedresource",\ + "unregistered", "invalidid" + +#define ERROR_NAMES LEVEL1_ERROR_NAMES, LEVEL2_ERROR_NAMES + + /* ------ Pseudo-errors used internally ------ */ + +/* + * Internal code for a fatal error. + * gs_interpret also returns this for a .quit with a positive exit code. + */ +#define e_Fatal (-100) + +/* + * Internal code for the .quit operator. + * The real quit code is an integer on the operand stack. + * gs_interpret returns this only for a .quit with a zero exit code. + */ +#define e_Quit (-101) + +/* + * Internal code for a normal exit from the interpreter. + * Do not use outside of interp.c. + */ +#define e_InterpreterExit (-102) + +/* + * Internal code that indicates that a procedure has been inserted + * on the e-stack at (former) esp+2, to be executed before retrying + * the current token. This is used for color remapping + * involving a call back into the interpreter -- inelegant, but effective. + */ +#define e_InsertProc (-103) + +/* + * Internal code to indicate we have underflowed the top block + * of the e-stack. + */ +#define e_ExecStackUnderflow (-104) + +/* + * Internal code for the vmreclaim operator with a positive operand. + * We need to handle this as an error because otherwise the interpreter + * won't reload enough of its state when the operator returns. + */ +#define e_VMreclaim (-105) + +/* + * Internal code for requesting more input from run_string. + */ +#define e_NeedInput (-106) + +/* + * Define which error codes require re-executing the current object. + */ +#define error_is_interrupt(ecode)\ + ((ecode) == e_interrupt || (ecode) == e_timeout) + +#endif /* errors_INCLUDED */ diff --git a/pstoraster/estack.h b/pstoraster/estack.h new file mode 100644 index 0000000000..2c42beace7 --- /dev/null +++ b/pstoraster/estack.h @@ -0,0 +1,139 @@ +/* Copyright (C) 1989, 1992, 1993, 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Definitions for the execution stack */ + +#ifndef estack_INCLUDED +# define estack_INCLUDED + +#include "iestack.h" + +/* There's only one exec stack right now.... */ +#define esfile (iexec_stack.current_file) +#define esfile_clear_cache() (esfile = 0) +#define esfile_set_cache(pref) (esfile = (pref)) +#define esfile_check_cache()\ + if ( r_has_type_attrs(esp, t_file, a_executable) )\ + esfile_set_cache(esp) + +/* Define the execution stack pointers. */ +extern exec_stack_t iexec_stack; + +#define e_stack (iexec_stack.stack) +#define esbot (e_stack.bot) +#define esp (e_stack.p) +#define estop (e_stack.top) + +/* + * The execution stack is used for three purposes: + * + * - Procedures being executed are held here. They always have + * type = t_array, t_mixedarray, or t_shortarray, with a_executable set. + * More specifically, the e-stack holds the as yet unexecuted tail of the + * procedure. + * + * - if, ifelse, etc. push arguments to be executed here. + * They may be any kind of object whatever. + * + * - Control operators (filenameforall, for, repeat, loop, forall, + * pathforall, run, stopped, ...) mark the stack by pushing whatever state + * they need to save or keep track of and then an object with type = t_null, + * attrs = a_executable, size = es_xxx (see below), and value.opproc = a + * cleanup procedure that will get called whenever the execution stack is + * about to get cut back beyond this point because of an error, stop, exit, + * or quit. (Executable null objects can't ever appear on the e-stack + * otherwise: if a control operator pushes one, it gets popped immediately.) + * The cleanup procedure is called with esp pointing just BELOW the mark, + * i.e., the mark has already been popped. + * + * The loop operators also push whatever state they need, + * followed by an operator object that handles continuing the loop. + * + * Note that there are many internal operators that need to be handled like + * looping operators -- for example, all the 'show' operators, since they + * may call out to BuildChar procedures. + */ + +/* Macro for marking the execution stack */ +#define make_mark_estack(ep, es_idx, proc)\ + make_tasv(ep, t_null, a_executable, es_idx, opproc, proc) +#define push_mark_estack(es_idx, proc)\ + (++esp, make_mark_estack(esp, es_idx, proc)) +#define r_is_estack_mark(ep)\ + r_has_type_attrs(ep, t_null, a_executable) +#define estack_mark_index(ep) r_size(ep) +#define set_estack_mark_index(ep, es_idx) r_set_size(ep, es_idx) + +/* Macro for pushing an operator on the execution stack */ +/* to represent a continuation procedure */ +#define make_op_estack(ep, proc)\ + make_oper(ep, 0, proc) +#define push_op_estack(proc)\ + (++esp, make_op_estack(esp, proc)) + +/* Macro to ensure enough room on the execution stack */ +#define check_estack(n)\ + if ( esp > estop - (n) )\ + { int es_code_ = ref_stack_extend(&e_stack, n);\ + if ( es_code_ < 0 ) return es_code_;\ + } + +/* Macro to ensure enough entries on the execution stack */ +#define check_esp(n)\ + if ( esp < esbot + ((n) - 1) )\ + { e_stack.requested = (n); return_error(e_ExecStackUnderflow); } + +/* Define the various kinds of execution stack marks. */ +#define es_other 0 /* internal use */ +#define es_show 1 /* show operators */ +#define es_for 2 /* iteration operators */ +#define es_stopped 3 /* stopped operator */ + +/* + * Pop a given number of elements off the execution stack, + * executing cleanup procedures as necessary. + */ +void pop_estack(P1(uint)); + +/* + * The execution stack is implemented as a linked list of blocks; + * operators that can push or pop an unbounded number of values, or that + * access the entire e-stack, must take this into account. These are: + * exit .stop .instopped countexecstack execstack currentfile + * .execn + * pop_estack(exit, stop, error recovery) + * gs_show_find(all the show operators) + * In addition, for e-stack entries created by control operators, we must + * ensure that the mark and its data are never separated. We do this + * by ensuring that when splitting the top block, at least N items + * are kept in the new top block above the bottommost retained mark, + * where N is the largest number of data items associated with a mark. + * Finally, in order to avoid specific checks for underflowing a block, + * we put a guard entry at the bottom of each block except the top one + * that contains a procedure that returns an internal "exec stack block + * underflow" error. + */ + +#endif /* estack_INCLUDED */ diff --git a/pstoraster/files.h b/pstoraster/files.h new file mode 100644 index 0000000000..bca695d4cd --- /dev/null +++ b/pstoraster/files.h @@ -0,0 +1,157 @@ +/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Requires stream.h */ + +#ifndef files_INCLUDED +# define files_INCLUDED + +/* + * File objects store a pointer to a stream in value.pfile. + * A file object is valid if its "size" matches the read_id or write_id + * (as appropriate) in the stream it points to. This arrangement + * allows us to detect closed files reliably, while allowing us to + * reuse closed streams for new files. + */ +#define fptr(pref) (pref)->value.pfile +#define make_file(pref,a,id,s)\ + make_tasv(pref,t_file,a,id,pfile,s) + +/* The stdxxx files. We have to access them through procedures, */ +/* because they might have to be opened when referenced. */ +int zget_stdin(P1(stream **)); +int zget_stdout(P1(stream **)); +int zget_stderr(P1(stream **)); +extern bool gs_stdin_is_interactive; + +/* Export the stdio refs for switching contexts. */ +extern ref ref_stdio[3]; + +#define ref_stdin ref_stdio[0] +#define ref_stdout ref_stdio[1] +#define ref_stderr ref_stdio[2] +/* An invalid (closed) file. */ +extern stream *invalid_file_entry; + +/* + * Macros for checking file validity. + * NOTE: in order to work around a bug in the Borland 5.0 compiler, + * you must use file_is_invalid rather than !file_is_valid. + */ +#define file_is_valid(svar,op)\ + (svar = fptr(op), (svar->read_id | svar->write_id) == r_size(op)) +#define file_is_invalid(svar,op)\ + (svar = fptr(op), (svar->read_id | svar->write_id) != r_size(op)) +#define check_file(svar,op)\ + BEGIN\ + check_type(*(op), t_file);\ + if ( file_is_invalid(svar, op) ) return_error(e_invalidaccess);\ + END + +/* + * If a file is open for both reading and writing, its read_id, write_id, + * and stream procedures and modes reflect the current mode of use; + * an id check failure will switch it to the other mode. + */ +int file_switch_to_read(P1(const ref *)); + +#define check_read_file(svar,op)\ + BEGIN\ + check_read_type(*(op), t_file);\ + check_read_known_file(svar, op, return);\ + END +#define check_read_known_file(svar,op,error_return)\ + check_read_known_file_else(svar, op, error_return, svar = invalid_file_entry) +/* The do... avoids problems with a possible enclosed 'if'. */ +#define check_read_known_file_else(svar,op,error_return,invalid_action)\ + BEGIN\ + svar = fptr(op);\ + if ( svar->read_id != r_size(op) )\ + { if ( svar->read_id == 0 && svar->write_id == r_size(op) )\ + { int fcode = file_switch_to_read(op);\ + if ( fcode < 0 ) error_return(fcode);\ + }\ + else BEGIN invalid_action; END; /* closed or reopened file */\ + }\ + END +int file_switch_to_write(P1(const ref *)); + +#define check_write_file(svar,op)\ + BEGIN\ + check_write_type(*(op), t_file);\ + check_write_known_file(svar, op, return);\ + END +#define check_write_known_file(svar,op,error_return)\ + BEGIN\ + svar = fptr(op);\ + if ( svar->write_id != r_size(op) )\ + { int fcode = file_switch_to_write(op);\ + if ( fcode < 0 ) error_return(fcode);\ + }\ + END + +/* Data exported by zfile.c. */ + /* for zfilter.c and ziodev.c */ +extern const uint file_default_buffer_size; + +/* Procedures exported by zfile.c. */ + /* for imainarg.c */ +FILE *lib_fopen(P1(const char *)); + + /* for imain.c */ +int lib_file_open(P6(const char *, uint, byte *, uint, uint *, ref *)); + + /* for iccinit.c */ +int file_read_string(P3(const byte *, uint, ref *)); + + /* for os_open in ziodev.c */ +#ifdef iodev_proc_fopen /* in gxiodev.h */ +int file_open_stream(P6(const char *, uint, const char *, uint, + stream **, iodev_proc_fopen_t)); + +#endif + /* for zfilter.c */ +int filter_open(P6(const char *, uint, ref *, const stream_procs *, + const stream_template *, const stream_state *)); + + /* for zfileio.c */ +void make_stream_file(P3(ref *, stream *, const char *)); + + /* for ziodev.c */ +int file_close_finish(P1(stream *)); +int file_close_disable(P1(stream *)); +int file_close_file(P1(stream *)); + + /* for gsmain.c, interp.c */ +int file_close(P1(ref *)); + + /* for zfproc.c, ziodev.c */ +stream *file_alloc_stream(P2(gs_memory_t *, client_name_t)); + +/* Procedures exported by zfileio.c. */ + /* for ziodev.c */ +int zreadline_from(P5(stream *, byte *, uint, uint *, bool *)); + +#endif /* files_INCLUDED */ diff --git a/pstoraster/fname.h b/pstoraster/fname.h new file mode 100644 index 0000000000..f6eeb8c73e --- /dev/null +++ b/pstoraster/fname.h @@ -0,0 +1,54 @@ +/* Copyright (C) 1993, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Requires gxiodev.h */ + +#ifndef fname_INCLUDED +# define fname_INCLUDED + +/* + * Define a structure for representing a parsed file name, consisting of + * an IODevice name in %'s, a file name, or both. Note that the file name + * may be either a gs_string (no terminator) or a C string (null terminator). + */ +typedef struct parsed_file_name_s { + gx_io_device *iodev; + const char *fname; + uint len; +} parsed_file_name; + +/* Parse a file name into device and individual name. */ +int parse_file_name(P2(const ref *, parsed_file_name *)); + +/* Parse a real (non-device) file name and convert to a C string. */ +int parse_real_file_name(P3(const ref *, parsed_file_name *, client_name_t)); + +/* Convert a file name to a C string by adding a null terminator. */ +int terminate_file_name(P2(parsed_file_name *, client_name_t)); + +/* Free a file name that was copied to a C string. */ +void free_file_name(P2(parsed_file_name *, client_name_t)); + +#endif /* fname_INCLUDED */ diff --git a/pstoraster/gconf.h b/pstoraster/gconf.h new file mode 100644 index 0000000000..0317aa9038 --- /dev/null +++ b/pstoraster/gconf.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Wrapper for gconfig.h or a substitute. */ + +/* + * NOTA BENE: This file, unlike all other header files, must *not* have + * double-inclusion protection, since it is used in peculiar ways. + */ + +/* + * Since not all C preprocessors implement #include with a non-quoted + * argument, we arrange things so that we can still compile with such + * compilers as long as GCONFIG_H isn't defined. + */ + +#ifndef GCONFIG_H +# include "gconfig.h" +#else +# include GCONFIG_H +#endif diff --git a/pstoraster/gconfig.c b/pstoraster/gconfig.c new file mode 100644 index 0000000000..71d5b106fb --- /dev/null +++ b/pstoraster/gconfig.c @@ -0,0 +1,127 @@ +/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Configuration tables */ +#include "memory_.h" +#include "gx.h" +#include "gscdefs.h" /* interface */ +#include "gconf.h" /* for #defines */ +#include "gxdevice.h" +#include "gxiodev.h" + +/* + * The makefile generates the file gconfig.h, which consists of + * lines of the form + * device_(gs_xxx_device) + * or + * device2_(gs_xxx_device) + * for each installed device; + * emulator_("emulator", strlen("emulator")) + * for each known emulator; + * init_(gs_xxx_init) + * for each initialization procedure; + * io_device_(gs_iodev_xxx) + * for each known IODevice; + * oper_(xxx_op_defs) + * for each operator option; + * psfile_("gs_xxxx.ps", strlen("gs_xxxx.ps")) + * for each optional initialization file. + * + * We include this file multiple times to generate various different + * source structures. (It's a hack, but we haven't come up with anything + * more satisfactory.) + */ + +/* ---------------- Resources (devices, inits, IODevices) ---------------- */ + +/* Declare devices, init procedures, and IODevices as extern. */ +#define device_(dev) extern far_data gx_device dev; +#define device2_(dev) extern const gx_device dev; +#define init_(proc) extern void proc(P1(gs_memory_t *)); +#define io_device_(iodev) extern const gx_io_device iodev; +#include "gconf.h" +#undef init_ +#undef io_device_ +#undef device2_ +#undef device_ + +/* Set up the initialization procedure table. */ +extern_gx_init_table(); +private void gconf_init(P1(gs_memory_t *)); +#define init_(proc) proc, +const gx_init_proc gx_init_table[] = { +#include "gconf.h" + gconf_init, + 0 +}; +#undef init_ + +/* Set up the IODevice table. The first entry must be %os%, */ +/* since it is the default for files with no explicit device specified. */ +extern_gx_io_device_table(); +extern gx_io_device gs_iodev_os; +#define io_device_(iodev) &iodev, +const gx_io_device *const gx_io_device_table[] = { + &gs_iodev_os, +#include "gconf.h" + 0 +}; +#undef io_device_ +const uint gx_io_device_table_count = countof(gx_io_device_table) - 1; + +/* Set up the device table. */ +#define device_(dev) (const gx_device *)&dev, +#define device2_(dev) &dev, +private const gx_device *const gx_device_list[] = { +#include "gconf.h" + 0 +}; +#undef device2_ +#undef device_ + +/* Allocate and initialize structure descriptors for the devices. */ +private gs_memory_struct_type_t gx_device_st_list[countof(gx_device_list) - 1]; +private void +gconf_init(gs_memory_t *mem) +{ + int i; + + for (i = 0; i < countof(gx_device_list) - 1; ++i) + gx_device_make_struct_type(&gx_device_st_list[i], gx_device_list[i]); +} + +/* Return the list of device prototypes, the list of their structure */ +/* descriptors, and (as the value) the length of the lists. */ +extern_gs_lib_device_list(); +int +gs_lib_device_list(const gx_device * const **plist, + gs_memory_struct_type_t ** pst) +{ + if (plist != 0) + *plist = gx_device_list; + if (pst != 0) + *pst = gx_device_st_list; + return countof(gx_device_list) - 1; +} diff --git a/pstoraster/gconfig.h b/pstoraster/gconfig.h new file mode 100644 index 0000000000..9d451fdbec --- /dev/null +++ b/pstoraster/gconfig.h @@ -0,0 +1,243 @@ +/* + * "$Id$" + * + * GNU GhostScript configuration file for the Common UNIX Printing + * System (CUPS). + * + * This file is normally generated by a lot of echogs and genconf + * commands... + * + * Copyright 1997-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + */ + +#include + +#ifdef device2_ +device2_(gs_cups_device) +device2_(gs_bbox_device) +/*device2_(gs_nullpage_device)*/ +#endif +#ifdef oper_ +oper_(zchar1_op_defs) +oper_(zfont1_op_defs) +oper_(zmisc1_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_type1.ps",11) +#endif +#ifdef oper_ +oper_(zvmem2_op_defs) +oper_(zdps1_l2_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_dps1.ps",10) +#endif +#ifdef oper_ +oper_(zusparam_op_defs) +oper_(zmisc2_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_lev2.ps",10) +psfile_("gs_res.ps",9) +#endif +#ifdef oper_ +oper_(zchar42_op_defs) +oper_(zfont42_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_typ42.ps",11) +psfile_("gs_cidfn.ps",11) +#endif +#ifdef oper_ +oper_(zcid_op_defs) +oper_(zcie_l2_op_defs) +oper_(zcrd_l2_op_defs) +oper_(zfcmap_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_cmap.ps",10) +#endif +#ifdef oper_ +oper_(zcfont_op_defs) +oper_(zfont0_op_defs) +# ifdef HAVE_LIBJPEG +oper_(zfdcte_op_defs) +oper_(zfdctd_op_defs) +# endif /* HAVE_LIBJPEG */ +oper_(zbseq_l2_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_btokn.ps",11) +#endif +#ifdef init_ +init_(gs_gxicolor_init) +#endif +#ifdef oper_ +oper_(zcolor1_op_defs) +oper_(zht1_op_defs) +oper_(zupath_l2_op_defs) +oper_(ireclaim_l2_op_defs) +oper_(zchar2_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_dps2.ps",10) +#endif +#ifdef oper_ +oper_(zfdecode_op_defs) +oper_(zfilter2_op_defs) +oper_(ziodev2_l2_op_defs) +#endif +#ifdef io_device_ +io_device_(gs_iodev_null) +io_device_(gs_iodev_ram) +io_device_(gs_iodev_calendar) +#endif +#ifdef oper_ +oper_(zdevice2_l2_op_defs) +oper_(zmedia2_l2_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_setpd.ps",11) +#endif +#ifdef oper_ +oper_(zpcolor_l2_op_defs) +oper_(zarith_op_defs) +oper_(zarray_op_defs) +oper_(zcontrol_op_defs) +oper_(zdict_op_defs) +oper_(zfile_op_defs) +oper_(zfileio_op_defs) +oper_(zfilter_op_defs) +oper_(zfproc_op_defs) +oper_(zgeneric_op_defs) +oper_(ziodev_op_defs) +oper_(zmath_op_defs) +oper_(zmisc_op_defs) +oper_(zpacked_op_defs) +oper_(zrelbit_op_defs) +oper_(zstack_op_defs) +oper_(zstring_op_defs) +oper_(zsysvm_op_defs) +oper_(ztoken_op_defs) +oper_(ztype_op_defs) +oper_(zvmem_op_defs) +oper_(zchar_op_defs) +oper_(zcolor_op_defs) +oper_(zdevice_op_defs) +oper_(zfont_op_defs) +oper_(zfont2_op_defs) +oper_(zgstate_op_defs) +oper_(zht_op_defs) +oper_(zimage_op_defs) +oper_(zmatrix_op_defs) +oper_(zpaint_op_defs) +oper_(zpath_op_defs) +#endif +#ifdef io_device_ +io_device_(gs_iodev_stdin) +io_device_(gs_iodev_stdout) +io_device_(gs_iodev_stderr) +io_device_(gs_iodev_lineedit) +io_device_(gs_iodev_statementedit) +#endif +#ifdef oper_ +oper_(zfbcp_op_defs) +oper_(zhsb_op_defs) +oper_(zpath1_op_defs) +#endif +#ifdef init_ +init_(gs_gstype1_init) +#endif +#ifdef emulator_ +emulator_("PostScript",10) +emulator_("PostScriptLevel1",16) +#endif +#ifdef init_ +init_(gs_gxi12bit_init) +init_(gs_gxiscale_init) +#endif +#ifdef oper_ +oper_(zcolor2_l2_op_defs) +oper_(zcsindex_l2_op_defs) +oper_(zht2_l2_op_defs) +oper_(zimage2_l2_op_defs) +oper_(zcssepr_l2_op_defs) +oper_(zchar32_op_defs) +oper_(zfont32_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_typ32.ps",11) +#endif +#ifdef oper_ +oper_(zfilterx_op_defs) +#endif +#ifdef emulator_ +emulator_("PostScriptLevel2",16) +#endif +#ifdef oper_ +oper_(zcspixel_op_defs) +oper_(zfunc_op_defs) +oper_(zfunc0_op_defs) +oper_(zcsdevn_op_defs) +oper_(zfreuse_op_defs) +oper_(zfunc3_op_defs) +oper_(zimage3_op_defs) +oper_(zmisc3_op_defs) +oper_(zshade_op_defs) +oper_(ztrap_op_defs) +#endif +#ifdef psfile_ +psfile_("gs_ll3.ps",9) +#endif +#ifdef oper_ +# ifdef HAVE_LIBZ +oper_(zfzlib_op_defs) +# endif /* HAVE_LIBZ */ +#endif +#ifdef psfile_ +psfile_("gs_mex_e.ps",11) +psfile_("gs_mro_e.ps",11) +psfile_("gs_wan_e.ps",11) +psfile_("gs_cff.ps",9) +psfile_("gs_ttf.ps",9) +#endif +#ifdef init_ +init_(gs_gstype2_init) +#endif +#ifdef io_device_ +io_device_(gs_iodev_pipe) +#endif +#ifdef psfile_ +psfile_("gs_epsf.ps",10) +#endif +#ifdef init_ +# ifdef HAVE_LIBZ +init_(gs_cl_zlib_init) +# endif /* HAVE_LIBZ */ +init_(gs_gshtscr_init) +init_(gs_gsutil_init) +init_(gs_gxcht_init) +init_(gs_gxifast_init) +init_(gs_gximono_init) +#endif +#define SEARCH_HERE_FIRST 1 + +/* + * End of "$Id$". + */ diff --git a/pstoraster/gconfig_.h b/pstoraster/gconfig_.h new file mode 100644 index 0000000000..518b790206 --- /dev/null +++ b/pstoraster/gconfig_.h @@ -0,0 +1,5 @@ +/* This file was generated automatically. */ +#define HAVE_DIRENT_H +#define HAVE_SYS_DIR_H +#define HAVE_SYS_TIME_H +#define HAVE_SYS_TIMES_H diff --git a/pstoraster/gconfigv.h b/pstoraster/gconfigv.h new file mode 100644 index 0000000000..a9ae98b88b --- /dev/null +++ b/pstoraster/gconfigv.h @@ -0,0 +1,4 @@ +#define USE_ASM (-0) +#define USE_FPU (1-0) +#define EXTEND_NAMES 0 +#define SYSTEM_CONSTANTS_ARE_WRITABLE 0 diff --git a/pstoraster/gdebug.h b/pstoraster/gdebug.h new file mode 100644 index 0000000000..9b14802488 --- /dev/null +++ b/pstoraster/gdebug.h @@ -0,0 +1,132 @@ +/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Debugging machinery definitions */ + +#ifndef gdebug_INCLUDED +# define gdebug_INCLUDED + +/* + * The compile-time DEBUG symbol determines whether debugging/tracing + * code is included in the compiled code. DEBUG may be set or not set + * independently for every compilation; however, a small amount of support + * machinery in gsmisc.c is always included in the executable, just + * in case *some* file was compiled with DEBUG set. + * + * When DEBUG is set, it does not cause debugging/tracing printout to occur. + * Rather, it includes code that produces such printout *if* (a) given + * one(s) of 128 debugging flags is set. In this way, one can selectively + * turn printout on and off during debugging. (In fact, we even provide a + * PostScript operator, .setdebug, that does this.) + * + * The debugging flags are normally indexed by character code. This is more + * than a convention: gs_debug_c, which tests whether a given flag is set, + * considers that if a flag named by a given upper-case letter is set, the + * flag named by the corresponding lower-case letter is also set. + * + * If the output selected by a given flag can be printed by a single + * printf, the conventional way to produce the output is + * if_debugN('x', "...format...", v1, ..., vN); + * Usually the flag appears in the output explicitly: + * if_debugN('x', "[x]...format...", v1, ..., vN); + * If the output is more complex, the conventional way to produce the + * output is + * if ( gs_debug_c('x') ) { + * ... start each line with dlprintfN(...) + * ... produce additional output within a line with dprintfN(...) + * } */ + +/* Define the array of debugging flags, indexed by character code. */ +extern char gs_debug[128]; +bool gs_debug_c(P1(int /*char */ )); + +/* + * Define an alias for a specialized debugging flag + * that used to be a separate variable. + */ +#define gs_log_errors gs_debug['#'] + +/* If debugging, direct all error output to gs_debug_out. */ +extern FILE *gs_debug_out; + +#ifdef DEBUG +#undef dstderr +#define dstderr gs_debug_out +#undef estderr +#define estderr gs_debug_out +#endif + +/* Debugging printout macros. */ +#ifdef DEBUG +# define if_debug0(c,s)\ + BEGIN if (gs_debug_c(c)) dlprintf(s); END +# define if_debug1(c,s,a1)\ + BEGIN if (gs_debug_c(c)) dlprintf1(s,a1); END +# define if_debug2(c,s,a1,a2)\ + BEGIN if (gs_debug_c(c)) dlprintf2(s,a1,a2); END +# define if_debug3(c,s,a1,a2,a3)\ + BEGIN if (gs_debug_c(c)) dlprintf3(s,a1,a2,a3); END +# define if_debug4(c,s,a1,a2,a3,a4)\ + BEGIN if (gs_debug_c(c)) dlprintf4(s,a1,a2,a3,a4); END +# define if_debug5(c,s,a1,a2,a3,a4,a5)\ + BEGIN if (gs_debug_c(c)) dlprintf5(s,a1,a2,a3,a4,a5); END +# define if_debug6(c,s,a1,a2,a3,a4,a5,a6)\ + BEGIN if (gs_debug_c(c)) dlprintf6(s,a1,a2,a3,a4,a5,a6); END +# define if_debug7(c,s,a1,a2,a3,a4,a5,a6,a7)\ + BEGIN if (gs_debug_c(c)) dlprintf7(s,a1,a2,a3,a4,a5,a6,a7); END +# define if_debug8(c,s,a1,a2,a3,a4,a5,a6,a7,a8)\ + BEGIN if (gs_debug_c(c)) dlprintf8(s,a1,a2,a3,a4,a5,a6,a7,a8); END +# define if_debug9(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9)\ + BEGIN if (gs_debug_c(c)) dlprintf9(s,a1,a2,a3,a4,a5,a6,a7,a8,a9); END +# define if_debug10(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10)\ + BEGIN if (gs_debug_c(c)) dlprintf10(s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10); END +# define if_debug11(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11)\ + BEGIN if (gs_debug_c(c)) dlprintf11(s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11); END +# define if_debug12(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12)\ + BEGIN if (gs_debug_c(c)) dlprintf12(s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12); END +#else +# define if_debug0(c,s) DO_NOTHING +# define if_debug1(c,s,a1) DO_NOTHING +# define if_debug2(c,s,a1,a2) DO_NOTHING +# define if_debug3(c,s,a1,a2,a3) DO_NOTHING +# define if_debug4(c,s,a1,a2,a3,a4) DO_NOTHING +# define if_debug5(c,s,a1,a2,a3,a4,a5) DO_NOTHING +# define if_debug6(c,s,a1,a2,a3,a4,a5,a6) DO_NOTHING +# define if_debug7(c,s,a1,a2,a3,a4,a5,a6,a7) DO_NOTHING +# define if_debug8(c,s,a1,a2,a3,a4,a5,a6,a7,a8) DO_NOTHING +# define if_debug9(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9) DO_NOTHING +# define if_debug10(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10) DO_NOTHING +# define if_debug11(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11) DO_NOTHING +# define if_debug12(c,s,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12) DO_NOTHING +#endif + +/* Debugging support procedures in gsmisc.c */ +void debug_dump_bytes(P3(const byte * from, const byte * to, + const char *msg)); +void debug_dump_bitmap(P4(const byte * from, uint raster, uint height, + const char *msg)); +void debug_print_string(P2(const byte * str, uint len)); + +#endif /* gdebug_INCLUDED */ diff --git a/pstoraster/gdev8bcm.h b/pstoraster/gdev8bcm.h new file mode 100644 index 0000000000..f9f6781142 --- /dev/null +++ b/pstoraster/gdev8bcm.h @@ -0,0 +1,78 @@ +/* Copyright (C) 1994 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Requires gxdevice.h (for gx_color_value) */ + +#ifndef gdev8bcm_INCLUDED +# define gdev8bcm_INCLUDED + +/* + * The MS-DOS, MS Windows, and X Windows drivers all use (at least on + * some platforms) an 8-bit color map in which some fraction is reserved + * for a pre-allocated cube and some or all of the remainder is + * allocated dynamically. Since looking up colors in this map can be + * a major performance bottleneck, we provide an efficient implementation + * that can be shared among drivers. + * + * As a performance compromise, we only look up the top 5 bits of the + * RGB value in the color map. This compromises color quality very little, + * and allows substantial optimizations. + */ + +#define gx_8bit_map_size 323 +#define gx_8bit_map_spreader 123 /* approx. 323 - (1.618 * 323) */ +typedef struct gx_8bit_map_entry_s { + ushort rgb; /* key = 0rrrrrgggggbbbbb */ +#define gx_8bit_no_rgb ((ushort)0xffff) +#define gx_8bit_rgb_key(r, g, b)\ + (((r >> (gx_color_value_bits - 5)) << 10) +\ + ((g >> (gx_color_value_bits - 5)) << 5) +\ + (b >> (gx_color_value_bits - 5))) + short index; /* value */ +} gx_8bit_map_entry; +typedef struct gx_8bit_color_map_s { + int count; /* # of occupied entries */ + int max_count; /* max # of occupied entries */ + gx_8bit_map_entry map[gx_8bit_map_size + 1]; +} gx_8bit_color_map; + +/* Initialize an 8-bit color map. */ +void gx_8bit_map_init(P2(gx_8bit_color_map *, int)); + +/* Look up a color in an 8-bit color map. */ +/* Return -1 if not found. */ +int gx_8bit_map_rgb_color(P4(const gx_8bit_color_map *, gx_color_value, + gx_color_value, gx_color_value)); + +/* Test whether an 8-bit color map has room for more entries. */ +#define gx_8bit_map_is_full(pcm)\ + ((pcm)->count == (pcm)->max_count) + +/* Add a color to an 8-bit color map. */ +/* Return -1 if the map is full. */ +int gx_8bit_add_rgb_color(P4(gx_8bit_color_map *, gx_color_value, + gx_color_value, gx_color_value)); + +#endif /* gdev8bcm_INCLUDED */ diff --git a/pstoraster/gdevabuf.c b/pstoraster/gdevabuf.c new file mode 100644 index 0000000000..991584c04a --- /dev/null +++ b/pstoraster/gdevabuf.c @@ -0,0 +1,404 @@ +/* Copyright (C) 1994, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Alpha-buffering memory devices */ +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gxdevice.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +/* ================ Alpha devices ================ */ + +/* + * These devices store 2 or 4 bits of alpha. They are a hybrid of a + * monobit device (for color mapping) and a 2- or 4-bit device (for painting). + * Currently, we only use them for character rasterizing, but they might be + * useful for other things someday. + */ + +/* We can't initialize the device descriptor statically very well, */ +/* so we patch up the image2 or image4 descriptor. */ +private dev_proc_map_rgb_color(mem_alpha_map_rgb_color); +private dev_proc_map_color_rgb(mem_alpha_map_color_rgb); +private dev_proc_map_rgb_alpha_color(mem_alpha_map_rgb_alpha_color); +private dev_proc_get_alpha_bits(mem_alpha_get_alpha_bits); +private dev_proc_copy_alpha(mem_alpha_copy_alpha); + +void +gs_make_mem_alpha_device(gx_device_memory * adev, gs_memory_t * mem, + gx_device * target, int alpha_bits) +{ + gs_make_mem_device(adev, gdev_mem_device_for_bits(alpha_bits), + mem, 0, target); + /* This is a black-and-white device ... */ + adev->color_info = gdev_mem_device_for_bits(1)->color_info; + /* ... but it has multiple bits per pixel ... */ + adev->color_info.depth = alpha_bits; + /* ... and different color mapping. */ + set_dev_proc(adev, map_rgb_color, mem_alpha_map_rgb_color); + set_dev_proc(adev, map_color_rgb, mem_alpha_map_color_rgb); + set_dev_proc(adev, map_rgb_alpha_color, mem_alpha_map_rgb_alpha_color); + set_dev_proc(adev, get_alpha_bits, mem_alpha_get_alpha_bits); + set_dev_proc(adev, copy_alpha, mem_alpha_copy_alpha); +} + +/* Reimplement color mapping. */ +private gx_color_index +mem_alpha_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g, + gx_color_value b) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + gx_color_index color = gx_forward_map_rgb_color(dev, r, g, b); + + return (color == 0 || color == gx_no_color_index ? color : + (gx_color_index) ((1 << mdev->log2_alpha_bits) - 1)); +} +private int +mem_alpha_map_color_rgb(gx_device * dev, gx_color_index color, + gx_color_value prgb[3]) +{ + return + gx_forward_map_color_rgb(dev, + (color == 0 ? color : (gx_color_index) 1), + prgb); +} +private gx_color_index +mem_alpha_map_rgb_alpha_color(gx_device * dev, gx_color_value r, + gx_color_value g, gx_color_value b, gx_color_value alpha) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + gx_color_index color = gx_forward_map_rgb_color(dev, r, g, b); + + return (color == 0 || color == gx_no_color_index ? color : + (gx_color_index) (alpha >> (gx_color_value_bits - + mdev->log2_alpha_bits))); +} +private int +mem_alpha_get_alpha_bits(gx_device * dev, graphics_object_type type) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + return 1 << mdev->log2_alpha_bits; +} +/* Implement alpha copying. */ +private int +mem_alpha_copy_alpha(gx_device * dev, const byte * data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + gx_color_index color, int depth) +{ /* Just use copy_color. */ + return (color == 0 ? + (*dev_proc(dev, fill_rectangle)) (dev, x, y, width, height, + color) : + (*dev_proc(dev, copy_color)) (dev, data, data_x, raster, id, + x, y, width, height)); +} + +/* ================ Alpha-buffer device ================ */ + +/* + * This device converts graphics sampled at a higher resolution to + * alpha values at a lower resolution. It does this by accumulating + * the bits of a band and then converting the band to alphas. + * In order to make this work, the client of the device must promise + * only to visit each band at most once, except possibly for a single + * scan line overlapping the adjacent band, and must promise only to write + * a single color into the output. In particular, this works + * within a single call on gx_fill_path (if the fill loop is constrained + * to process bands of limited height on each pass) or a single masked image + * scanned in Y order, but not across such calls and not for other + * kinds of painting operations. + * + * We implement this device as a subclass of a monobit memory device. + * (We put its state in the definition of gx_device_memory just because + * actual subclassing introduces a lot of needless boilerplate.) + * We only allocate enough bits for one band. The height of the band + * must be a multiple of the Y scale factor; the minimum height + * of the band is twice the Y scale factor. + * + * The bits in storage are actually a sliding window on the true + * oversampled image. To avoid having to copy the bits around when we + * move the window, we adjust the mapping between the client's Y values + * and our own, as follows: + * Client Stored + * ------ ------ + * y0..y0+m-1 n-m..n-1 + * y0+m..y0+n-1 0..n-m-1 + * where n and m are multiples of the Y scale factor and 0 <= m <= n <= + * the height of the band. (In the device structure, m is called + * mapped_start and n is called mapped_height.) This allows us to slide + * the window incrementally in either direction without copying any bits. + */ + +/* Procedures */ +private dev_proc_close_device(mem_abuf_close); +private dev_proc_copy_mono(mem_abuf_copy_mono); +private dev_proc_fill_rectangle(mem_abuf_fill_rectangle); +private dev_proc_get_clipping_box(mem_abuf_get_clipping_box); + +/* The device descriptor. */ +private const gx_device_memory mem_alpha_buffer_device = +mem_device("image(alpha buffer)", 0, 1, + gx_forward_map_rgb_color, gx_forward_map_color_rgb, + mem_abuf_copy_mono, gx_default_copy_color, mem_abuf_fill_rectangle, + gx_no_strip_copy_rop); + +/* Make an alpha-buffer memory device. */ +/* We use abuf instead of alpha_buffer because */ +/* gcc under VMS only retains 23 characters of procedure names. */ +void +gs_make_mem_abuf_device(gx_device_memory * adev, gs_memory_t * mem, + gx_device * target, const gs_log2_scale_point * pscale, + int alpha_bits, int mapped_x) +{ + gs_make_mem_device(adev, &mem_alpha_buffer_device, mem, 0, target); + adev->max_fill_band = 1 << pscale->y; + adev->log2_scale = *pscale; + adev->log2_alpha_bits = alpha_bits >> 1; /* works for 1,2,4 */ + adev->mapped_x = mapped_x; + set_dev_proc(adev, close_device, mem_abuf_close); + set_dev_proc(adev, get_clipping_box, mem_abuf_get_clipping_box); +} + +/* Test whether a device is an alpha-buffering device. */ +bool +gs_device_is_abuf(const gx_device * dev) +{ /* We can't just compare the procs, or even an individual proc, */ + /* because we might be tracing. Instead, check the identity of */ + /* the device name. */ + return dev->dname == mem_alpha_buffer_device.dname; +} + +/* Internal routine to flush a block of the buffer. */ +/* A block is a group of scan lines whose initial Y is a multiple */ +/* of the Y scale and whose height is equal to the Y scale. */ +private int +abuf_flush_block(gx_device_memory * adev, int y) +{ + gx_device *target = adev->target; + int block_height = 1 << adev->log2_scale.y; + int alpha_bits = 1 << adev->log2_alpha_bits; + int ddepth = + (adev->width >> adev->log2_scale.x) << adev->log2_alpha_bits; + uint draster = bitmap_raster(ddepth); + int buffer_y = y - adev->mapped_y + adev->mapped_start; + byte *bits; + + if (buffer_y >= adev->height) + buffer_y -= adev->height; + bits = scan_line_base(adev, buffer_y); + { /* + * Many bits are typically zero. Save time by computing + * an accurate X bounding box before compressing. + * Unfortunately, in order to deal with alpha nibble swapping + * (see gsbitops.c), we can't expand the box only to pixel + * boundaries: + int alpha_mask = -1 << adev->log2_alpha_bits; + * Instead, we must expand it to byte boundaries, + */ + int alpha_mask = ~7; + gs_int_rect bbox; + int width; + + bits_bounding_box(bits, block_height, adev->raster, &bbox); + bbox.p.x &= alpha_mask; + bbox.q.x = (bbox.q.x + ~alpha_mask) & alpha_mask; + width = bbox.q.x - bbox.p.x; + bits_compress_scaled(bits, bbox.p.x, width, block_height, + adev->raster, bits, draster, &adev->log2_scale, + adev->log2_alpha_bits); + return (*dev_proc(target, copy_alpha)) (target, + bits, 0, draster, gx_no_bitmap_id, + (adev->mapped_x + bbox.p.x) >> + adev->log2_scale.x, + y >> adev->log2_scale.y, + width >> adev->log2_scale.x, 1, + adev->save_color, alpha_bits); + } +} +/* Flush the entire buffer. */ +private int +abuf_flush(gx_device_memory * adev) +{ + int y, code = 0; + int block_height = 1 << adev->log2_scale.y; + + for (y = 0; y < adev->mapped_height; y += block_height) + if ((code = abuf_flush_block(adev, adev->mapped_y + y)) < 0) + return code; + adev->mapped_height = adev->mapped_start = 0; + return 0; +} + +/* Close the device, flushing the buffer. */ +private int +mem_abuf_close(gx_device * dev) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + int code = abuf_flush(mdev); + + if (code < 0) + return code; + return mem_close(dev); +} + +/* + * Framework for mapping a requested imaging operation to the buffer. + * For now, we assume top-to-bottom transfers and use a very simple algorithm. + */ +typedef struct y_transfer_s { + int y_next; + int height_left; + int transfer_y; + int transfer_height; +} y_transfer; +private void near +y_transfer_init(y_transfer * pyt, gx_device * dev, int ty, int th) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + int bh = 1 << mdev->log2_scale.y; + + if (ty < mdev->mapped_y || ty > mdev->mapped_y + mdev->mapped_height) { + abuf_flush(mdev); + mdev->mapped_y = ty & -bh; + mdev->mapped_height = bh; + memset(scan_line_base(mdev, 0), 0, bh * mdev->raster); + } + pyt->y_next = ty; + pyt->height_left = th; + pyt->transfer_height = 0; +} +/* while ( yt.height_left > 0 ) { y_transfer_next(&yt, mdev); ... } */ +private void near +y_transfer_next(y_transfer * pyt, gx_device * dev) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + int my = mdev->mapped_y, mh = mdev->mapped_height; + int ms = mdev->mapped_start; + int ty = pyt->y_next += pyt->transfer_height; + int th = pyt->height_left; + int bh = 1 << mdev->log2_scale.y; + + /* From here on, we know that my <= ty <= my + mh. */ + int tby, tbh; + + if (ty == my + mh) { /* Add a new block at my1. */ + if (mh == mdev->height) { + abuf_flush_block(mdev, my); + mdev->mapped_y = my += bh; + if ((mdev->mapped_start = ms += bh) == mh) + mdev->mapped_start = ms = 0; + } else { /* Because we currently never extend backwards, */ + /* we know we can't wrap around in this case. */ + mdev->mapped_height = mh += bh; + } + memset(scan_line_base(mdev, (ms == 0 ? mh : ms) - bh), + 0, bh * mdev->raster); + } + /* Now we know that my <= ty < my + mh. */ + tby = ty - my + ms; + if (tby < mdev->height) { + tbh = mdev->height - ms; + if (tbh > mh) + tbh = mh; + tbh -= tby - ms; + } else { /* wrap around */ + tby -= mdev->height; + tbh = ms + mh - dev->height - tby; + } + if_debug7('v', "[v]my=%d, mh=%d, ms=%d, ty=%d, th=%d, tby=%d, tbh=%d\n", + my, mh, ms, ty, th, tby, tbh); + if (tbh > th) + tbh = th; + pyt->height_left = th - tbh; + pyt->transfer_y = tby; + pyt->transfer_height = tbh; +} + +/* Copy a monobit image. */ +private int +mem_abuf_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + y_transfer yt; + + if (zero != gx_no_color_index || one == gx_no_color_index) + return_error(gs_error_undefinedresult); + x -= mdev->mapped_x; + fit_copy_xyw(dev, base, sourcex, sraster, id, x, y, w, h); /* don't limit h */ + if (w <= 0 || h <= 0) + return 0; + mdev->save_color = one; + y_transfer_init(&yt, dev, y, h); + while (yt.height_left > 0) { + y_transfer_next(&yt, dev); + (*dev_proc(&mem_mono_device, copy_mono)) (dev, + base + (yt.y_next - y) * sraster, + sourcex, sraster, gx_no_bitmap_id, + x, yt.transfer_y, w, yt.transfer_height, + gx_no_color_index, (gx_color_index) 1); + } + return 0; +} + +/* Fill a rectangle. */ +private int +mem_abuf_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + y_transfer yt; + + x -= mdev->mapped_x; + fit_fill_xy(dev, x, y, w, h); + fit_fill_w(dev, x, w); /* don't limit h */ + /* or check w <= 0, h <= 0 */ + mdev->save_color = color; + y_transfer_init(&yt, dev, y, h); + while (yt.height_left > 0) { + y_transfer_next(&yt, dev); + (*dev_proc(&mem_mono_device, fill_rectangle)) (dev, + x, yt.transfer_y, w, yt.transfer_height, + (gx_color_index) 1); + } + return 0; +} + +/* Get the clipping box. We must scale this up by the number of alpha bits. */ +private void +mem_abuf_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + gx_device *tdev = mdev->target; + + (*dev_proc(tdev, get_clipping_box)) (tdev, pbox); + pbox->p.x <<= mdev->log2_scale.x; + pbox->p.y <<= mdev->log2_scale.y; + pbox->q.x <<= mdev->log2_scale.x; + pbox->q.y <<= mdev->log2_scale.y; +} diff --git a/pstoraster/gdevbbox.c b/pstoraster/gdevbbox.c new file mode 100644 index 0000000000..5641b36752 --- /dev/null +++ b/pstoraster/gdevbbox.c @@ -0,0 +1,1069 @@ +/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Device for tracking bounding box */ +#include "math_.h" +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gsparam.h" +#include "gxdevice.h" +#include "gsdevice.h" /* requires gsmatrix.h */ +#include "gdevbbox.h" +#include "gxdcolor.h" /* for gx_device_black/white */ +#include "gxiparam.h" /* for image source size */ +#include "gxistate.h" +#include "gxpaint.h" +#include "gxpath.h" +#include "gxcpath.h" + +/* GC descriptor */ +public_st_device_bbox(); + +/* Device procedures */ +private dev_proc_open_device(bbox_open_device); +private dev_proc_close_device(bbox_close_device); +private dev_proc_output_page(bbox_output_page); +private dev_proc_fill_rectangle(bbox_fill_rectangle); +private dev_proc_copy_mono(bbox_copy_mono); +private dev_proc_copy_color(bbox_copy_color); +private dev_proc_get_params(bbox_get_params); +private dev_proc_put_params(bbox_put_params); +private dev_proc_copy_alpha(bbox_copy_alpha); +private dev_proc_fill_path(bbox_fill_path); +private dev_proc_stroke_path(bbox_stroke_path); +private dev_proc_fill_mask(bbox_fill_mask); +private dev_proc_fill_trapezoid(bbox_fill_trapezoid); +private dev_proc_fill_parallelogram(bbox_fill_parallelogram); +private dev_proc_fill_triangle(bbox_fill_triangle); +private dev_proc_draw_thin_line(bbox_draw_thin_line); +private dev_proc_strip_tile_rectangle(bbox_strip_tile_rectangle); +private dev_proc_strip_copy_rop(bbox_strip_copy_rop); +private dev_proc_begin_typed_image(bbox_begin_typed_image); +private dev_proc_create_compositor(bbox_create_compositor); +private dev_proc_text_begin(bbox_text_begin); + +/* The device prototype */ +/* + * Normally this would be private, but if the device is going to be used + * stand-alone, it has to be public. + */ +/*private */ const +/* + * The bbox device sets the resolution to some value R (currently 4000), and + * the page size in device pixels to slightly smaller than the largest + * representable values (around 500K), leaving a little room for stroke + * widths, rounding, etc. If an input file (or the command line) resets the + * resolution to a value R' > R, the page size in pixels will get multiplied + * by R'/R, and will thereby exceed the representable range, causing a + * limitcheck. That is why the bbox device must set the resolution to a + * value larger than that of any real device. A consequence of this is that + * the page size in inches is limited to the maximum representable pixel + * size divided by R, which gives a limit of about 120" in each dimension. + */ +#define max_coord (max_int_in_fixed - 1000) +#define max_resolution 4000 +gx_device_bbox far_data gs_bbox_device = +{ + std_device_std_body(gx_device_bbox, 0, "bbox", + max_coord, max_coord, + max_resolution, max_resolution), + {bbox_open_device, + NULL, /* get_initial_matrix */ + NULL, /* sync_output */ + bbox_output_page, + bbox_close_device, + NULL, /* map_rgb_color */ + NULL, /* map_color_rgb */ + bbox_fill_rectangle, + NULL, /* tile_rectangle */ + bbox_copy_mono, + bbox_copy_color, + NULL, /* draw_line */ + NULL, /* get_bits */ + bbox_get_params, + bbox_put_params, + NULL, /* map_cmyk_color */ + NULL, /* get_xfont_procs */ + NULL, /* get_xfont_device */ + NULL, /* map_rgb_alpha_color */ + gx_page_device_get_page_device, + NULL, /* get_alpha_bits */ + bbox_copy_alpha, + NULL, /* get_band */ + NULL, /* copy_rop */ + bbox_fill_path, + bbox_stroke_path, + bbox_fill_mask, + bbox_fill_trapezoid, + bbox_fill_parallelogram, + bbox_fill_triangle, + bbox_draw_thin_line, + gx_default_begin_image, + NULL, /* image_data */ + NULL, /* end_image */ + bbox_strip_tile_rectangle, + bbox_strip_copy_rop, + NULL, /* get_clipping_box */ + bbox_begin_typed_image, + NULL, /* get_bits_rectangle */ + NULL, /* map_color_rgb_alpha */ + bbox_create_compositor, + NULL, /* get_hardware_params */ + bbox_text_begin + }, + 0, /* target */ + 1 /*true *//* free_standing */ +}; + +#undef max_coord +#undef max_resolution + +/* Copy device parameters back from the target. */ +private void +bbox_copy_params(gx_device_bbox * bdev, bool remap_white) +{ + gx_device *tdev = bdev->target; + + if (tdev != 0) + gx_device_copy_params((gx_device *)bdev, tdev); + if (remap_white) + bdev->white = gx_device_white((gx_device *)bdev); +} + +#define gx_dc_is_white(pdevc, bdev)\ + (gx_dc_is_pure(pdevc) && gx_dc_pure_color(pdevc) == (bdev)->white) + +private int +bbox_close_device(gx_device * dev) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device *tdev = bdev->target; + + if ((gx_device *) bdev->box_device != dev) { + /* + * This device was created as a wrapper for a compositor. + * Just free the devices. + */ + int code = (*dev_proc(tdev, close_device)) (tdev); + + gs_free_object(dev->memory, dev, "bbox_close_device(composite)"); + return code; + } else { + return (tdev == 0 ? 0 : (*dev_proc(tdev, close_device)) (tdev)); + } +} + +/* Bounding box utilities */ + +private void near +bbox_initialize(gs_fixed_rect * pr) +{ + pr->p.x = pr->p.y = max_fixed; + pr->q.x = pr->q.y = min_fixed; +} + +private void near +bbox_add_rect(gs_fixed_rect * pr, fixed x0, fixed y0, fixed x1, fixed y1) +{ + if (x0 < pr->p.x) + pr->p.x = x0; + if (y0 < pr->p.y) + pr->p.y = y0; + if (x1 > pr->q.x) + pr->q.x = x1; + if (y1 > pr->q.y) + pr->q.y = y1; +} +private void near +bbox_add_point(gs_fixed_rect * pr, fixed x, fixed y) +{ + bbox_add_rect(pr, x, y, x, y); +} +private void near +bbox_add_int_rect(gs_fixed_rect * pr, int x0, int y0, int x1, int y1) +{ + bbox_add_rect(pr, int2fixed(x0), int2fixed(y0), int2fixed(x1), + int2fixed(y1)); +} + +#define rect_is_page(dev, x, y, w, h)\ + (x <= 0 && y <= 0 && w >= x + dev->width && h >= y + dev->height) + + /* ---------------- Open/close/page ---------------- */ + +/* Initialize a bounding box device. */ +void +gx_device_bbox_init(gx_device_bbox * dev, gx_device * target) +{ + gx_device_init((gx_device *) dev, (const gx_device *)&gs_bbox_device, + (target ? target->memory : NULL), true); + gx_device_forward_fill_in_procs((gx_device_forward *) dev); + dev->target = target; + dev->box_device = dev; + bbox_copy_params(dev, false); + dev->free_standing = false; /* being used as a component */ +} + +/* Read back the bounding box in 1/72" units. */ +void +gx_device_bbox_bbox(gx_device_bbox * dev, gs_rect * pbbox) +{ + const gx_device_bbox *bbdev = dev->box_device; + gs_matrix mat; + gs_rect dbox; + + gs_deviceinitialmatrix((gx_device *) dev, &mat); + dbox.p.x = fixed2float(bbdev->bbox.p.x); + dbox.p.y = fixed2float(bbdev->bbox.p.y); + dbox.q.x = fixed2float(bbdev->bbox.q.x); + dbox.q.y = fixed2float(bbdev->bbox.q.y); + gs_bbox_transform_inverse(&dbox, &mat, pbbox); +} + + +private int +bbox_open_device(gx_device * dev) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + + if (bdev->free_standing) { + gx_device_forward_fill_in_procs((gx_device_forward *) dev); + bdev->box_device = bdev; + } + if (bdev->box_device == bdev) + bbox_initialize(&bdev->bbox); + /* gx_forward_open_device doesn't exist */ + { + gx_device *tdev = bdev->target; + int code = (tdev == 0 ? 0 : (*dev_proc(tdev, open_device)) (tdev)); + + bbox_copy_params(bdev, true); + return code; + } +} + +private int +bbox_output_page(gx_device * dev, int num_copies, int flush) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + + if (bdev->free_standing) { + /* + * This is a free-standing device. Print the page bounding box. + */ + gs_rect bbox; + + gx_device_bbox_bbox(bdev, &bbox); + dlprintf4("%%%%BoundingBox: %d %d %d %d\n", + (int)floor(bbox.p.x), (int)floor(bbox.p.y), + (int)ceil(bbox.q.x), (int)ceil(bbox.q.y)); + dlprintf4("%%%%HiResBoundingBox: %f %f %f %f\n", + bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y); + } + /* + * Propagate the PageCount to the target, + * since it changes every time gs_output_page is called. + */ + if (bdev->target) + bdev->target->PageCount = dev->PageCount; + return gx_forward_output_page(dev, num_copies, flush); +} + +/* ---------------- Low-level drawing ---------------- */ + +private int +bbox_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device_bbox *bbdev = bdev->box_device; + + /* Check for erasing the entire page. */ + if (rect_is_page(dev, x, y, w, h)) + bbox_initialize(&bbdev->bbox); + else if (color != bdev->white) + bbox_add_int_rect(&bbdev->bbox, x, y, x + w, y + h); + /* gx_forward_fill_rectangle doesn't exist */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, fill_rectangle)) (tdev, x, y, w, h, color)); + } +} + +private int +bbox_copy_mono(gx_device * dev, const byte * data, + int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index zero, gx_color_index one) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device_bbox *bbdev = bdev->box_device; + + if ((one != gx_no_color_index && one != bdev->white) || + (zero != gx_no_color_index && zero != bdev->white) + ) + bbox_add_int_rect(&bbdev->bbox, x, y, x + w, y + h); + /* gx_forward_copy_mono doesn't exist */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, copy_mono)) + (tdev, data, dx, raster, id, x, y, w, h, zero, one)); + } +} + +private int +bbox_copy_color(gx_device * dev, const byte * data, + int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device_bbox *bbdev = bdev->box_device; + + bbox_add_int_rect(&bbdev->bbox, x, y, x + w, y + h); + /* gx_forward_copy_color doesn't exist */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, copy_color)) + (tdev, data, dx, raster, id, x, y, w, h)); + } +} + +private int +bbox_copy_alpha(gx_device * dev, const byte * data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index color, int depth) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device_bbox *bbdev = bdev->box_device; + + bbox_add_int_rect(&bbdev->bbox, x, y, x + w, y + h); + /* gx_forward_copy_alpha doesn't exist */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, copy_alpha)) + (tdev, data, data_x, raster, id, x, y, w, h, color, depth)); + } +} + +private int +bbox_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, + int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, + int px, int py) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device_bbox *bbdev = bdev->box_device; + + if (rect_is_page(dev, x, y, w, h)) + bbox_initialize(&bbdev->bbox); + else + bbox_add_int_rect(&bbdev->bbox, x, y, x + w, y + h); + /* Skip the call if there is no target. */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, strip_tile_rectangle)) + (tdev, tiles, x, y, w, h, color0, color1, px, py)); + } +} + +private int +bbox_strip_copy_rop(gx_device * dev, + const byte * sdata, int sourcex, uint sraster, + gx_bitmap_id id, + const gx_color_index * scolors, + const gx_strip_bitmap * textures, + const gx_color_index * tcolors, + int x, int y, int w, int h, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device_bbox *bbdev = bdev->box_device; + + bbox_add_int_rect(&bbdev->bbox, x, y, x + w, y + h); + /* gx_forward_strip_copy_rop doesn't exist */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, strip_copy_rop)) + (tdev, sdata, sourcex, sraster, id, scolors, + textures, tcolors, x, y, w, h, phase_x, phase_y, lop)); + } +} + +/* ---------------- Parameters ---------------- */ + +/* We implement get_params to provide a way to read out the bounding box. */ +private int +bbox_get_params(gx_device * dev, gs_param_list * plist) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + const gx_device_bbox *bbdev = bdev->box_device; + int code = gx_forward_get_params(dev, plist); + gs_param_float_array bba; + float bbox[4]; + + if (code < 0) + return code; + /* + * We might be calling get_params before the device has been + * initialized: in this case, bbdev = 0. + */ + if (bbdev == 0) + bbdev = (const gx_device_bbox *)dev; + bbox[0] = fixed2float(bbdev->bbox.p.x); + bbox[1] = fixed2float(bbdev->bbox.p.y); + bbox[2] = fixed2float(bbdev->bbox.q.x); + bbox[3] = fixed2float(bbdev->bbox.q.y); + bba.data = bbox, bba.size = 4, bba.persistent = false; + return param_write_float_array(plist, "PageBoundingBox", &bba); +} + +/* We implement put_params to ensure that we keep the important */ +/* device parameters up to date, and to prevent an /undefined error */ +/* from PageBoundingBox. */ +private int +bbox_put_params(gx_device * dev, gs_param_list * plist) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + int code; + int ecode = 0; + gs_param_name param_name; + gs_param_float_array bba; + + code = param_read_float_array(plist, (param_name = "PageBoundingBox"), + &bba); + switch (code) { + case 0: + if (bba.size != 4) { + ecode = gs_note_error(gs_error_rangecheck); + goto e; + } + break; + default: + ecode = code; + e:param_signal_error(plist, param_name, ecode); + case 1: + bba.data = 0; + } + + code = gx_forward_put_params(dev, plist); + if (ecode < 0) + code = ecode; + if (code >= 0 && bba.data != 0) { + gx_device_bbox *bbdev = bdev->box_device; + + bbdev->bbox.p.x = float2fixed(bba.data[0]); + bbdev->bbox.p.y = float2fixed(bba.data[1]); + bbdev->bbox.q.x = float2fixed(bba.data[2]); + bbdev->bbox.q.y = float2fixed(bba.data[3]); + } + bbox_copy_params(bdev, true); + return code; +} + +/* ---------------- Polygon drawing ---------------- */ + +private fixed +edge_x_at_y(const gs_fixed_edge * edge, fixed y) +{ + return fixed_mult_quo(edge->end.x - edge->start.x, + y - edge->start.y, + edge->end.y - edge->start.y) + edge->start.x; +} +private int +bbox_fill_trapezoid(gx_device * dev, + const gs_fixed_edge * left, const gs_fixed_edge * right, + fixed ybot, fixed ytop, bool swap_axes, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + + if (!gx_dc_is_white(pdevc, bdev)) { + gx_device_bbox *bbdev = bdev->box_device; + fixed x0l = + (left->start.y == ybot ? left->start.x : + edge_x_at_y(left, ybot)); + fixed x1l = + (left->end.y == ytop ? left->end.x : + edge_x_at_y(left, ytop)); + fixed x0r = + (right->start.y == ybot ? right->start.x : + edge_x_at_y(right, ybot)); + fixed x1r = + (right->end.y == ytop ? right->end.x : + edge_x_at_y(right, ytop)); + fixed xminl = min(x0l, x1l), xmaxl = max(x0l, x1l); + fixed xminr = min(x0r, x1r), xmaxr = max(x0r, x1r); + fixed x0 = min(xminl, xminr), x1 = max(xmaxl, xmaxr); + + if (swap_axes) + bbox_add_rect(&bbdev->bbox, ybot, x0, ytop, x1); + else + bbox_add_rect(&bbdev->bbox, x0, ybot, x1, ytop); + } + /* Skip the call if there is no target. */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, fill_trapezoid)) + (tdev, left, right, ybot, ytop, swap_axes, pdevc, lop)); + } +} + +private int +bbox_fill_parallelogram(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, + fixed bx, fixed by, const gx_device_color * pdevc, + gs_logical_operation_t lop) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + + if (!gx_dc_is_white(pdevc, bdev)) { + gx_device_bbox *bbdev = bdev->box_device; + fixed pax = px + ax, pay = py + ay; + + bbox_add_rect(&bbdev->bbox, px, py, px + bx, py + by); + bbox_add_rect(&bbdev->bbox, pax, pay, pax + bx, pay + by); + } + /* Skip the call if there is no target. */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, fill_parallelogram)) + (tdev, px, py, ax, ay, bx, by, pdevc, lop)); + } +} + +private int +bbox_fill_triangle(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + + if (!gx_dc_is_white(pdevc, bdev)) { + gx_device_bbox *bbdev = bdev->box_device; + + bbox_add_rect(&bbdev->bbox, px, py, px + bx, py + by); + bbox_add_point(&bbdev->bbox, px + ax, py + ay); + } + /* Skip the call if there is no target. */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, fill_triangle)) + (tdev, px, py, ax, ay, bx, by, pdevc, lop)); + } +} + +private int +bbox_draw_thin_line(gx_device * dev, + fixed fx0, fixed fy0, fixed fx1, fixed fy1, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + + if (!gx_dc_is_white(pdevc, bdev)) { + gx_device_bbox *bbdev = bdev->box_device; + + bbox_add_rect(&bbdev->bbox, fx0, fy0, fx1, fy1); + } + /* Skip the call if there is no target. */ + { + gx_device *tdev = bdev->target; + + return (tdev == 0 ? 0 : + (*dev_proc(tdev, draw_thin_line)) + (tdev, fx0, fy0, fx1, fy0, pdevc, lop)); + } +} + +/* ---------------- High-level drawing ---------------- */ + +#define adjust_box(pbox, adj)\ +((pbox)->p.x -= (adj).x, (pbox)->p.y -= (adj).y,\ + (pbox)->q.x += (adj).x, (pbox)->q.y += (adj).y) + +private int +bbox_fill_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath, + const gx_fill_params * params, const gx_device_color * pdevc, + const gx_clip_path * pcpath) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device *tdev = bdev->target; + + if (!gx_dc_is_white(pdevc, bdev)) { + gs_fixed_rect ibox; + gs_fixed_point adjust; + + if (gx_path_bbox(ppath, &ibox) < 0) + return 0; + adjust = params->adjust; + if (params->fill_zero_width) + gx_adjust_if_empty(&ibox, &adjust); + adjust_box(&ibox, adjust); + if (pcpath != NULL && + !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y, + ibox.q.x, ibox.q.y) + ) { + /* Let the target do the drawing, but break down the */ + /* fill path into pieces for computing the bounding box. */ + bdev->target = NULL; + gx_default_fill_path(dev, pis, ppath, params, pdevc, pcpath); + bdev->target = tdev; + } else { /* Just use the path bounding box. */ + bbox_add_rect(&bdev->bbox, ibox.p.x, ibox.p.y, ibox.q.x, + ibox.q.y); + } + } + /* Skip the call if there is no target. */ + return (tdev == 0 ? 0 : + (*dev_proc(tdev, fill_path)) + (tdev, pis, ppath, params, pdevc, pcpath)); +} + +private int +bbox_stroke_path(gx_device * dev, const gs_imager_state * pis, gx_path * ppath, + const gx_stroke_params * params, + const gx_drawing_color * pdevc, const gx_clip_path * pcpath) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device *tdev = bdev->target; + + if (!gx_dc_is_white(pdevc, bdev)) { + gs_fixed_rect ibox; + gs_fixed_point expand; + + if (gx_path_bbox(ppath, &ibox) < 0) + return 0; + if (gx_stroke_path_expansion(pis, ppath, &expand) < 0) + ibox.p.x = ibox.p.y = min_fixed, ibox.q.x = ibox.q.y = max_fixed; + else + adjust_box(&ibox, expand); + if (pcpath != NULL && + !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y, + ibox.q.x, ibox.q.y) + ) { + /* Let the target do the drawing, but break down the */ + /* fill path into pieces for computing the bounding box. */ + bdev->target = NULL; + gx_default_stroke_path(dev, pis, ppath, params, pdevc, pcpath); + bdev->target = tdev; + } else { + /* Just use the path bounding box. */ + gx_device_bbox *bbdev = bdev->box_device; + + bbox_add_rect(&bbdev->bbox, ibox.p.x, ibox.p.y, ibox.q.x, + ibox.q.y); + } + } + /* Skip the call if there is no target. */ + return (tdev == 0 ? 0 : + (*dev_proc(tdev, stroke_path)) + (tdev, pis, ppath, params, pdevc, pcpath)); +} + +private int +bbox_fill_mask(gx_device * dev, + const byte * data, int dx, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + const gx_drawing_color * pdcolor, int depth, + gs_logical_operation_t lop, const gx_clip_path * pcpath) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device *tdev = bdev->target; + + if (pcpath != NULL && + !gx_cpath_includes_rectangle(pcpath, int2fixed(x), int2fixed(y), + int2fixed(x + w), + int2fixed(y + h)) + ) { + /* Let the target do the drawing, but break down the */ + /* image into pieces for computing the bounding box. */ + bdev->target = NULL; + gx_default_fill_mask(dev, data, dx, raster, id, x, y, w, h, + pdcolor, depth, lop, pcpath); + bdev->target = tdev; + } else { + /* Just use the mask bounding box. */ + gx_device_bbox *bbdev = bdev->box_device; + + bbox_add_int_rect(&bbdev->bbox, x, y, x + w, y + h); + } + /* Skip the call if there is no target. */ + return (tdev == 0 ? 0 : + (*dev_proc(tdev, fill_mask)) + (tdev, data, dx, raster, id, x, y, w, h, + pdcolor, depth, lop, pcpath)); +} + +/* ------ Bitmap imaging ------ */ + +typedef struct bbox_image_enum_s { + gx_image_enum_common; + gs_memory_t *memory; + gs_matrix matrix; /* map from image space to device space */ + const gx_clip_path *pcpath; + gx_image_enum_common_t *target_info; + int x0, x1; + int y, height; +} bbox_image_enum; + +gs_private_st_ptrs2(st_bbox_image_enum, bbox_image_enum, "bbox_image_enum", +bbox_image_enum_enum_ptrs, bbox_image_enum_reloc_ptrs, pcpath, target_info); + +private image_enum_proc_plane_data(bbox_image_plane_data); +private image_enum_proc_end_image(bbox_image_end_image); +private const gx_image_enum_procs_t bbox_image_enum_procs = +{ + bbox_image_plane_data, bbox_image_end_image +}; + +private int +bbox_image_begin(const gs_imager_state * pis, const gs_matrix * pmat, + const gs_image_common_t * pic, const gs_int_rect * prect, + const gx_clip_path * pcpath, gs_memory_t * memory, + bbox_image_enum ** ppbe) +{ + int code; + gs_matrix mat; + bbox_image_enum *pbe; + + if (pmat == 0) + pmat = &ctm_only(pis); + if ((code = gs_matrix_invert(&pic->ImageMatrix, &mat)) < 0 || + (code = gs_matrix_multiply(&mat, pmat, &mat)) < 0 + ) + return code; + pbe = gs_alloc_struct(memory, bbox_image_enum, &st_bbox_image_enum, + "bbox_image_begin"); + if (pbe == 0) + return_error(gs_error_VMerror); + pbe->memory = memory; + pbe->matrix = mat; + pbe->pcpath = pcpath; + pbe->target_info = 0; /* in case no target */ + if (prect) { + pbe->x0 = prect->p.x, pbe->x1 = prect->q.x; + pbe->y = prect->p.y, pbe->height = prect->q.y - prect->p.y; + } else { + gs_int_point size; + int code = (*pic->type->source_size) (pis, pic, &size); + + if (code < 0) { + gs_free_object(memory, pbe, "bbox_image_begin"); + return code; + } + pbe->x0 = 0, pbe->x1 = size.x; + pbe->y = 0, pbe->height = size.y; + } + *ppbe = pbe; + return 0; +} + +private void +bbox_image_copy_target_info(bbox_image_enum * pbe, gx_device_bbox * dev) +{ + const gx_image_enum_common_t *target_info = pbe->target_info; + + pbe->num_planes = target_info->num_planes; + memcpy(pbe->plane_depths, target_info->plane_depths, + pbe->num_planes * sizeof(pbe->plane_depths[0])); + if (dev->target == 0) { + gx_image_end(pbe->target_info, false); + pbe->target_info = 0; + } +} + +private int +bbox_begin_typed_image(gx_device * dev, + const gs_imager_state * pis, const gs_matrix * pmat, + const gs_image_common_t * pic, const gs_int_rect * prect, + const gx_drawing_color * pdcolor, + const gx_clip_path * pcpath, + gs_memory_t * memory, gx_image_enum_common_t ** pinfo) +{ + bbox_image_enum *pbe; + int code = + bbox_image_begin(pis, pmat, pic, prect, pcpath, memory, &pbe); + + if (code < 0) + return code; + /* We fill in num_planes and plane_depths later. */ + /* format is irrelevant. */ + code = gx_image_enum_common_init((gx_image_enum_common_t *) pbe, pic, + &bbox_image_enum_procs, dev, + 0, 0, gs_image_format_chunky); + if (code < 0) + return code; + *pinfo = (gx_image_enum_common_t *) pbe; + /* + * If there is no target, we still have to call default_begin_image + * to get the correct num_planes and plane_depths. + */ + { + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device *tdev = bdev->target; + + dev_proc_begin_typed_image((*begin_typed_image)); + + if (tdev == 0) { + tdev = dev; + begin_typed_image = gx_default_begin_typed_image; + } else { + begin_typed_image = dev_proc(tdev, begin_typed_image); + } + code = (*begin_typed_image) + (tdev, pis, pmat, pic, prect, pdcolor, pcpath, memory, + &pbe->target_info); + if (code < 0) + return code; + bbox_image_copy_target_info(pbe, bdev); + } + return 0; +} + +private int +bbox_image_plane_data(gx_device * dev, + gx_image_enum_common_t * info, const gx_image_plane_t * planes, int height) +{ + + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device *tdev = bdev->target; + bbox_image_enum *pbe = (bbox_image_enum *) info; + const gx_clip_path *pcpath = pbe->pcpath; + gs_rect sbox, dbox; + gs_point corners[4]; + gs_fixed_rect ibox; + + sbox.p.x = pbe->x0; + sbox.p.y = pbe->y; + sbox.q.x = pbe->x1; + sbox.q.y = pbe->y += height; + gs_bbox_transform_only(&sbox, &pbe->matrix, corners); + gs_points_bbox(corners, &dbox); + ibox.p.x = float2fixed(dbox.p.x); + ibox.p.y = float2fixed(dbox.p.y); + ibox.q.x = float2fixed(dbox.q.x); + ibox.q.y = float2fixed(dbox.q.y); + if (pcpath != NULL && + !gx_cpath_includes_rectangle(pcpath, ibox.p.x, ibox.p.y, + ibox.q.x, ibox.q.y) + ) { + /* Let the target do the drawing, but drive two triangles */ + /* through the clipping path to get an accurate bounding box. */ + gx_device_clip cdev; + gx_drawing_color devc; + fixed x0 = float2fixed(corners[0].x), y0 = float2fixed(corners[0].y); + fixed bx2 = float2fixed(corners[2].x) - x0, by2 = float2fixed(corners[2].y) - y0; + + gx_make_clip_path_device(&cdev, pcpath); + cdev.target = dev; + (*dev_proc(&cdev, open_device)) ((gx_device *) & cdev); + color_set_pure(&devc, 0); /* any color will do */ + bdev->target = NULL; + gx_default_fill_triangle((gx_device *) & cdev, x0, y0, + float2fixed(corners[1].x) - x0, + float2fixed(corners[1].y) - y0, + bx2, by2, &devc, lop_default); + gx_default_fill_triangle((gx_device *) & cdev, x0, y0, + float2fixed(corners[3].x) - x0, + float2fixed(corners[3].y) - y0, + bx2, by2, &devc, lop_default); + bdev->target = tdev; + } else { + /* Just use the bounding box. */ + gx_device_bbox *bbdev = bdev->box_device; + + bbox_add_rect(&bbdev->bbox, ibox.p.x, ibox.p.y, ibox.q.x, ibox.q.y); + } + /* Skip the call if there is no target. */ + return (tdev == 0 ? pbe->y >= pbe->height : + gx_image_plane_data(pbe->target_info, planes, height)); +} + +private int +bbox_image_end_image(gx_device * dev, gx_image_enum_common_t * info, + bool draw_last) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + bbox_image_enum *pbe = (bbox_image_enum *) info; + void *target_info = pbe->target_info; + + /* Skip the call if there is no target. */ + gx_device *tdev = bdev->target; + int code = + (tdev == 0 ? 0 : gx_image_end(target_info, draw_last)); + + gs_free_object(pbe->memory, pbe, "bbox_end_image"); + return code; +} + +private int +bbox_create_compositor(gx_device * dev, + gx_device ** pcdev, const gs_composite_t * pcte, + const gs_imager_state * pis, gs_memory_t * memory) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device *target = bdev->target; + + /* + * If there isn't a target, all we care about is the bounding box, + * so don't bother with actually compositing. + */ + if (target == 0) { + *pcdev = dev; + return 0; + } + /* + * Create a compositor for the target, and then wrap another + * bbox device around it, but still accumulating the bounding + * box in the same place. + */ + { + gx_device *cdev; + gx_device_bbox *bbcdev; + int code = (*dev_proc(target, create_compositor)) + (target, &cdev, pcte, pis, memory); + + if (code < 0) + return code; + bbcdev = gs_alloc_struct_immovable(memory, gx_device_bbox, + &st_device_bbox, + "bbox_create_compositor"); + if (bbcdev == 0) { + (*dev_proc(cdev, close_device)) (cdev); + return_error(gs_error_VMerror); + } + gx_device_bbox_init(bbcdev, target); + bbcdev->target = cdev; + bbcdev->box_device = bdev; + *pcdev = (gx_device *) bbcdev; + return 0; + } +} + +/* ------ Text imaging ------ */ + +extern_st(st_gs_text_enum); + +typedef struct bbox_text_enum_s { + gs_text_enum_common; + gs_text_enum_t *target_info; +} bbox_text_enum; + +gs_private_st_suffix_add1(st_bbox_text_enum, bbox_text_enum, "bbox_text_enum", + bbox_text_enum_enum_ptrs, bbox_text_enum_reloc_ptrs, + st_gs_text_enum, target_info); + +private text_enum_proc_process(bbox_text_process); +private text_enum_proc_set_cache(bbox_text_set_cache); +private rc_free_proc(bbox_text_free); + +private const gs_text_enum_procs_t bbox_text_procs = +{ + bbox_text_process, bbox_text_set_cache +}; + +private int +bbox_text_begin(gx_device * dev, gs_imager_state * pis, + const gs_text_params_t * text, const gs_font * font, +gx_path * path, const gx_device_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * memory, gs_text_enum_t ** ppenum) +{ + gx_device_bbox *const bdev = (gx_device_bbox *) dev; + gx_device *tdev = bdev->target; + bbox_text_enum *pbte; + int code; + + if (tdev == 0) + return gx_default_text_begin(dev, pis, text, font, path, pdcolor, + pcpath, memory, ppenum); + rc_alloc_struct_1(pbte, bbox_text_enum, &st_bbox_text_enum, memory, + return_error(gs_error_VMerror), + "bbox_text_begin"); + pbte->rc.free = bbox_text_free; + code = + (*dev_proc(tdev, text_begin)) + (tdev, pis, text, font, path, pdcolor, pcpath, memory, + &pbte->target_info); + if (code < 0) { + gs_free_object(memory, pbte, "bbox_text_begin"); + return code; + } + *(gs_text_enum_t *) pbte = *pbte->target_info; /* copy common info */ + pbte->procs = &bbox_text_procs; + *ppenum = (gs_text_enum_t *) pbte; + return code; +} + +private int +bbox_text_process(gs_text_enum_t * pte) +{ + bbox_text_enum *const pbte = (bbox_text_enum *) pte; + int code = gs_text_process(pbte->target_info); + + if (code < 0) + return code; + /* Copy back the dynamic information for the client. */ + pte->index = pbte->target_info->index; + return code; +} + +private int +bbox_text_set_cache(gs_text_enum_t * pte, const double *values, + gs_text_cache_control_t control) +{ + bbox_text_enum *const pbte = (bbox_text_enum *) pte; + gs_text_enum_t *tpte = pbte->target_info; + int code = tpte->procs->set_cache(tpte, values, control); + + if (code < 0) + return code; + /* Copy back the dynamic information for the client. */ + pte->index = tpte->index; + return code; +} + +private void +bbox_text_free(gs_memory_t * memory, void *vpte, client_name_t cname) +{ + bbox_text_enum *const pbte = (bbox_text_enum *) vpte; + + gs_text_release(pbte->target_info, cname); + rc_free_struct_only(memory, vpte, cname); +} diff --git a/pstoraster/gdevbbox.h b/pstoraster/gdevbbox.h new file mode 100644 index 0000000000..5b647347b0 --- /dev/null +++ b/pstoraster/gdevbbox.h @@ -0,0 +1,100 @@ +/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Requires gxdevice.h */ + +#ifndef gdevbbox_INCLUDED +# define gdevbbox_INCLUDED + +/* + * This device keeps track of the per-page bounding box, and also optionally + * forwards all drawing commands to a target. It can be used either as a + * free-standing device or as a component (e.g., by the EPS writer). + * + * One way to use a bounding box device is simply to include bbox.dev in the + * value of DEVICE_DEVSn in the makefile. This produces a free-standing + * device named 'bbox' that can be selected in the usual way (-sDEVICE=bbox) + * and that prints out the bounding box at each showpage or copypage without + * doing any drawing. + * + * The other way to use a bounding box device is from C code as a component + * in a device pipeline. To set up a bounding box device that doesn't do + * any drawing: + * gx_device_bbox *bdev = + * gs_alloc_struct_immovable(some_memory, + * gx_device_bbox, &st_device_bbox, + * "some identifying string for debugging"); + * gx_device_bbox_init(bdev, NULL); + * Non-drawing bounding box devices have an "infinite" page size. + * + * To set up a bounding box device that draws to another device tdev: + * gx_device_bbox *bdev = + * gs_alloc_struct_immovable(some_memory, + * gx_device_bbox, &st_device_bbox, + * "some identifying string for debugging"); + * gx_device_bbox_init(bdev, tdev); + * Bounding box devices that draw to a real device appear to have the + * same page size as that device. + * + * To intercept the end-of-page to call a routine eop of your own, after + * setting up the device: + * dev_proc_output_page(eop); -- declare a prototype for eop + * ... + * set_dev_proc(bdev, output_page, eop); + * ... + * int eop(gx_device *dev, int num_copies, int flush) + * { gs_rect bbox; + * gx_device_bbox_bbox((gx_device_bbox *)dev, &bbox); + * << do whatever you want >> + * return gx_forward_output_page(dev, num_copies, flush); + * } + */ +#define gx_device_bbox_common\ + gx_device_forward_common;\ + bool free_standing;\ + /* In order to handle compositors, we provide a separate pointer */\ + /* to the bbox device instance that holds the actual box. */\ + gx_device_bbox *box_device;\ + /* The following are updated dynamically. */\ + gs_fixed_rect bbox;\ + gx_color_index white +typedef struct gx_device_bbox_s gx_device_bbox; +struct gx_device_bbox_s { + gx_device_bbox_common; +}; + +extern_st(st_device_bbox); +#define public_st_device_bbox() /* in gdevbbox.c */\ + gs_public_st_suffix_add1_final(st_device_bbox, gx_device_bbox,\ + "gx_device_bbox", device_bbox_enum_ptrs, device_bbox_reloc_ptrs,\ + gx_device_finalize, st_device_forward, box_device) + +/* Initialize a bounding box device. */ +void gx_device_bbox_init(P2(gx_device_bbox * dev, gx_device * target)); + +/* Read back the bounding box in 1/72" units. */ +void gx_device_bbox_bbox(P2(gx_device_bbox * dev, gs_rect * pbbox)); + +#endif /* gdevbbox_INCLUDED */ diff --git a/pstoraster/gdevcmap.h b/pstoraster/gdevcmap.h new file mode 100644 index 0000000000..abfa9266f7 --- /dev/null +++ b/pstoraster/gdevcmap.h @@ -0,0 +1,74 @@ +/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Interface to special color mapping device */ + +#ifndef gdevcmap_INCLUDED +# define gdevcmap_INCLUDED + +/* Define the color mapping algorithms. */ +typedef enum { + + /* Don't change the color. */ + + device_cmap_identity = 0, + + /* Snap each RGB primary component to 0 or 1 individually. */ + + device_cmap_snap_to_primaries, + + /* Snap black to white, other colors to black. */ + + device_cmap_color_to_black_over_white, + + /* Convert to a gray shade of the correct brightness. */ + + device_cmap_monochrome + +} gx_device_color_mapping_method_t; + +#define device_cmap_max_method device_cmap_monochrome + +/* Define the color mapping forwarding device. */ +typedef struct gx_device_cmap_s { + gx_device_forward_common; + gx_device_color_mapping_method_t mapping_method; +} gx_device_cmap; + +extern_st(st_device_cmap); +#define public_st_device_cmap() /* in gdevcmap.c */\ + gs_public_st_suffix_add0_final(st_device_cmap, gx_device_cmap,\ + "gx_device_cmap", device_cmap_enum_ptrs, device_cmap_reloc_ptrs,\ + gx_device_finalize, st_device_forward) + +/* Initialize a color mapping device. Do this just once after allocation. */ +int gdev_cmap_init(P3(gx_device_cmap * dev, gx_device * target, + gx_device_color_mapping_method_t mapping_method)); + +/* Set the color mapping method. This may be called at any time. */ +int gdev_cmap_set_method(P2(gx_device_cmap * dev, + gx_device_color_mapping_method_t mapping_method)); + +#endif /* gdevcmap_INCLUDED */ diff --git a/pstoraster/gdevcups.c b/pstoraster/gdevcups.c new file mode 100644 index 0000000000..07cd6ee51f --- /dev/null +++ b/pstoraster/gdevcups.c @@ -0,0 +1,2518 @@ +/* + * "$Id$" + * + * GNU Ghostscript raster output driver for the Common UNIX Printing + * System (CUPS). + * + * Copyright 1993-2000 by Easy Software Products. + * + * These coded instructions, statements, and computer programs are the + * property of Easy Software Products and are protected by Federal + * copyright law. Distribution and use rights are outlined in the file + * "LICENSE.txt" which should have been included with this file. If this + * file is missing or damaged please contact Easy Software Products + * at: + * + * Attn: CUPS Licensing Information + * Easy Software Products + * 44141 Airport View Drive, Suite 204 + * Hollywood, Maryland 20636-3111 USA + * + * Voice: (301) 373-9603 + * EMail: cups-info@cups.org + * WWW: http://www.cups.org + * + * This code and any derivative of it may be used and distributed + * freely under the terms of the GNU General Public License when + * used with GNU Ghostscript or its derivatives. Use of the code + * (or any derivative of it) with software other than GNU + * GhostScript (or its derivatives) is governed by the CUPS license + * agreement. + * + * Contents: + * + * cups_close() - Close the output file. + * cups_get_matrix() - Generate the default page matrix. + * cups_get_params() - Get pagedevice parameters. + * cups_map_color_rgb() - Map a color index to an RGB color. + * cups_map_rgb_color() - Map an RGB color to a color index. We map the + * RGB color to the output colorspace & bits (we + * figure out the format when we output a page). + * cups_open() - Open the output file and initialize things. + * cups_print_pages() - Send one or more pages to the output file. + * cups_put_params() - Set pagedevice parameters. + * cups_set_color_info() - Set the color information structure based on + * the required output. + * cups_print_chunked() - Print a page of chunked pixels. + * cups_print_banded() - Print a page of banded pixels. + * cups_print_planar() - Print a page of planar pixels. + */ + +/* + * Include necessary headers... + */ + +#include "std.h" /* to stop stdlib.h redefining types */ +#include "gdevprn.h" +#include "gsparam.h" +#include "gsexit.h" + +#include +#include +#include +#include + +#undef private +#define private + + +/* + * Globals... + */ + +extern const char *cupsProfile; + + +/* + * Macros... + */ + +#define x_dpi (pdev->HWResolution[0]) +#define y_dpi (pdev->HWResolution[1]) +#define cups ((gx_device_cups *)pdev) + +/* + * Macros from ; we can't include because it also + * defines DEBUG, one of our flags to insert various debugging code. + */ + +#ifndef max +# define max(a,b) ((a)<(b) ? (b) : (a)) +#endif /* !max */ + +#ifndef min +# define min(a,b) ((a)>(b) ? (b) : (a)) +#endif /* !min */ + +#ifndef abs +# define abs(x) ((x)>=0 ? (x) : -(x)) +#endif /* !abs */ + + +/* + * Procedures + */ + +private dev_proc_close_device(cups_close); +private dev_proc_get_initial_matrix(cups_get_matrix); +private int cups_get_params(gx_device *, gs_param_list *); +private dev_proc_map_color_rgb(cups_map_color_rgb); +private dev_proc_map_rgb_color(cups_map_rgb_color); +private dev_proc_open_device(cups_open); +private int cups_print_pages(gx_device_printer *, FILE *, int); +private int cups_put_params(gx_device *, gs_param_list *); +private void cups_set_color_info(gx_device *); +private dev_proc_sync_output(cups_sync_output); + +/* + * The device descriptors... + */ + +typedef struct gx_device_cups_s +{ + gx_device_common; /* Standard GhostScript device stuff */ + gx_prn_device_common; /* Standard printer device stuff */ + int page; /* Page number */ + cups_raster_t *stream; /* Raster stream */ + ppd_file_t *ppd; /* PPD file for this printer */ + cups_page_header_t header; /* PostScript page device info */ +} gx_device_cups; + +private gx_device_procs cups_procs = +{ + cups_open, + cups_get_matrix, + cups_sync_output, + gdev_prn_output_page, + cups_close, + cups_map_rgb_color, + cups_map_color_rgb, + NULL, /* fill_rectangle */ + NULL, /* tile_rectangle */ + NULL, /* copy_mono */ + NULL, /* copy_color */ + NULL, /* draw_line */ + gx_default_get_bits, + cups_get_params, + cups_put_params, + NULL, + NULL, /* get_xfont_procs */ + NULL, /* get_xfont_device */ + NULL, /* map_rgb_alpha_color */ + gx_page_device_get_page_device, + NULL, /* get_alpha_bits */ + NULL, /* copy_alpha */ + NULL, /* get_band */ + NULL, /* copy_rop */ + NULL, /* fill_path */ + NULL, /* stroke_path */ + NULL, /* fill_mask */ + NULL, /* fill_trapezoid */ + NULL, /* fill_parallelogram */ + NULL, /* fill_triangle */ + NULL, /* draw_thin_line */ + NULL, /* begin_image */ + NULL, /* image_data */ + NULL, /* end_image */ + NULL, /* strip_tile_rectangle */ + NULL /* strip_copy_rop */ +}; + +gx_device_cups gs_cups_device = +{ + prn_device_body_copies(gx_device_cups, cups_procs, "cups", 85, 110, 100, 100, + 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, cups_print_pages), + 0, /* page */ + NULL, /* stream */ + NULL, /* ppd */ + { /* header */ + "", /* MediaClass */ + "", /* MediaColor */ + "", /* MediaType */ + "", /* OutputType */ + 0, /* AdvanceDistance */ + CUPS_ADVANCE_NONE, /* AdvanceMedia */ + CUPS_FALSE, /* Collate */ + CUPS_CUT_NONE, /* CutMedia */ + CUPS_FALSE, /* Duplex */ + { 100, 100 }, /* HWResolution */ + { 0, 0, 612, 792 }, /* ImagingBoundingBox */ + CUPS_FALSE, /* InsertSheet */ + CUPS_JOG_NONE, /* Jog */ + CUPS_EDGE_TOP, /* LeadingEdge */ + { 0, 0 }, /* Margins */ + CUPS_FALSE, /* ManualFeed */ + 0, /* MediaPosition */ + 0, /* MediaWeight */ + CUPS_FALSE, /* MirrorPrint */ + CUPS_FALSE, /* NegativePrint */ + 1, /* NumCopies */ + CUPS_ORIENT_0, /* Orientation */ + CUPS_FALSE, /* OutputFaceUp */ + { 612, 792 }, /* PageSize */ + CUPS_FALSE, /* Separations */ + CUPS_FALSE, /* TraySwitch */ + CUPS_FALSE, /* Tumble */ + 850, /* cupsWidth */ + 1100, /* cupsHeight */ + 0, /* cupsMediaType */ + 1, /* cupsBitsPerColor */ + 1, /* cupsBitsPerPixel */ + 107, /* cupsBytesPerLine */ + CUPS_ORDER_CHUNKED, /* cupsColorOrder */ + CUPS_CSPACE_K, /* cupsColorSpace */ + 0, /* cupsCompression */ + 0, /* cupsRowCount */ + 0, /* cupsRowFeed */ + 0 /* cupsRowStep */ + } +}; + +/* + * Color lookup tables... + */ + +static gx_color_value lut_color_rgb[256]; +static unsigned char lut_rgb_color[gx_max_color_value + 1]; +static int cupsHaveProfile = 0; +static int cupsMatrix[3][3][gx_max_color_value + 1]; +static int cupsDensity[gx_max_color_value + 1]; + + +/* + * Local functions... + */ + +static void cups_print_chunked(gx_device_printer *, unsigned char *); +static void cups_print_banded(gx_device_printer *, unsigned char *, + unsigned char *, int); +static void cups_print_planar(gx_device_printer *, unsigned char *, + unsigned char *, int); + +/*static void cups_set_margins(gx_device *);*/ + + +/* + * 'cups_close()' - Close the output file. + */ + +private int +cups_close(gx_device *pdev) /* I - Device info */ +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: cups_close(%08x)\n", pdev); +#endif /* DEBUG */ + + if (cups->stream != NULL) + { + cupsRasterClose(cups->stream); + cups->stream = NULL; + } + +#if 0 /* Can't do this here because put_params() might close the device */ + if (cups->ppd != NULL) + { + ppdClose(cups->ppd); + cups->ppd = NULL; + } +#endif /* 0 */ + + return (gdev_prn_close(pdev)); +} + + +/* + * 'cups_get_matrix()' - Generate the default page matrix. + */ + +private void +cups_get_matrix(gx_device *pdev, /* I - Device info */ + gs_matrix *pmat) /* O - Physical transform matrix */ +{ +#ifdef DEBUG + fprintf(stderr, "DEBUG: cups_get_matrix(%08x, %08x)\n", pdev, pmat); +#endif /* DEBUG */ + + /* + * Set the raster width and height... + */ + + cups->header.cupsWidth = cups->width; + cups->header.cupsHeight = cups->height; + + /* + * Set the transform matrix... + */ + +#if 0 + if (cups->header.Duplex && cups->ppd->flip_duplex && !(cups->page & 1)) + { + pmat->xx = (float)-cups->header.HWResolution[0] / 72.0; + pmat->xy = 0.0; + pmat->yx = 0.0; + pmat->yy = (float)cups->header.HWResolution[1] / 72.0; + pmat->tx = (float)cups->header.HWResolution[0] * + ((float)cups->header.PageSize[0] - pdev->HWMargins[2]) / 72.0; + pmat->ty = -(float)cups->header.HWResolution[1] * pdev->HWMargins[1] / 72.0; + } + else +#endif /* 0 */ + { + pmat->xx = (float)cups->header.HWResolution[0] / 72.0; + pmat->xy = 0.0; + pmat->yx = 0.0; + pmat->yy = -(float)cups->header.HWResolution[1] / 72.0; + pmat->tx = -(float)cups->header.HWResolution[0] * pdev->HWMargins[0] / 72.0; + pmat->ty = (float)cups->header.HWResolution[1] * + ((float)cups->header.PageSize[1] - pdev->HWMargins[3]) / 72.0; + } + +#ifdef DEBUG + fprintf(stderr, "DEBUG: width = %d, height = %d\n", cups->width, + cups->height); + fprintf(stderr, "DEBUG: PageSize = [ %d %d ], HWResolution = [ %d %d ]\n", + cups->header.PageSize[0], cups->header.PageSize[1], + cups->header.HWResolution[0], cups->header.HWResolution[1]); + fprintf(stderr, "DEBUG: matrix = [ %.3f %.3f %.3f %.3f %.3f %.3f ]\n", + pmat->xx, pmat->xy, pmat->yx, pmat->yy, pmat->tx, pmat->ty); +#endif /* DEBUG */ +} + + +/* + * 'cups_get_params()' - Get pagedevice parameters. + */ + +private int /* O - Error status */ +cups_get_params(gx_device *pdev, /* I - Device info */ + gs_param_list *plist) /* I - Parameter list */ +{ + int code; /* Return code */ + gs_param_string s; /* Temporary string value */ + bool b; /* Temporary boolean value */ + + +#ifdef DEBUG + fprintf(stderr, "DEBUG: cups_get_params(%08x, %08x)\n", pdev, plist); +#endif /* DEBUG */ + + /* + * First process the "standard" page device parameters... + */ + +#ifdef DEBUG + fputs("DEBUG: before gdev_prn_get_params()\n", stderr); +#endif /* DEBUG */ + + if ((code = gdev_prn_get_params(pdev, plist)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: after gdev_prn_get_params()\n", stderr); +#endif /* DEBUG */ + + /* + * Then write the CUPS parameters... + */ + +#ifdef DEBUG + fputs("DEBUG: MediaClass\n", stderr); +#endif /* DEBUG */ + + param_string_from_string(s, cups->header.MediaClass); + if ((code = param_write_string(plist, "MediaClass", &s)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: AdvanceDistance\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "AdvanceDistance", + (int *)&(cups->header.AdvanceDistance))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: AdvanceDistance\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "AdvanceMedia", + (int *)&(cups->header.AdvanceMedia))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: Collate\n", stderr); +#endif /* DEBUG */ + + b = cups->header.Collate; + if ((code = param_write_bool(plist, "Collate", &b)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: CutMedia\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "CutMedia", + (int *)&(cups->header.CutMedia))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: InsertSheet\n", stderr); +#endif /* DEBUG */ + + b = cups->header.InsertSheet; + if ((code = param_write_bool(plist, "InsertSheet", &b)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: Jog\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "Jog", + (int *)&(cups->header.Jog))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: LeadingEdge\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "LeadingEdge", + (int *)&(cups->header.LeadingEdge))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: ManualFeed\n", stderr); +#endif /* DEBUG */ + + b = cups->header.ManualFeed; + if ((code = param_write_bool(plist, "ManualFeed", &b)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: MediaPosition\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "MediaPosition", + (int *)&(cups->header.MediaPosition))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: MirrorPrint\n", stderr); +#endif /* DEBUG */ + + b = cups->header.MirrorPrint; + if ((code = param_write_bool(plist, "MirrorPrint", &b)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: NegativePrint\n", stderr); +#endif /* DEBUG */ + + b = cups->header.NegativePrint; + if ((code = param_write_bool(plist, "NegativePrint", &b)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: OutputFaceUp\n", stderr); +#endif /* DEBUG */ + + b = cups->header.OutputFaceUp; + if ((code = param_write_bool(plist, "OutputFaceUp", &b)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: Separations\n", stderr); +#endif /* DEBUG */ + + b = cups->header.Separations; + if ((code = param_write_bool(plist, "Separations", &b)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: TraySwitch\n", stderr); +#endif /* DEBUG */ + + b = cups->header.TraySwitch; + if ((code = param_write_bool(plist, "TraySwitch", &b)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: Tumble\n", stderr); +#endif /* DEBUG */ + + b = cups->header.Tumble; + if ((code = param_write_bool(plist, "Tumble", &b)) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsWidth\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsWidth", + (int *)&(cups->header.cupsWidth))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsHeight\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsHeight", + (int *)&(cups->header.cupsHeight))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsMediaType\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsMediaType", + (int *)&(cups->header.cupsMediaType))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsBitsPerColor\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsBitsPerColor", + (int *)&(cups->header.cupsBitsPerColor))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsBitsPerPixel\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsBitsPerPixel", + (int *)&(cups->header.cupsBitsPerPixel))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsBytesPerLine\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsBytesPerLine", + (int *)&(cups->header.cupsBytesPerLine))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsColorOrder\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsColorOrder", + (int *)&(cups->header.cupsColorOrder))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsColorSpace\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsColorSpace", + (int *)&(cups->header.cupsColorSpace))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsCompression\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsCompression", + (int *)&(cups->header.cupsCompression))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsRowCount\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsRowCount", + (int *)&(cups->header.cupsRowCount))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsRowFeed\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsRowFeed", + (int *)&(cups->header.cupsRowFeed))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: cupsRowStep\n", stderr); +#endif /* DEBUG */ + + if ((code = param_write_int(plist, "cupsRowStep", + (int *)&(cups->header.cupsRowStep))) < 0) + return (code); + +#ifdef DEBUG + fputs("DEBUG: Leaving cups_get_params()\n", stderr); +#endif /* DEBUG */ + + return (0); +} + + +/* + * 'cups_map_color_rgb()' - Map a color index to an RGB color. + */ + +private int +cups_map_color_rgb(gx_device *pdev, /* I - Device info */ + gx_color_index color, /* I - Color index */ + gx_color_value prgb[3]) /* O - RGB values */ +{ + unsigned char c0, c1, c2, c3; /* Color index components */ + gx_color_value k, divk; /* Black & divisor */ + + +#ifdef DEBUG + fprintf(stderr, "DEBUG: cups_map_color_rgb(%08x, %d, %08x)\n", pdev, + color, prgb); +#endif /* DEBUG */ + + /* + * Setup the color info data as needed... + */ + + if (pdev->color_info.num_components == 0) + cups_set_color_info(pdev); + +#ifdef DEBUG + fprintf(stderr, "DEBUG: COLOR %08x = ", color); +#endif /* DEBUG */ + + /* + * Extract the color components from the color index... + */ + + switch (cups->header.cupsBitsPerColor) + { + case 1 : + c3 = color & 1; + color >>= 1; + c2 = color & 1; + color >>= 1; + c1 = color & 1; + color >>= 1; + c0 = color; + break; + case 2 : + c3 = color & 3; + color >>= 2; + c2 = color & 3; + color >>= 2; + c2 = color & 3; + color >>= 2; + c0 = color; + break; + case 4 : + c3 = color & 15; + color >>= 4; + c2 = color & 15; + color >>= 4; + c1 = color & 15; + color >>= 4; + c0 = color; + break; + case 8 : + c3 = color & 255; + color >>= 8; + c2 = color & 255; + color >>= 8; + c1 = color & 255; + color >>= 8; + c0 = color; + break; + } + + /* + * Convert the color components to RGB... + */ + + switch (cups->header.cupsColorSpace) + { + case CUPS_CSPACE_K : + case CUPS_CSPACE_WHITE : + case CUPS_CSPACE_GOLD : + case CUPS_CSPACE_SILVER : + prgb[0] = + prgb[1] = + prgb[2] = lut_color_rgb[c3]; + break; + + case CUPS_CSPACE_W : + prgb[0] = + prgb[1] = + prgb[2] = lut_color_rgb[c3]; + break; + + case CUPS_CSPACE_RGB : + prgb[0] = lut_color_rgb[c1]; + prgb[1] = lut_color_rgb[c2]; + prgb[2] = lut_color_rgb[c3]; + break; + + case CUPS_CSPACE_CMY : + prgb[0] = lut_color_rgb[c1]; + prgb[1] = lut_color_rgb[c2]; + prgb[2] = lut_color_rgb[c3]; + break; + + case CUPS_CSPACE_YMC : + prgb[0] = lut_color_rgb[c3]; + prgb[1] = lut_color_rgb[c2]; + prgb[2] = lut_color_rgb[c1]; + break; + + case CUPS_CSPACE_KCMY : + k = lut_color_rgb[c0]; + divk = gx_max_color_value - k; + if (divk == 0) + { + prgb[0] = 0; + prgb[1] = 0; + prgb[2] = 0; + } + else + { + prgb[0] = gx_max_color_value + divk - + gx_max_color_value * c1 / divk; + prgb[1] = gx_max_color_value + divk - + gx_max_color_value * c2 / divk; + prgb[2] = gx_max_color_value + divk - + gx_max_color_value * c3 / divk; + } + break; + + case CUPS_CSPACE_CMYK : + k = lut_color_rgb[c3]; + divk = gx_max_color_value - k; + if (divk == 0) + { + prgb[0] = 0; + prgb[1] = 0; + prgb[2] = 0; + } + else + { + prgb[0] = gx_max_color_value + divk - + gx_max_color_value * c0 / divk; + prgb[1] = gx_max_color_value + divk - + gx_max_color_value * c1 / divk; + prgb[2] = gx_max_color_value + divk - + gx_max_color_value * c2 / divk; + } + break; + + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_GMCK : + case CUPS_CSPACE_GMCS : + k = lut_color_rgb[c3]; + divk = gx_max_color_value - k; + if (divk == 0) + { + prgb[0] = 0; + prgb[1] = 0; + prgb[2] = 0; + } + else + { + prgb[0] = gx_max_color_value + divk - + gx_max_color_value * c2 / divk; + prgb[1] = gx_max_color_value + divk - + gx_max_color_value * c1 / divk; + prgb[2] = gx_max_color_value + divk - + gx_max_color_value * c0 / divk; + } + break; + } + +#ifdef DEBUG + fprintf(stderr, "%d,%d,%d\n", prgb[0], prgb[1], prgb[2]); +#endif /* DEBUG */ + + return (0); +} + + +/* + * 'cups_map_rgb_color()' - Map an RGB color to a color index. We map the + * RGB color to the output colorspace & bits (we + * figure out the format when we output a page). + */ + +private gx_color_index /* O - Color index */ +cups_map_rgb_color(gx_device *pdev, /* I - Device info */ + gx_color_value r, /* I - Red value */ + gx_color_value g, /* I - Green value */ + gx_color_value b) /* I - Blue value */ +{ + gx_color_index i; /* Temporary index */ + gx_color_value ic, im, iy, ik, mk; /* Integral CMYK values */ + int tc, tm, ty; /* Temporary color values */ + + +#ifdef DEBUG + fprintf(stderr, "DEBUG: cups_map_rgb_color(%08x, %d, %d, %d)\n", pdev, r, g, b); +#endif /* DEBUG */ + + /* + * Setup the color info data as needed... + */ + + if (pdev->color_info.num_components == 0) + cups_set_color_info(pdev); + + /* + * Do color correction as needed... + */ + + if (cupsHaveProfile) + { + /* + * Compute CMYK values... + */ + + ic = gx_max_color_value - r; + im = gx_max_color_value - g; + iy = gx_max_color_value - b; + ik = min(ic, min(im, iy)); + ic -= ik; + im -= ik; + iy -= ik; + + /* + * Color correct CMY... + */ + + tc = cupsMatrix[0][0][ic] + + cupsMatrix[0][1][im] + + cupsMatrix[0][2][iy] + + ik; + tm = cupsMatrix[1][0][ic] + + cupsMatrix[1][1][im] + + cupsMatrix[1][2][iy] + + ik; + ty = cupsMatrix[2][0][ic] + + cupsMatrix[2][1][im] + + cupsMatrix[2][2][iy] + + ik; + + /* + * Density correct combined CMYK... + */ + + if (tc < 0) + r = gx_max_color_value; + else if (tc > gx_max_color_value) + r = gx_max_color_value - cupsDensity[gx_max_color_value]; + else + r = gx_max_color_value - cupsDensity[tc]; + + if (tm < 0) + g = gx_max_color_value; + else if (tm > gx_max_color_value) + g = gx_max_color_value - cupsDensity[gx_max_color_value]; + else + g = gx_max_color_value - cupsDensity[tm]; + + if (ty < 0) + b = gx_max_color_value; + else if (ty > gx_max_color_value) + b = gx_max_color_value - cupsDensity[gx_max_color_value]; + else + b = gx_max_color_value - cupsDensity[ty]; + } + + /* + * Convert the RGB color to a color index... + */ + + switch (cups->header.cupsColorSpace) + { + case CUPS_CSPACE_W : + i = lut_rgb_color[(r * 31 + g * 61 + b * 8) / 100]; + break; + + case CUPS_CSPACE_RGB : + ic = lut_rgb_color[r]; + im = lut_rgb_color[g]; + iy = lut_rgb_color[b]; + + switch (cups->header.cupsBitsPerColor) + { + case 1 : + i = (((ic << 1) | im) << 1) | iy; + break; + case 2 : + i = (((ic << 2) | im) << 2) | iy; + break; + case 4 : + i = (((ic << 4) | im) << 4) | iy; + break; + case 8 : + i = (((ic << 8) | im) << 8) | iy; + break; + } + break; + + case CUPS_CSPACE_K : + case CUPS_CSPACE_WHITE : + case CUPS_CSPACE_GOLD : + case CUPS_CSPACE_SILVER : + i = lut_rgb_color[gx_max_color_value - (r * 31 + g * 61 + b * 8) / 100]; + break; + + case CUPS_CSPACE_CMY : + ic = lut_rgb_color[gx_max_color_value - r]; + im = lut_rgb_color[gx_max_color_value - g]; + iy = lut_rgb_color[gx_max_color_value - b]; + + switch (cups->header.cupsBitsPerColor) + { + case 1 : + i = (((ic << 1) | im) << 1) | iy; + break; + case 2 : + i = (((ic << 2) | im) << 2) | iy; + break; + case 4 : + i = (((ic << 4) | im) << 4) | iy; + break; + case 8 : + i = (((ic << 8) | im) << 8) | iy; + break; + } + break; + + case CUPS_CSPACE_YMC : + ic = lut_rgb_color[gx_max_color_value - r]; + im = lut_rgb_color[gx_max_color_value - g]; + iy = lut_rgb_color[gx_max_color_value - b]; + + switch (cups->header.cupsBitsPerColor) + { + case 1 : + i = (((iy << 1) | im) << 1) | ic; + break; + case 2 : + i = (((iy << 2) | im) << 2) | ic; + break; + case 4 : + i = (((iy << 4) | im) << 4) | ic; + break; + case 8 : + i = (((iy << 8) | im) << 8) | ic; + break; + } + break; + + case CUPS_CSPACE_CMYK : + ic = gx_max_color_value - r; + im = gx_max_color_value - g; + iy = gx_max_color_value - b; + ik = min(ic, min(im, iy)); + + mk = max(ic, max(im, iy)); + if (mk > ik) + ik = ik * ik / mk; + + ic = lut_rgb_color[ic - ik]; + im = lut_rgb_color[im - ik]; + iy = lut_rgb_color[iy - ik]; + ik = lut_rgb_color[ik]; + + switch (cups->header.cupsBitsPerColor) + { + case 1 : + i = (((((ic << 1) | im) << 1) | iy) << 1) | ik; + break; + case 2 : + i = (((((ic << 2) | im) << 2) | iy) << 2) | ik; + break; + case 4 : + i = (((((ic << 4) | im) << 4) | iy) << 4) | ik; + break; + case 8 : + i = (((((ic << 8) | im) << 8) | iy) << 8) | ik; + break; + } + + if (gs_log_errors > 1) + fprintf(stderr, "DEBUG: CMY (%d,%d,%d) -> CMYK %08.8x (%d,%d,%d,%d)\n", + r, g, b, i, ic, im, iy, ik); + break; + + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_GMCK : + case CUPS_CSPACE_GMCS : + ic = gx_max_color_value - r; + im = gx_max_color_value - g; + iy = gx_max_color_value - b; + ik = min(ic, min(im, iy)); + + mk = max(ic, max(im, iy)); + if (mk > ik) + ik = ik * ik / mk; + + ic = lut_rgb_color[ic - ik]; + im = lut_rgb_color[im - ik]; + iy = lut_rgb_color[iy - ik]; + ik = lut_rgb_color[ik]; + + switch (cups->header.cupsBitsPerColor) + { + case 1 : + i = (((((iy << 1) | im) << 1) | ic) << 1) | ik; + break; + case 2 : + i = (((((iy << 2) | im) << 2) | ic) << 2) | ik; + break; + case 4 : + i = (((((iy << 4) | im) << 4) | ic) << 4) | ik; + break; + case 8 : + i = (((((iy << 8) | im) << 8) | ic) << 8) | ik; + break; + } + break; + + case CUPS_CSPACE_KCMYcm : + if (cups->header.cupsBitsPerColor == 1) + { + ic = gx_max_color_value - r; + im = gx_max_color_value - g; + iy = gx_max_color_value - b; + ik = min(ic, min(im, iy)); + + ic = lut_rgb_color[ic - ik]; + im = lut_rgb_color[im - ik]; + iy = lut_rgb_color[iy - ik]; + ik = lut_rgb_color[ik]; + if (ik) + i = 32; + else if (ic && im) + i = 17; + else if (ic && iy) + i = 6; + else if (im && iy) + i = 12; + else if (ic) + i = 16; + else if (im) + i = 8; + else if (iy) + i = 4; + else + i = 0; + break; + } + + case CUPS_CSPACE_KCMY : + ic = gx_max_color_value - r; + im = gx_max_color_value - g; + iy = gx_max_color_value - b; + ik = min(ic, min(im, iy)); + + mk = max(ic, max(im, iy)); + if (mk > ik) + ik = ik * ik / mk; + + ic = lut_rgb_color[ic - ik]; + im = lut_rgb_color[im - ik]; + iy = lut_rgb_color[iy - ik]; + ik = lut_rgb_color[ik]; + + switch (cups->header.cupsBitsPerColor) + { + case 1 : + i = (((((ik << 1) | ic) << 1) | im) << 1) | iy; + break; + case 2 : + i = (((((ik << 2) | ic) << 2) | im) << 2) | iy; + break; + case 4 : + i = (((((ik << 4) | ic) << 4) | im) << 4) | iy; + break; + case 8 : + i = (((((ik << 8) | ic) << 8) | im) << 8) | iy; + break; + } + break; + } + +#ifdef DEBUG + fprintf(stderr, "DEBUG: RGB %d,%d,%d = %08x\n", r, g, b, i); +#endif /* DEBUG */ + + return (i); +} + + +/* + * 'cups_open()' - Open the output file and initialize things. + */ + +private int /* O - Error status */ +cups_open(gx_device *pdev) /* I - Device info */ +{ + int code; /* Return status */ + + +#ifdef DEBUG + fprintf(stderr, "DEBUG: cups_open(%08x)\n", pdev); +#endif /* DEBUG */ + + if (cups->page == 0) + { + fputs("INFO: Processing page 1...\n", stderr); + cups->page = 1; + } + + if (pdev->color_info.num_components == 0) + cups_set_color_info(pdev); + + if ((code = gdev_prn_open(pdev)) != 0) + return (code); + + if (cups->ppd == NULL) + cups->ppd = ppdOpenFile(getenv("PPD")); + + return (0); +} + + +/* + * 'cups_print_pages()' - Send one or more pages to the output file. + */ + +private int /* O - 0 if everything is OK */ +cups_print_pages(gx_device_printer *pdev, /* I - Device info */ + FILE *fp, /* I - Output file */ + int num_copies) /* I - Number of copies */ +{ + int copy; /* Copy number */ + int srcbytes; /* Byte width of scanline */ + unsigned char *src, /* Scanline data */ + *dst; /* Bitmap data */ + + +#ifdef DEBUG + fprintf(stderr, "DEBUG: cups_print_pages(%08x, %08x, %d)\n", pdev, fp, + num_copies); +#endif /* DEBUG */ + + /* + * Figure out the number of bytes per line... + */ + + switch (cups->header.cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerPixel * + cups->header.cupsWidth + 7) / 8; + break; + + case CUPS_ORDER_BANDED : + if (cups->header.cupsColorSpace == CUPS_CSPACE_KCMYcm && + cups->header.cupsBitsPerColor == 1) + cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerColor * + cups->header.cupsWidth + 7) / 8 * 6; + else + cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerColor * + cups->header.cupsWidth + 7) / 8 * + cups->color_info.num_components; + break; + + case CUPS_ORDER_PLANAR : + cups->header.cupsBytesPerLine = (cups->header.cupsBitsPerColor * + cups->header.cupsWidth + 7) / 8; + break; + } + + /* + * Compute the width of a scanline and allocate input/output buffers... + */ + + srcbytes = gdev_prn_raster(pdev); + +#ifdef DEBUG + fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d, cupsWidth = %d, cupsBytesPerLine = %d, srcbytes = %d\n", + cups->header.cupsBitsPerPixel, cups->header.cupsWidth, + cups->header.cupsBytesPerLine, srcbytes); +#endif /* DEBUG */ + + src = (unsigned char *)gs_malloc(srcbytes, 1, "cups_print_pages"); + + if (src == NULL) /* can't allocate input buffer */ + return_error(gs_error_VMerror); + + if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED) + { + /* + * Need an output buffer, too... + */ + + dst = (unsigned char *)gs_malloc(cups->header.cupsBytesPerLine, 2, + "cups_print_pages"); + + if (dst == NULL) /* can't allocate working area */ + return_error(gs_error_VMerror); + } + else + dst = NULL; + + /* + * See if the stream has been initialized yet... + */ + + if (cups->stream == NULL) + { + if ((cups->stream = cupsRasterOpen(1, CUPS_RASTER_WRITE)) == NULL) + { + perror("ERROR: Unable to open raster stream - "); + gs_exit(0); + } + } + + /* + * Output a page of graphics... + */ + + if (num_copies < 1) + num_copies = 1; + + if (cups->ppd != NULL && !cups->ppd->manual_copies) + { + cups->header.NumCopies = num_copies; + num_copies = 1; + } + +#ifdef DEBUG + fprintf(stderr, "DEBUG: cupsWidth = %d, cupsHeight = %d, cupsBytesPerLine = %d\n", + cups->header.cupsWidth, cups->header.cupsHeight, + cups->header.cupsBytesPerLine); +#endif /* DEBUG */ + + for (copy = num_copies; copy > 0; copy --) + { + cupsRasterWriteHeader(cups->stream, &(cups->header)); + + if (pdev->color_info.num_components == 1) + cups_print_chunked(pdev, src); + else + switch (cups->header.cupsColorOrder) + { + case CUPS_ORDER_CHUNKED : + cups_print_chunked(pdev, src); + break; + case CUPS_ORDER_BANDED : + cups_print_banded(pdev, src, dst, srcbytes); + break; + case CUPS_ORDER_PLANAR : + cups_print_planar(pdev, src, dst, srcbytes); + break; + } + } + + /* + * Free temporary storage and return... + */ + + gs_free((char *)src, srcbytes, 1, "cups_print_pages"); + if (dst) + gs_free((char *)dst, cups->header.cupsBytesPerLine, 1, "cups_print_pages"); + + cups->page ++; + fprintf(stderr, "INFO: Processing page %d...\n", cups->page); + + return (0); +} + + +/* + * 'cups_put_params()' - Set pagedevice parameters. + */ + +private int /* O - Error status */ +cups_put_params(gx_device *pdev, /* I - Device info */ + gs_param_list *plist) /* I - Parameter list */ +{ + int i; /* Looping var */ + float margins[4]; /* Physical margins of print */ + ppd_size_t *size; /* Page size */ + int code; /* Error code */ + int intval; /* Integer value */ + bool boolval; /* Boolean value */ + float floatval; /* Floating point value */ + gs_param_string stringval; /* String value */ + gs_param_float_array arrayval; /* Float array value */ + + +#ifdef DEBUG + fprintf(stderr, "DEBUG: cups_put_params(%08x, %08x)\n", pdev, plist); +#endif /* DEBUG */ + + /* + * Process other options for CUPS... + */ + +#define stringoption(name, sname) \ + if ((code = param_read_string(plist, sname, &stringval)) < 0) \ + { \ + param_signal_error(plist, sname, code); \ + return (code); \ + } \ + else if (code == 0) \ + { \ + strncpy(cups->header.name, (const char *)stringval.data, \ + stringval.size); \ + cups->header.name[stringval.size] = '\0'; \ + } + +#define intoption(name, sname, type) \ + if ((code = param_read_int(plist, sname, &intval)) < 0) \ + { \ + param_signal_error(plist, sname, code); \ + return (code); \ + } \ + else if (code == 0) \ + cups->header.name = (type)intval; + +#define floatoption(name, sname) \ + if ((code = param_read_float(plist, sname, &floatval)) < 0) \ + { \ + param_signal_error(plist, sname, code); \ + return (code); \ + } \ + else if (code == 0) \ + cups->header.name = (unsigned)floatval; + +#define booloption(name, sname) \ + if ((code = param_read_bool(plist, sname, &boolval)) < 0) \ + { \ + if ((code = param_read_null(plist, sname)) < 0) \ + { \ + param_signal_error(plist, sname, code); \ + return (code); \ + } \ + if (code == 0) \ + cups->header.name = CUPS_FALSE; \ + } \ + else if (code == 0) \ + cups->header.name = (cups_bool_t)boolval; + +#define arrayoption(name, sname, count) \ + if ((code = param_read_float_array(plist, sname, &arrayval)) < 0) \ + { \ + if ((code = param_read_null(plist, sname)) < 0) \ + { \ + param_signal_error(plist, sname, code); \ + return (code); \ + } \ + if (code == 0) \ + for (i = 0; i < count; i ++) \ + cups->header.name[i] = 0; \ + } \ + else if (code == 0) \ + { \ + for (i = 0; i < count; i ++) \ + cups->header.name[i] = (unsigned)arrayval.data[i]; \ + } + + stringoption(MediaClass, "MediaClass") + stringoption(MediaColor, "MediaColor") + stringoption(MediaType, "MediaType") + stringoption(OutputType, "OutputType") + floatoption(AdvanceDistance, "AdvanceDistance") + intoption(AdvanceMedia, "AdvanceMedia", cups_adv_t) + booloption(Collate, "Collate") + intoption(CutMedia, "CutMedia", cups_cut_t) + booloption(Duplex, "Duplex") + arrayoption(ImagingBoundingBox, "ImagingBoundingBox", 4) + booloption(InsertSheet, "InsertSheet") + intoption(Jog, "Jog", cups_jog_t) + intoption(LeadingEdge, "LeadingEdge", cups_edge_t) + arrayoption(Margins, "Margins", 2) + booloption(ManualFeed, "ManualFeed") + intoption(MediaPosition, "cupsMediaPosition", unsigned) /* Compatibility */ + intoption(MediaPosition, "MediaPosition", unsigned) + floatoption(MediaWeight, "MediaWeight") + booloption(MirrorPrint, "MirrorPrint") + booloption(NegativePrint, "NegativePrint") + intoption(NumCopies, "NumCopies", unsigned) + intoption(Orientation, "Orientation", cups_orient_t) + booloption(OutputFaceUp, "OutputFaceUp") + booloption(Separations, "Separations") + booloption(TraySwitch, "TraySwitch") + booloption(Tumble, "Tumble") + intoption(cupsWidth, "cupsWidth", unsigned) + intoption(cupsHeight, "cupsHeight", unsigned) + intoption(cupsMediaType, "cupsMediaType", unsigned) + intoption(cupsBitsPerColor, "cupsBitsPerColor", unsigned) + intoption(cupsBitsPerPixel, "cupsBitsPerPixel", unsigned) + intoption(cupsBytesPerLine, "cupsBytesPerLine", unsigned) + intoption(cupsColorOrder, "cupsColorOrder", cups_order_t) + intoption(cupsColorSpace, "cupsColorSpace", cups_cspace_t) + intoption(cupsCompression, "cupsCompression", unsigned) + intoption(cupsRowCount, "cupsRowCount", unsigned) + intoption(cupsRowFeed, "cupsRowFeed", unsigned) + intoption(cupsRowStep, "cupsRowStep", unsigned) + + cups_set_color_info(pdev); + + /* + * Compute the page margins... + */ + + if (cups->ppd != NULL) + { + /* + * Pull the margins from the first size entry; since the margins are not + * like the bounding box we have to adjust the top and right values + * accordingly. + */ + + size = cups->ppd->sizes; + margins[0] = size->left / 72.0; + margins[1] = size->bottom / 72.0; + margins[2] = (size->width - size->right) / 72.0; + margins[3] = (size->length - size->top) / 72.0; + } + else + { + /* + * Set default margins of 0.0... + */ + + memset(margins, 0, sizeof(margins)); + } + + /* + * Set the margins to update the bitmap size... + */ + + gx_device_set_margins(pdev, margins, false); + + /* + * Then process standard page device options... + */ + + if ((code = gdev_prn_put_params(pdev, plist)) < 0) + return (code); + + cups->header.HWResolution[0] = pdev->HWResolution[0]; + cups->header.HWResolution[1] = pdev->HWResolution[1]; + + cups->header.PageSize[0] = pdev->PageSize[0]; + cups->header.PageSize[1] = pdev->PageSize[1]; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: ppd = %08x\n", cups->ppd); + fprintf(stderr, "DEBUG: PageSize = [ %.3f %.3f ]\n", + pdev->PageSize[0], pdev->PageSize[1]); + fprintf(stderr, "DEBUG: margins = [ %.3f %.3f %.3f %.3f ]\n", + margins[0], margins[1], margins[2], margins[3]); + fprintf(stderr, "DEBUG: HWResolution = [ %.3f %.3f ]\n", + pdev->HWResolution[0], pdev->HWResolution[1]); + fprintf(stderr, "DEBUG: width = %d, height = %d\n", + pdev->width, pdev->height); + fprintf(stderr, "DEBUG: HWMargins = [ %.3f %.3f %.3f %.3f ]\n", + pdev->HWMargins[0], pdev->HWMargins[1], + pdev->HWMargins[2], pdev->HWMargins[3]); +#endif /* DEBUG */ + + return (0); +} + + +/* + * 'cups_set_color_info()' - Set the color information structure based on + * the required output. + */ + +private void +cups_set_color_info(gx_device *pdev) /* I - Device info */ +{ + int i, j, k; /* Looping vars */ + float d, g; /* Density and gamma correction */ + float m[3][3]; /* Color correction matrix */ + char resolution[41]; /* Resolution string */ + ppd_profile_t *profile; /* Color profile information */ + + +#ifdef DEBUG + fprintf(stderr, "DEBUG: cups_set_color_info(%08x)\n", pdev); +#endif /* DEBUG */ + + switch (cups->header.cupsColorSpace) + { + default : + case CUPS_CSPACE_W : + case CUPS_CSPACE_K : + case CUPS_CSPACE_WHITE : + case CUPS_CSPACE_GOLD : + case CUPS_CSPACE_SILVER : + cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor; + cups->color_info.depth = cups->header.cupsBitsPerPixel; + cups->color_info.num_components = 1; + break; + + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + case CUPS_CSPACE_RGB : + if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED) + cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor; + else if (cups->header.cupsBitsPerColor < 8) + cups->header.cupsBitsPerPixel = 4 * cups->header.cupsBitsPerColor; + else + cups->header.cupsBitsPerPixel = 3 * cups->header.cupsBitsPerColor; + + if (cups->header.cupsBitsPerColor < 8) + cups->color_info.depth = 4 * cups->header.cupsBitsPerColor; + else + cups->color_info.depth = 3 * cups->header.cupsBitsPerColor; + + cups->color_info.num_components = 3; + break; + + case CUPS_CSPACE_KCMYcm : + if (cups->header.cupsBitsPerColor == 1) + { + cups->header.cupsBitsPerPixel = 8; + cups->color_info.depth = 8; + cups->color_info.num_components = 4; + break; + } + + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + case CUPS_CSPACE_GMCK : + case CUPS_CSPACE_GMCS : + if (cups->header.cupsColorOrder != CUPS_ORDER_CHUNKED) + cups->header.cupsBitsPerPixel = cups->header.cupsBitsPerColor; + else + cups->header.cupsBitsPerPixel = 4 * cups->header.cupsBitsPerColor; + + cups->color_info.depth = 4 * cups->header.cupsBitsPerColor; + cups->color_info.num_components = 4; + break; + } + + if (cups->color_info.num_components > 1) + { + cups->color_info.max_gray = (1 << cups->header.cupsBitsPerColor) - 1; + cups->color_info.max_color = (1 << cups->header.cupsBitsPerColor) - 1; + cups->color_info.dither_grays = (1 << cups->header.cupsBitsPerColor); + cups->color_info.dither_colors = (1 << cups->header.cupsBitsPerColor); + } + else + { + cups->color_info.max_gray = (1 << cups->header.cupsBitsPerColor) - 1; + cups->color_info.max_color = 0; + cups->color_info.dither_grays = (1 << cups->header.cupsBitsPerColor); + cups->color_info.dither_colors = 0; + } + + /* + * Compute the lookup tables... + */ + + for (i = 0; i <= gx_max_color_value; i ++) + lut_rgb_color[i] = cups->color_info.max_gray * i / gx_max_color_value; + + for (i = 0; i < cups->color_info.dither_grays; i ++) + lut_color_rgb[i] = gx_max_color_value * i / cups->color_info.max_gray; + +#ifdef DEBUG + fprintf(stderr, "DEBUG: num_components = %d, depth = %d\n", + cups->color_info.num_components, cups->color_info.depth); + fprintf(stderr, "DEBUG: cupsColorSpace = %d, cupsColorOrder = %d\n", + cups->header.cupsColorSpace, cups->header.cupsColorOrder); + fprintf(stderr, "DEBUG: cupsBitsPerPixel = %d, cupsBitsPerColor = %d\n", + cups->header.cupsBitsPerPixel, cups->header.cupsBitsPerColor); + fprintf(stderr, "DEBUG: max_gray = %d, dither_grays = %d\n", + cups->color_info.max_gray, cups->color_info.dither_grays); + fprintf(stderr, "DEBUG: max_color = %d, dither_colors = %d\n", + cups->color_info.max_color, cups->color_info.dither_colors); +#endif /* DEBUG */ + + /* + * Set the color profile as needed... + */ + + cupsHaveProfile = 0; + + if (cupsProfile && cups->header.cupsBitsPerColor == 8) + { + fprintf(stderr, "DEBUG: Using user-defined profile \"%s\"...\n", cupsProfile); + + if (sscanf(cupsProfile, "%f,%f,%f,%f,%f,%f,%f,%f,%f,%f,%f", &d, &g, + m[0] + 0, m[0] + 1, m[0] + 2, + m[1] + 0, m[1] + 1, m[1] + 2, + m[2] + 0, m[2] + 1, m[2] + 2) != 11) + fputs("DEBUG: User-defined profile does not contain 11 integers!\n", stderr); + else + { + cupsHaveProfile = 1; + + d *= 0.001f; + g *= 0.001f; + m[0][0] *= 0.001f; + m[0][1] *= 0.001f; + m[0][2] *= 0.001f; + m[1][0] *= 0.001f; + m[1][1] *= 0.001f; + m[1][2] *= 0.001f; + m[2][0] *= 0.001f; + m[2][1] *= 0.001f; + m[2][2] *= 0.001f; + } + } + else if (cups->ppd != NULL && cups->header.cupsBitsPerColor == 8) + { + /* + * Find the appropriate color profile... + */ + + if (pdev->HWResolution[0] != pdev->HWResolution[1]) + sprintf(resolution, "%.0fx%.0fdpi", pdev->HWResolution[0], + pdev->HWResolution[1]); + else + sprintf(resolution, "%.0fdpi", pdev->HWResolution[0]); + + for (i = 0, profile = cups->ppd->profiles; + i < cups->ppd->num_profiles; + i ++, profile ++) + if ((strcmp(profile->resolution, resolution) == 0 || + profile->resolution[0] == '-') && + (strcmp(profile->media_type, cups->header.MediaType) == 0 || + profile->media_type[0] == '-')) + break; + + /* + * If we found a color profile, use it! + */ + + if (i < cups->ppd->num_profiles) + { +#ifdef DEBUG + fputs("DEBUG: Using color profile!\n", stderr); +#endif /* DEBUG */ + + cupsHaveProfile = 1; + + d = profile->density; + g = profile->gamma; + + memcpy(m, profile->matrix, sizeof(m)); + } + } + + if (cupsHaveProfile) + { + for (i = 0; i < 3; i ++) + for (j = 0; j < 3; j ++) + for (k = 0; k <= gx_max_color_value; k ++) + { + cupsMatrix[i][j][k] = (int)((float)k * m[i][j] + 0.5); + +#ifdef DEBUG + if ((k & 4095) == 0) + fprintf(stderr, "DEBUG: cupsMatrix[%d][%d][%d] = %d\n", + i, j, k, cupsMatrix[i][j][k]); +#endif /* DEBUG */ + } + + + for (k = 0; k <= gx_max_color_value; k ++) + { + cupsDensity[k] = (int)((float)gx_max_color_value * d * + pow((float)k / (float)gx_max_color_value, g) + + 0.5); + +#ifdef DEBUG + if ((k & 4095) == 0) + fprintf(stderr, "DEBUG: cupsDensity[%d] = %d\n", k, cupsDensity[k]); +#endif /* DEBUG */ + } + } +} + + +/* + * 'cups_sync_output()' - Keep the user informed of our status... + */ + +private int /* O - Error status */ +cups_sync_output(gx_device *pdev) /* I - Device info */ +{ + fprintf(stderr, "INFO: Processing page %d...\n", cups->page); + + return (0); +} + + +/* + * 'cups_print_chunked()' - Print a page of chunked pixels. + */ + +static void +cups_print_chunked(gx_device_printer *pdev, /* I - Printer device */ + unsigned char *src) /* I - Scanline buffer */ +{ + int y; /* Looping var */ + unsigned char *srcptr; /* Pointer to data */ + + + /* + * Loop through the page bitmap and write chunked pixels (the format + * is identical to GhostScript's... + */ + + for (y = 0; y < cups->height; y ++) + { + /* + * Grab the scanline data... + */ + + if (gdev_prn_get_bits((gx_device_printer *)pdev, y, src, &srcptr) < 0) + { + fprintf(stderr, "ERROR: Unable to get scanline %d!\n", y); + gs_exit(1); + } + + /* + * Write the scanline data to the raster stream... + */ + + cupsRasterWritePixels(cups->stream, srcptr, cups->header.cupsBytesPerLine); + } +} + + +/* + * 'cups_print_banded()' - Print a page of banded pixels. + */ + +static void +cups_print_banded(gx_device_printer *pdev, /* I - Printer device */ + unsigned char *src, /* I - Scanline buffer */ + unsigned char *dst, /* I - Bitmap buffer */ + int srcbytes) /* I - Number of bytes in src */ +{ + int x; /* Looping var */ + int y; /* Looping var */ + int bandbytes; /* Bytes per band */ + unsigned char bit; /* Current bit */ + unsigned char temp; /* Temporary variable */ + unsigned char *srcptr; /* Pointer to data */ + unsigned char *cptr, *mptr, *yptr, *kptr; /* Pointer to components */ + unsigned char *lcptr, *lmptr; /* ... */ + + + /* + * Loop through the page bitmap and write banded pixels... We have + * to separate each chunked color as needed... + */ + + bandbytes = (cups->header.cupsWidth * cups->header.cupsBitsPerColor + 7) / 8; + + for (y = 0; y < cups->height; y ++) + { + /* + * Grab the scanline data... + */ + + if (gdev_prn_get_bits((gx_device_printer *)pdev, y, src, &srcptr) < 0) + { + fprintf(stderr, "ERROR: Unable to get scanline %d!\n", y); + gs_exit(1); + } + + /* + * Separate the chunked colors into their components... + */ + + if (srcptr[0] == 0 && memcmp(srcptr, srcptr + 1, srcbytes - 1) == 0) + memset(dst, 0, cups->header.cupsBytesPerLine); + else + switch (cups->header.cupsBitsPerColor) + { + case 1 : + memset(dst, 0, cups->header.cupsBytesPerLine); + + switch (cups->header.cupsColorSpace) + { + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + for (x = cups->width, cptr = dst, mptr = cptr + bandbytes, + yptr = mptr + bandbytes, bit = 128; + x > 0; + x --, srcptr ++) + { + if (*srcptr & 0x40) + *cptr |= bit; + if (*srcptr & 0x20) + *mptr |= bit; + if (*srcptr & 0x10) + *yptr |= bit; + + bit >>= 1; + x --; + if (x == 0) + break; + + if (*srcptr & 0x4) + *cptr |= bit; + if (*srcptr & 0x2) + *mptr |= bit; + if (*srcptr & 0x1) + *yptr |= bit; + + if (bit > 1) + bit >>= 1; + else + { + cptr ++; + mptr ++; + yptr ++; + bit = 128; + } + } + break; + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + for (x = cups->width, cptr = dst, mptr = cptr + bandbytes, + yptr = mptr + bandbytes, kptr = yptr + bandbytes, + bit = 128; + x > 0; + x --, srcptr ++) + { + if (*srcptr & 0x80) + *cptr |= bit; + if (*srcptr & 0x40) + *mptr |= bit; + if (*srcptr & 0x20) + *yptr |= bit; + if (*srcptr & 0x10) + *kptr |= bit; + + bit >>= 1; + x --; + if (x == 0) + break; + + if (*srcptr & 0x8) + *cptr |= bit; + if (*srcptr & 0x4) + *mptr |= bit; + if (*srcptr & 0x2) + *yptr |= bit; + if (*srcptr & 0x1) + *kptr |= bit; + + if (bit > 1) + bit >>= 1; + else + { + cptr ++; + mptr ++; + yptr ++; + kptr ++; + bit = 128; + } + } + break; + case CUPS_CSPACE_KCMYcm : + for (x = cups->width, kptr = dst, cptr = kptr + bandbytes, + mptr = cptr + bandbytes, yptr = mptr + bandbytes, + lcptr = yptr + bandbytes, lmptr = lcptr + bandbytes, + bit = 128; + x > 0; + x --, srcptr ++) + { + if (*srcptr & 0x20) + *kptr |= bit; + if (*srcptr & 0x10) + *cptr |= bit; + if (*srcptr & 0x08) + *mptr |= bit; + if (*srcptr & 0x04) + *yptr |= bit; + if (*srcptr & 0x02) + *lcptr |= bit; + if (*srcptr & 0x01) + *lmptr |= bit; + + if (bit > 1) + bit >>= 1; + else + { + cptr ++; + mptr ++; + yptr ++; + kptr ++; + lcptr ++; + lmptr ++; + bit = 128; + } + } + break; + } + break; + + case 2 : + memset(dst, 0, cups->header.cupsBytesPerLine); + + switch (cups->header.cupsColorSpace) + { + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + for (x = cups->width, cptr = dst, mptr = cptr + bandbytes, + yptr = mptr + bandbytes, bit = 0xc0; + x > 0; + x --, srcptr ++) + switch (bit) + { + case 0xc0 : + if (temp = *srcptr & 0x30) + *cptr |= temp << 2; + if (temp = *srcptr & 0x0c) + *mptr |= temp << 4; + if (temp = *srcptr & 0x03) + *yptr |= temp << 6; + + bit = 0x30; + break; + case 0x30 : + if (temp = *srcptr & 0x30) + *cptr |= temp; + if (temp = *srcptr & 0x0c) + *mptr |= temp << 2; + if (temp = *srcptr & 0x03) + *yptr |= temp << 4; + + bit = 0x0c; + break; + case 0x0c : + if (temp = *srcptr & 0x30) + *cptr |= temp >> 2; + if (temp = *srcptr & 0x0c) + *mptr |= temp; + if (temp = *srcptr & 0x03) + *yptr |= temp << 2; + + bit = 0x03; + break; + case 0x03 : + if (temp = *srcptr & 0x30) + *cptr |= temp >> 4; + if (temp = *srcptr & 0x0c) + *mptr |= temp >> 2; + if (temp = *srcptr & 0x03) + *yptr |= temp; + + bit = 0xc0; + cptr ++; + mptr ++; + yptr ++; + break; + } + break; + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + for (x = cups->width, cptr = dst, mptr = cptr + bandbytes, + yptr = mptr + bandbytes, kptr = yptr + bandbytes, + bit = 0xc0; + x > 0; + x --, srcptr ++) + switch (bit) + { + case 0xc0 : + if (temp = *srcptr & 0xc0) + *cptr |= temp; + if (temp = *srcptr & 0x30) + *mptr |= temp << 2; + if (temp = *srcptr & 0x0c) + *yptr |= temp << 4; + if (temp = *srcptr & 0x03) + *kptr |= temp << 6; + + bit = 0x30; + break; + case 0x30 : + if (temp = *srcptr & 0xc0) + *cptr |= temp >> 2; + if (temp = *srcptr & 0x30) + *mptr |= temp; + if (temp = *srcptr & 0x0c) + *yptr |= temp << 2; + if (temp = *srcptr & 0x03) + *kptr |= temp << 4; + + bit = 0x0c; + break; + case 0x0c : + if (temp = *srcptr & 0xc0) + *cptr |= temp >> 4; + if (temp = *srcptr & 0x30) + *mptr |= temp >> 2; + if (temp = *srcptr & 0x0c) + *yptr |= temp; + if (temp = *srcptr & 0x03) + *kptr |= temp << 2; + + bit = 0x03; + break; + case 0x03 : + if (temp = *srcptr & 0xc0) + *cptr |= temp >> 6; + if (temp = *srcptr & 0x30) + *mptr |= temp >> 4; + if (temp = *srcptr & 0x0c) + *yptr |= temp >> 2; + if (temp = *srcptr & 0x03) + *kptr |= temp; + + bit = 0xc0; + cptr ++; + mptr ++; + yptr ++; + kptr ++; + break; + } + break; + } + break; + + case 4 : + memset(dst, 0, cups->header.cupsBytesPerLine); + + switch (cups->header.cupsColorSpace) + { + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + for (x = cups->width, cptr = dst, mptr = cptr + bandbytes, + yptr = mptr + bandbytes, bit = 0xf0; + x > 0; + x --, srcptr += 2) + switch (bit) + { + case 0xf0 : + if (temp = srcptr[0] & 0x0f) + *cptr |= temp << 4; + if (temp = srcptr[1] & 0xf0) + *mptr |= temp; + if (temp = srcptr[1] & 0x0f) + *yptr |= temp << 4; + + bit = 0x0f; + break; + case 0x0f : + if (temp = srcptr[0] & 0x0f) + *cptr |= temp; + if (temp = srcptr[1] & 0xf0) + *mptr |= temp >> 4; + if (temp = srcptr[1] & 0x0f) + *yptr |= temp; + + bit = 0xf0; + cptr ++; + mptr ++; + yptr ++; + kptr ++; + break; + } + break; + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + case CUPS_CSPACE_KCMYcm : + for (x = cups->width, cptr = dst, mptr = cptr + bandbytes, + yptr = mptr + bandbytes, kptr = yptr + bandbytes, + bit = 0xf0; + x > 0; + x --, srcptr += 2) + switch (bit) + { + case 0xf0 : + if (temp = srcptr[0] & 0xf0) + *cptr |= temp; + if (temp = srcptr[0] & 0x0f) + *mptr |= temp << 4; + if (temp = srcptr[1] & 0xf0) + *yptr |= temp; + if (temp = srcptr[1] & 0x0f) + *kptr |= temp << 4; + + bit = 0x0f; + break; + case 0x0f : + if (temp = srcptr[0] & 0xf0) + *cptr |= temp >> 4; + if (temp = srcptr[0] & 0x0f) + *mptr |= temp; + if (temp = srcptr[1] & 0xf0) + *yptr |= temp >> 4; + if (temp = srcptr[1] & 0x0f) + *kptr |= temp; + + bit = 0xf0; + cptr ++; + mptr ++; + yptr ++; + kptr ++; + break; + } + break; + } + break; + + case 8 : + switch (cups->header.cupsColorSpace) + { + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + for (x = cups->width, cptr = dst, mptr = cptr + bandbytes, + yptr = mptr + bandbytes; + x > 0; + x --) + { + *cptr++ = *srcptr++; + *mptr++ = *srcptr++; + *yptr++ = *srcptr++; + } + break; + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + case CUPS_CSPACE_KCMYcm : + for (x = cups->width, cptr = dst, mptr = cptr + bandbytes, + yptr = mptr + bandbytes, kptr = yptr + bandbytes; + x > 0; + x --) + { + *cptr++ = *srcptr++; + *mptr++ = *srcptr++; + *yptr++ = *srcptr++; + *kptr++ = *srcptr++; + } + break; + } + break; + } + + /* + * Write the bitmap data to the raster stream... + */ + + cupsRasterWritePixels(cups->stream, dst, cups->header.cupsBytesPerLine); + } +} + + +/* + * 'cups_print_planar()' - Print a page of planar pixels. + */ + +static void +cups_print_planar(gx_device_printer *pdev, /* I - Printer device */ + unsigned char *src, /* I - Scanline buffer */ + unsigned char *dst, /* I - Bitmap buffer */ + int srcbytes) /* I - Number of bytes in src */ +{ + int x; /* Looping var */ + int y; /* Looping var */ + int z; /* Looping var */ + unsigned char srcbit; /* Current source bit */ + unsigned char dstbit; /* Current destination bit */ + unsigned char temp; /* Temporary variable */ + unsigned char *srcptr; /* Pointer to data */ + unsigned char *dstptr; /* Pointer to bitmap */ + + + /* + * Loop through the page bitmap and write planar pixels... We have + * to separate each chunked color as needed... + */ + + for (z = 0; z < pdev->color_info.num_components; z ++) + for (y = 0; y < cups->height; y ++) + { + /* + * Grab the scanline data... + */ + + if (gdev_prn_get_bits((gx_device_printer *)pdev, y, src, &srcptr) < 0) + { + fprintf(stderr, "ERROR: Unable to get scanline %d!\n", y); + gs_exit(1); + } + + /* + * Pull the individual color planes out of the pixels... + */ + + if (srcptr[0] == 0 && memcmp(srcptr, srcptr + 1, srcbytes - 1) == 0) + memset(dst, 0, cups->header.cupsBytesPerLine); + else + switch (cups->header.cupsBitsPerColor) + { + case 1 : + memset(dst, 0, cups->header.cupsBytesPerLine); + + switch (cups->header.cupsColorSpace) + { + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + for (dstptr = dst, x = cups->width, srcbit = 64 >> z, + dstbit = 128; + x > 0; + x --) + { + if (*srcptr & srcbit) + *dstptr |= dstbit; + + if (srcbit >= 16) + srcbit >>= 4; + else + { + srcbit = 64 >> z; + srcptr ++; + } + + if (dstbit > 1) + dstbit >>= 1; + else + { + dstbit = 128; + dstptr ++; + } + } + break; + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + for (dstptr = dst, x = cups->width, srcbit = 128 >> z, + dstbit = 128; + x > 0; + x --) + { + if (*srcptr & srcbit) + *dstptr |= dstbit; + + if (srcbit >= 16) + srcbit >>= 4; + else + { + srcbit = 128 >> z; + srcptr ++; + } + + if (dstbit > 1) + dstbit >>= 1; + else + { + dstbit = 128; + dstptr ++; + } + } + break; + case CUPS_CSPACE_KCMYcm : + for (dstptr = dst, x = cups->width, srcbit = 32 >> z, + dstbit = 128; + x > 0; + x --, srcptr ++) + { + if (*srcptr & srcbit) + *dstptr |= dstbit; + + if (dstbit > 1) + dstbit >>= 1; + else + { + dstbit = 128; + dstptr ++; + } + } + break; + } + break; + + case 2 : + memset(dst, 0, cups->header.cupsBytesPerLine); + + switch (cups->header.cupsColorSpace) + { + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + for (dstptr = dst, x = cups->width, srcbit = 48 >> (z * 2), + dstbit = 0xc0; + x > 0; + x --, srcptr ++) + { + if (temp = *srcptr & srcbit) + { + if (srcbit == dstbit) + *dstptr |= temp; + else + { + switch (srcbit) + { + case 0x30 : + temp >>= 4; + break; + case 0x0c : + temp >>= 2; + break; + } + + switch (dstbit) + { + case 0xc0 : + *dstptr |= temp << 6; + break; + case 0x30 : + *dstptr |= temp << 4; + break; + case 0x0c : + *dstptr |= temp << 2; + break; + case 0x03 : + *dstptr |= temp; + break; + } + } + } + + if (dstbit > 0x03) + dstbit >>= 2; + else + { + dstbit = 0xc0; + dstptr ++; + } + } + break; + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + case CUPS_CSPACE_KCMYcm : + for (dstptr = dst, x = cups->width, srcbit = 192 >> (z * 2), + dstbit = 0xc0; + x > 0; + x --, srcptr ++) + { + if (temp = *srcptr & srcbit) + { + if (srcbit == dstbit) + *dstptr |= temp; + else + { + switch (srcbit) + { + case 0xc0 : + temp >>= 6; + break; + case 0x30 : + temp >>= 4; + break; + case 0x0c : + temp >>= 2; + break; + } + + switch (dstbit) + { + case 0xc0 : + *dstptr |= temp << 6; + break; + case 0x30 : + *dstptr |= temp << 4; + break; + case 0x0c : + *dstptr |= temp << 2; + break; + case 0x03 : + *dstptr |= temp; + break; + } + } + } + + if (dstbit > 0x03) + dstbit >>= 2; + else + { + dstbit = 0xc0; + dstptr ++; + } + } + break; + } + break; + + case 4 : + memset(dst, 0, cups->header.cupsBytesPerLine); + + switch (cups->header.cupsColorSpace) + { + case CUPS_CSPACE_RGB : + case CUPS_CSPACE_CMY : + case CUPS_CSPACE_YMC : + if (z > 0) + srcptr ++; + + if (z == 1) + srcbit = 0xf0; + else + srcbit = 0x0f; + + for (dstptr = dst, x = cups->width, dstbit = 0xf0; + x > 0; + x --, srcptr += 2) + { + if (temp = *srcptr & srcbit) + { + if (srcbit == dstbit) + *dstptr |= temp; + else + { + if (srcbit == 0xf0) + temp >>= 4; + + if (dstbit == 0xf0) + *dstptr |= temp << 4; + else + *dstptr |= temp; + } + } + + if (dstbit == 0xf0) + dstbit = 0x0f; + else + { + dstbit = 0xf0; + dstptr ++; + } + } + break; + case CUPS_CSPACE_CMYK : + case CUPS_CSPACE_YMCK : + case CUPS_CSPACE_KCMY : + case CUPS_CSPACE_KCMYcm : + if (z > 1) + srcptr ++; + + if (z & 1) + srcbit = 0x0f; + else + srcbit = 0xf0; + + for (dstptr = dst, x = cups->width, dstbit = 0xf0; + x > 0; + x --, srcptr += 2) + { + if (temp = *srcptr & srcbit) + { + if (srcbit == dstbit) + *dstptr |= temp; + else + { + if (srcbit == 0xf0) + temp >>= 4; + + if (dstbit == 0xf0) + *dstptr |= temp << 4; + else + *dstptr |= temp; + } + } + + if (dstbit == 0xf0) + dstbit = 0x0f; + else + { + dstbit = 0xf0; + dstptr ++; + } + } + break; + } + break; + + case 8 : + for (srcptr += z, dstptr = dst, x = cups->header.cupsBytesPerLine; + x > 0; + srcptr += pdev->color_info.num_components, x --) + *dstptr++ = *srcptr; + break; + } + + /* + * Write the bitmap data to the raster stream... + */ + + cupsRasterWritePixels(cups->stream, dst, cups->header.cupsBytesPerLine); + } +} + + +/* + * End of "$Id$". + */ diff --git a/pstoraster/gdevdbit.c b/pstoraster/gdevdbit.c new file mode 100644 index 0000000000..0e2180f0f3 --- /dev/null +++ b/pstoraster/gdevdbit.c @@ -0,0 +1,706 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Default device bitmap copying implementation */ +#include "gx.h" +#include "gpcheck.h" +#include "gserrors.h" +#include "gsbittab.h" +#include "gsrect.h" +#include "gsropt.h" +#include "gxdcolor.h" +#include "gxdevice.h" +#include "gxdevmem.h" +#include "gdevmem.h" +#undef mdev +#include "gxcpath.h" + +/* By default, implement tile_rectangle using strip_tile_rectangle. */ +int +gx_default_tile_rectangle(gx_device * dev, const gx_tile_bitmap * tile, + int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, + int px, int py) +{ + gx_strip_bitmap tiles; + + *(gx_tile_bitmap *) & tiles = *tile; + tiles.shift = tiles.rep_shift = 0; + return (*dev_proc(dev, strip_tile_rectangle)) + (dev, &tiles, x, y, w, h, color0, color1, px, py); +} + +/* Implement copy_mono by filling lots of small rectangles. */ +/* This is very inefficient, but it works as a default. */ +int +gx_default_copy_mono(gx_device * dev, const byte * data, + int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index zero, gx_color_index one) +{ + bool invert; + gx_color_index color; + gx_device_color devc; + + fit_copy(dev, data, dx, raster, id, x, y, w, h); + if (one != gx_no_color_index) { + invert = false; + color = one; + if (zero != gx_no_color_index) { + int code = (*dev_proc(dev, fill_rectangle)) + (dev, x, y, w, h, zero); + + if (code < 0) + return code; + } + } else { + invert = true; + color = zero; + } + color_set_pure(&devc, color); + return gx_dc_default_fill_masked + (&devc, data, dx, raster, id, x, y, w, h, dev, rop3_T, invert); +} + +/* Implement copy_color by filling lots of small rectangles. */ +/* This is very inefficient, but it works as a default. */ +int +gx_default_copy_color(gx_device * dev, const byte * data, + int dx, int raster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + int depth = dev->color_info.depth; + byte mask; + + dev_proc_fill_rectangle((*fill)); + const byte *row; + int iy; + + if (depth == 1) + return (*dev_proc(dev, copy_mono)) (dev, data, dx, raster, id, + x, y, w, h, + (gx_color_index) 0, (gx_color_index) 1); + fit_copy(dev, data, dx, raster, id, x, y, w, h); + fill = dev_proc(dev, fill_rectangle); + mask = (byte) ((1 << depth) - 1); + for (row = data, iy = 0; iy < h; row += raster, ++iy) { + int ix; + gx_color_index c0 = gx_no_color_index; + const byte *ptr = row + ((dx * depth) >> 3); + int i0; + + for (i0 = ix = 0; ix < w; ++ix) { + gx_color_index color; + + if (depth >= 8) { + color = *ptr++; + switch (depth) { + case 32: + color = (color << 8) + *ptr++; + case 24: + color = (color << 8) + *ptr++; + case 16: + color = (color << 8) + *ptr++; + } + } else { + uint dbit = (-(ix + dx + 1) * depth) & 7; + + color = (*ptr >> dbit) & mask; + if (dbit == 0) + ptr++; + } + if (color != c0) { + if (ix > i0) { + int code = (*fill) + (dev, i0 + x, iy + y, ix - i0, 1, c0); + + if (code < 0) + return code; + } + c0 = color; + i0 = ix; + } + } + if (ix > i0) { + int code = (*fill) (dev, i0 + x, iy + y, ix - i0, 1, c0); + + if (code < 0) + return code; + } + } + return 0; +} + +int +gx_no_copy_alpha(gx_device * dev, const byte * data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + gx_color_index color, int depth) +{ + return_error(gs_error_unknownerror); +} + +int +gx_default_copy_alpha(gx_device * dev, const byte * data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + gx_color_index color, int depth) +{ /* This might be called with depth = 1.... */ + if (depth == 1) + return (*dev_proc(dev, copy_mono)) (dev, data, data_x, raster, id, + x, y, width, height, + gx_no_color_index, color); + /* + * Simulate alpha by weighted averaging of RGB values. + * This is very slow, but functionally correct. + */ + { + const byte *row; + gs_memory_t *mem = dev->memory; + int bpp = dev->color_info.depth; + uint in_size = gx_device_raster(dev, false); + byte *lin; + uint out_size; + byte *lout; + int code = 0; + gx_color_value color_rgb[3]; + int ry; + + fit_copy(dev, data, data_x, raster, id, x, y, width, height); + row = data; + out_size = bitmap_raster(width * bpp); + lin = gs_alloc_bytes(mem, in_size, "copy_alpha(lin)"); + lout = gs_alloc_bytes(mem, out_size, "copy_alpha(lout)"); + if (lin == 0 || lout == 0) { + code = gs_note_error(gs_error_VMerror); + goto out; + } + (*dev_proc(dev, map_color_rgb)) (dev, color, color_rgb); + for (ry = y; ry < y + height; row += raster, ++ry) { + byte *line; + int sx, rx; + + declare_line_accum(lout, bpp, x); + + code = (*dev_proc(dev, get_bits)) (dev, ry, lin, &line); + if (code < 0) + break; + for (sx = data_x, rx = x; sx < data_x + width; ++sx, ++rx) { + gx_color_index previous = gx_no_color_index; + gx_color_index composite; + int alpha2, alpha; + + if (depth == 2) /* map 0 - 3 to 0 - 15 */ + alpha = ((row[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5; + else + alpha2 = row[sx >> 1], + alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4); + blend:if (alpha == 15) { /* Just write the new color. */ + composite = color; + } else { + if (previous == gx_no_color_index) { /* Extract the old color. */ + if (bpp < 8) { + const uint bit = rx * bpp; + const byte *src = line + (bit >> 3); + + previous = + (*src >> (8 - (bit + bpp))) & + ((1 << bpp) - 1); + } else { + const byte *src = line + (rx * (bpp >> 3)); + + previous = 0; + switch (bpp >> 3) { + case 4: + previous += (gx_color_index) * src++ << 24; + case 3: + previous += (gx_color_index) * src++ << 16; + case 2: + previous += (gx_color_index) * src++ << 8; + case 1: + previous += *src++; + } + } + } + if (alpha == 0) { /* Just write the old color. */ + composite = previous; + } else { /* Blend RGB values. */ + gx_color_value rgb[3]; + + (*dev_proc(dev, map_color_rgb)) (dev, previous, rgb); +#if arch_ints_are_short +# define b_int long +#else +# define b_int int +#endif +#define make_shade(old, clr, alpha, amax) \ + (old) + (((b_int)(clr) - (b_int)(old)) * (alpha) / (amax)) + rgb[0] = make_shade(rgb[0], color_rgb[0], alpha, 15); + rgb[1] = make_shade(rgb[1], color_rgb[1], alpha, 15); + rgb[2] = make_shade(rgb[2], color_rgb[2], alpha, 15); +#undef b_int +#undef make_shade + composite = + (*dev_proc(dev, map_rgb_color)) (dev, rgb[0], + rgb[1], rgb[2]); + if (composite == gx_no_color_index) { /* The device can't represent this color. */ + /* Move the alpha value towards 0 or 1. */ + if (alpha == 7) /* move 1/2 towards 1 */ + ++alpha; + alpha = (alpha & 8) | (alpha >> 1); + goto blend; + } + } + } + line_accum(composite, bpp); + } + line_accum_copy(dev, lout, bpp, x, rx, raster, ry); + } + out:gs_free_object(mem, lout, "copy_alpha(lout)"); + gs_free_object(mem, lin, "copy_alpha(lin)"); + return code; + } +} + +int +gx_no_copy_rop(gx_device * dev, + const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index * scolors, + const gx_tile_bitmap * texture, const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + return_error(gs_error_unknownerror); /* not implemented */ +} + +int +gx_default_fill_mask(gx_device * orig_dev, + const byte * data, int dx, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + const gx_drawing_color * pdcolor, int depth, + gs_logical_operation_t lop, const gx_clip_path * pcpath) +{ + gx_device *dev; + gx_device_clip cdev; + gx_color_index colors[2]; + gx_strip_bitmap *tile; + + if (gx_dc_is_pure(pdcolor)) { + tile = 0; + colors[0] = gx_no_color_index; + colors[1] = gx_dc_pure_color(pdcolor); + } else if (gx_dc_is_binary_halftone(pdcolor)) { + tile = gx_dc_binary_tile(pdcolor); + colors[0] = gx_dc_binary_color0(pdcolor); + colors[1] = gx_dc_binary_color1(pdcolor); + } else + return_error(gs_error_unknownerror); /* not implemented */ + if (pcpath != 0) { + gx_make_clip_path_device(&cdev, pcpath); + cdev.target = orig_dev; + dev = (gx_device *) & cdev; + (*dev_proc(dev, open_device)) (dev); + } else + dev = orig_dev; + if (depth > 1) { + /****** CAN'T DO ROP OR HALFTONE WITH ALPHA ******/ + return (*dev_proc(dev, copy_alpha)) + (dev, data, dx, raster, id, x, y, w, h, colors[1], depth); + } + if (lop != lop_default) { + gx_color_index scolors[2]; + + scolors[0] = gx_device_white(dev); + scolors[1] = gx_device_black(dev); + if (tile == 0) + colors[0] = colors[1]; /* pure color */ + /* + * We want to write only where the mask is a 1, so enable source + * transparency. We have to include S in the operation, + * otherwise S_transparent will be ignored. + */ + return (*dev_proc(dev, strip_copy_rop)) + (dev, data, dx, raster, id, scolors, tile, colors, + x, y, w, h, + gx_dc_phase(pdcolor).x, gx_dc_phase(pdcolor).y, + lop | (rop3_S | lop_S_transparent)); + } + if (tile == 0) { + return (*dev_proc(dev, copy_mono)) + (dev, data, dx, raster, id, x, y, w, h, + gx_no_color_index, colors[1]); + } + /* + * Use the same approach as the default copy_mono (above). We + * should really clip to the intersection of the bounding boxes of + * the device and the clipping path, but it's too much work. + */ + fit_copy(orig_dev, data, dx, raster, id, x, y, w, h); + { + dev_proc_strip_tile_rectangle((*tile_proc)) = + dev_proc(dev, strip_tile_rectangle); + const byte *row = data + (dx >> 3); + int dx_bit = dx & 7; + int wdx = w + dx_bit; + int iy; + + for (row = data, iy = 0; iy < h; row += raster, iy++) { + int ix; + + for (ix = dx_bit; ix < wdx;) { + int i0; + uint b; + uint len; + int code; + + /* Skip 0-bits. */ + b = row[ix >> 3]; + len = byte_bit_run_length[ix & 7][b ^ 0xff]; + if (len) { + ix += ((len - 1) & 7) + 1; + continue; + } + /* Scan 1-bits. */ + i0 = ix; + for (;;) { + b = row[ix >> 3]; + len = byte_bit_run_length[ix & 7][b]; + if (!len) + break; + ix += ((len - 1) & 7) + 1; + if (ix >= wdx) { + ix = wdx; + break; + } + if (len < 8) + break; + } + /* Now color the run from i0 to ix. */ + code = (*tile_proc) + (dev, tile, i0 - dx_bit + x, iy + y, ix - i0, 1, + colors[0], colors[1], + gx_dc_phase(pdcolor).x, gx_dc_phase(pdcolor).y); + if (code < 0) + return code; +#undef row_bit + } + } + } + return 0; +} + +/* Default implementation of strip_tile_rectangle */ +int +gx_default_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, + int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, + int px, int py) +{ /* Fill the rectangle in chunks. */ + int width = tiles->size.x; + int height = tiles->size.y; + int raster = tiles->raster; + int rwidth = tiles->rep_width; + int rheight = tiles->rep_height; + int shift = tiles->shift; + + fit_fill_xy(dev, x, y, w, h); + +#ifdef DEBUG + if (gs_debug_c('t')) { + int ptx, pty; + const byte *ptp = tiles->data; + + dlprintf3("[t]tile %dx%d raster=%d;", + tiles->size.x, tiles->size.y, tiles->raster); + dlprintf6(" x,y=%d,%d w,h=%d,%d p=%d,%d\n", + x, y, w, h, px, py); + dlputs(""); + for (pty = 0; pty < tiles->size.y; pty++) { + dprintf(" "); + for (ptx = 0; ptx < tiles->raster; ptx++) + dprintf1("%3x", *ptp++); + } + dputc('\n'); + } +#endif + + if (dev_proc(dev, tile_rectangle) != gx_default_tile_rectangle) { + if (shift == 0) { /* + * Temporarily patch the tile_rectangle procedure in the + * device so we don't get into a recursion loop if the + * device has a tile_rectangle procedure that conditionally + * calls the strip_tile_rectangle procedure. + */ + dev_proc_tile_rectangle((*tile_proc)) = + dev_proc(dev, tile_rectangle); + int code; + + set_dev_proc(dev, tile_rectangle, gx_default_tile_rectangle); + code = (*tile_proc) + (dev, (const gx_tile_bitmap *)tiles, x, y, w, h, + color0, color1, px, py); + set_dev_proc(dev, tile_rectangle, tile_proc); + return code; + } + /* We should probably optimize this case too, for the benefit */ + /* of window systems, but we don't yet. */ + } { /* + * Note: we can't do the following computations until after + * the fit_fill_xy. + */ + int xoff = + (shift == 0 ? px : + px + (y + py) / rheight * tiles->rep_shift); + int irx = ((rwidth & (rwidth - 1)) == 0 ? /* power of 2 */ + (x + xoff) & (rwidth - 1) : + (x + xoff) % rwidth); + int ry = ((rheight & (rheight - 1)) == 0 ? /* power of 2 */ + (y + py) & (rheight - 1) : + (y + py) % rheight); + int icw = width - irx; + int ch = height - ry; + byte *row = tiles->data + ry * raster; + + dev_proc_copy_mono((*proc_mono)); + dev_proc_copy_color((*proc_color)); + int code; + + if (color0 == gx_no_color_index && color1 == gx_no_color_index) + proc_color = dev_proc(dev, copy_color); + else + proc_color = 0, proc_mono = dev_proc(dev, copy_mono); + +/****** SHOULD ALSO PASS id IF COPYING A FULL TILE ******/ +#define real_copy_tile(srcx, tx, ty, tw, th)\ + code =\ + (proc_color != 0 ?\ + (*proc_color)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th) :\ + (*proc_mono)(dev, row, srcx, raster, gx_no_bitmap_id, tx, ty, tw, th, color0, color1));\ + if ( code < 0 ) return_error(code);\ + return_if_interrupt() +#ifdef DEBUG +#define copy_tile(sx, tx, ty, tw, th)\ + if_debug5('t', " copy sx=%d x=%d y=%d w=%d h=%d\n",\ + sx, tx, ty, tw, th);\ + real_copy_tile(sx, tx, ty, tw, th) +#else +#define copy_tile(sx, tx, ty, tw, th)\ + real_copy_tile(sx, tx, ty, tw, th) +#endif + if (ch >= h) { /* Shallow operation */ + if (icw >= w) { /* Just one (partial) tile to transfer. */ + copy_tile(irx, x, y, w, h); + } else { + int ex = x + w; + int fex = ex - width; + int cx = x + icw; + + copy_tile(irx, x, y, icw, h); + while (cx <= fex) { + copy_tile(0, cx, y, width, h); + cx += width; + } + if (cx < ex) { + copy_tile(0, cx, y, ex - cx, h); + } + } + } else if (icw >= w && shift == 0) { /* Narrow operation, no shift */ + int ey = y + h; + int fey = ey - height; + int cy = y + ch; + + copy_tile(irx, x, y, w, ch); + row = tiles->data; + do { + ch = (cy > fey ? ey - cy : height); + copy_tile(irx, x, cy, w, ch); + } + while ((cy += ch) < ey); + } else { /* Full operation. If shift != 0, some scan lines */ + /* may be narrow. We could test shift == 0 in advance */ + /* and use a slightly faster loop, but right now */ + /* we don't bother. */ + int ex = x + w, ey = y + h; + int fex = ex - width, fey = ey - height; + int cx, cy; + + for (cy = y;;) { + if (icw >= w) { + copy_tile(irx, x, cy, w, ch); + } else { + copy_tile(irx, x, cy, icw, ch); + cx = x + icw; + while (cx <= fex) { + copy_tile(0, cx, cy, width, ch); + cx += width; + } + if (cx < ex) { + copy_tile(0, cx, cy, ex - cx, ch); + } + } + if ((cy += ch) >= ey) + break; + ch = (cy > fey ? ey - cy : height); + if ((irx += shift) >= rwidth) + irx -= rwidth; + icw = width - irx; + row = tiles->data; + } + } +#undef copy_tile +#undef real_copy_tile + } + return 0; +} + +int +gx_no_strip_copy_rop(gx_device * dev, + const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index * scolors, + const gx_strip_bitmap * textures, const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + return_error(gs_error_unknownerror); /* not implemented */ +} + +/* ---------------- Unaligned copy operations ---------------- */ + +/* + * Implementing unaligned operations in terms of the standard aligned + * operations requires adjusting the bitmap origin and/or the raster to be + * aligned. Adjusting the origin is simple; adjusting the raster requires + * doing the operation one scan line at a time. + */ +int +gx_copy_mono_unaligned(gx_device * dev, const byte * data, + int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index zero, gx_color_index one) +{ + dev_proc_copy_mono((*copy_mono)) = dev_proc(dev, copy_mono); + uint offset = alignment_mod(data, align_bitmap_mod); + int step = raster & (align_bitmap_mod - 1); + + /* Adjust the origin. */ + data -= offset; + dx += offset << 3; + + /* Adjust the raster. */ + if (!step) { /* No adjustment needed. */ + return (*copy_mono) (dev, data, dx, raster, id, + x, y, w, h, zero, one); + } + /* Do the transfer one scan line at a time. */ + { + const byte *p = data; + int d = dx; + int code = 0; + int i; + + for (i = 0; i < h && code >= 0; + ++i, p += raster - step, d += step << 3 + ) + code = (*copy_mono) (dev, p, d, raster, gx_no_bitmap_id, + x, y + i, w, 1, zero, one); + return code; + } +} + +int +gx_copy_color_unaligned(gx_device * dev, const byte * data, + int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height) +{ + dev_proc_copy_color((*copy_color)) = dev_proc(dev, copy_color); + int depth = dev->color_info.depth; + uint offset = (uint) (data - (const byte *)0) & (align_bitmap_mod - 1); + int step = raster & (align_bitmap_mod - 1); + + /* + * Adjust the origin. + * We have to do something very special for 24-bit data, + * because that is the only depth that doesn't divide + * align_bitmap_mod exactly. In particular, we need to find + * M*B + R == 0 mod 3, where M is align_bitmap_mod, R is the + * offset value just calculated, and B is an integer unknown; + * the new value of offset will be M*B + R. + */ + if (depth == 24) + offset += (offset % 3) * + (align_bitmap_mod * (3 - (align_bitmap_mod % 3))); + data -= offset; + data_x += (offset << 3) / depth; + + /* Adjust the raster. */ + if (!step) { /* No adjustment needed. */ + return (*copy_color) (dev, data, data_x, raster, id, + x, y, width, height); + } + /* Do the transfer one scan line at a time. */ + { + const byte *p = data; + int d = data_x; + int dstep = (step << 3) / depth; + int code = 0; + int i; + + for (i = 0; i < height && code >= 0; + ++i, p += raster - step, d += dstep + ) + code = (*copy_color) (dev, p, d, raster, gx_no_bitmap_id, + x, y + i, width, 1); + return code; + } +} + +int +gx_copy_alpha_unaligned(gx_device * dev, const byte * data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + gx_color_index color, int depth) +{ + dev_proc_copy_alpha((*copy_alpha)) = dev_proc(dev, copy_alpha); + uint offset = (uint) (data - (const byte *)0) & (align_bitmap_mod - 1); + int step = raster & (align_bitmap_mod - 1); + + /* Adjust the origin. */ + data -= offset; + data_x += (offset << 3) / depth; + + /* Adjust the raster. */ + if (!step) { /* No adjustment needed. */ + return (*copy_alpha) (dev, data, data_x, raster, id, + x, y, width, height, color, depth); + } + /* Do the transfer one scan line at a time. */ + { + const byte *p = data; + int d = data_x; + int dstep = (step << 3) / depth; + int code = 0; + int i; + + for (i = 0; i < height && code >= 0; + ++i, p += raster - step, d += dstep + ) + code = (*copy_alpha) (dev, p, d, raster, gx_no_bitmap_id, + x, y + i, width, 1, color, depth); + return code; + } +} diff --git a/pstoraster/gdevddrw.c b/pstoraster/gdevddrw.c new file mode 100644 index 0000000000..c02c0c1d4d --- /dev/null +++ b/pstoraster/gdevddrw.c @@ -0,0 +1,635 @@ +/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Default polygon and image drawing device procedures */ +#include "math_.h" +#include "memory_.h" +#include "gx.h" +#include "gpcheck.h" +#include "gserrors.h" +#include "gxfixed.h" +#include "gxmatrix.h" +#include "gxdcolor.h" +#include "gxdevice.h" +#include "gxiparam.h" +#include "gxistate.h" + +/* ---------------- Polygon and line drawing ---------------- */ + +/* Define the 'remainder' analogue of fixed_mult_quo. */ +private fixed +fixed_mult_rem(fixed a, fixed b, fixed c) +{ + double prod = (double)a * b; + + return (fixed) (prod - floor(prod / c) * c); +} + +/* + * Fill a trapezoid. Requires: + * {left,right}->start.y <= ybot <= ytop <= {left,right}->end.y. + * Lines where left.x >= right.x will not be drawn. Thanks to Paul Haeberli + * for an early floating point version of this algorithm. + */ +typedef struct trap_line_s { + int di; + fixed df; /* dx/dy ratio = di + df/h */ + fixed ldi, ldf; /* increment per scan line = ldi + ldf/h */ + fixed x, xf; /* current value */ + fixed h; +} trap_line; +int +gx_default_fill_trapezoid(gx_device * dev, const gs_fixed_edge * left, + const gs_fixed_edge * right, fixed ybot, fixed ytop, bool swap_axes, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + const fixed ymin = fixed_pixround(ybot) + fixed_half; + const fixed ymax = fixed_pixround(ytop); + + if (ymin >= ymax) + return 0; /* no scan lines to sample */ + { + int iy = fixed2int_var(ymin); + const int iy1 = fixed2int_var(ymax); + trap_line l, r; + int rxl, rxr, ry; + const fixed + x0l = left->start.x, x1l = left->end.x, x0r = right->start.x, + x1r = right->end.x, dxl = x1l - x0l, dxr = x1r - x0r; + const fixed /* partial pixel offset to first line to sample */ + ysl = ymin - left->start.y, ysr = ymin - right->start.y; + fixed fxl; + bool fill_direct = color_writes_pure(pdevc, lop); + gx_color_index cindex; + + dev_proc_fill_rectangle((*fill_rect)); + int max_rect_height = 1; /* max height to do fill as rectangle */ + int code; + + if_debug2('z', "[z]y=[%d,%d]\n", iy, iy1); + + if (fill_direct) + cindex = pdevc->colors.pure, + fill_rect = dev_proc(dev, fill_rectangle); + l.h = left->end.y - left->start.y; + r.h = right->end.y - right->start.y; + l.x = x0l + (fixed_half - fixed_epsilon); + r.x = x0r + (fixed_half - fixed_epsilon); + ry = iy; + +#define fill_trap_rect(x,y,w,h)\ + (fill_direct ?\ + (swap_axes ? (*fill_rect)(dev, y, x, h, w, cindex) :\ + (*fill_rect)(dev, x, y, w, h, cindex)) :\ + swap_axes ? gx_fill_rectangle_device_rop(y, x, h, w, pdevc, dev, lop) :\ + gx_fill_rectangle_device_rop(x, y, w, h, pdevc, dev, lop)) + + /* Compute the dx/dy ratios. */ + /* dx# = dx#i + (dx#f / h#). */ +#define compute_dx(tl, d, ys)\ + if ( d >= 0 )\ + { if ( d < tl.h ) tl.di = 0, tl.df = d;\ + else tl.di = (int)(d / tl.h), tl.df = d - tl.di * tl.h,\ + tl.x += ys * tl.di;\ + }\ + else\ + { if ( (tl.df = d + tl.h) >= 0 /* d >= -tl.h */ ) tl.di = -1, tl.x -= ys;\ + else tl.di = (int)-((tl.h - 1 - d) / tl.h), tl.df = d - tl.di * tl.h,\ + tl.x += ys * tl.di;\ + } + + /* Compute the x offsets at the first scan line to sample. */ + /* We need to be careful in computing ys# * dx#f {/,%} h# */ + /* because the multiplication may overflow. We know that */ + /* all the quantities involved are non-negative, and that */ + /* ys# is usually than 1 (as a fixed, of course); this gives us */ + /* a cheap conservative check for overflow in the multiplication. */ +#define ymult_limit (max_fixed / fixed_1) +#define ymult_quo(ys, tl)\ + (ys < fixed_1 && tl.df < ymult_limit ? ys * tl.df / tl.h :\ + fixed_mult_quo(ys, tl.df, tl.h)) + + /* + * It's worth checking for dxl == dxr, since this is the case + * for parallelograms (including stroked lines). + * Also check for left or right vertical edges. + */ + if (fixed_floor(l.x) == fixed_pixround(x1l)) { /* Left edge is vertical, we don't need to increment. */ + l.di = 0, l.df = 0; + fxl = 0; + } else { + compute_dx(l, dxl, ysl); + fxl = ymult_quo(ysl, l); + l.x += fxl; + } + if (fixed_floor(r.x) == fixed_pixround(x1r)) { /* Right edge is vertical. If both are vertical, */ + /* we have a rectangle. */ + if (l.di == 0 && l.df == 0) + max_rect_height = max_int; + else + r.di = 0, r.df = 0; + } + /* The test for fxl != 0 is required because the right edge */ + /* might cross some pixel centers even if the left edge doesn't. */ + else if (dxr == dxl && fxl != 0) { + if (l.di == 0) + r.di = 0, r.df = l.df; + else /* too hard to do adjustments right */ + compute_dx(r, dxr, ysr); + if (ysr == ysl && r.h == l.h) + r.x += fxl; + else + r.x += ymult_quo(ysr, r); + } else { + compute_dx(r, dxr, ysr); + r.x += ymult_quo(ysr, r); + } + rxl = fixed2int_var(l.x); + rxr = fixed2int_var(r.x); + + /* + * Take a shortcut if we're only sampling a single scan line, + * or if we have a rectangle. + */ + if (iy1 - iy <= max_rect_height) { + iy = iy1; + if_debug2('z', "[z]rectangle, x=[%d,%d]\n", rxl, rxr); + goto last; + } + /* Compute one line's worth of dx/dy. */ + /* dx# * fixed_1 = ld#i + (ld#f / h#). */ +#define compute_ldx(tl, ys)\ + if ( tl.df < ymult_limit )\ + { if ( tl.df == 0 ) /* vertical edge, worth checking for */\ + tl.ldi = int2fixed(tl.di),\ + tl.ldf = 0,\ + tl.xf = -tl.h;\ + else\ + tl.ldi = int2fixed(tl.di) + int2fixed(tl.df) / tl.h,\ + tl.ldf = int2fixed(tl.df) % tl.h,\ + tl.xf = (ys < fixed_1 ? ys * tl.df % tl.h :\ + fixed_mult_rem(ys, tl.df, tl.h)) - tl.h;\ + }\ + else\ + tl.ldi = int2fixed(tl.di) + fixed_mult_quo(fixed_1, tl.df, tl.h),\ + tl.ldf = fixed_mult_rem(fixed_1, tl.df, tl.h),\ + tl.xf = fixed_mult_rem(ys, tl.df, tl.h) - tl.h + compute_ldx(l, ysl); + if (dxr == dxl && ysr == ysl && r.h == l.h) + r.ldi = l.ldi, r.ldf = l.ldf, r.xf = l.xf; + else { + compute_ldx(r, ysr); + } +#undef compute_ldx + + while (++iy != iy1) { + int ixl, ixr; + +#define step_line(tl)\ + tl.x += tl.ldi;\ + if ( (tl.xf += tl.ldf) >= 0 ) tl.xf -= tl.h, tl.x++; + step_line(l); + step_line(r); +#undef step_line + ixl = fixed2int_var(l.x); + ixr = fixed2int_var(r.x); + if (ixl != rxl || ixr != rxr) { + code = fill_trap_rect(rxl, ry, rxr - rxl, iy - ry); + if (code < 0) + goto xit; + rxl = ixl, rxr = ixr, ry = iy; + } + } + last:code = fill_trap_rect(rxl, ry, rxr - rxl, iy - ry); + xit:if (code < 0 && fill_direct) + return_error(code); + return_if_interrupt(); + return code; + } +} + +/* Fill a parallelogram whose points are p, p+a, p+b, and p+a+b. */ +/* We should swap axes to get best accuracy, but we don't. */ +/* We must be very careful to follow the center-of-pixel rule in all cases. */ +int +gx_default_fill_parallelogram(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + fixed t; + fixed qx, qy, ym; + + dev_proc_fill_trapezoid((*fill_trapezoid)); + gs_fixed_edge left, right; + int code; + + /* Ensure ay >= 0, by >= 0. */ + if (ay < 0) + px += ax, py += ay, ax = -ax, ay = -ay; + if (by < 0) + px += bx, py += by, bx = -bx, by = -by; + qx = px + ax + bx; + /* Make a special fast check for rectangles. */ + if ((ay | bx) == 0 || (by | ax) == 0) { /* If a point falls exactly on the middle of a pixel, */ + /* we must round it down, not up. */ + int rx = fixed2int_pixround(px); + int ry = fixed2int_pixround(py); + + /* Exactly one of (ax,bx) and one of (ay,by) is non-zero. */ + int w = fixed2int_pixround(qx) - rx; + + if (w < 0) + rx += w, w = -w; + return gx_fill_rectangle_device_rop(rx, ry, w, + fixed2int_pixround(py + ay + by) - ry, + pdevc, dev, lop); + } + /* + * Not a rectangle. Ensure that the 'a' line is to the left of + * the 'b' line. Testing ax <= bx is neither sufficient nor + * necessary: in general, we need to compare the slopes. + */ +#define swap(r, s) (t = r, r = s, s = t) + if ((ax ^ bx) < 0) { /* In this case, the test ax <= bx is sufficient. */ + if (ax > bx) + swap(ax, bx), swap(ay, by); + } else { /* + * Compare the slopes. We know that ay >= 0, by >= 0, + * and ax and bx have the same sign; the lines are in the + * correct order iff + * ay/ax >= by/bx, or + * ay*bx >= by*ax + * Eventually we can probably find a better way to test this, + * without using floating point. + */ + if ((double)ay * bx < (double)by * ax) + swap(ax, bx), swap(ay, by); + } + fill_trapezoid = dev_proc(dev, fill_trapezoid); + qy = py + ay + by; + left.start.x = right.start.x = px; + left.start.y = right.start.y = py; + left.end.x = px + ax; + left.end.y = py + ay; + right.end.x = px + bx; + right.end.y = py + by; +#define rounded_same(p1, p2)\ + (fixed_pixround(p1) == fixed_pixround(p2)) + if (ay < by) { + if (!rounded_same(py, left.end.y)) { + code = (*fill_trapezoid) (dev, &left, &right, py, left.end.y, + false, pdevc, lop); + if (code < 0) + return code; + } + left.start = left.end; + left.end.x = qx, left.end.y = qy; + ym = right.end.y; + if (!rounded_same(left.start.y, ym)) { + code = (*fill_trapezoid) (dev, &left, &right, left.start.y, ym, + false, pdevc, lop); + if (code < 0) + return code; + } + right.start = right.end; + right.end.x = qx, right.end.y = qy; + } else { + if (!rounded_same(py, right.end.y)) { + code = (*fill_trapezoid) (dev, &left, &right, py, right.end.y, + false, pdevc, lop); + if (code < 0) + return code; + } + right.start = right.end; + right.end.x = qx, right.end.y = qy; + ym = left.end.y; + if (!rounded_same(right.start.y, ym)) { + code = (*fill_trapezoid) (dev, &left, &right, right.start.y, ym, + false, pdevc, lop); + if (code < 0) + return code; + } + left.start = left.end; + left.end.x = qx, left.end.y = qy; + } + if (!rounded_same(ym, qy)) + return (*fill_trapezoid) (dev, &left, &right, ym, qy, + false, pdevc, lop); + else + return 0; +#undef rounded_same +#undef swap +} + +/* Fill a triangle whose points are p, p+a, and p+b. */ +/* We should swap axes to get best accuracy, but we don't. */ +int +gx_default_fill_triangle(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + fixed t; + fixed ym; + + dev_proc_fill_trapezoid((*fill_trapezoid)) = + dev_proc(dev, fill_trapezoid); + gs_fixed_edge left, right; + int code; + + /* Ensure ay >= 0, by >= 0. */ + if (ay < 0) + px += ax, py += ay, bx -= ax, by -= ay, ax = -ax, ay = -ay; + if (by < 0) + px += bx, py += by, ax -= bx, ay -= by, bx = -bx, by = -by; + /* Ensure ay <= by. */ +#define swap(r, s) (t = r, r = s, s = t) + if (ay > by) + swap(ax, bx), swap(ay, by); +#undef swap + /* + * Make a special check for a flat bottom or top, + * which we can handle with a single call on fill_trapezoid. + */ + left.start.x = right.start.x = px; + left.start.y = right.start.y = py; + if (ay == 0) { + /* Flat top */ + if (ax < 0) + left.start.x = px + ax; + else + right.start.x = px + ax; + left.end.x = right.end.x = px + bx; + left.end.y = right.end.y = py + by; + ym = py; + } else if (ay == by) { + /* Flat bottom */ + if (ax < bx) + left.end.x = px + ax, right.end.x = px + bx; + else + left.end.x = px + bx, right.end.x = px + ax; + left.end.y = right.end.y = py + by; + ym = py; + } else { + ym = py + ay; + if (fixed_mult_quo(bx, ay, by) < ax) { + /* The 'b' line is to the left of the 'a' line. */ + left.end.x = px + bx, left.end.y = py + by; + right.end.x = px + ax, right.end.y = py + ay; + code = (*fill_trapezoid) (dev, &left, &right, py, ym, + false, pdevc, lop); + right.start = right.end; + right.end = left.end; + } else { + /* The 'a' line is to the left of the 'b' line. */ + left.end.x = px + ax, left.end.y = py + ay; + right.end.x = px + bx, right.end.y = py + by; + code = (*fill_trapezoid) (dev, &left, &right, py, ym, + false, pdevc, lop); + left.start = left.end; + left.end = right.end; + } + if (code < 0) + return code; + } + return (*fill_trapezoid) (dev, &left, &right, ym, right.end.y, + false, pdevc, lop); +} + +/* Draw a one-pixel-wide line. */ +int +gx_default_draw_thin_line(gx_device * dev, + fixed fx0, fixed fy0, fixed fx1, fixed fy1, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + int ix = fixed2int_var(fx0); + int iy = fixed2int_var(fy0); + int itox = fixed2int_var(fx1); + int itoy = fixed2int_var(fy1); + + return_if_interrupt(); + if (itoy == iy) { /* horizontal line */ + return (ix <= itox ? + gx_fill_rectangle_device_rop(ix, iy, itox - ix + 1, 1, + pdevc, dev, lop) : + gx_fill_rectangle_device_rop(itox, iy, ix - itox + 1, 1, + pdevc, dev, lop) + ); + } + if (itox == ix) { /* vertical line */ + return (iy <= itoy ? + gx_fill_rectangle_device_rop(ix, iy, 1, itoy - iy + 1, + pdevc, dev, lop) : + gx_fill_rectangle_device_rop(ix, itoy, 1, iy - itoy + 1, + pdevc, dev, lop) + ); + } { + fixed h = fy1 - fy0; + fixed w = fx1 - fx0; + fixed tf; + bool swap_axes; + gs_fixed_edge left, right; + +#define fswap(a, b) tf = a, a = b, b = tf + if ((w < 0 ? -w : w) <= (h < 0 ? -h : h)) { + if (h < 0) + fswap(fx0, fx1), fswap(fy0, fy1), + h = -h; + right.start.x = (left.start.x = fx0 - fixed_half) + fixed_1; + right.end.x = (left.end.x = fx1 - fixed_half) + fixed_1; + left.start.y = right.start.y = fy0; + left.end.y = right.end.y = fy1; + swap_axes = false; + } else { + if (w < 0) + fswap(fx0, fx1), fswap(fy0, fy1), + w = -w; + right.start.x = (left.start.x = fy0 - fixed_half) + fixed_1; + right.end.x = (left.end.x = fy1 - fixed_half) + fixed_1; + left.start.y = right.start.y = fx0; + left.end.y = right.end.y = fx1; + swap_axes = true; + } + return (*dev_proc(dev, fill_trapezoid)) (dev, &left, &right, + left.start.y, left.end.y, + swap_axes, pdevc, lop); +#undef fswap + } +} + +/* Stub out the obsolete procedure. */ +int +gx_default_draw_line(gx_device * dev, + int x0, int y0, int x1, int y1, gx_color_index color) +{ + return -1; +} + +/* ---------------- Image drawing ---------------- */ + +/* GC structures for image enumerator */ +public_st_gx_image_enum_common(); + +#define eptr ((gx_image_enum_common_t *)vptr) + +private +ENUM_PTRS_BEGIN(image_enum_common_enum_ptrs) return 0; + +case 0: +return ENUM_OBJ(gx_device_enum_ptr(eptr->dev)); +ENUM_PTRS_END + +private RELOC_PTRS_BEGIN(image_enum_common_reloc_ptrs) +{ + eptr->dev = gx_device_reloc_ptr(eptr->dev, gcst); +} +RELOC_PTRS_END + +#undef eptr + +/* + * gx_default_begin_image is only invoked for ImageType 1 images. However, + * the argument types are different, and if the device provides a + * begin_typed_image procedure, we should use it. See gxdevice.h. + */ +private int +gx_no_begin_image(gx_device * dev, + const gs_imager_state * pis, const gs_image_t * pim, + gs_image_format_t format, const gs_int_rect * prect, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * memory, gx_image_enum_common_t ** pinfo) +{ + return -1; +} +int +gx_default_begin_image(gx_device * dev, + const gs_imager_state * pis, const gs_image_t * pim, + gs_image_format_t format, const gs_int_rect * prect, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * memory, gx_image_enum_common_t ** pinfo) +{ + /* + * Hand off to begin_typed_image, being careful to avoid a + * possible recursion loop. + */ + dev_proc_begin_image((*save_begin_image)) = dev_proc(dev, begin_image); + gs_image_t image; + const gs_image_t *ptim; + int code; + + set_dev_proc(dev, begin_image, gx_no_begin_image); + if (pim->format == format) + ptim = pim; + else { + image = *pim; + image.format = format; + ptim = ℑ + } + code = (*dev_proc(dev, begin_typed_image)) + (dev, pis, NULL, (const gs_image_common_t *)ptim, prect, pdcolor, + pcpath, memory, pinfo); + set_dev_proc(dev, begin_image, save_begin_image); + return code; +} + +int +gx_default_begin_typed_image(gx_device * dev, + const gs_imager_state * pis, const gs_matrix * pmat, + const gs_image_common_t * pic, const gs_int_rect * prect, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * memory, gx_image_enum_common_t ** pinfo) +{ /* + * If this is an ImageType 1 image using the imager's CTM, + * defer to begin_image. + */ + if (pic->type->begin_typed_image == gx_begin_image1) { + const gs_image_t *pim = (const gs_image_t *)pic; + + if (pmat == 0 || + (pis != 0 && !memcmp(pmat, &ctm_only(pis), sizeof(*pmat))) + ) { + int code = (*dev_proc(dev, begin_image)) + (dev, pis, pim, pim->format, prect, pdcolor, + pcpath, memory, pinfo); + + if (code >= 0) + return code; + } + } + return (*pic->type->begin_typed_image) + (dev, pis, pmat, pic, prect, pdcolor, pcpath, memory, pinfo); +} + +int +gx_image_data(gx_image_enum_common_t * info, const byte ** plane_data, + int data_x, uint raster, int height) +{ + int num_planes = info->num_planes; + gx_image_plane_t planes[gs_image_max_components]; + int i; + +#ifdef DEBUG + if (num_planes > gs_image_max_components) { + lprintf2("num_planes=%d > gs_image_max_components=%d!\n", + num_planes, gs_image_max_components); + return_error(gs_error_Fatal); + } +#endif + for (i = 0; i < num_planes; ++i) { + planes[i].data = plane_data[i]; + planes[i].data_x = data_x; + planes[i].raster = raster; + } + return gx_image_plane_data(info, planes, height); +} + +int +gx_image_plane_data(gx_image_enum_common_t * info, + const gx_image_plane_t * planes, int height) +{ + return info->procs->plane_data(info->dev, info, planes, height); +} + +int +gx_image_end(gx_image_enum_common_t * info, bool draw_last) +{ + return info->procs->end_image(info->dev, info, draw_last); +} + +/* Backward compatibility for obsolete driver procedures. */ + +int +gx_default_image_data(gx_device *dev, gx_image_enum_common_t * info, + const byte ** plane_data, + int data_x, uint raster, int height) +{ + return gx_image_data(info, plane_data, data_x, raster, height); +} + +int +gx_default_end_image(gx_device *dev, gx_image_enum_common_t * info, + bool draw_last) +{ + return gx_image_end(info, draw_last); +} diff --git a/pstoraster/gdevdflt.c b/pstoraster/gdevdflt.c new file mode 100644 index 0000000000..7633b7b43b --- /dev/null +++ b/pstoraster/gdevdflt.c @@ -0,0 +1,270 @@ +/* Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Default device implementation */ +#include "gx.h" +#include "gserrors.h" +#include "gsropt.h" +#include "gxcomp.h" +#include "gxdevice.h" +#include "gxdevmem.h" +#undef mdev + +/* ---------------- Default device procedures ---------------- */ + +/* Fill in NULL procedures in a device procedure record. */ +void +gx_device_fill_in_procs(register gx_device * dev) +{ + gx_device_set_procs(dev); + fill_dev_proc(dev, open_device, gx_default_open_device); + fill_dev_proc(dev, get_initial_matrix, gx_default_get_initial_matrix); + fill_dev_proc(dev, sync_output, gx_default_sync_output); + fill_dev_proc(dev, output_page, gx_default_output_page); + fill_dev_proc(dev, close_device, gx_default_close_device); + fill_dev_proc(dev, map_rgb_color, gx_default_map_rgb_color); + fill_dev_proc(dev, map_color_rgb, gx_default_map_color_rgb); + /* NOT fill_rectangle */ + fill_dev_proc(dev, tile_rectangle, gx_default_tile_rectangle); + fill_dev_proc(dev, copy_mono, gx_default_copy_mono); + fill_dev_proc(dev, copy_color, gx_default_copy_color); + fill_dev_proc(dev, obsolete_draw_line, gx_default_draw_line); + fill_dev_proc(dev, get_bits, gx_default_get_bits); + fill_dev_proc(dev, get_params, gx_default_get_params); + fill_dev_proc(dev, put_params, gx_default_put_params); + fill_dev_proc(dev, map_cmyk_color, gx_default_map_cmyk_color); + fill_dev_proc(dev, get_xfont_procs, gx_default_get_xfont_procs); + fill_dev_proc(dev, get_xfont_device, gx_default_get_xfont_device); + fill_dev_proc(dev, map_rgb_alpha_color, gx_default_map_rgb_alpha_color); + fill_dev_proc(dev, get_page_device, gx_default_get_page_device); + fill_dev_proc(dev, get_alpha_bits, gx_default_get_alpha_bits); + fill_dev_proc(dev, copy_alpha, gx_default_copy_alpha); + fill_dev_proc(dev, get_band, gx_default_get_band); + fill_dev_proc(dev, copy_rop, gx_default_copy_rop); + fill_dev_proc(dev, fill_path, gx_default_fill_path); + fill_dev_proc(dev, stroke_path, gx_default_stroke_path); + fill_dev_proc(dev, fill_mask, gx_default_fill_mask); + fill_dev_proc(dev, fill_trapezoid, gx_default_fill_trapezoid); + fill_dev_proc(dev, fill_parallelogram, gx_default_fill_parallelogram); + fill_dev_proc(dev, fill_triangle, gx_default_fill_triangle); + fill_dev_proc(dev, draw_thin_line, gx_default_draw_thin_line); + fill_dev_proc(dev, begin_image, gx_default_begin_image); + /* + * We always replace image_data and end_image with the new + * procedures, and, if in a DEBUG configuration, print a warning + * if the definitions aren't the default ones. + */ +#ifdef DEBUG +# define CHECK_NON_DEFAULT(proc, default, procname)\ + BEGIN\ + if ( dev_proc(dev, proc) != NULL && dev_proc(dev, proc) != default )\ + dprintf2("**** Warning: device %s implements obsolete procedure %s\n",\ + dev->dname, procname);\ + END +#else +# define CHECK_NON_DEFAULT(proc, default, procname)\ + DO_NOTHING +#endif + CHECK_NON_DEFAULT(image_data, gx_default_image_data, "image_data"); + set_dev_proc(dev, image_data, gx_default_image_data); + CHECK_NON_DEFAULT(end_image, gx_default_end_image, "end_image"); + set_dev_proc(dev, end_image, gx_default_end_image); +#undef CHECK_NON_DEFAULT + fill_dev_proc(dev, strip_tile_rectangle, gx_default_strip_tile_rectangle); + fill_dev_proc(dev, strip_copy_rop, gx_default_strip_copy_rop); + fill_dev_proc(dev, get_clipping_box, gx_default_get_clipping_box); + fill_dev_proc(dev, begin_typed_image, gx_default_begin_typed_image); + fill_dev_proc(dev, get_bits_rectangle, gx_default_get_bits_rectangle); + fill_dev_proc(dev, map_color_rgb_alpha, gx_default_map_color_rgb_alpha); + fill_dev_proc(dev, create_compositor, gx_default_create_compositor); + fill_dev_proc(dev, get_hardware_params, gx_default_get_hardware_params); + fill_dev_proc(dev, text_begin, gx_default_text_begin); +} + +int +gx_default_open_device(gx_device * dev) +{ + return 0; +} + +/* Get the initial matrix for a device with inverted Y. */ +/* This includes essentially all printers and displays. */ +void +gx_default_get_initial_matrix(gx_device * dev, register gs_matrix * pmat) +{ + pmat->xx = dev->HWResolution[0] / 72.0; /* x_pixels_per_inch */ + pmat->xy = 0; + pmat->yx = 0; + pmat->yy = dev->HWResolution[1] / -72.0; /* y_pixels_per_inch */ +/****** tx/y is WRONG for devices with ******/ +/****** arbitrary initial matrix ******/ + pmat->tx = 0; + pmat->ty = dev->height; +} +/* Get the initial matrix for a device with upright Y. */ +/* This includes just a few printers and window systems. */ +void +gx_upright_get_initial_matrix(gx_device * dev, register gs_matrix * pmat) +{ + pmat->xx = dev->HWResolution[0] / 72.0; /* x_pixels_per_inch */ + pmat->xy = 0; + pmat->yx = 0; + pmat->yy = dev->HWResolution[1] / 72.0; /* y_pixels_per_inch */ +/****** tx/y is WRONG for devices with ******/ +/****** arbitrary initial matrix ******/ + pmat->tx = 0; + pmat->ty = 0; +} + +int +gx_default_sync_output(gx_device * dev) +{ + return 0; +} + +int +gx_default_output_page(gx_device * dev, int num_copies, int flush) +{ + return (*dev_proc(dev, sync_output)) (dev); +} + +int +gx_default_close_device(gx_device * dev) +{ + return 0; +} + +const gx_xfont_procs * +gx_default_get_xfont_procs(gx_device * dev) +{ + return NULL; +} + +gx_device * +gx_default_get_xfont_device(gx_device * dev) +{ + return dev; +} + +gx_device * +gx_default_get_page_device(gx_device * dev) +{ + return NULL; +} +gx_device * +gx_page_device_get_page_device(gx_device * dev) +{ + return dev; +} + +int +gx_default_get_alpha_bits(gx_device * dev, graphics_object_type type) +{ + return 1; +} + +int +gx_default_get_band(gx_device * dev, int y, int *band_start) +{ + return 0; +} + +void +gx_default_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox) +{ + pbox->p.x = 0; + pbox->p.y = 0; + pbox->q.x = int2fixed(dev->width); + pbox->q.y = int2fixed(dev->height); +} +void +gx_get_largest_clipping_box(gx_device * dev, gs_fixed_rect * pbox) +{ + pbox->p.x = min_fixed; + pbox->p.y = min_fixed; + pbox->q.x = max_fixed; + pbox->q.y = max_fixed; +} + +int +gx_no_create_compositor(gx_device * dev, gx_device ** pcdev, + const gs_composite_t * pcte, const gs_imager_state * pis, gs_memory_t * memory) +{ + return_error(gs_error_unknownerror); /* not implemented */ +} +int +gx_default_create_compositor(gx_device * dev, gx_device ** pcdev, + const gs_composite_t * pcte, const gs_imager_state * pis, gs_memory_t * memory) +{ + return (*pcte->type->procs.create_default_compositor) + (pcte, pcdev, dev, pis, memory); +} +int +gx_non_imaging_create_compositor(gx_device * dev, gx_device ** pcdev, + const gs_composite_t * pcte, const gs_imager_state * pis, gs_memory_t * memory) +{ + *pcdev = dev; + return 0; +} + +/* The following is not really a device procedure. See gxdevice.h. */ + +/* Create an ordinary memory device for page or band buffering. */ +int +gx_default_make_buffer_device(gx_device_memory * mdev, + gx_device * target, gs_memory_t * mem, bool for_band) +{ + const gx_device_memory *mdproto = + gdev_mem_device_for_bits(target->color_info.depth); + + if (mdproto == 0) + return_error(gs_error_rangecheck); + if (target == (gx_device *) mdev) + assign_dev_procs(mdev, mdproto); + else + gs_make_mem_device(mdev, mdproto, mem, (for_band ? 1 : 0), + (target == (gx_device *) mdev ? 0 : target)); + return 0; +} + +/* ---------------- Default per-instance procedures ---------------- */ + +int +gx_default_install(gx_device * dev, gs_state * pgs) +{ + return 0; +} + +int +gx_default_begin_page(gx_device * dev, gs_state * pgs) +{ + return 0; +} + +int +gx_default_end_page(gx_device * dev, int reason, gs_state * pgs) +{ + return (reason != 2 ? 1 : 0); +} diff --git a/pstoraster/gdevdgbr.c b/pstoraster/gdevdgbr.c new file mode 100644 index 0000000000..c156696950 --- /dev/null +++ b/pstoraster/gdevdgbr.c @@ -0,0 +1,586 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Default implementation of device get_bits[_rectangle] */ +#include "gx.h" +#include "gserrors.h" +#include "gxdevice.h" +#include "gxdevmem.h" +#include "gxgetbit.h" +#include "gxlum.h" +#include "gdevmem.h" + +int +gx_no_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data) +{ + return_error(gs_error_unknownerror); +} +int +gx_default_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data) +{ /* + * Hand off to get_bits_rectangle, being careful to avoid a + * possible recursion loop. + */ + dev_proc_get_bits((*save_get_bits)) = dev_proc(dev, get_bits); + gs_int_rect rect; + gs_get_bits_params_t params; + int code; + + rect.p.x = 0, rect.p.y = y; + rect.q.x = dev->width, rect.q.y = y + 1; + params.options = + (actual_data ? GB_RETURN_POINTER : 0) | GB_RETURN_COPY | + (GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_RASTER_STANDARD | + /* No depth specified, we always use native colors. */ + GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE); + params.x_offset = 0; + params.raster = bitmap_raster(dev->width * dev->color_info.depth); + params.data[0] = data; + set_dev_proc(dev, get_bits, gx_no_get_bits); + code = (*dev_proc(dev, get_bits_rectangle)) + (dev, &rect, ¶ms, NULL); + if (actual_data) + *actual_data = params.data[0]; + set_dev_proc(dev, get_bits, save_get_bits); + return code; +} + +/* + * Determine whether we can satisfy a request by simply using the stored + * representation. + */ +private bool +requested_includes_stored(gs_get_bits_options_t requested, + gs_get_bits_options_t stored) +{ + gs_get_bits_options_t both = requested & stored; + + if (!(both & GB_PACKING_ALL)) + return false; + if (both & GB_COLORS_NATIVE) + return true; + if (both & GB_COLORS_STANDARD_ALL) { + if ((both & GB_ALPHA_ALL) && (both & GB_DEPTH_ALL)) + return true; + } + return false; +} + +/* + * Try to implement get_bits_rectangle by returning a pointer. + * Note that dev is used only for computing the default raster + * and for color_info.depth. + * This routine does not check x or h for validity. + */ +int +gx_get_bits_return_pointer(gx_device * dev, int x, int h, + gs_get_bits_params_t * params, gs_get_bits_options_t stored, + byte * stored_base) +{ + gs_get_bits_options_t options = params->options; + + if (!(options & GB_RETURN_POINTER) || + !requested_includes_stored(options, stored) + ) + return -1; + /* + * See whether we can return the bits in place. Note that even if + * offset_any isn't set, x_offset and x don't have to be equal: their + * bit offsets only have to match modulo align_bitmap_mod * 8 (to + * preserve alignment) if align_any isn't set, or mod 8 (since + * byte alignment is always required) if align_any is set. + */ + { + int depth = dev->color_info.depth; + uint dev_raster = gx_device_raster(dev, 1); + uint raster = + (options & (GB_RASTER_STANDARD | GB_RASTER_ANY) ? dev_raster : + params->raster); + + if (h <= 1 || raster == dev_raster) { + int x_offset = + (options & GB_OFFSET_ANY ? x : + options & GB_OFFSET_0 ? 0 : params->x_offset); + + if (x_offset == x) { + params->data[0] = stored_base; + params->x_offset = x; + } else { + uint align_mod = + (options & GB_ALIGN_ANY ? 8 : align_bitmap_mod * 8); + int bit_offset = x - x_offset; + int bytes; + + if (bit_offset & (align_mod - 1)) + return -1; /* can't align */ + if (depth & (depth - 1)) { + /* step = lcm(depth, align_mod) */ + int step = depth / igcd(depth, align_mod) * align_mod; + + bytes = bit_offset / step * step; + } else { + /* Use a faster algorithm if depth is a power of 2. */ + bytes = bit_offset & (-depth & -align_mod); + } + params->data[0] = stored_base + arith_rshift(bytes, 3); + params->x_offset = (bit_offset - bytes) / depth; + } + params->options = + GB_ALIGN_STANDARD | GB_RETURN_POINTER | GB_RASTER_STANDARD | + GB_PACKING_CHUNKY | stored | + (params->x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED); + return 0; + } + } + return -1; +} + +/* + * Convert pixels between representations, primarily for get_bits_rectangle. + * stored indicates how the data are actually stored, and includes: + * - one option from the GB_PACKING group; + * - if h > 1, one option from the GB_RASTER group; + * - optionally (and normally), GB_COLORS_NATIVE; + * - optionally, one option each from the GB_COLORS_STANDARD, GB_DEPTH, + * and GB_ALPHA groups. + * Note that dev is used only for color mapping. This routine assumes that + * the stored data are aligned. + * + * Note: this routine does not check x, w, h for validity. + */ +int +gx_get_bits_copy(gx_device * dev, int x, int w, int h, + gs_get_bits_params_t * params, gs_get_bits_options_t stored, + const byte * src_base, uint dev_raster) +{ + gs_get_bits_options_t options = params->options; + byte *data = params->data[0]; + int depth = dev->color_info.depth; + int bit_x = x * depth; + const byte *src = src_base; + + /* + * If the stored representation matches a requested representation, + * we can copy the data without any transformations. + */ + bool direct_copy = requested_includes_stored(options, stored); + + /* + * The request must include GB_PACKING_CHUNKY, GB_RETURN_COPY, + * and an offset and raster specification. + */ + if ((~options & (GB_PACKING_CHUNKY | GB_RETURN_COPY)) || + !(options & (GB_OFFSET_0 | GB_OFFSET_SPECIFIED)) || + !(options & (GB_RASTER_STANDARD | GB_RASTER_SPECIFIED)) + ) + return_error(gs_error_rangecheck); + { + int x_offset = (options & GB_OFFSET_0 ? 0 : params->x_offset); + int end_bit = (x_offset + w) * depth; + uint std_raster = + (options & GB_ALIGN_STANDARD ? bitmap_raster(end_bit) : + (end_bit + 7) >> 3); + uint raster = + (options & GB_RASTER_STANDARD ? std_raster : params->raster); + int dest_bit_x = x_offset * depth; + int skew = bit_x - dest_bit_x; + + /* + * If the bit positions line up, use bytes_copy_rectangle. + * Since bytes_copy_rectangle doesn't require alignment, + * the bit positions only have to match within a byte, + * not within align_bitmap_mod bytes. + */ + if (!(skew & 7) && direct_copy) { + int bit_w = w * depth; + + bytes_copy_rectangle(data + (dest_bit_x >> 3), raster, + src + (bit_x >> 3), dev_raster, + ((bit_x + bit_w + 7) >> 3) - (bit_x >> 3), h); + } else if (direct_copy) { + /* + * Use the logic already in mem_mono_copy_mono to copy the + * bits to the destination. We do this one line at a time, + * to avoid having to allocate a line pointer table. + */ + gx_device_memory tdev; + byte *line_ptr = data; + + tdev.line_ptrs = &tdev.base; + for (; h > 0; line_ptr += raster, src += dev_raster, --h) { + /* Make sure the destination is aligned. */ + int align = alignment_mod(line_ptr, align_bitmap_mod); + + tdev.base = line_ptr - align; + (*dev_proc(&mem_mono_device, copy_mono)) + ((gx_device *) & tdev, src, bit_x, dev_raster, gx_no_bitmap_id, + dest_bit_x + (align << 3), 0, w, 1, + (gx_color_index) 0, (gx_color_index) 1); + } + } else if (options & ~stored & GB_COLORS_NATIVE) { + /* + * Convert standard colors to native. Note that the source + * may have depths other than 8 bits per component. + */ + int dest_bit_offset = x_offset * depth; + byte *dest_line = data + (dest_bit_offset >> 3); + int ncolors = + (stored & GB_COLORS_RGB ? 3 : stored & GB_COLORS_CMYK ? 4 : + stored & GB_COLORS_GRAY ? 1 : -1); + int ncomp = ncolors + + ((stored & (GB_ALPHA_FIRST | GB_ALPHA_LAST)) != 0); + int src_depth = GB_OPTIONS_DEPTH(stored); + int src_bit_offset = x * src_depth * ncomp; + const byte *src_line = src_base + (src_bit_offset >> 3); + gx_color_value src_max = (1 << src_depth) - 1; + +#define v2cv(value) ((ulong)(value) * gx_max_color_value / src_max) + gx_color_value alpha_default = src_max; + + options &= ~GB_COLORS_ALL | GB_COLORS_NATIVE; + for (; h > 0; dest_line += raster, src_line += dev_raster, --h) { + int i; + + sample_load_declare_setup(src, sbit, src_line, + src_bit_offset & 7, src_depth); + sample_store_declare_setup(dest, dbit, dbyte, dest_line, + dest_bit_offset & 7, depth); + + for (i = 0; i < w; ++i) { + int j; + gx_color_value v[4], va = alpha_default; + gx_color_index pixel; + + /* Fetch the source data. */ + if (stored & GB_ALPHA_FIRST) { + sample_load_next16(va, src, sbit, src_depth); + va = v2cv(va); + } + for (j = 0; j < ncolors; ++j) { + gx_color_value vj; + + sample_load_next16(vj, src, sbit, src_depth); + v[j] = v2cv(vj); + } + if (stored & GB_ALPHA_LAST) { + sample_load_next16(va, src, sbit, src_depth); + va = v2cv(va); + } + /* Convert and store the pixel value. */ + switch (ncolors) { + case 1: + v[2] = v[1] = v[0]; + case 3: + pixel = (*dev_proc(dev, map_rgb_alpha_color)) + (dev, v[0], v[1], v[2], va); + break; + case 4: + /****** NO ALPHA FOR CMYK ******/ + pixel = (*dev_proc(dev, map_cmyk_color)) + (dev, v[0], v[1], v[2], v[3]); + break; + default: + return_error(gs_error_rangecheck); + } + sample_store_next32(pixel, dest, dbit, depth, dbyte); + } + sample_store_flush(dest, dbit, depth, dbyte); + } + } else if (!(options & GB_DEPTH_8)) { + /* + * We don't support general depths yet, or conversion between + * different formats. Punt. + */ + return_error(gs_error_rangecheck); + } else { + /* + * We have to do some conversion to each pixel. This is the + * slowest, most general case. + */ + int src_bit_offset = x * depth; + const byte *src_line = src_base + (src_bit_offset >> 3); + int ncomp = + (options & (GB_ALPHA_FIRST | GB_ALPHA_LAST) ? 4 : 3); + byte *dest_line = data + x_offset * ncomp; + + /* Pick the representation that's most likely to be useful. */ + if (options & GB_COLORS_RGB) + options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_RGB; + else if (options & GB_COLORS_CMYK) + options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_CMYK; + else if (options & GB_COLORS_GRAY) + options &= ~GB_COLORS_STANDARD_ALL | GB_COLORS_GRAY; + else + return_error(gs_error_rangecheck); + for (; h > 0; dest_line += raster, src_line += dev_raster, --h) { + int i; + + sample_load_declare_setup(src, bit, src_line, src_bit_offset & 7, + depth); + byte *dest = dest_line; + + for (i = 0; i < w; ++i) { + gx_color_index pixel = 0; + gx_color_value rgba[4]; + + sample_load_next32(pixel, src, bit, depth); + (*dev_proc(dev, map_color_rgb_alpha)) (dev, pixel, rgba); + if (options & GB_ALPHA_FIRST) + *dest++ = gx_color_value_to_byte(rgba[3]); + /* Convert to the requested color space. */ + if (options & GB_COLORS_RGB) { + dest[0] = gx_color_value_to_byte(rgba[0]); + dest[1] = gx_color_value_to_byte(rgba[1]); + dest[2] = gx_color_value_to_byte(rgba[2]); + dest += 3; + } else if (options & GB_COLORS_CMYK) { + /* Use the standard RGB to CMYK algorithm, */ + /* with maximum black generation and undercolor removal. */ + gx_color_value white = max(rgba[0], max(rgba[1], rgba[2])); + + dest[0] = gx_color_value_to_byte(white - rgba[0]); + dest[1] = gx_color_value_to_byte(white - rgba[1]); + dest[2] = gx_color_value_to_byte(white - rgba[2]); + dest[3] = gx_color_value_to_byte(gx_max_color_value - white); + dest += 4; + } else { /* GB_COLORS_GRAY */ + /* Use the standard RGB to Gray algorithm. */ + *dest++ = gx_color_value_to_byte( + ((rgba[0] * (ulong) lum_red_weight) + + (rgba[1] * (ulong) lum_green_weight) + + (rgba[2] * (ulong) lum_blue_weight) + + (lum_all_weights / 2)) + / lum_all_weights); + } + if (options & GB_ALPHA_LAST) + *dest++ = gx_color_value_to_byte(rgba[3]); + } + } + } + params->options = + (options & (GB_COLORS_ALL | GB_ALPHA_ALL)) | GB_PACKING_CHUNKY | + (options & GB_COLORS_NATIVE ? 0 : options & GB_DEPTH_ALL) | + (options & GB_ALIGN_STANDARD ? GB_ALIGN_STANDARD : GB_ALIGN_ANY) | + GB_RETURN_COPY | + (x_offset == 0 ? GB_OFFSET_0 : GB_OFFSET_SPECIFIED) | + (raster == std_raster ? GB_RASTER_STANDARD : GB_RASTER_SPECIFIED); + } + return 0; +} + +int +gx_no_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, + gs_get_bits_params_t * params, gs_int_rect ** unread) +{ + return_error(gs_error_unknownerror); +} +int +gx_default_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, + gs_get_bits_params_t * params, gs_int_rect ** unread) +{ + dev_proc_get_bits_rectangle((*save_get_bits_rectangle)) = + dev_proc(dev, get_bits_rectangle); + int depth = dev->color_info.depth; + uint min_raster = (dev->width * depth + 7) >> 3; + gs_get_bits_options_t options = params->options; + int code; + + /* Avoid a recursion loop. */ + set_dev_proc(dev, get_bits_rectangle, gx_no_get_bits_rectangle); + /* + * If the parameters are right, try to call get_bits directly. Note + * that this may fail if a device only implements get_bits_rectangle + * (not get_bits) for a limited set of options. Note also that this + * must handle the case of the recursive call from within + * get_bits_rectangle (see below): because of this, and only because + * of this, it must handle partial scan lines. + */ + if (prect->q.y == prect->p.y + 1 && + !(~options & + (GB_RETURN_COPY | GB_PACKING_CHUNKY | GB_COLORS_NATIVE)) && + (options & (GB_ALIGN_STANDARD | GB_ALIGN_ANY)) && + ((options & (GB_OFFSET_0 | GB_OFFSET_ANY)) || + ((options & GB_OFFSET_SPECIFIED) && params->x_offset == 0)) && + ((options & (GB_RASTER_STANDARD | GB_RASTER_ANY)) || + ((options & GB_RASTER_SPECIFIED) && + params->raster >= min_raster)) && + unread == NULL + ) { + byte *data = params->data[0]; + byte *row = data; + + if (!(prect->p.x == 0 && prect->q.x == dev->width)) { + /* Allocate an intermediate row buffer. */ + row = gs_alloc_bytes(dev->memory, min_raster, + "gx_default_get_bits_rectangle"); + + if (row == 0) { + code = gs_note_error(gs_error_VMerror); + goto ret; + } + } + code = (*dev_proc(dev, get_bits)) + (dev, prect->p.y, row, ¶ms->data[0]); + if (code >= 0) { + if (row != data) { + if (prect->p.x == 0 && params->data[0] != row) { + /* + * get_bits returned an appropriate pointer: we can + * avoid doing any copying. + */ + DO_NOTHING; + } else { + /* Copy the partial row into the supplied buffer. */ + int width_bits = (prect->q.x - prect->p.x) * depth; + gx_device_memory tdev; + + tdev.width = width_bits; + tdev.height = 1; + tdev.line_ptrs = &tdev.base; + tdev.base = data; + code = (*dev_proc(&mem_mono_device, copy_mono)) + ((gx_device *) & tdev, params->data[0], prect->p.x * depth, + min_raster, gx_no_bitmap_id, 0, 0, width_bits, 1, + (gx_color_index) 0, (gx_color_index) 1); + params->data[0] = data; + } + gs_free_object(dev->memory, row, + "gx_default_get_bits_rectangle"); + } + params->options = + GB_ALIGN_STANDARD | GB_OFFSET_0 | GB_PACKING_CHUNKY | + GB_ALPHA_NONE | GB_COLORS_NATIVE | GB_RASTER_STANDARD | + (params->data[0] == data ? GB_RETURN_COPY : GB_RETURN_POINTER); + goto ret; + } + } { + /* Do the transfer row-by-row using a buffer. */ + int x = prect->p.x, w = prect->q.x - x; + int bits_per_pixel = depth; + byte *row; + + if (options & GB_COLORS_STANDARD_ALL) { + /* + * Make sure the row buffer can hold the standard color + * representation, in case the device decides to use it. + */ + int bpc = GB_OPTIONS_MAX_DEPTH(options); + int nc = + (options & GB_COLORS_CMYK ? 4 : + options & GB_COLORS_RGB ? 3 : 1) + + (options & (GB_ALPHA_ALL - GB_ALPHA_NONE) ? 1 : 0); + int bpp = bpc * nc; + + if (bpp > bits_per_pixel) + bits_per_pixel = bpp; + } + row = gs_alloc_bytes(dev->memory, (bits_per_pixel * w + 7) >> 3, + "gx_default_get_bits_rectangle"); + if (row == 0) { + code = gs_note_error(gs_error_VMerror); + } else { + uint dev_raster = gx_device_raster(dev, true); + uint raster = + (options & GB_RASTER_SPECIFIED ? params->raster : + options & GB_ALIGN_STANDARD ? bitmap_raster(depth * w) : + (depth * w + 7) >> 3); + gs_int_rect rect; + gs_get_bits_params_t copy_params; + gs_get_bits_options_t copy_options = + GB_ALIGN_ANY | (GB_RETURN_COPY | GB_RETURN_POINTER) | + (GB_OFFSET_0 | GB_OFFSET_ANY) | + (GB_RASTER_STANDARD | GB_RASTER_ANY) | GB_PACKING_CHUNKY | + GB_COLORS_NATIVE | (options & (GB_DEPTH_ALL | GB_COLORS_ALL)) | + GB_ALPHA_ALL; + byte *dest = params->data[0]; + int y; + + rect.p.x = x, rect.q.x = x + w; + code = 0; + for (y = prect->p.y; y < prect->q.y; ++y) { + rect.p.y = y, rect.q.y = y + 1; + copy_params.options = copy_options; + copy_params.data[0] = row; + code = (*save_get_bits_rectangle) + (dev, &rect, ©_params, NULL); + if (code < 0) + break; + if (copy_params.options & GB_OFFSET_0) + copy_params.x_offset = 0; + params->data[0] = dest + (y - prect->p.y) * raster; + code = gx_get_bits_copy(dev, copy_params.x_offset, w, 1, + params, copy_params.options, + copy_params.data[0], dev_raster); + if (code < 0) + break; + } + gs_free_object(dev->memory, row, "gx_default_get_bits_rectangle"); + params->data[0] = dest; + } + } + ret:set_dev_proc(dev, get_bits_rectangle, save_get_bits_rectangle); + return (code < 0 ? code : 0); +} + +/* ------ Debugging printout ------ */ + +#ifdef DEBUG + +void +debug_print_gb_options(gx_bitmap_format_t options) +{ + static const char *const option_names[] = + { + GX_BITMAP_FORMAT_NAMES + }; + const char *prev = " "; + int i; + + dlprintf1("0x%lx", (ulong) options); + for (i = 0; i < sizeof(options) * 8; ++i) + if ((options >> i) & 1) { + dprintf2("%c%s", + (!memcmp(prev, option_names[i], 3) ? '|' : ','), + option_names[i]); + prev = option_names[i]; + } + dputc('\n'); +} + +void +debug_print_gb_params(gs_get_bits_params_t * params) +{ + gs_get_bits_options_t options = params->options; + + debug_print_gb_options(options); + dprintf1("data[0]=0x%lx", (ulong) params->data[0]); + if (options & GB_OFFSET_SPECIFIED) + dprintf1(" x_offset=%d", params->x_offset); + if (options & GB_RASTER_SPECIFIED) + dprintf1(" raster=%u", params->raster); + dputc('\n'); +} + +#endif /* DEBUG */ diff --git a/pstoraster/gdevhit.c b/pstoraster/gdevhit.c new file mode 100644 index 0000000000..9e16a2a0d7 --- /dev/null +++ b/pstoraster/gdevhit.c @@ -0,0 +1,98 @@ +/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Hit detection device */ +#include "std.h" +#include "gserror.h" +#include "gserrors.h" +#include "gstypes.h" +#include "gsmemory.h" +#include "gxdevice.h" + +/* Define the value returned for a detected hit. */ +const int gs_hit_detected = gs_error_hit_detected; + +/* + * Define a minimal device for insideness testing. + * It returns e_hit whenever it is asked to actually paint any pixels. + */ +private dev_proc_fill_rectangle(hit_fill_rectangle); +const gx_device gs_hit_device = +{std_device_std_body(gx_device, 0, "hit detector", + 0, 0, 1, 1), + {NULL, /* open_device */ + NULL, /* get_initial_matrix */ + NULL, /* sync_output */ + NULL, /* output_page */ + NULL, /* close_device */ + gx_default_map_rgb_color, + gx_default_map_color_rgb, + hit_fill_rectangle, + NULL, /* tile_rectangle */ + NULL, /* copy_mono */ + NULL, /* copy_color */ + gx_default_draw_line, + NULL, /* get_bits */ + NULL, /* get_params */ + NULL, /* put_params */ + gx_default_map_cmyk_color, + NULL, /* get_xfont_procs */ + NULL, /* get_xfont_device */ + gx_default_map_rgb_alpha_color, + gx_default_get_page_device, + gx_default_get_alpha_bits, + NULL, /* copy_alpha */ + gx_default_get_band, + NULL, /* copy_rop */ + gx_default_fill_path, + NULL, /* stroke_path */ + NULL, /* fill_mask */ + gx_default_fill_trapezoid, + gx_default_fill_parallelogram, + gx_default_fill_triangle, + gx_default_draw_thin_line, + gx_default_begin_image, + gx_default_image_data, + gx_default_end_image, + gx_default_strip_tile_rectangle, + gx_default_strip_copy_rop, + gx_get_largest_clipping_box, + gx_default_begin_typed_image, + NULL, /* get_bits_rectangle */ + gx_default_map_color_rgb_alpha, + gx_non_imaging_create_compositor, + NULL /* get_hardware_params */ + } +}; + +/* Test for a hit when filling a rectangle. */ +private int +hit_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + if (w > 0 && h > 0) + return_error(gs_error_hit_detected); + return 0; +} diff --git a/pstoraster/gdevht.h b/pstoraster/gdevht.h new file mode 100644 index 0000000000..a2f665f12a --- /dev/null +++ b/pstoraster/gdevht.h @@ -0,0 +1,51 @@ +/* Copyright (C) 1995, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Requires gxdevice.h */ + +#ifndef gdevht_INCLUDED +# define gdevht_INCLUDED + +#include "gzht.h" + +/* + * A halftoning device converts between a non-halftoned device color space + * (e.g., 8-bit gray) and a halftoned space (e.g., 1-bit black and white). + * We represent colors by packing the two colors being halftoned and the + * halftone level into a gx_color_index. + */ +typedef struct gx_device_ht_s { + gx_device_forward_common; + /* Following + target are set before opening. */ + const gx_device_halftone *dev_ht; + gs_int_point ht_phase; /* halftone phase from gstate */ + /* Following are computed when device is opened. */ + int color_shift; /* # of bits of color */ + int level_shift; /* = color_shift * 2 */ + gx_color_index color_mask; /* (1 << color_shift) - 1 */ + gs_int_point phase; /* halftone tile offset */ +} gx_device_ht; + +#endif /* gdevht_INCLUDED */ diff --git a/pstoraster/gdevm1.c b/pstoraster/gdevm1.c new file mode 100644 index 0000000000..d474967110 --- /dev/null +++ b/pstoraster/gdevm1.c @@ -0,0 +1,759 @@ +/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Monobit "memory" (stored bitmap) device */ +#include "memory_.h" +#include "gx.h" +#include "gxdevice.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +extern dev_proc_strip_copy_rop(mem_mono_strip_copy_rop); /* in gdevmrop.c */ + +/* Optionally, use the slow RasterOp implementations for testing. */ +/*#define USE_COPY_ROP */ + +#ifdef USE_COPY_ROP +#include "gsrop.h" +#endif + +/* ================ Standard (byte-oriented) device ================ */ + +/* We went to a lot of trouble to optimize mem_mono_tile_rectangle. */ +/* It has a substantial effect on the total time at high resolutions. */ +/* However, it takes quite a lot of code, so we omit it on 16-bit systems. */ +#define OPTIMIZE_TILE (arch_sizeof_int > 2) + +/* Procedures */ +private dev_proc_map_rgb_color(mem_mono_map_rgb_color); +private dev_proc_map_color_rgb(mem_mono_map_color_rgb); +private dev_proc_copy_mono(mem_mono_copy_mono); +private dev_proc_fill_rectangle(mem_mono_fill_rectangle); + +#if OPTIMIZE_TILE +private dev_proc_strip_tile_rectangle(mem_mono_strip_tile_rectangle); + +#else +# define mem_mono_strip_tile_rectangle gx_default_strip_tile_rectangle +#endif + +/* The device descriptor. */ +/* The instance is public. */ +const gx_device_memory mem_mono_device = +mem_full_alpha_device("image1", 0, 1, mem_open, + mem_mono_map_rgb_color, mem_mono_map_color_rgb, + mem_mono_copy_mono, gx_default_copy_color, mem_mono_fill_rectangle, + gx_default_map_cmyk_color, gx_no_copy_alpha, + mem_mono_strip_tile_rectangle, mem_mono_strip_copy_rop, + mem_get_bits_rectangle); + +/* Map color to/from RGB. This may be inverted. */ +private gx_color_index +mem_mono_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g, + gx_color_value b) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + return (gx_default_w_b_map_rgb_color(dev, r, g, b) ^ + mdev->palette.data[0]) & 1; +} +private int +mem_mono_map_color_rgb(gx_device * dev, gx_color_index color, + gx_color_value prgb[3]) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + return gx_default_w_b_map_color_rgb(dev, + (color ^ mdev->palette.data[0]) & 1, + prgb); +} + +/* Fill a rectangle with a color. */ +private int +mem_mono_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + +#ifdef USE_COPY_ROP + return mem_mono_copy_rop(dev, NULL, 0, 0, gx_no_bitmap_id, NULL, + NULL, NULL, + x, y, w, h, 0, 0, + (color ? rop3_1 : rop3_0)); +#else + fit_fill(dev, x, y, w, h); + bits_fill_rectangle(scan_line_base(mdev, y), x, mdev->raster, + -(mono_fill_chunk) color, w, h); + return 0; +#endif +} + +/* Convert x coordinate to byte offset in scan line. */ +#define x_to_byte(x) ((x) >> 3) + +/* Copy a monochrome bitmap. */ +#undef mono_masks +#define mono_masks mono_copy_masks + +/* + * Fetch a chunk from the source. + * + * Since source and destination are both always big-endian, + * fetching an aligned chunk never requires byte swapping. + */ +#define CFETCH_ALIGNED(cptr)\ + (*(const chunk *)(cptr)) + +/* + * Note that the macros always cast cptr, + * so it doesn't matter what the type of cptr is. + */ +/* cshift = chunk_bits - shift. */ +#undef chunk +#if arch_is_big_endian +# define chunk uint +# define CFETCH_RIGHT(cptr, shift, cshift)\ + (CFETCH_ALIGNED(cptr) >> shift) +# define CFETCH_LEFT(cptr, shift, cshift)\ + (CFETCH_ALIGNED(cptr) << shift) +/* Fetch a chunk that straddles a chunk boundary. */ +# define CFETCH2(cptr, cskew, skew)\ + (CFETCH_LEFT(cptr, cskew, skew) +\ + CFETCH_RIGHT((const chunk *)(cptr) + 1, skew, cskew)) +#else /* little-endian */ +# define chunk bits16 +private const bits16 right_masks2[9] = +{ + 0xffff, 0x7f7f, 0x3f3f, 0x1f1f, 0x0f0f, 0x0707, 0x0303, 0x0101, 0x0000 +}; +private const bits16 left_masks2[9] = +{ + 0xffff, 0xfefe, 0xfcfc, 0xf8f8, 0xf0f0, 0xe0e0, 0xc0c0, 0x8080, 0x0000 +}; + +# define CCONT(cptr, off) (((const chunk *)(cptr))[off]) +# define CFETCH_RIGHT(cptr, shift, cshift)\ + ((shift) < 8 ?\ + ((CCONT(cptr, 0) >> (shift)) & right_masks2[shift]) +\ + (CCONT(cptr, 0) << (cshift)) :\ + ((chunk)*(const byte *)(cptr) << (cshift)) & 0xff00) +# define CFETCH_LEFT(cptr, shift, cshift)\ + ((shift) < 8 ?\ + ((CCONT(cptr, 0) << (shift)) & left_masks2[shift]) +\ + (CCONT(cptr, 0) >> (cshift)) :\ + ((CCONT(cptr, 0) & 0xff00) >> (cshift)) & 0xff) +/* Fetch a chunk that straddles a chunk boundary. */ +/* We can avoid testing the shift amount twice */ +/* by expanding the CFETCH_LEFT/right macros in-line. */ +# define CFETCH2(cptr, cskew, skew)\ + ((cskew) < 8 ?\ + ((CCONT(cptr, 0) << (cskew)) & left_masks2[cskew]) +\ + (CCONT(cptr, 0) >> (skew)) +\ + (((chunk)(((const byte *)(cptr))[2]) << (cskew)) & 0xff00) :\ + (((CCONT(cptr, 0) & 0xff00) >> (skew)) & 0xff) +\ + ((CCONT(cptr, 1) >> (skew)) & right_masks2[skew]) +\ + (CCONT(cptr, 1) << (cskew))) +#endif + +typedef enum { + COPY_OR = 0, COPY_STORE, COPY_AND, COPY_FUNNY +} copy_function; +typedef struct { + uint invert; + copy_function op; +} copy_mode; + +/* + * Map from to copy_mode. + * Logically, this is a 2-D array. + * The indexing is (transparent, 0, 1, unused). */ +private const copy_mode copy_modes[16] = +{ + {~0, COPY_FUNNY}, /* NN */ + {~0, COPY_AND}, /* N0 */ + {0, COPY_OR}, /* N1 */ + {0, 0}, /* unused */ + {0, COPY_AND}, /* 0N */ + {0, COPY_FUNNY}, /* 00 */ + {0, COPY_STORE}, /* 01 */ + {0, 0}, /* unused */ + {~0, COPY_OR}, /* 1N */ + {~0, COPY_STORE}, /* 10 */ + {0, COPY_FUNNY}, /* 11 */ + {0, 0}, /* unused */ + {0, 0}, /* unused */ + {0, 0}, /* unused */ + {0, 0}, /* unused */ + {0, 0}, /* unused */ +}; + +/* Handle the funny cases that aren't supposed to happen. */ +#define FUNNY_CASE()\ + (invert ? gs_note_error(-1) :\ + mem_mono_fill_rectangle(dev, x, y, w, h, color0)) + +private int +mem_mono_copy_mono(gx_device * dev, + const byte * source_data, int source_x, int source_raster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index color0, gx_color_index color1) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + +#ifdef USE_COPY_ROP + return mem_mono_copy_rop(dev, source_data, source_x, source_raster, + id, NULL, NULL, NULL, + x, y, w, h, 0, 0, + ((color0 == gx_no_color_index ? rop3_D : + color0 == 0 ? rop3_0 : rop3_1) & ~rop3_S) | + ((color1 == gx_no_color_index ? rop3_D : + color1 == 0 ? rop3_0 : rop3_1) & rop3_S)); +#else /* !USE_COPY_ROP */ + register const byte *bptr; /* actually chunk * */ + int dbit, wleft; + uint mask; + copy_mode mode; + + DECLARE_SCAN_PTR_VARS(dbptr, byte *, dest_raster); +#define optr ((chunk *)dbptr) + register int skew; + register uint invert; + + fit_copy(dev, source_data, source_x, source_raster, id, x, y, w, h); +#if gx_no_color_index_value != -1 /* hokey! */ + if (color0 == gx_no_color_index) + color0 = -1; + if (color1 == gx_no_color_index) + color1 = -1; +#endif + mode = copy_modes[((int)color0 << 2) + (int)color1 + 5]; + invert = mode.invert; /* load register */ + SETUP_RECT_VARS(dbptr, byte *, dest_raster); + bptr = source_data + ((source_x & ~chunk_align_bit_mask) >> 3); + dbit = x & chunk_align_bit_mask; + skew = dbit - (source_x & chunk_align_bit_mask); + +/* Macros for writing partial chunks. */ +/* The destination pointer is always named optr, */ +/* and must be declared as chunk *. */ +/* CINVERT may be temporarily redefined. */ +#define CINVERT(bits) ((bits) ^ invert) +#define WRITE_OR_MASKED(bits, mask, off)\ + optr[off] |= (CINVERT(bits) & mask) +#define WRITE_STORE_MASKED(bits, mask, off)\ + optr[off] = ((optr[off] & ~mask) | (CINVERT(bits) & mask)) +#define WRITE_AND_MASKED(bits, mask, off)\ + optr[off] &= (CINVERT(bits) | ~mask) +/* Macros for writing full chunks. */ +#define WRITE_OR(bits) *optr |= CINVERT(bits) +#define WRITE_STORE(bits) *optr = CINVERT(bits) +#define WRITE_AND(bits) *optr &= CINVERT(bits) +/* Macro for incrementing to next chunk. */ +#define NEXT_X_CHUNK()\ + bptr += chunk_bytes; dbptr += chunk_bytes +/* Common macro for the end of each scan line. */ +#define END_Y_LOOP(sdelta, ddelta)\ + bptr += sdelta; dbptr += ddelta + + if ((wleft = w + dbit - chunk_bits) <= 0) { /* The entire operation fits in one (destination) chunk. */ + set_mono_thin_mask(mask, w, dbit); + +#define WRITE_SINGLE(wr_op, src)\ + for ( ; ; )\ + { wr_op(src, mask, 0);\ + if ( --h == 0 ) break;\ + END_Y_LOOP(source_raster, dest_raster);\ + } + +#define WRITE1_LOOP(src)\ + switch ( mode.op ) {\ + case COPY_OR: WRITE_SINGLE(WRITE_OR_MASKED, src); break;\ + case COPY_STORE: WRITE_SINGLE(WRITE_STORE_MASKED, src); break;\ + case COPY_AND: WRITE_SINGLE(WRITE_AND_MASKED, src); break;\ + default: return FUNNY_CASE();\ + } + + if (skew >= 0) { /* single -> single, right/no shift */ + if (skew == 0) { /* no shift */ + WRITE1_LOOP(CFETCH_ALIGNED(bptr)); + } else { /* right shift */ + int cskew = chunk_bits - skew; + + WRITE1_LOOP(CFETCH_RIGHT(bptr, skew, cskew)); + } + } else if (wleft <= skew) { /* single -> single, left shift */ + int cskew = chunk_bits + skew; + + skew = -skew; + WRITE1_LOOP(CFETCH_LEFT(bptr, skew, cskew)); + } else { /* double -> single */ + int cskew = -skew; + + skew += chunk_bits; + WRITE1_LOOP(CFETCH2(bptr, cskew, skew)); + } +#undef WRITE1_LOOP +#undef WRITE_SINGLE + } else if (wleft <= skew) { /* 1 source chunk -> 2 destination chunks. */ + /* This is an important special case for */ + /* both characters and halftone tiles. */ + uint rmask; + int cskew = chunk_bits - skew; + + set_mono_left_mask(mask, dbit); + set_mono_right_mask(rmask, wleft); +#undef CINVERT +#define CINVERT(bits) (bits) /* pre-inverted here */ + +#if arch_is_big_endian /* no byte swapping */ +# define WRITE_1TO2(wr_op)\ + for ( ; ; )\ + { register uint bits = CFETCH_ALIGNED(bptr) ^ invert;\ + wr_op(bits >> skew, mask, 0);\ + wr_op(bits << cskew, rmask, 1);\ + if ( --h == 0 ) break;\ + END_Y_LOOP(source_raster, dest_raster);\ + } +#else /* byte swapping */ +# define WRITE_1TO2(wr_op)\ + for ( ; ; )\ + { wr_op(CFETCH_RIGHT(bptr, skew, cskew) ^ invert, mask, 0);\ + wr_op(CFETCH_LEFT(bptr, cskew, skew) ^ invert, rmask, 1);\ + if ( --h == 0 ) break;\ + END_Y_LOOP(source_raster, dest_raster);\ + } +#endif + + switch (mode.op) { + case COPY_OR: + WRITE_1TO2(WRITE_OR_MASKED); + break; + case COPY_STORE: + WRITE_1TO2(WRITE_STORE_MASKED); + break; + case COPY_AND: + WRITE_1TO2(WRITE_AND_MASKED); + break; + default: + return FUNNY_CASE(); + } +#undef CINVERT +#define CINVERT(bits) ((bits) ^ invert) +#undef WRITE_1TO2 + } else { /* More than one source chunk and more than one */ + /* destination chunk are involved. */ + uint rmask; + int words = (wleft & ~chunk_bit_mask) >> 3; + uint sskip = source_raster - words; + uint dskip = dest_raster - words; + register uint bits; + + set_mono_left_mask(mask, dbit); + set_mono_right_mask(rmask, wleft & chunk_bit_mask); + if (skew == 0) { /* optimize the aligned case */ + +#define WRITE_ALIGNED(wr_op, wr_op_masked)\ + for ( ; ; )\ + { int count = wleft;\ + /* Do first partial chunk. */\ + wr_op_masked(CFETCH_ALIGNED(bptr), mask, 0);\ + /* Do full chunks. */\ + while ( (count -= chunk_bits) >= 0 )\ + { NEXT_X_CHUNK(); wr_op(CFETCH_ALIGNED(bptr)); }\ + /* Do last chunk */\ + if ( count > -chunk_bits )\ + { wr_op_masked(CFETCH_ALIGNED(bptr + chunk_bytes), rmask, 1); }\ + if ( --h == 0 ) break;\ + END_Y_LOOP(sskip, dskip);\ + } + + switch (mode.op) { + case COPY_OR: + WRITE_ALIGNED(WRITE_OR, WRITE_OR_MASKED); + break; + case COPY_STORE: + WRITE_ALIGNED(WRITE_STORE, WRITE_STORE_MASKED); + break; + case COPY_AND: + WRITE_ALIGNED(WRITE_AND, WRITE_AND_MASKED); + break; + default: + return FUNNY_CASE(); + } +#undef WRITE_ALIGNED + } else { /* not aligned */ + int cskew = -skew & chunk_bit_mask; + bool case_right = + (skew >= 0 ? true : + ((bptr += chunk_bytes), false)); + + skew &= chunk_bit_mask; + +#define WRITE_UNALIGNED(wr_op, wr_op_masked)\ + /* Prefetch partial word. */\ + bits =\ + (case_right ? CFETCH_RIGHT(bptr, skew, cskew) :\ + CFETCH2(bptr - chunk_bytes, cskew, skew));\ + wr_op_masked(bits, mask, 0);\ + /* Do full chunks. */\ + while ( count >= chunk_bits )\ + { bits = CFETCH2(bptr, cskew, skew);\ + NEXT_X_CHUNK(); wr_op(bits); count -= chunk_bits;\ + }\ + /* Do last chunk */\ + if ( count > 0 )\ + { bits = CFETCH_LEFT(bptr, cskew, skew);\ + if ( count > skew ) bits += CFETCH_RIGHT(bptr + chunk_bytes, skew, cskew);\ + wr_op_masked(bits, rmask, 1);\ + } + + switch (mode.op) { + case COPY_OR: + for (;;) { + int count = wleft; + + WRITE_UNALIGNED(WRITE_OR, WRITE_OR_MASKED); + if (--h == 0) + break; + END_Y_LOOP(sskip, dskip); + } + break; + case COPY_STORE: + for (;;) { + int count = wleft; + + WRITE_UNALIGNED(WRITE_STORE, WRITE_STORE_MASKED); + if (--h == 0) + break; + END_Y_LOOP(sskip, dskip); + } + break; + case COPY_AND: + for (;;) { + int count = wleft; + + WRITE_UNALIGNED(WRITE_AND, WRITE_AND_MASKED); + if (--h == 0) + break; + END_Y_LOOP(sskip, dskip); + } + break; + default /*case COPY_FUNNY */ : + return FUNNY_CASE(); + } +#undef WRITE_UNALIGNED + } + } +#undef END_Y_LOOP +#undef NEXT_X_CHUNK + return 0; +#undef optr +#endif /* !USE_COPY_ROP */ +} + +#if OPTIMIZE_TILE /**************** *************** */ + +/* Strip-tile with a monochrome halftone. */ +/* This is a performance bottleneck for monochrome devices, */ +/* so we re-implement it, even though it takes a lot of code. */ +private int +mem_mono_strip_tile_rectangle(gx_device * dev, + register const gx_strip_bitmap * tiles, +int tx, int y, int tw, int th, gx_color_index color0, gx_color_index color1, + int px, int py) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + +#ifdef USE_COPY_ROP + return mem_mono_strip_copy_rop(dev, NULL, 0, 0, tile->id, NULL, + tiles, NULL, + tx, y, tw, th, px, py, + ((color0 == gx_no_color_index ? rop3_D : + color0 == 0 ? rop3_0 : rop3_1) & ~rop3_T) | + ((color1 == gx_no_color_index ? rop3_D : + color1 == 0 ? rop3_0 : rop3_1) & rop3_T)); +#else /* !USE_COPY_ROP */ + register uint invert; + int source_raster; + uint tile_bits_size; + const byte *source_data; + const byte *end; + int x, rw, w, h; + register const byte *bptr; /* actually chunk * */ + int dbit, wleft; + uint mask; + byte *dbase; + + DECLARE_SCAN_PTR_VARS(dbptr, byte *, dest_raster); +#define optr ((chunk *)dbptr) + register int skew; + + /* This implementation doesn't handle strips yet. */ + if (color0 != (color1 ^ 1) || tiles->shift != 0) + return gx_default_strip_tile_rectangle(dev, tiles, tx, y, tw, th, + color0, color1, px, py); + fit_fill(dev, tx, y, tw, th); + invert = -(uint) color0; + source_raster = tiles->raster; + source_data = tiles->data + ((y + py) % tiles->rep_height) * source_raster; + tile_bits_size = tiles->size.y * source_raster; + end = tiles->data + tile_bits_size; +#undef END_Y_LOOP +#define END_Y_LOOP(sdelta, ddelta)\ + if ( end - bptr <= sdelta ) /* wrap around */\ + bptr -= tile_bits_size;\ + bptr += sdelta; dbptr += ddelta + dest_raster = mdev->raster; + dbase = scan_line_base(mdev, y); + x = tx; + rw = tw; + /* + * The outermost loop here works horizontally, one iteration per + * copy of the tile. Note that all iterations except the first + * have source_x = 0. + */ + { + int source_x = (x + px) % tiles->rep_width; + + w = tiles->size.x - source_x; + bptr = source_data + ((source_x & ~chunk_align_bit_mask) >> 3); + dbit = x & chunk_align_bit_mask; + skew = dbit - (source_x & chunk_align_bit_mask); + } + outer:if (w > rw) + w = rw; + h = th; + dbptr = dbase + ((x >> 3) & -chunk_align_bytes); + if ((wleft = w + dbit - chunk_bits) <= 0) { /* The entire operation fits in one (destination) chunk. */ + set_mono_thin_mask(mask, w, dbit); +#define WRITE1_LOOP(src)\ + for ( ; ; )\ + { WRITE_STORE_MASKED(src, mask, 0);\ + if ( --h == 0 ) break;\ + END_Y_LOOP(source_raster, dest_raster);\ + } + if (skew >= 0) { /* single -> single, right/no shift */ + if (skew == 0) { /* no shift */ + WRITE1_LOOP(CFETCH_ALIGNED(bptr)); + } else { /* right shift */ + int cskew = chunk_bits - skew; + + WRITE1_LOOP(CFETCH_RIGHT(bptr, skew, cskew)); + } + } else if (wleft <= skew) { /* single -> single, left shift */ + int cskew = chunk_bits + skew; + + skew = -skew; + WRITE1_LOOP(CFETCH_LEFT(bptr, skew, cskew)); + } else { /* double -> single */ + int cskew = -skew; + + skew += chunk_bits; + WRITE1_LOOP(CFETCH2(bptr, cskew, skew)); + } +#undef WRITE1_LOOP + } else if (wleft <= skew) { /* 1 source chunk -> 2 destination chunks. */ + /* This is an important special case for */ + /* both characters and halftone tiles. */ + uint rmask; + int cskew = chunk_bits - skew; + + set_mono_left_mask(mask, dbit); + set_mono_right_mask(rmask, wleft); +#if arch_is_big_endian /* no byte swapping */ +#undef CINVERT +#define CINVERT(bits) (bits) /* pre-inverted here */ + for (;;) { + register uint bits = CFETCH_ALIGNED(bptr) ^ invert; + + WRITE_STORE_MASKED(bits >> skew, mask, 0); + WRITE_STORE_MASKED(bits << cskew, rmask, 1); + if (--h == 0) + break; + END_Y_LOOP(source_raster, dest_raster); + } +#undef CINVERT +#define CINVERT(bits) ((bits) ^ invert) +#else /* byte swapping */ + for (;;) { + WRITE_STORE_MASKED(CFETCH_RIGHT(bptr, skew, cskew), mask, 0); + WRITE_STORE_MASKED(CFETCH_LEFT(bptr, cskew, skew), rmask, 1); + if (--h == 0) + break; + END_Y_LOOP(source_raster, dest_raster); + } +#endif + } else { /* More than one source chunk and more than one */ + /* destination chunk are involved. */ + uint rmask; + int words = (wleft & ~chunk_bit_mask) >> 3; + uint sskip = source_raster - words; + uint dskip = dest_raster - words; + register uint bits; + +#define NEXT_X_CHUNK()\ + bptr += chunk_bytes; dbptr += chunk_bytes + + set_mono_right_mask(rmask, wleft & chunk_bit_mask); + if (skew == 0) { /* optimize the aligned case */ + if (dbit == 0) + mask = 0; + else + set_mono_left_mask(mask, dbit); + for (;;) { + int count = wleft; + + /* Do first partial chunk. */ + if (mask) + WRITE_STORE_MASKED(CFETCH_ALIGNED(bptr), mask, 0); + else + WRITE_STORE(CFETCH_ALIGNED(bptr)); + /* Do full chunks. */ + while ((count -= chunk_bits) >= 0) { + NEXT_X_CHUNK(); + WRITE_STORE(CFETCH_ALIGNED(bptr)); + } + /* Do last chunk */ + if (count > -chunk_bits) { + WRITE_STORE_MASKED(CFETCH_ALIGNED(bptr + chunk_bytes), rmask, 1); + } + if (--h == 0) + break; + END_Y_LOOP(sskip, dskip); + } + } else { /* not aligned */ + bool case_right = + (skew >= 0 ? true : + ((bptr += chunk_bytes), false)); + int cskew = -skew & chunk_bit_mask; + + skew &= chunk_bit_mask; + set_mono_left_mask(mask, dbit); + for (;;) { + int count = wleft; + + if (case_right) + bits = CFETCH_RIGHT(bptr, skew, cskew); + else + bits = CFETCH2(bptr - chunk_bytes, cskew, skew); + WRITE_STORE_MASKED(bits, mask, 0); + /* Do full chunks. */ + while (count >= chunk_bits) { + bits = CFETCH2(bptr, cskew, skew); + NEXT_X_CHUNK(); + WRITE_STORE(bits); + count -= chunk_bits; + } + /* Do last chunk */ + if (count > 0) { + bits = CFETCH_LEFT(bptr, cskew, skew); + if (count > skew) + bits += CFETCH_RIGHT(bptr + chunk_bytes, skew, cskew); + WRITE_STORE_MASKED(bits, rmask, 1); + } + if (--h == 0) + break; + END_Y_LOOP(sskip, dskip); + } + } + } +#undef END_Y_LOOP +#undef NEXT_X_CHUNK +#undef optr + if ((rw -= w) > 0) { + x += w; + w = tiles->size.x; + bptr = source_data; + skew = dbit = x & chunk_align_bit_mask; + goto outer; + } + return 0; +#endif /* !USE_COPY_ROP */ +} + +#endif /**************** *************** */ + +/* ================ "Word"-oriented device ================ */ + +/* Note that on a big-endian machine, this is the same as the */ +/* standard byte-oriented-device. */ + +#if !arch_is_big_endian + +/* Procedures */ +private dev_proc_copy_mono(mem1_word_copy_mono); +private dev_proc_fill_rectangle(mem1_word_fill_rectangle); + +#define mem1_word_strip_tile_rectangle gx_default_strip_tile_rectangle + +/* Here is the device descriptor. */ +const gx_device_memory mem_mono_word_device = +mem_full_alpha_device("image1w", 0, 1, mem_open, + mem_mono_map_rgb_color, mem_mono_map_color_rgb, + mem1_word_copy_mono, gx_default_copy_color, mem1_word_fill_rectangle, + gx_default_map_cmyk_color, gx_no_copy_alpha, + mem1_word_strip_tile_rectangle, gx_no_strip_copy_rop, + mem_word_get_bits_rectangle); + +/* Fill a rectangle with a color. */ +private int +mem1_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *base; + uint raster; + + fit_fill(dev, x, y, w, h); + base = scan_line_base(mdev, y); + raster = mdev->raster; + mem_swap_byte_rect(base, raster, x, w, h, true); + bits_fill_rectangle(base, x, raster, -(mono_fill_chunk) color, w, h); + mem_swap_byte_rect(base, raster, x, w, h, true); + return 0; +} + +/* Copy a bitmap. */ +private int +mem1_word_copy_mono(gx_device * dev, + const byte * source_data, int source_x, int source_raster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index color0, gx_color_index color1) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *row; + uint raster; + bool store; + + fit_copy(dev, source_data, source_x, source_raster, id, x, y, w, h); + row = scan_line_base(mdev, y); + raster = mdev->raster; + store = (color0 != gx_no_color_index && color1 != gx_no_color_index); + mem_swap_byte_rect(row, raster, x, w, h, store); + mem_mono_copy_mono(dev, source_data, source_x, source_raster, id, + x, y, w, h, color0, color1); + mem_swap_byte_rect(row, raster, x, w, h, false); + return 0; +} + +#endif /* !arch_is_big_endian */ diff --git a/pstoraster/gdevm16.c b/pstoraster/gdevm16.c new file mode 100644 index 0000000000..9a9413a94f --- /dev/null +++ b/pstoraster/gdevm16.c @@ -0,0 +1,168 @@ +/* Copyright (C) 1994, 1996, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* 16-bit-per-pixel "memory" (stored bitmap) device */ +#include "memory_.h" +#include "gx.h" +#include "gxdevice.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +#undef chunk +#define chunk byte + +/* The 16 bits are divided 5 for red, 6 for green, and 5 for blue. */ +/* Note that the bits must always be kept in big-endian order. */ + +/* Procedures */ +declare_mem_map_procs(mem_true16_map_rgb_color, mem_true16_map_color_rgb); +declare_mem_procs(mem_true16_copy_mono, mem_true16_copy_color, mem_true16_fill_rectangle); + +/* The device descriptor. */ +const gx_device_memory mem_true16_device = + mem_device("image16", 16, 0, + mem_true16_map_rgb_color, mem_true16_map_color_rgb, + mem_true16_copy_mono, mem_true16_copy_color, + mem_true16_fill_rectangle, gx_default_strip_copy_rop); + +/* Map a r-g-b color to a color index. */ +private gx_color_index +mem_true16_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g, + gx_color_value b) +{ + return ((r >> (gx_color_value_bits - 5)) << 11) + + ((g >> (gx_color_value_bits - 6)) << 5) + + (b >> (gx_color_value_bits - 5)); +} + +/* Map a color index to a r-g-b color. */ +private int +mem_true16_map_color_rgb(gx_device * dev, gx_color_index color, + gx_color_value prgb[3]) +{ + ushort value = color >> 11; + + prgb[0] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) + >> (16 - gx_color_value_bits); + value = (color >> 5) & 0x3f; + prgb[1] = ((value << 10) + (value << 4) + (value >> 2)) + >> (16 - gx_color_value_bits); + value = color & 0x1f; + prgb[2] = ((value << 11) + (value << 6) + (value << 1) + (value >> 4)) + >> (16 - gx_color_value_bits); + return 0; +} + +/* Convert x coordinate to byte offset in scan line. */ +#undef x_to_byte +#define x_to_byte(x) ((x) << 1) + +/* Fill a rectangle with a color. */ +private int +mem_true16_fill_rectangle(gx_device * dev, + int x, int y, int w, int h, gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; +#if arch_is_big_endian + const ushort color16 = (ushort)color; +#else + const ushort color16 = (ushort)((color << 8) | (color >> 8)); +#endif + declare_scan_ptr(dest); + fit_fill(dev, x, y, w, h); + setup_rect(dest); + while (h-- > 0) { + ushort *pptr = (ushort *) dest; + int cnt = w; + + do { + *pptr++ = color16; + } while (--cnt > 0); + inc_ptr(dest, draster); + } + return 0; +} + +/* Copy a monochrome bitmap. */ +private int +mem_true16_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, + gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; +#if arch_is_big_endian + const ushort zero16 = (ushort)zero; + const ushort one16 = (ushort)one; +#else + ushort zero16 = ((uint) (byte) zero << 8) + ((ushort) zero >> 8); + ushort one16 = ((uint) (byte) one << 8) + ((ushort) one >> 8); +#endif + const byte *line; + int first_bit; + + declare_scan_ptr(dest); + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + setup_rect(dest); + line = base + (sourcex >> 3); + first_bit = 0x80 >> (sourcex & 7); + while (h-- > 0) { + register ushort *pptr = (ushort *) dest; + const byte *sptr = line; + register int sbyte = *sptr++; + register int bit = first_bit; + int count = w; + + do { + if (sbyte & bit) { + if (one != gx_no_color_index) + *pptr = one16; + } else { + if (zero != gx_no_color_index) + *pptr = zero16; + } + if ((bit >>= 1) == 0) + bit = 0x80, sbyte = *sptr++; + pptr++; + } + while (--count > 0); + line += sraster; + inc_ptr(dest, draster); + } + return 0; +} + +/* Copy a color bitmap. */ +private int +mem_true16_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h); + return 0; +} diff --git a/pstoraster/gdevm2.c b/pstoraster/gdevm2.c new file mode 100644 index 0000000000..12cf8ec9b8 --- /dev/null +++ b/pstoraster/gdevm2.c @@ -0,0 +1,259 @@ +/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* 2-bit-per-pixel "memory" (stored bitmap) device */ +#include "memory_.h" +#include "gx.h" +#include "gxdevice.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +extern dev_proc_strip_copy_rop(mem_gray_strip_copy_rop); + +/* ================ Standard (byte-oriented) device ================ */ + +#undef chunk +#define chunk byte +#define fpat(byt) mono_fill_make_pattern(byt) + +/* Procedures */ +declare_mem_procs(mem_mapped2_copy_mono, mem_mapped2_copy_color, mem_mapped2_fill_rectangle); + +/* The device descriptor. */ +const gx_device_memory mem_mapped2_device = +mem_device("image2", 2, 0, + mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, + mem_mapped2_copy_mono, mem_mapped2_copy_color, mem_mapped2_fill_rectangle, + mem_gray_strip_copy_rop); + +/* Convert x coordinate to byte offset in scan line. */ +#undef x_to_byte +#define x_to_byte(x) ((x) >> 2) + +/* Define the 2-bit fill patterns. */ +static const mono_fill_chunk tile_patterns[4] = +{fpat(0x00), fpat(0x55), fpat(0xaa), fpat(0xff) +}; + +/* Fill a rectangle with a color. */ +private int +mem_mapped2_fill_rectangle(gx_device * dev, + int x, int y, int w, int h, gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + fit_fill(dev, x, y, w, h); + bits_fill_rectangle(scan_line_base(mdev, y), x << 1, mdev->raster, + tile_patterns[color], w << 1, h); + return 0; +} + +/* Copy a bitmap. */ +private int +mem_mapped2_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + const byte *line; + int first_bit; + byte first_mask, b0, b1, bxor, left_mask, right_mask; + static const byte btab[4] = + {0, 0x55, 0xaa, 0xff}; + static const byte bmask[4] = + {0xc0, 0x30, 0xc, 3}; + static const byte lmask[4] = + {0, 0xc0, 0xf0, 0xfc}; + + declare_scan_ptr(dest); + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + setup_rect(dest); + line = base + (sourcex >> 3); + first_bit = 0x80 >> (sourcex & 7); + first_mask = bmask[x & 3]; + left_mask = lmask[x & 3]; + right_mask = ~lmask[(x + w) & 3]; + if ((x & 3) + w <= 4) + left_mask = right_mask = left_mask | right_mask; + b0 = btab[zero & 3]; + b1 = btab[one & 3]; + bxor = b0 ^ b1; + while (h-- > 0) { + register byte *pptr = (byte *) dest; + const byte *sptr = line; + register int sbyte = *sptr++; + register int bit = first_bit; + register byte mask = first_mask; + int count = w; + + /* We have 4 cases, of which only 2 really matter. */ + if (one != gx_no_color_index) { + if (zero != gx_no_color_index) { /* Copying an opaque bitmap. */ + byte data = + (*pptr & left_mask) | (b0 & ~left_mask); + + do { + if (sbyte & bit) + data ^= bxor & mask; + if ((bit >>= 1) == 0) + bit = 0x80, sbyte = *sptr++; + if ((mask >>= 2) == 0) + mask = 0xc0, *pptr++ = data, data = b0; + } + while (--count > 0); + if (mask != 0xc0) + *pptr = + (*pptr & right_mask) | (data & ~right_mask); + } else { /* Filling a mask. */ + do { + if (sbyte & bit) + *pptr = (*pptr & ~mask) + (b1 & mask); + if ((bit >>= 1) == 0) + bit = 0x80, sbyte = *sptr++; + if ((mask >>= 2) == 0) + mask = 0xc0, pptr++; + } + while (--count > 0); + } + } else { /* Some other case. */ + do { + if (!(sbyte & bit)) { + if (zero != gx_no_color_index) + *pptr = (*pptr & ~mask) + (b0 & mask); + } + if ((bit >>= 1) == 0) + bit = 0x80, sbyte = *sptr++; + if ((mask >>= 2) == 0) + mask = 0xc0, pptr++; + } + while (--count > 0); + } + line += sraster; + inc_ptr(dest, draster); + } + return 0; +} + +/* Copy a color bitmap. */ +private int +mem_mapped2_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + int code; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + /* Use monobit copy_mono. */ + /* Patch the width in the device temporarily. */ + dev->width <<= 1; + code = (*dev_proc(&mem_mono_device, copy_mono)) + (dev, base, sourcex << 1, sraster, id, + x << 1, y, w << 1, h, (gx_color_index) 0, (gx_color_index) 1); + /* Restore the correct width. */ + dev->width >>= 1; + return code; +} + +/* ================ "Word"-oriented device ================ */ + +/* Note that on a big-endian machine, this is the same as the */ +/* standard byte-oriented-device. */ + +#if !arch_is_big_endian + +/* Procedures */ +declare_mem_procs(mem2_word_copy_mono, mem2_word_copy_color, mem2_word_fill_rectangle); + +/* Here is the device descriptor. */ +const gx_device_memory mem_mapped2_word_device = +mem_full_device("image2w", 2, 0, mem_open, + mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, + mem2_word_copy_mono, mem2_word_copy_color, mem2_word_fill_rectangle, + gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + +/* Fill a rectangle with a color. */ +private int +mem2_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *base; + uint raster; + + fit_fill(dev, x, y, w, h); + base = scan_line_base(mdev, y); + raster = mdev->raster; + mem_swap_byte_rect(base, raster, x << 1, w << 1, h, true); + bits_fill_rectangle(base, x << 1, raster, + tile_patterns[color], w << 1, h); + mem_swap_byte_rect(base, raster, x << 1, w << 1, h, true); + return 0; +} + +/* Copy a bitmap. */ +private int +mem2_word_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *row; + uint raster; + bool store; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + row = scan_line_base(mdev, y); + raster = mdev->raster; + store = (zero != gx_no_color_index && one != gx_no_color_index); + mem_swap_byte_rect(row, raster, x << 1, w << 1, h, store); + mem_mapped2_copy_mono(dev, base, sourcex, sraster, id, + x, y, w, h, zero, one); + mem_swap_byte_rect(row, raster, x << 1, w << 1, h, false); + return 0; +} + +/* Copy a color bitmap. */ +private int +mem2_word_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + int code; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + /* Use monobit copy_mono. */ + /* Patch the width in the device temporarily. */ + dev->width <<= 1; + code = (*dev_proc(&mem_mono_word_device, copy_mono)) + (dev, base, sourcex << 1, sraster, id, + x << 1, y, w << 1, h, (gx_color_index) 0, (gx_color_index) 1); + /* Restore the correct width. */ + dev->width >>= 1; + return code; +} + +#endif /* !arch_is_big_endian */ diff --git a/pstoraster/gdevm24.c b/pstoraster/gdevm24.c new file mode 100644 index 0000000000..1e3a4b9328 --- /dev/null +++ b/pstoraster/gdevm24.c @@ -0,0 +1,526 @@ +/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* 24-bit-per-pixel "memory" (stored bitmap) device */ +#include "memory_.h" +#include "gx.h" +#include "gxdevice.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +extern dev_proc_strip_copy_rop(mem_gray8_rgb24_strip_copy_rop); /* in gdevmrop.c */ + +#define mem_true24_strip_copy_rop mem_gray8_rgb24_strip_copy_rop + +/* ================ Standard (byte-oriented) device ================ */ + +#undef chunk +#define chunk byte + +/* Procedures */ +declare_mem_procs(mem_true24_copy_mono, mem_true24_copy_color, mem_true24_fill_rectangle); +private dev_proc_copy_alpha(mem_true24_copy_alpha); + +/* The device descriptor. */ +const gx_device_memory mem_true24_device = +mem_full_alpha_device("image24", 24, 0, mem_open, + gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, + mem_true24_copy_mono, mem_true24_copy_color, mem_true24_fill_rectangle, + gx_default_map_cmyk_color, mem_true24_copy_alpha, + gx_default_strip_tile_rectangle, mem_true24_strip_copy_rop, + mem_get_bits_rectangle); + +/* Convert x coordinate to byte offset in scan line. */ +#undef x_to_byte +#define x_to_byte(x) ((x) * 3) + +/* Unpack a color into its bytes. */ +#define declare_unpack_color(r, g, b, color)\ + byte r = (byte)(color >> 16);\ + byte g = (byte)((uint)color >> 8);\ + byte b = (byte)color +/* Put a 24-bit color into the bitmap. */ +#define put3(ptr, r, g, b)\ + (ptr)[0] = r, (ptr)[1] = g, (ptr)[2] = b +/* Put 4 bytes of color into the bitmap. */ +#define putw(ptr, wxyz)\ + *(bits32 *)(ptr) = (wxyz) +/* Load the 3-word 24-bit-color cache. */ +/* Free variables: [m]dev, rgbr, gbrg, brgb. */ +#if arch_is_big_endian +# define set_color24_cache(crgb, r, g, b)\ + mdev->color24.rgbr = rgbr = ((bits32)(crgb) << 8) | (r),\ + mdev->color24.gbrg = gbrg = (rgbr << 8) | (g),\ + mdev->color24.brgb = brgb = (gbrg << 8) | (b),\ + mdev->color24.rgb = (crgb) +#else +# define set_color24_cache(crgb, r, g, b)\ + mdev->color24.rgbr = rgbr =\ + ((bits32)(r) << 24) | ((bits32)(b) << 16) |\ + ((bits16)(g) << 8) | (r),\ + mdev->color24.brgb = brgb = (rgbr << 8) | (b),\ + mdev->color24.gbrg = gbrg = (brgb << 8) | (g),\ + mdev->color24.rgb = (crgb) +#endif + +/* Fill a rectangle with a color. */ +private int +mem_true24_fill_rectangle(gx_device * dev, + int x, int y, int w, int h, gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + declare_unpack_color(r, g, b, color); + declare_scan_ptr(dest); + + /* + * In order to avoid testing w > 0 and h > 0 twice, we defer + * executing setup_rect, and use fit_fill_xywh instead of + * fit_fill. + */ + fit_fill_xywh(dev, x, y, w, h); + if (w >= 5) { + if (h <= 0) + return 0; + setup_rect(dest); + if (r == g && r == b) { +#if 1 + /* We think we can do better than the library's memset.... */ + int bcntm7 = w * 3 - 7; + register bits32 cword = color | (color << 24); + + while (h-- > 0) { + register byte *pptr = dest; + byte *limit = pptr + bcntm7; + + /* We want to store full words, but we have to */ + /* guarantee that they are word-aligned. */ + switch (x & 3) { + case 3: + *pptr++ = (byte) cword; + case 2: + *pptr++ = (byte) cword; + case 1: + *pptr++ = (byte) cword; + case 0:; + } + /* Even with w = 5, we always store at least */ + /* 3 full words, regardless of the starting x. */ + *(bits32 *) pptr = + ((bits32 *) pptr)[1] = + ((bits32 *) pptr)[2] = cword; + pptr += 12; + while (pptr < limit) { + *(bits32 *) pptr = + ((bits32 *) pptr)[1] = cword; + pptr += 8; + } + switch (pptr - limit) { + case 0: + pptr[6] = (byte) cword; + case 1: + pptr[5] = (byte) cword; + case 2: + pptr[4] = (byte) cword; + case 3: + *(bits32 *) pptr = cword; + break; + case 4: + pptr[2] = (byte) cword; + case 5: + pptr[1] = (byte) cword; + case 6: + pptr[0] = (byte) cword; + case 7:; + } + inc_ptr(dest, draster); + } +#else + int bcnt = w * 3; + + while (h-- > 0) { + memset(dest, r, bcnt); + inc_ptr(dest, draster); + } +#endif + } else { + int x3 = -x & 3, ww = w - x3; /* we know ww >= 2 */ + bits32 rgbr, gbrg, brgb; + + if (mdev->color24.rgb == color) + rgbr = mdev->color24.rgbr, + gbrg = mdev->color24.gbrg, + brgb = mdev->color24.brgb; + else + set_color24_cache(color, r, g, b); + while (h-- > 0) { + register byte *pptr = dest; + int w1 = ww; + + switch (x3) { + case 1: + put3(pptr, r, g, b); + pptr += 3; + break; + case 2: + pptr[0] = r; + pptr[1] = g; + putw(pptr + 2, brgb); + pptr += 6; + break; + case 3: + pptr[0] = r; + putw(pptr + 1, gbrg); + putw(pptr + 5, brgb); + pptr += 9; + break; + case 0: + ; + } + while (w1 >= 4) { + putw(pptr, rgbr); + putw(pptr + 4, gbrg); + putw(pptr + 8, brgb); + pptr += 12; + w1 -= 4; + } + switch (w1) { + case 1: + put3(pptr, r, g, b); + break; + case 2: + putw(pptr, rgbr); + pptr[4] = g; + pptr[5] = b; + break; + case 3: + putw(pptr, rgbr); + putw(pptr + 4, gbrg); + pptr[8] = b; + break; + case 0: + ; + } + inc_ptr(dest, draster); + } + } + } else if (h > 0) { /* w < 5 */ + setup_rect(dest); + switch (w) { + case 4: + do { + dest[9] = dest[6] = dest[3] = dest[0] = r; + dest[10] = dest[7] = dest[4] = dest[1] = g; + dest[11] = dest[8] = dest[5] = dest[2] = b; + inc_ptr(dest, draster); + } + while (--h); + break; + case 3: + do { + dest[6] = dest[3] = dest[0] = r; + dest[7] = dest[4] = dest[1] = g; + dest[8] = dest[5] = dest[2] = b; + inc_ptr(dest, draster); + } + while (--h); + break; + case 2: + do { + dest[3] = dest[0] = r; + dest[4] = dest[1] = g; + dest[5] = dest[2] = b; + inc_ptr(dest, draster); + } + while (--h); + break; + case 1: + do { + dest[0] = r, dest[1] = g, dest[2] = b; + inc_ptr(dest, draster); + } + while (--h); + break; + case 0: + default: + ; + } + } + return 0; +} + +/* Copy a monochrome bitmap. */ +private int +mem_true24_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + const byte *line; + int sbit; + int first_bit; + + declare_scan_ptr(dest); + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + setup_rect(dest); + line = base + (sourcex >> 3); + sbit = sourcex & 7; + first_bit = 0x80 >> sbit; + if (zero != gx_no_color_index) { /* Loop for halftones or inverted masks */ + /* (never used). */ + declare_unpack_color(r0, g0, b0, zero); + declare_unpack_color(r1, g1, b1, one); + while (h-- > 0) { + register byte *pptr = dest; + const byte *sptr = line; + register int sbyte = *sptr++; + register int bit = first_bit; + int count = w; + + do { + if (sbyte & bit) { + if (one != gx_no_color_index) + put3(pptr, r1, g1, b1); + } else + put3(pptr, r0, g0, b0); + pptr += 3; + if ((bit >>= 1) == 0) + bit = 0x80, sbyte = *sptr++; + } + while (--count > 0); + line += sraster; + inc_ptr(dest, draster); + } + } else if (one != gx_no_color_index) { /* Loop for character and pattern masks. */ + /* This is used heavily. */ + declare_unpack_color(r1, g1, b1, one); + int first_mask = first_bit << 1; + int first_count, first_skip; + + if (sbit + w > 8) + first_mask -= 1, + first_count = 8 - sbit; + else + first_mask -= first_mask >> w, + first_count = w; + first_skip = first_count * 3; + while (h-- > 0) { + register byte *pptr = dest; + const byte *sptr = line; + register int sbyte = *sptr++ & first_mask; + int count = w - first_count; + + if (sbyte) { + register int bit = first_bit; + + do { + if (sbyte & bit) + put3(pptr, r1, g1, b1); + pptr += 3; + } + while ((bit >>= 1) & first_mask); + } else + pptr += first_skip; + while (count >= 8) { + sbyte = *sptr++; + if (sbyte & 0xf0) { + if (sbyte & 0x80) + put3(pptr, r1, g1, b1); + if (sbyte & 0x40) + put3(pptr + 3, r1, g1, b1); + if (sbyte & 0x20) + put3(pptr + 6, r1, g1, b1); + if (sbyte & 0x10) + put3(pptr + 9, r1, g1, b1); + } + if (sbyte & 0xf) { + if (sbyte & 8) + put3(pptr + 12, r1, g1, b1); + if (sbyte & 4) + put3(pptr + 15, r1, g1, b1); + if (sbyte & 2) + put3(pptr + 18, r1, g1, b1); + if (sbyte & 1) + put3(pptr + 21, r1, g1, b1); + } + pptr += 24; + count -= 8; + } + if (count > 0) { + register int bit = 0x80; + + sbyte = *sptr++; + do { + if (sbyte & bit) + put3(pptr, r1, g1, b1); + pptr += 3; + bit >>= 1; + } + while (--count > 0); + } + line += sraster; + inc_ptr(dest, draster); + } + } + return 0; +} + +/* Copy a color bitmap. */ +private int +mem_true24_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h); + return 0; +} + +/* Copy an alpha map. */ +private int +mem_true24_copy_alpha(gx_device * dev, const byte * base, int sourcex, + int sraster, gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index color, int depth) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + const byte *line; + + declare_scan_ptr(dest); + declare_unpack_color(r, g, b, color); + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + setup_rect(dest); + line = base; + while (h-- > 0) { + register byte *pptr = dest; + int sx; + + for (sx = sourcex; sx < sourcex + w; ++sx, pptr += 3) { + int alpha2, alpha; + + if (depth == 2) /* map 0 - 3 to 0 - 15 */ + alpha = + ((line[sx >> 2] >> ((3 - (sx & 3)) << 1)) & 3) * 5; + else + alpha2 = line[sx >> 1], + alpha = (sx & 1 ? alpha2 & 0xf : alpha2 >> 4); + if (alpha == 15) { /* Just write the new color. */ + put3(pptr, r, g, b); + } else if (alpha != 0) { /* Blend RGB values. */ +#define make_shade(old, clr, alpha, amax) \ + (old) + (((int)(clr) - (int)(old)) * (alpha) / (amax)) + pptr[0] = make_shade(pptr[0], r, alpha, 15); + pptr[1] = make_shade(pptr[1], g, alpha, 15); + pptr[2] = make_shade(pptr[2], b, alpha, 15); +#undef make_shade + } + } + line += sraster; + inc_ptr(dest, draster); + } + return 0; +} + +/* ================ "Word"-oriented device ================ */ + +/* Note that on a big-endian machine, this is the same as the */ +/* standard byte-oriented-device. */ + +#if !arch_is_big_endian + +/* Procedures */ +declare_mem_procs(mem24_word_copy_mono, mem24_word_copy_color, mem24_word_fill_rectangle); + +/* Here is the device descriptor. */ +const gx_device_memory mem_true24_word_device = +mem_full_device("image24w", 24, 0, mem_open, + gx_default_rgb_map_rgb_color, gx_default_rgb_map_color_rgb, + mem24_word_copy_mono, mem24_word_copy_color, mem24_word_fill_rectangle, + gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + +/* Fill a rectangle with a color. */ +private int +mem24_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *base; + uint raster; + + fit_fill(dev, x, y, w, h); + base = scan_line_base(mdev, y); + raster = mdev->raster; + mem_swap_byte_rect(base, raster, x * 24, w * 24, h, true); + mem_true24_fill_rectangle(dev, x, y, w, h, color); + mem_swap_byte_rect(base, raster, x * 24, w * 24, h, false); + return 0; +} + +/* Copy a bitmap. */ +private int +mem24_word_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *row; + uint raster; + bool store; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + row = scan_line_base(mdev, y); + raster = mdev->raster; + store = (zero != gx_no_color_index && one != gx_no_color_index); + mem_swap_byte_rect(row, raster, x * 24, w * 24, h, store); + mem_true24_copy_mono(dev, base, sourcex, sraster, id, + x, y, w, h, zero, one); + mem_swap_byte_rect(row, raster, x * 24, w * 24, h, false); + return 0; +} + +/* Copy a color bitmap. */ +private int +mem24_word_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *row; + uint raster; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + row = scan_line_base(mdev, y); + raster = mdev->raster; + mem_swap_byte_rect(row, raster, x * 24, w * 24, h, true); + bytes_copy_rectangle(row + x * 3, raster, base + sourcex * 3, sraster, + w * 3, h); + mem_swap_byte_rect(row, raster, x * 24, w * 24, h, false); + return 0; +} + +#endif /* !arch_is_big_endian */ diff --git a/pstoraster/gdevm32.c b/pstoraster/gdevm32.c new file mode 100644 index 0000000000..d354833236 --- /dev/null +++ b/pstoraster/gdevm32.c @@ -0,0 +1,249 @@ +/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* 32-bit-per-pixel "memory" (stored bitmap) device */ +#include "memory_.h" +#include "gx.h" +#include "gxdevice.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +/* ================ Standard (byte-oriented) device ================ */ + +#undef chunk +#define chunk byte + +/* Procedures */ +declare_mem_procs(mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle); + +/* The device descriptor. */ +const gx_device_memory mem_true32_device = +mem_full_device("image32", 24, 8, mem_open, + gx_default_map_rgb_color, gx_default_map_color_rgb, + mem_true32_copy_mono, mem_true32_copy_color, mem_true32_fill_rectangle, + gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle, + gx_default_strip_copy_rop, mem_get_bits_rectangle); + +/* Convert x coordinate to byte offset in scan line. */ +#undef x_to_byte +#define x_to_byte(x) ((x) << 2) + +/* Swap the bytes of a color if needed. */ +#define color_swap_bytes(color)\ + (((color) >> 24) + (((color) >> 8) & 0xff00) +\ + (((color) & 0xff00) << 8) + ((color) << 24)) +#if arch_is_big_endian +# define arrange_bytes(color) (color) +#else +# define arrange_bytes(color) color_swap_bytes(color) +#endif + +/* Fill a rectangle with a color. */ +private int +mem_true32_fill_rectangle(gx_device * dev, + int x, int y, int w, int h, gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + bits32 a_color; + + declare_scan_ptr(dest); + + fit_fill(dev, x, y, w, h); + a_color = arrange_bytes(color); + setup_rect(dest); + if (w <= 4) + switch (w) { + /*case 0: *//* not possible */ +#define dest32 ((bits32 *)dest) + case 1: + do { + dest32[0] = a_color; + inc_ptr(dest, draster); + } + while (--h > 0); + break; + case 2: + do { + dest32[1] = dest32[0] = a_color; + inc_ptr(dest, draster); + } + while (--h > 0); + break; + case 3: + do { + dest32[2] = dest32[1] = dest32[0] = a_color; + inc_ptr(dest, draster); + } + while (--h > 0); + break; + case 4: + do { + dest32[3] = dest32[2] = dest32[1] = dest32[0] = a_color; + inc_ptr(dest, draster); + } + while (--h > 0); + break; + default: /* not possible */ + ; + } else if (a_color == 0) + do { + memset(dest, 0, w << 2); + inc_ptr(dest, draster); + } + while (--h > 0); + else + do { + bits32 *pptr = dest32; + int cnt = w; + + do { + pptr[3] = pptr[2] = pptr[1] = pptr[0] = a_color; + pptr += 4; + } + while ((cnt -= 4) > 4); + do { + *pptr++ = a_color; + } while (--cnt > 0); + inc_ptr(dest, draster); + } + while (--h > 0); +#undef dest32 + return 0; +} + +/* Copy a monochrome bitmap. */ +private int +mem_true32_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + bits32 a_zero = arrange_bytes(zero); + bits32 a_one = arrange_bytes(one); + const byte *line; + int first_bit; + + declare_scan_ptr(dest); + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + setup_rect(dest); + line = base + (sourcex >> 3); + first_bit = 0x80 >> (sourcex & 7); + while (h-- > 0) { + register bits32 *pptr = (bits32 *) dest; + const byte *sptr = line; + register int sbyte = *sptr++; + register int bit = first_bit; + int count = w; + + do { + if (sbyte & bit) { + if (one != gx_no_color_index) + *pptr = a_one; + } else { + if (zero != gx_no_color_index) + *pptr = a_zero; + } + if ((bit >>= 1) == 0) + bit = 0x80, sbyte = *sptr++; + pptr++; + } + while (--count > 0); + line += sraster; + inc_ptr(dest, draster); + } + return 0; +} + +/* Copy a color bitmap. */ +private int +mem_true32_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h); + return 0; +} + +/* ================ "Word"-oriented device ================ */ + +/* Note that on a big-endian machine, this is the same as the */ +/* standard byte-oriented-device. */ + +#if !arch_is_big_endian + +/* Procedures */ +declare_mem_procs(mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle); + +/* Here is the device descriptor. */ +const gx_device_memory mem_true32_word_device = +mem_full_device("image32w", 24, 8, mem_open, + gx_default_map_rgb_color, gx_default_map_color_rgb, + mem32_word_copy_mono, mem32_word_copy_color, mem32_word_fill_rectangle, + gx_default_cmyk_map_cmyk_color, gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + +/* Fill a rectangle with a color. */ +private int +mem32_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + return mem_true32_fill_rectangle(dev, x, y, w, h, + color_swap_bytes(color)); +} + +/* Copy a bitmap. */ +private int +mem32_word_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + return mem_true32_copy_mono(dev, base, sourcex, sraster, id, + x, y, w, h, color_swap_bytes(zero), + color_swap_bytes(one)); +} + +/* Copy a color bitmap. */ +private int +mem32_word_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *row; + uint raster; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + row = scan_line_base(mdev, y); + raster = mdev->raster; + bytes_copy_rectangle(row + (x << 2), raster, base + (sourcex << 2), + sraster, w << 2, h); + mem_swap_byte_rect(row, raster, x << 5, w << 5, h, false); + return 0; +} + +#endif /* !arch_is_big_endian */ diff --git a/pstoraster/gdevm4.c b/pstoraster/gdevm4.c new file mode 100644 index 0000000000..e0df0e13f6 --- /dev/null +++ b/pstoraster/gdevm4.c @@ -0,0 +1,319 @@ +/* Copyright (C) 1992, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* 4-bit-per-pixel "memory" (stored bitmap) device */ +#include "memory_.h" +#include "gx.h" +#include "gxdevice.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +extern dev_proc_strip_copy_rop(mem_gray_strip_copy_rop); + +/* ================ Standard (byte-oriented) device ================ */ + +#undef chunk +#define chunk byte +#define fpat(byt) mono_fill_make_pattern(byt) + +/* Procedures */ +declare_mem_procs(mem_mapped4_copy_mono, mem_mapped4_copy_color, mem_mapped4_fill_rectangle); + +/* The device descriptor. */ +const gx_device_memory mem_mapped4_device = +mem_device("image4", 4, 0, + mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, + mem_mapped4_copy_mono, mem_mapped4_copy_color, mem_mapped4_fill_rectangle, + mem_gray_strip_copy_rop); + +/* Convert x coordinate to byte offset in scan line. */ +#undef x_to_byte +#define x_to_byte(x) ((x) >> 1) + +/* Define the 4-bit fill patterns. */ +static const mono_fill_chunk tile_patterns[16] = +{fpat(0x00), fpat(0x11), fpat(0x22), fpat(0x33), + fpat(0x44), fpat(0x55), fpat(0x66), fpat(0x77), + fpat(0x88), fpat(0x99), fpat(0xaa), fpat(0xbb), + fpat(0xcc), fpat(0xdd), fpat(0xee), fpat(0xff) +}; + + +/* Fill a rectangle with a color. */ +private int +mem_mapped4_fill_rectangle(gx_device * dev, + int x, int y, int w, int h, gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + fit_fill(dev, x, y, w, h); + bits_fill_rectangle(scan_line_base(mdev, y), x << 2, mdev->raster, + tile_patterns[color], w << 2, h); + return 0; +} + +/* Copy a bitmap. */ +private int +mem_mapped4_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + const byte *line; + declare_scan_ptr(dest); + byte invert, bb; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + setup_rect(dest); + line = base + (sourcex >> 3); + /* Divide into opaque and masked cases. */ + if (one == gx_no_color_index) { + if (zero == gx_no_color_index) + return 0; /* nothing to do */ + invert = 0xff; + bb = ((byte) zero << 4) | (byte) zero; + } else if (zero == gx_no_color_index) { + invert = 0; + bb = ((byte) one << 4) | (byte) one; + } else { + /* Opaque case. */ + int shift = ~(sourcex ^ x) & 1; + byte oz[4]; + + oz[0] = (byte)((zero << 4) | zero); + oz[1] = (byte)((zero << 4) | one); + oz[2] = (byte)((one << 4) | zero); + oz[3] = (byte)((one << 4) | one); + do { + register byte *dptr = (byte *) dest; + const byte *sptr = line; + register uint sbyte = *sptr++; + register int sbit = ~sourcex & 7; + int count = w; + + /* + * If the first source bit corresponds to an odd X in the + * destination, process it now. + */ + if (x & 1) { + *dptr = (*dptr & 0xf0) | + ((sbyte >> sbit) & 1 ? one : zero); + --count; /* may now be 0 */ + if (--sbit < 0) + sbit = 7, sbyte = *sptr++; + ++dptr; + } + /* + * Now we know the next destination X is even. We want to + * process 2 source bits at a time from now on, so set things up + * properly depending on whether the next source X (bit) is even + * or odd. In both even and odd cases, the active source bits + * are in bits 8..1 of sbyte. + */ + sbyte <<= shift; + sbit += shift - 1; + /* + * Now bit # sbit+1 is the most significant unprocessed bit + * in sbyte. -1 <= sbit <= 7; sbit is odd. + * Note that if sbit = -1, all of sbyte has been processed. + * + * Continue processing pairs of bits in the first source byte. + */ + while (count >= 2 && sbit >= 0) { + *dptr++ = oz[(sbyte >> sbit) & 3]; + sbit -= 2, count -= 2; + } + /* + * Now sbit = -1 iff we have processed the entire first source + * byte. + * + * Process full source bytes. + */ + if (shift) { + sbyte >>= 1; /* in case count < 8 */ + for (; count >= 8; dptr += 4, count -= 8) { + sbyte = *sptr++; + dptr[0] = oz[sbyte >> 6]; + dptr[1] = oz[(sbyte >> 4) & 3]; + dptr[2] = oz[(sbyte >> 2) & 3]; + dptr[3] = oz[sbyte & 3]; + } + sbyte <<= 1; + } else { + for (; count >= 8; dptr += 4, count -= 8) { + sbyte = (sbyte << 8) | *sptr++; + dptr[0] = oz[(sbyte >> 7) & 3]; + dptr[1] = oz[(sbyte >> 5) & 3]; + dptr[2] = oz[(sbyte >> 3) & 3]; + dptr[3] = oz[(sbyte >> 1) & 3]; + } + } + if (!count) + continue; + /* + * Process pairs of bits in the final source byte. Note that + * if sbit > 0, this is still the first source byte (the + * full-byte loop wasn't executed). + */ + if (sbit < 0) { + sbyte = (sbyte << 8) | (*sptr << shift); + sbit = 7; + } + while (count >= 2) { + *dptr++ = oz[(sbyte >> sbit) & 3]; + sbit -= 2, count -= 2; + } + /* + * If the final source bit corresponds to an even X value, + * process it now. + */ + if (count) { + *dptr = (*dptr & 0x0f) | + (((sbyte >> sbit) & 2 ? one : zero) << 4); + } + } while ((line += sraster, inc_ptr(dest, draster), --h) > 0); + return 0; + } + /* Masked case. */ + do { + register byte *dptr = (byte *) dest; + const byte *sptr = line; + register int sbyte = *sptr++ ^ invert; + register int sbit = 0x80 >> (sourcex & 7); + register byte mask = (x & 1 ? 0x0f : 0xf0); + int count = w; + + do { + if (sbyte & sbit) + *dptr = (*dptr & ~mask) | (bb & mask); + if ((sbit >>= 1) == 0) + sbit = 0x80, sbyte = *sptr++ ^ invert; + dptr += (mask = ~mask) >> 7; + } while (--count > 0); + line += sraster; + inc_ptr(dest, draster); + } while (--h > 0); + return 0; +} + +/* Copy a color bitmap. */ +private int +mem_mapped4_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + /* Use monobit copy_mono. */ + int code; + + /* Patch the width in the device temporarily. */ + dev->width <<= 2; + code = (*dev_proc(&mem_mono_device, copy_mono)) + (dev, base, sourcex << 2, sraster, id, + x << 2, y, w << 2, h, (gx_color_index) 0, (gx_color_index) 1); + /* Restore the correct width. */ + dev->width >>= 2; + return code; +} + +/* ================ "Word"-oriented device ================ */ + +/* Note that on a big-endian machine, this is the same as the */ +/* standard byte-oriented-device. */ + +#if !arch_is_big_endian + +/* Procedures */ +declare_mem_procs(mem4_word_copy_mono, mem4_word_copy_color, mem4_word_fill_rectangle); + +/* Here is the device descriptor. */ +const gx_device_memory mem_mapped4_word_device = +mem_full_device("image4w", 4, 0, mem_open, + mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, + mem4_word_copy_mono, mem4_word_copy_color, mem4_word_fill_rectangle, + gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + +/* Fill a rectangle with a color. */ +private int +mem4_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *base; + uint raster; + + fit_fill(dev, x, y, w, h); + base = scan_line_base(mdev, y); + raster = mdev->raster; + mem_swap_byte_rect(base, raster, x << 2, w << 2, h, true); + bits_fill_rectangle(base, x << 2, raster, + tile_patterns[color], w << 2, h); + mem_swap_byte_rect(base, raster, x << 2, w << 2, h, true); + return 0; +} + +/* Copy a bitmap. */ +private int +mem4_word_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *row; + uint raster; + bool store; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + row = scan_line_base(mdev, y); + raster = mdev->raster; + store = (zero != gx_no_color_index && one != gx_no_color_index); + mem_swap_byte_rect(row, raster, x << 2, w << 2, h, store); + mem_mapped4_copy_mono(dev, base, sourcex, sraster, id, + x, y, w, h, zero, one); + mem_swap_byte_rect(row, raster, x << 2, w << 2, h, false); + return 0; +} + +/* Copy a color bitmap. */ +private int +mem4_word_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + int code; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + /* Use monobit copy_mono. */ + /* Patch the width in the device temporarily. */ + dev->width <<= 2; + code = (*dev_proc(&mem_mono_word_device, copy_mono)) + (dev, base, sourcex << 2, sraster, id, + x << 2, y, w << 2, h, (gx_color_index) 0, (gx_color_index) 1); + /* Restore the correct width. */ + dev->width >>= 2; + return code; +} + +#endif /* !arch_is_big_endian */ diff --git a/pstoraster/gdevm8.c b/pstoraster/gdevm8.c new file mode 100644 index 0000000000..875bcaddb8 --- /dev/null +++ b/pstoraster/gdevm8.c @@ -0,0 +1,247 @@ +/* Copyright (C) 1994, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* 8-bit-per-pixel "memory" (stored bitmap) device */ +#include "memory_.h" +#include "gx.h" +#include "gxdevice.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +/**************** NOTE: copy_rop only works for gray scale ****************/ +extern dev_proc_strip_copy_rop(mem_gray8_rgb24_strip_copy_rop); /* in gdevmrop.c */ + +#define mem_gray8_strip_copy_rop mem_gray8_rgb24_strip_copy_rop + +/* ================ Standard (byte-oriented) device ================ */ + +#undef chunk +#define chunk byte + +/* Procedures */ +declare_mem_procs(mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fill_rectangle); + +/* The device descriptor. */ +const gx_device_memory mem_mapped8_device = +mem_device("image8", 8, 0, + mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, + mem_mapped8_copy_mono, mem_mapped8_copy_color, mem_mapped8_fill_rectangle, + mem_gray8_strip_copy_rop); + +/* Convert x coordinate to byte offset in scan line. */ +#undef x_to_byte +#define x_to_byte(x) (x) + +/* Fill a rectangle with a color. */ +private int +mem_mapped8_fill_rectangle(gx_device * dev, + int x, int y, int w, int h, gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + fit_fill(dev, x, y, w, h); + bytes_fill_rectangle(scan_line_base(mdev, y) + x, mdev->raster, + (byte) color, w, h); + return 0; +} + +/* Copy a monochrome bitmap. */ +/* We split up this procedure because of limitations in the bcc32 compiler. */ +private void mapped8_copy01(P9(chunk *, const byte *, int, int, uint, + int, int, byte, byte)); +private void mapped8_copyN1(P8(chunk *, const byte *, int, int, uint, + int, int, byte)); +private void mapped8_copy0N(P8(chunk *, const byte *, int, int, uint, + int, int, byte)); +private int +mem_mapped8_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + const byte *line; + int first_bit; + + declare_scan_ptr(dest); + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + setup_rect(dest); + line = base + (sourcex >> 3); + first_bit = 0x80 >> (sourcex & 7); +#define is_color(c) ((int)(c) != (int)gx_no_color_index) + if (is_color(one)) { + if (is_color(zero)) + mapped8_copy01(dest, line, first_bit, sraster, draster, + w, h, (byte) zero, (byte) one); + else + mapped8_copyN1(dest, line, first_bit, sraster, draster, + w, h, (byte) one); + } else if (is_color(zero)) + mapped8_copy0N(dest, line, first_bit, sraster, draster, + w, h, (byte) zero); +#undef is_color + return 0; +} +/* Macros for copy loops */ +#define COPY_BEGIN\ + while ( h-- > 0 )\ + { register byte *pptr = dest;\ + const byte *sptr = line;\ + register int sbyte = *sptr;\ + register uint bit = first_bit;\ + int count = w;\ + do\ + { +#define COPY_END\ + if ( (bit >>= 1) == 0 )\ + bit = 0x80, sbyte = *++sptr;\ + pptr++;\ + }\ + while ( --count > 0 );\ + line += sraster;\ + inc_ptr(dest, draster);\ + } +/* Halftone coloring */ +private void +mapped8_copy01(chunk * dest, const byte * line, int first_bit, + int sraster, uint draster, int w, int h, byte b0, byte b1) +{ + COPY_BEGIN + * pptr = (sbyte & bit ? b1 : b0); + COPY_END +} +/* Stenciling */ +private void +mapped8_copyN1(chunk * dest, const byte * line, int first_bit, + int sraster, uint draster, int w, int h, byte b1) +{ + COPY_BEGIN + if (sbyte & bit) + *pptr = b1; + COPY_END +} +/* Reverse stenciling */ +private void +mapped8_copy0N(chunk * dest, const byte * line, int first_bit, + int sraster, uint draster, int w, int h, byte b0) +{ + COPY_BEGIN + if (!(sbyte & bit)) + *pptr = b0; + COPY_END +} +#undef COPY_BEGIN +#undef COPY_END + +/* Copy a color bitmap. */ +private int +mem_mapped8_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h); + return 0; +} + +/* ================ "Word"-oriented device ================ */ + +/* Note that on a big-endian machine, this is the same as the */ +/* standard byte-oriented-device. */ + +#if !arch_is_big_endian + +/* Procedures */ +declare_mem_procs(mem8_word_copy_mono, mem8_word_copy_color, mem8_word_fill_rectangle); + +/* Here is the device descriptor. */ +const gx_device_memory mem_mapped8_word_device = +mem_full_device("image8w", 8, 0, mem_open, + mem_mapped_map_rgb_color, mem_mapped_map_color_rgb, + mem8_word_copy_mono, mem8_word_copy_color, mem8_word_fill_rectangle, + gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop, mem_word_get_bits_rectangle); + +/* Fill a rectangle with a color. */ +private int +mem8_word_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *base; + uint raster; + + fit_fill(dev, x, y, w, h); + base = scan_line_base(mdev, y); + raster = mdev->raster; + mem_swap_byte_rect(base, raster, x << 3, w << 3, h, true); + bytes_fill_rectangle(base + x, raster, (byte) color, w, h); + mem_swap_byte_rect(base, raster, x << 3, w << 3, h, true); + return 0; +} + +/* Copy a bitmap. */ +private int +mem8_word_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *row; + uint raster; + bool store; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + row = scan_line_base(mdev, y); + raster = mdev->raster; + store = (zero != gx_no_color_index && one != gx_no_color_index); + mem_swap_byte_rect(row, raster, x << 3, w << 3, h, store); + mem_mapped8_copy_mono(dev, base, sourcex, sraster, id, + x, y, w, h, zero, one); + mem_swap_byte_rect(row, raster, x << 3, w << 3, h, false); + return 0; +} + +/* Copy a color bitmap. */ +private int +mem8_word_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *row; + uint raster; + + fit_copy(dev, base, sourcex, sraster, id, x, y, w, h); + row = scan_line_base(mdev, y); + raster = mdev->raster; + mem_swap_byte_rect(row, raster, x << 3, w << 3, h, true); + mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h); + mem_swap_byte_rect(row, raster, x << 3, w << 3, h, false); + return 0; +} + +#endif /* !arch_is_big_endian */ diff --git a/pstoraster/gdevmem.c b/pstoraster/gdevmem.c new file mode 100644 index 0000000000..231e41920d --- /dev/null +++ b/pstoraster/gdevmem.c @@ -0,0 +1,498 @@ +/* Copyright (C) 1989, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Generic "memory" (stored bitmap) device */ +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gsrect.h" +#include "gsstruct.h" +#include "gxarith.h" +#include "gxdevice.h" +#include "gxgetbit.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +/* Structure descriptor */ +public_st_device_memory(); + +/* GC procedures */ +#define mptr ((gx_device_memory *)vptr) +private +ENUM_PTRS_BEGIN(device_memory_enum_ptrs) +{ + return ENUM_USING(st_device_forward, vptr, sizeof(gx_device_forward), index - 2); +} +case 0: +ENUM_RETURN((mptr->foreign_bits ? NULL : (void *)mptr->base)); +ENUM_STRING_PTR(1, gx_device_memory, palette); +ENUM_PTRS_END +private RELOC_PTRS_BEGIN(device_memory_reloc_ptrs) +{ + if (!mptr->foreign_bits) { + byte *base_old = mptr->base; + long reloc; + int y; + + RELOC_PTR(gx_device_memory, base); + reloc = base_old - mptr->base; + for (y = 0; y < mptr->height; y++) + mptr->line_ptrs[y] -= reloc; + /* Relocate line_ptrs, which also points into the data area. */ + mptr->line_ptrs = (byte **) ((byte *) mptr->line_ptrs - reloc); + } + RELOC_CONST_STRING_PTR(gx_device_memory, palette); + RELOC_USING(st_device_forward, vptr, sizeof(gx_device_forward)); +} +RELOC_PTRS_END +#undef mptr + +/* Define the palettes for monobit devices. */ +private const byte b_w_palette_string[6] = +{0xff, 0xff, 0xff, 0, 0, 0}; +const gs_const_string mem_mono_b_w_palette = +{b_w_palette_string, 6}; +private const byte w_b_palette_string[6] = +{0, 0, 0, 0xff, 0xff, 0xff}; +const gs_const_string mem_mono_w_b_palette = +{w_b_palette_string, 6}; + +/* ------ Generic code ------ */ + +/* Return the appropriate memory device for a given */ +/* number of bits per pixel (0 if none suitable). */ +const gx_device_memory * +gdev_mem_device_for_bits(int bits_per_pixel) +{ + switch (bits_per_pixel) { + case 1: + return &mem_mono_device; + case 2: + return &mem_mapped2_device; + case 4: + return &mem_mapped4_device; + case 8: + return &mem_mapped8_device; + case 16: + return &mem_true16_device; + case 24: + return &mem_true24_device; + case 32: + return &mem_true32_device; + default: + return 0; + } +} +/* Do the same for a word-oriented device. */ +const gx_device_memory * +gdev_mem_word_device_for_bits(int bits_per_pixel) +{ + switch (bits_per_pixel) { + case 1: + return &mem_mono_word_device; + case 2: + return &mem_mapped2_word_device; + case 4: + return &mem_mapped4_word_device; + case 8: + return &mem_mapped8_word_device; + case 24: + return &mem_true24_word_device; + case 32: + return &mem_true32_word_device; + default: + return 0; + } +} + +/* Make a memory device. */ +/* Note that the default for monobit devices is white = 0, black = 1. */ +void +gs_make_mem_device(gx_device_memory * dev, const gx_device_memory * mdproto, + gs_memory_t * mem, int page_device, gx_device * target) +{ + gx_device_init((gx_device *) dev, (const gx_device *)mdproto, + mem, true); + dev->stype = &st_device_memory; + switch (page_device) { + case -1: + set_dev_proc(dev, get_page_device, gx_default_get_page_device); + break; + case 1: + set_dev_proc(dev, get_page_device, gx_page_device_get_page_device); + break; + } + dev->target = target; + if (target != 0) { + /* Forward the color mapping operations to the target. */ + gx_device_forward_color_procs((gx_device_forward *) dev); + } + if (dev->color_info.depth == 1) + gdev_mem_mono_set_inverted(dev, + (target == 0 || + (*dev_proc(target, map_rgb_color)) + (target, (gx_color_value) 0, (gx_color_value) 0, + (gx_color_value) 0) != 0)); +} +/* Make a monobit memory device. This is never a page device. */ +/* Note that white=0, black=1. */ +void +gs_make_mem_mono_device(gx_device_memory * dev, gs_memory_t * mem, + gx_device * target) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + *dev = mem_mono_device; + dev->memory = mem; + set_dev_proc(dev, get_page_device, gx_default_get_page_device); + mdev->target = target; + gdev_mem_mono_set_inverted(dev, true); + rc_init(dev, mem, 0); +} + + +/* Define whether a monobit memory device is inverted (black=1). */ +void +gdev_mem_mono_set_inverted(gx_device_memory * dev, bool black_is_1) +{ + if (black_is_1) + dev->palette = mem_mono_b_w_palette; + else + dev->palette = mem_mono_w_b_palette; +} + +/* Compute the size of the bitmap storage, */ +/* including the space for the scan line pointer table. */ +/* Note that scan lines are padded to a multiple of align_bitmap_mod bytes, */ +/* and additional padding may be needed if the pointer table */ +/* must be aligned to an even larger modulus. */ +private ulong +mem_bitmap_bits_size(const gx_device_memory * dev, int width, int height) +{ + return round_up((ulong) height * + bitmap_raster(width * dev->color_info.depth), + max(align_bitmap_mod, arch_align_ptr_mod)); +} +ulong +gdev_mem_data_size(const gx_device_memory * dev, int width, int height) +{ + return mem_bitmap_bits_size(dev, width, height) + + (ulong) height *sizeof(byte *); + +} +/* + * Do the inverse computation: given a width (in pixels) and a buffer size, + * compute the maximum height. + */ +int +gdev_mem_max_height(const gx_device_memory * dev, int width, ulong size) +{ + ulong max_height = size / + (bitmap_raster(width * dev->color_info.depth) + sizeof(byte *)); + int height = (int)min(max_height, max_int); + + /* + * Because of alignment rounding, the just-computed height might + * be too large by a small amount. Adjust it the easy way. + */ + while (gdev_mem_data_size(dev, width, height) > size) + --height; + return height; +} + +/* Open a memory device, allocating the data area if appropriate, */ +/* and create the scan line table. */ +private void mem_set_line_ptrs(P4(gx_device_memory *, byte **, byte *, int)); +int +mem_open(gx_device * dev) +{ + return gdev_mem_open_scan_lines((gx_device_memory *)dev, dev->height); +} +int +gdev_mem_open_scan_lines(gx_device_memory *mdev, int setup_height) +{ + if (setup_height < 0 || setup_height > mdev->height) + return_error(gs_error_rangecheck); + if (mdev->bitmap_memory != 0) { /* Allocate the data now. */ + ulong size = gdev_mem_bitmap_size(mdev); + + if ((uint) size != size) + return_error(gs_error_limitcheck); + mdev->base = gs_alloc_bytes(mdev->bitmap_memory, (uint)size, + "mem_open"); + if (mdev->base == 0) + return_error(gs_error_VMerror); + mdev->foreign_bits = false; + } +/* + * Macro for adding an offset to a pointer when setting up the + * scan line table. This isn't just pointer arithmetic, because of + * the segmenting considerations discussed in gdevmem.h. + */ +#define huge_ptr_add(base, offset)\ + ((void *)((byte huge *)(base) + (offset))) + mem_set_line_ptrs(mdev, + huge_ptr_add(mdev->base, + mem_bitmap_bits_size(mdev, mdev->width, + mdev->height)), + mdev->base, setup_height); + return 0; +} +/* Set up the scan line pointers of a memory device. */ +/* Sets line_ptrs, base, raster; uses width, color_info.depth. */ +private void +mem_set_line_ptrs(gx_device_memory * mdev, byte ** line_ptrs, byte * base, + int count /* >= 0 */) +{ + byte **pptr = mdev->line_ptrs = line_ptrs; + byte **pend = pptr + count; + byte *scan_line = mdev->base = base; + uint raster = mdev->raster = gdev_mem_raster(mdev); + + while (pptr < pend) { + *pptr++ = scan_line; + scan_line = huge_ptr_add(scan_line, raster); + } +} + +/* Return the initial transformation matrix */ +void +mem_get_initial_matrix(gx_device * dev, gs_matrix * pmat) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + pmat->xx = mdev->initial_matrix.xx; + pmat->xy = mdev->initial_matrix.xy; + pmat->yx = mdev->initial_matrix.yx; + pmat->yy = mdev->initial_matrix.yy; + pmat->tx = mdev->initial_matrix.tx; + pmat->ty = mdev->initial_matrix.ty; +} + +/* Test whether a device is a memory device */ +bool +gs_device_is_memory(const gx_device * dev) +{ /* We can't just compare the procs, or even an individual proc, */ + /* because we might be tracing. Instead, check the identity of */ + /* the device name. */ + const gx_device_memory *bdev = + gdev_mem_device_for_bits(dev->color_info.depth); + + if (bdev != 0 && bdev->dname == dev->dname) + return true; + bdev = gdev_mem_word_device_for_bits(dev->color_info.depth); + return (bdev != 0 && bdev->dname == dev->dname); +} + +/* Close a memory device, freeing the data area if appropriate. */ +int +mem_close(gx_device * dev) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + + if (mdev->bitmap_memory != 0) + gs_free_object(mdev->bitmap_memory, mdev->base, "mem_close"); + return 0; +} + +/* Copy bits to a client. */ +#undef chunk +#define chunk byte +int +mem_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, + gs_get_bits_params_t * params, gs_int_rect ** unread) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + gs_get_bits_options_t options = params->options; + int x = prect->p.x, w = prect->q.x - x, y = prect->p.y, h = prect->q.y - y; + + if (options == 0) { + params->options = + (GB_ALIGN_STANDARD | GB_ALIGN_ANY) | + (GB_RETURN_COPY | GB_RETURN_POINTER) | + (GB_OFFSET_0 | GB_OFFSET_SPECIFIED | GB_OFFSET_ANY) | + (GB_RASTER_STANDARD | GB_RASTER_SPECIFIED | GB_RASTER_ANY) | + GB_PACKING_CHUNKY | GB_COLORS_NATIVE | GB_ALPHA_NONE; + return_error(gs_error_rangecheck); + } + if ((w <= 0) | (h <= 0)) { + if ((w | h) < 0) + return_error(gs_error_rangecheck); + return 0; + } + if (x < 0 || w > dev->width - x || + y < 0 || h > dev->height - y + ) + return_error(gs_error_rangecheck); + { + byte *base = scan_line_base(mdev, y); + int code = gx_get_bits_return_pointer(dev, x, h, params, + GB_COLORS_NATIVE | GB_PACKING_CHUNKY | + GB_ALPHA_NONE, base); + + if (code >= 0) + return code; + return gx_get_bits_copy(dev, x, w, h, params, + GB_COLORS_NATIVE | GB_PACKING_CHUNKY | + GB_ALPHA_NONE, base, + gx_device_raster(dev, true)); + } +} + +#if !arch_is_big_endian + +/* + * Swap byte order in a rectangular subset of a bitmap. If store = true, + * assume the rectangle will be overwritten, so don't swap any bytes where + * it doesn't matter. The caller has already done a fit_fill or fit_copy. + * Note that the coordinates are specified in bits, not in terms of the + * actual device depth. + */ +void +mem_swap_byte_rect(byte * base, uint raster, int x, int w, int h, bool store) +{ + int xbit = x & 31; + + if (store) { + if (xbit + w > 64) { /* Operation spans multiple words. */ + /* Just swap the words at the left and right edges. */ + if (xbit != 0) + mem_swap_byte_rect(base, raster, x, 1, h, false); + x += w - 1; + xbit = x & 31; + if (xbit == 31) + return; + w = 1; + } + } + /* Swap the entire rectangle (or what's left of it). */ + { + byte *row = base + ((x >> 5) << 2); + int nw = (xbit + w + 31) >> 5; + int ny; + + for (ny = h; ny > 0; row += raster, --ny) { + int nx = nw; + bits32 *pw = (bits32 *) row; + + do { + bits32 w = *pw; + + *pw++ = (w >> 24) + ((w >> 8) & 0xff00) + + ((w & 0xff00) << 8) + (w << 24); + } + while (--nx); + } + } +} + +/* Copy a word-oriented rectangle to the client, swapping bytes as needed. */ +int +mem_word_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, + gs_get_bits_params_t * params, gs_int_rect ** unread) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte *src; + uint dev_raster = gx_device_raster(dev, 1); + int x = prect->p.x; + int w = prect->q.x - x; + int y = prect->p.y; + int h = prect->q.y - y; + int bit_x, bit_w; + int code; + + fit_fill_xywh(dev, x, y, w, h); + if (w <= 0 || h <= 0) { + /* + * It's easiest to just keep going with an empty rectangle. + * We pass the original rectangle to mem_get_bits_rectangle, + * so unread will be filled in correctly. + */ + x = y = w = h = 0; + } + bit_x = x * dev->color_info.depth; + bit_w = w * dev->color_info.depth; + src = scan_line_base(mdev, y); + mem_swap_byte_rect(src, dev_raster, bit_x, bit_w, h, false); + code = mem_get_bits_rectangle(dev, prect, params, unread); + mem_swap_byte_rect(src, dev_raster, bit_x, bit_w, h, false); + return code; +} + +#endif /* !arch_is_big_endian */ + +/* Map a r-g-b color to a color index for a mapped color memory device */ +/* (2, 4, or 8 bits per pixel.) */ +/* This requires searching the palette. */ +gx_color_index +mem_mapped_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g, + gx_color_value b) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte br = gx_color_value_to_byte(r); + byte bg = gx_color_value_to_byte(g); + byte bb = gx_color_value_to_byte(b); + register const byte *pptr = mdev->palette.data; + int cnt = mdev->palette.size; + const byte *which = 0; /* initialized only to pacify gcc */ + int best = 256 * 3; + + while ((cnt -= 3) >= 0) { + register int diff = *pptr - br; + + if (diff < 0) + diff = -diff; + if (diff < best) { /* quick rejection */ + int dg = pptr[1] - bg; + + if (dg < 0) + dg = -dg; + if ((diff += dg) < best) { /* quick rejection */ + int db = pptr[2] - bb; + + if (db < 0) + db = -db; + if ((diff += db) < best) + which = pptr, best = diff; + } + } + pptr += 3; + } + return (gx_color_index) ((which - mdev->palette.data) / 3); +} + +/* Map a color index to a r-g-b color for a mapped color memory device. */ +int +mem_mapped_map_color_rgb(gx_device * dev, gx_color_index color, + gx_color_value prgb[3]) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + const byte *pptr = mdev->palette.data + (int)color * 3; + + prgb[0] = gx_color_value_from_byte(pptr[0]); + prgb[1] = gx_color_value_from_byte(pptr[1]); + prgb[2] = gx_color_value_from_byte(pptr[2]); + return 0; +} diff --git a/pstoraster/gdevmem.h b/pstoraster/gdevmem.h new file mode 100644 index 0000000000..17dc5c059e --- /dev/null +++ b/pstoraster/gdevmem.h @@ -0,0 +1,233 @@ +/* Copyright (C) 1991, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Private definitions for memory devices. */ + +#ifndef gdevmem_INCLUDED +# define gdevmem_INCLUDED + +#include "gxbitops.h" + +/* + The representation for a "memory" device is simply a + contiguous bitmap stored in something like the PostScript + representation, i.e., each scan line (in left-to-right order), padded + to a multiple of bitmap_align_mod bytes, followed immediately by + the next one. + + The representation of strings in the interpreter limits + the size of a string to 64K-1 bytes, which means we can't simply use + a string for the contents of a memory device. + We get around this problem by making the client read out the + contents of a memory device bitmap in pieces. + + On 80x86 PCs running in 16-bit mode, there may be no way to + obtain a contiguous block of storage larger than 64K bytes, + which typically isn't big enough for a full-screen bitmap. + We take the following compromise position: if the PC is running in + native mode (pseudo-segmenting), we limit the bitmap to 64K; + if the PC is running in protected mode (e.g., under MS Windows), + we assume that blocks larger than 64K have sequential segment numbers, + and that the client arranges things so that an individual scan line, + the scan line pointer table, and any single call on a drawing routine + do not cross a segment boundary. + + Even though the scan lines are stored contiguously, we store a table + of their base addresses, because indexing into it is faster than + the multiplication that would otherwise be needed. + */ + +/* + * Macros for scan line access. + * x_to_byte is different for each number of bits per pixel. + * Note that these macros depend on the definition of chunk: + * each procedure that uses the scanning macros should #define + * (not typedef) chunk as either uint or byte. + */ +#define declare_scan_ptr(ptr)\ + DECLARE_SCAN_PTR_VARS(ptr, chunk *, draster) +#define DECLARE_SCAN_PTR_VARS(ptr, ptype, draster)\ + register ptype ptr;\ + uint draster +#define setup_rect(ptr)\ + SETUP_RECT_VARS(ptr, chunk *, draster) +#define SETUP_RECT_VARS(ptr, ptype, draster)\ + draster = mdev->raster;\ + ptr = (ptype)(scan_line_base(mdev, y) +\ + (x_to_byte(x) & -chunk_align_bytes)) + +/* ------ Generic macros ------ */ + +/* Macro for declaring the essential device procedures. */ +dev_proc_get_initial_matrix(mem_get_initial_matrix); +dev_proc_close_device(mem_close); +#define declare_mem_map_procs(map_rgb_color, map_color_rgb)\ + private dev_proc_map_rgb_color(map_rgb_color);\ + private dev_proc_map_color_rgb(map_color_rgb) +#define declare_mem_procs(copy_mono, copy_color, fill_rectangle)\ + private dev_proc_copy_mono(copy_mono);\ + private dev_proc_copy_color(copy_color);\ + private dev_proc_fill_rectangle(fill_rectangle) + +/* The following are used for all except planar or word-oriented devices. */ +dev_proc_open_device(mem_open); +dev_proc_get_bits_rectangle(mem_get_bits_rectangle); +/* The following are for word-oriented devices. */ +#if arch_is_big_endian +# define mem_word_get_bits_rectangle mem_get_bits_rectangle +#else +dev_proc_get_bits_rectangle(mem_word_get_bits_rectangle); +#endif +/* The following are used for the non-true-color devices. */ +dev_proc_map_rgb_color(mem_mapped_map_rgb_color); +dev_proc_map_color_rgb(mem_mapped_map_color_rgb); + +/* + * Macro for generating the device descriptor. + * Various compilers have problems with the obvious definition + * for max_value, namely: + * (depth >= 8 ? 255 : (1 << depth) - 1) + * I tried changing (1 << depth) to (1 << (depth & 15)) to forestall bogus + * error messages about invalid shift counts, but the H-P compiler chokes + * on this. Since the only values of depth we ever plan to support are + * powers of 2 (and 24), we just go ahead and enumerate them. + */ +#define max_value_gray(rgb_depth, gray_depth)\ + (gray_depth ? (1 << gray_depth) - 1 : max_value_rgb(rgb_depth, 0)) +#define max_value_rgb(rgb_depth, gray_depth)\ + (rgb_depth >= 8 ? 255 : rgb_depth == 4 ? 15 : rgb_depth == 2 ? 3 :\ + rgb_depth == 1 ? 1 : (1 << gray_depth) - 1) +#define mem_full_alpha_device(name, rgb_depth, gray_depth, open, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, map_cmyk_color, copy_alpha, strip_tile_rectangle, strip_copy_rop, get_bits_rectangle)\ +{ std_device_dci_body(gx_device_memory, 0, name,\ + 0, 0, 72, 72,\ + (rgb_depth ? 3 : 0) + (gray_depth ? 1 : 0), /* num_components */\ + rgb_depth + gray_depth, /* depth */\ + max_value_gray(rgb_depth, gray_depth), /* max_gray */\ + max_value_rgb(rgb_depth, gray_depth), /* max_color */\ + max_value_gray(rgb_depth, gray_depth) + 1, /* dither_grays */\ + max_value_rgb(rgb_depth, gray_depth) + 1 /* dither_colors */\ + ),\ + { open, /* differs */\ + mem_get_initial_matrix,\ + gx_default_sync_output,\ + gx_default_output_page,\ + mem_close,\ + map_rgb_color, /* differs */\ + map_color_rgb, /* differs */\ + fill_rectangle, /* differs */\ + gx_default_tile_rectangle,\ + copy_mono, /* differs */\ + copy_color, /* differs */\ + gx_default_draw_line,\ + gx_default_get_bits,\ + gx_default_get_params,\ + gx_default_put_params,\ + map_cmyk_color, /* differs */\ + gx_forward_get_xfont_procs,\ + gx_forward_get_xfont_device,\ + gx_default_map_rgb_alpha_color,\ + gx_forward_get_page_device,\ + gx_default_get_alpha_bits, /* default is no alpha */\ + copy_alpha, /* differs */\ + gx_default_get_band,\ + gx_default_copy_rop,\ + gx_default_fill_path,\ + gx_default_stroke_path,\ + gx_default_fill_mask,\ + gx_default_fill_trapezoid,\ + gx_default_fill_parallelogram,\ + gx_default_fill_triangle,\ + gx_default_draw_thin_line,\ + gx_default_begin_image,\ + gx_default_image_data,\ + gx_default_end_image,\ + strip_tile_rectangle, /* differs */\ + strip_copy_rop, /* differs */\ + gx_default_get_clipping_box,\ + gx_default_begin_typed_image,\ + get_bits_rectangle, /* differs */\ + gx_default_map_color_rgb_alpha,\ + gx_default_create_compositor,\ + gx_default_get_hardware_params,\ + gx_default_text_begin\ + },\ + 0, /* target */\ + mem_device_init_private /* see gxdevmem.h */\ +} +#define mem_full_device(name, rgb_depth, gray_depth, open, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, map_cmyk_color, strip_tile_rectangle, strip_copy_rop, get_bits_rectangle)\ + mem_full_alpha_device(name, rgb_depth, gray_depth, open, map_rgb_color,\ + map_color_rgb, copy_mono, copy_color, fill_rectangle,\ + map_cmyk_color, gx_default_copy_alpha,\ + strip_tile_rectangle, strip_copy_rop,\ + get_bits_rectangle) +#define mem_device(name, rgb_depth, gray_depth, map_rgb_color, map_color_rgb, copy_mono, copy_color, fill_rectangle, strip_copy_rop)\ + mem_full_device(name, rgb_depth, gray_depth, mem_open, map_rgb_color,\ + map_color_rgb, copy_mono, copy_color, fill_rectangle,\ + gx_default_map_cmyk_color, gx_default_strip_tile_rectangle,\ + strip_copy_rop, mem_get_bits_rectangle) + +/* Swap a rectangle of bytes, for converting between word- and */ +/* byte-oriented representation. */ +void mem_swap_byte_rect(P6(byte *, uint, int, int, int, bool)); + +/* Copy a rectangle of bytes from a source to a destination. */ +#define mem_copy_byte_rect(mdev, base, sourcex, sraster, x, y, w, h)\ + bytes_copy_rectangle(scan_line_base(mdev, y) + x_to_byte(x),\ + (mdev)->raster,\ + base + x_to_byte(sourcex), sraster,\ + x_to_byte(w), h) + +/* ------ Implementations ------ */ + +extern const gx_device_memory mem_mono_device; +extern const gx_device_memory mem_mapped2_device; +extern const gx_device_memory mem_mapped4_device; +extern const gx_device_memory mem_mapped8_device; +extern const gx_device_memory mem_true16_device; +extern const gx_device_memory mem_true24_device; +extern const gx_device_memory mem_true32_device; +extern const gx_device_memory mem_planar_device; + +#if arch_is_big_endian +# define mem_mono_word_device mem_mono_device +# define mem_mapped2_word_device mem_mapped2_device +# define mem_mapped4_word_device mem_mapped4_device +# define mem_mapped8_word_device mem_mapped8_device +# define mem_true24_word_device mem_true24_device +# define mem_true32_word_device mem_true32_device +#else +extern const gx_device_memory mem_mono_word_device; +extern const gx_device_memory mem_mapped2_word_device; +extern const gx_device_memory mem_mapped4_word_device; +extern const gx_device_memory mem_mapped8_word_device; +extern const gx_device_memory mem_true24_word_device; +extern const gx_device_memory mem_true32_word_device; + +#endif +/* Provide standard palettes for 1-bit devices. */ +extern const gs_const_string mem_mono_b_w_palette; /* black=1, white=0 */ +extern const gs_const_string mem_mono_w_b_palette; /* black=0, white=1 */ + +#endif /* gdevmem_INCLUDED */ diff --git a/pstoraster/gdevmgr.h b/pstoraster/gdevmgr.h new file mode 100644 index 0000000000..0cab14414d --- /dev/null +++ b/pstoraster/gdevmgr.h @@ -0,0 +1,127 @@ +/* Copyright (C) 1992, 1993, 1994 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$*/ +/* Common header file for MGR devices */ + +#ifndef gdevmgr_INCLUDED +# define gdevmgr_INCLUDED + +#define MGR_RESERVEDCOLORS 16 + +/* Color mapping routines for 8-bit color (with a fixed palette). */ +dev_proc_map_rgb_color(mgr_8bit_map_rgb_color); +dev_proc_map_color_rgb(mgr_8bit_map_color_rgb); + + +/* extract from dump.h */ + +/* + * format for saved bitmaps + */ + +#define B_PUTHDR8(hdr, w, h, d) ( \ + (hdr)->magic[0] = 'y', (hdr)->magic[1] = 'z', \ + (hdr)->h_wide = (((w) >> 6) & 0x3f) + ' ', \ + (hdr)->l_wide = ((w) & 0x3f) + ' ', \ + (hdr)->h_high = (((h) >> 6) & 0x3f) + ' ', \ + (hdr)->l_high = ((h) & 0x3f) + ' ', \ + (hdr)->depth = ((d) & 0x3f) + ' ', \ + (hdr)->_reserved = ' ' ) + +struct b_header { + char magic[2]; /* magics */ + char h_wide; /* upper byte width (biased with 0x20) */ + char l_wide; /* lower byte width (biased with 0x20) */ + char h_high; /* upper byte height (biased with 0x20) */ + char l_high; /* lower byte height (biased with 0x20) */ + char depth; /* depth (biased with 0x20) */ + char _reserved; /* for alignment */ +}; + +/* + * Color lookup table information + */ +struct nclut { + unsigned short colnum; + unsigned short red, green, blue; +} ; + + +/* extract from color.h */ + +/* + * MGR Color Definitions + */ + +#define LUT_BW 0 +#define LUT_GREY 1 +#define LUT_BGREY 2 +#define LUT_VGA 3 +#define LUT_BCT 4 +#define LUT_USER 5 +#define LUT 6 +#define LUT_8 LUT + +#define RGB_RED 0 +#define RGB_GREEN 1 +#define RGB_BLUE 2 +#define RGB 3 + +#define LUTENTRIES 16 + +#define BW_RED 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0, 15, 0 +#define BW_GREEN BW_RED +#define BW_BLUE BW_RED + +#define GREY_RED 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 +#define GREY_GREEN GREY_RED +#define GREY_BLUE GREY_RED + +#define BGREY_RED 1, 0, 2, 8, 4, 3, 13, 11, 7, 6, 10, 12, 14, 5, 9, 15 +#define BGREY_GREEN BGREY_RED +#define BGREY_BLUE BGREY_RED + +#define VGA_RED 0, 0, 0, 0, 8, 8, 8, 12, 8, 0, 0, 0, 15, 15, 15, 15 +#define VGA_GREEN 0, 0, 8, 8, 0, 0, 8, 12, 8, 0, 15, 15, 0, 0, 15, 15 +#define VGA_BLUE 0, 8, 0, 8, 0, 8, 0, 12, 8, 15, 0, 15, 0, 15, 0, 15 + +#define BCT_RED 1, 7, 6, 15, 14, 3, 13, 11, 7, 13, 13, 15, 15, 5, 9, 15 +#define BCT_GREEN 1, 7, 13, 12, 5, 3, 13, 11, 7, 14, 15, 15, 14, 5, 9, 15 +#define BCT_BLUE 1, 14, 6, 8, 5, 3, 13, 11, 7, 15, 14, 12, 13, 5, 9, 15 + +#define USER_RED 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +#define USER_GREEN USER_RED +#define USER_BLUE USER_RED + +static char mgrlut[LUT][RGB][LUTENTRIES] = { + { { BW_RED }, { BW_GREEN }, { BW_BLUE } }, + { { GREY_RED }, { GREY_GREEN }, { GREY_BLUE } }, + { { BGREY_RED }, { BGREY_GREEN }, { BGREY_BLUE } }, + { { VGA_RED }, { VGA_GREEN }, { VGA_BLUE } }, + { { BCT_RED }, { BCT_GREEN }, { BCT_BLUE } }, + { { USER_RED }, { USER_GREEN }, { USER_BLUE } } +}; + +#endif /* gdevmgr_INCLUDED */ diff --git a/pstoraster/gdevmpla.c b/pstoraster/gdevmpla.c new file mode 100644 index 0000000000..239ffbcc8a --- /dev/null +++ b/pstoraster/gdevmpla.c @@ -0,0 +1,200 @@ +/* Copyright (C) 1993, 1994, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Any-depth planar "memory" (stored bitmap) devices */ +#include "memory_.h" +#include "gx.h" +#include "gxdevice.h" +#include "gxdevmem.h" /* semi-public definitions */ +#include "gdevmem.h" /* private definitions */ + +/* + * Planar memory devices store the bits by planes instead of by chunks. + * The plane corresponding to the least significant bit of the color index + * is stored first. + * + * The current implementations are quite inefficient. + * We may improve them someday if anyone cares. + */ + +/* Procedures */ +declare_mem_map_procs(mem_planar_map_rgb_color, mem_planar_map_color_rgb); +declare_mem_procs(mem_planar_copy_mono, mem_planar_copy_color, mem_planar_fill_rectangle); + +/* The device descriptor. */ +/* The instance is public. */ +/* The default instance has depth = 1, but clients may set this */ +/* to other values before opening the device. */ +private dev_proc_open_device(mem_planar_open); +private dev_proc_get_bits_rectangle(mem_planar_get_bits_rectangle); +const gx_device_memory mem_planar_device = +mem_full_device("image(planar)", 0, 1, mem_planar_open, + mem_planar_map_rgb_color, mem_planar_map_color_rgb, + mem_planar_copy_mono, mem_planar_copy_color, mem_planar_fill_rectangle, + gx_default_map_cmyk_color, gx_default_strip_tile_rectangle, + gx_no_strip_copy_rop, mem_planar_get_bits_rectangle); + +/* Open a planar memory device. */ +private int +mem_planar_open(gx_device * dev) +{ /* Temporarily reset the parameters, and call */ + /* the generic open procedure. */ + int depth = dev->color_info.depth; + int height = dev->height; + int code; + + dev->height *= depth; + dev->color_info.depth = 1; + code = mem_open(dev); + dev->height = height; + dev->color_info.depth = depth; + return code; +} + +/* Map a r-g-b color to a color index. */ +private gx_color_index +mem_planar_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g, + gx_color_value b) +{ + int depth = dev->color_info.depth; + + return (*dev_proc(gdev_mem_device_for_bits(depth), map_rgb_color)) + (dev, r, g, b); +} + +/* Map a color index to a r-g-b color. */ +private int +mem_planar_map_color_rgb(gx_device * dev, gx_color_index color, + gx_color_value prgb[3]) +{ + int depth = dev->color_info.depth; + + return (*dev_proc(gdev_mem_device_for_bits(depth), map_color_rgb)) + (dev, color, prgb); +} + +/* Fill a rectangle with a color. */ +private int +mem_planar_fill_rectangle(gx_device * dev, + int x, int y, int w, int h, gx_color_index color) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte **ptrs = mdev->line_ptrs; + int i; + + for (i = 0; i < dev->color_info.depth; + i++, mdev->line_ptrs += dev->height + ) + (*dev_proc(&mem_mono_device, fill_rectangle)) (dev, + x, y, w, h, (color >> i) & 1); + mdev->line_ptrs = ptrs; + return 0; +} + +/* Copy a bitmap. */ +private int +mem_planar_copy_mono(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h, gx_color_index zero, gx_color_index one) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte **ptrs = mdev->line_ptrs; + int i; + + for (i = 0; i < dev->color_info.depth; + i++, mdev->line_ptrs += dev->height + ) + (*dev_proc(&mem_mono_device, copy_mono)) (dev, + base, sourcex, sraster, id, x, y, w, h, + (zero == gx_no_color_index ? gx_no_color_index : + (zero >> i) & 1), + (one == gx_no_color_index ? gx_no_color_index : + (one >> i) & 1)); + mdev->line_ptrs = ptrs; + return 0; +} + +/* Copy a color bitmap. */ +/* This is very slow and messy. */ +private int +mem_planar_copy_color(gx_device * dev, + const byte * base, int sourcex, int sraster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + gx_device_memory * const mdev = (gx_device_memory *)dev; + byte **ptrs = mdev->line_ptrs; + int depth = dev->color_info.depth; + int wleft = w; + int hleft = h; + const byte *srow = base; + int ynext = y; + +#define max_w 32 + union _b { + long l[max_w / sizeof(long)]; + byte b[max_w / 8]; + } buf; + + while (wleft > max_w) { + mem_planar_copy_color(dev, base, + sourcex + wleft - max_w, sraster, gx_no_bitmap_id, + x + wleft - max_w, y, max_w, h); + wleft -= max_w; + } + for (; hleft > 0; + srow += sraster, ynext++, hleft--, + mdev->line_ptrs += dev->height + ) { + int i; + + for (i = 0; i < depth; + i++, mdev->line_ptrs += dev->height + ) { + int sx, bx; + + memset(buf.b, 0, sizeof(buf.b)); + for (sx = 0, bx = sourcex * depth + depth - 1 - i; + sx < w; sx++, bx += depth + ) + if (srow[bx >> 3] & (0x80 >> (bx & 7))) + buf.b[sx >> 3] |= 0x80 >> (sx & 7); + (*dev_proc(&mem_mono_device, copy_mono)) (dev, + buf.b, 0, sizeof(buf), gx_no_bitmap_id, + x, ynext, w, 1, + (gx_color_index) 0, (gx_color_index) 1); + } + mdev->line_ptrs = ptrs; + } + return 0; +} + +/* Copy bits back from a planar memory device. */ +/****** NOT IMPLEMENTED YET ******/ +private int +mem_planar_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, + gs_get_bits_params_t * params, gs_int_rect ** unread) +{ + return_error(-1); +} diff --git a/pstoraster/gdevmrop.h b/pstoraster/gdevmrop.h new file mode 100644 index 0000000000..3c143c9212 --- /dev/null +++ b/pstoraster/gdevmrop.h @@ -0,0 +1,97 @@ +/* Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Definitions for device RasterOp implementations. */ +/* Requires gxdevmem.h, gsropt.h */ + +#ifndef gdevmrop_INCLUDED +# define gdevmrop_INCLUDED + +/* Define the table of RasterOp implementation procedures. */ +extern const rop_proc rop_proc_table[256]; + +/* Define the table of RasterOp operand usage. */ +extern const byte /*rop_usage_t */ rop_usage_table[256]; + +/* + * Compute the effective RasterOp for the 1-bit case, + * taking transparency into account. + */ +gs_rop3_t gs_transparent_rop(P1(gs_logical_operation_t lop)); + +#ifdef DEBUG +/* Trace a [strip_]copy_rop call. */ +void trace_copy_rop(P16(const char *cname, gx_device * dev, + const byte * sdata, int sourcex, uint sraster, + gx_bitmap_id id, const gx_color_index * scolors, + const gx_strip_bitmap * textures, + const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop)); +#endif + +/* + * PostScript colors normally act as the texture for RasterOp, with a null + * (all zeros) source. For images with CombineWithColor = true, we need + * a way to use the image data as the source. We implement this with a + * device that applies RasterOp with a specified texture to drawing + * operations, treating the drawing color as source rather than texture. + * The texture is a gx_device_color; it may be any type of color, even a + * pattern. + */ +#ifndef gx_device_color_DEFINED +# define gx_device_color_DEFINED +typedef struct gx_device_color_s gx_device_color; + +#endif + +#ifndef gx_device_rop_texture_DEFINED +# define gx_device_rop_texture_DEFINED +typedef struct gx_device_rop_texture_s gx_device_rop_texture; + +#endif + +struct gx_device_rop_texture_s { + gx_device_forward_common; + gs_logical_operation_t log_op; + gx_device_color texture; +}; + +#define private_st_device_rop_texture() /* in gdevrops.c */\ + gs_private_st_composite(st_device_rop_texture, gx_device_rop_texture,\ + "gx_device_rop_texture", device_rop_texture_enum_ptrs, device_rop_texture_reloc_ptrs) + +/* Create a RasterOp source device. */ +int gx_alloc_rop_texture_device(P3(gx_device_rop_texture ** prsdev, + gs_memory_t * mem, + client_name_t cname)); + +/* Initialize a RasterOp source device. */ +void gx_make_rop_texture_device(P4(gx_device_rop_texture * rsdev, + gx_device * target, + gs_logical_operation_t lop, + const gx_device_color * texture)); + +#endif /* gdevmrop_INCLUDED */ diff --git a/pstoraster/gdevnfwd.c b/pstoraster/gdevnfwd.c new file mode 100644 index 0000000000..e8cbb0fd92 --- /dev/null +++ b/pstoraster/gdevnfwd.c @@ -0,0 +1,797 @@ +/* Copyright (C) 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Null and forwarding device implementation */ +#include "gx.h" +#include "gserrors.h" +#include "gxdevice.h" + +/* ---------------- Forwarding procedures ---------------- */ + +/* Fill in NULL procedures in a forwarding device procedure record. */ +/* We don't fill in: open_device, close_device, or the lowest-level */ +/* drawing operations. */ +void +gx_device_forward_fill_in_procs(register gx_device_forward * dev) +{ + gx_device_set_procs((gx_device *) dev); + /* NOT open_device */ + fill_dev_proc(dev, get_initial_matrix, gx_forward_get_initial_matrix); + fill_dev_proc(dev, sync_output, gx_forward_sync_output); + fill_dev_proc(dev, output_page, gx_forward_output_page); + /* NOT close_device */ + fill_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + fill_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + /* NOT fill_rectangle */ + /* NOT tile_rectangle */ + /* NOT copy_mono */ + /* NOT copy_color */ + /* NOT draw_line (OBSOLETE) */ + fill_dev_proc(dev, get_bits, gx_forward_get_bits); + fill_dev_proc(dev, get_params, gx_forward_get_params); + fill_dev_proc(dev, put_params, gx_forward_put_params); + fill_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); + fill_dev_proc(dev, get_xfont_procs, gx_forward_get_xfont_procs); + fill_dev_proc(dev, get_xfont_device, gx_forward_get_xfont_device); + fill_dev_proc(dev, map_rgb_alpha_color, gx_forward_map_rgb_alpha_color); + fill_dev_proc(dev, get_page_device, gx_forward_get_page_device); + fill_dev_proc(dev, get_alpha_bits, gx_forward_get_alpha_bits); + /* NOT copy_alpha */ + fill_dev_proc(dev, get_band, gx_forward_get_band); + fill_dev_proc(dev, copy_rop, gx_forward_copy_rop); + fill_dev_proc(dev, fill_path, gx_forward_fill_path); + fill_dev_proc(dev, stroke_path, gx_forward_stroke_path); + fill_dev_proc(dev, fill_mask, gx_forward_fill_mask); + fill_dev_proc(dev, fill_trapezoid, gx_forward_fill_trapezoid); + fill_dev_proc(dev, fill_parallelogram, gx_forward_fill_parallelogram); + fill_dev_proc(dev, fill_triangle, gx_forward_fill_triangle); + fill_dev_proc(dev, draw_thin_line, gx_forward_draw_thin_line); + fill_dev_proc(dev, begin_image, gx_forward_begin_image); + /* NOT image_data (OBSOLETE) */ + /* NOT end_image (OBSOLETE) */ + /* NOT strip_tile_rectangle */ + fill_dev_proc(dev, strip_copy_rop, gx_forward_strip_copy_rop); + fill_dev_proc(dev, get_clipping_box, gx_forward_get_clipping_box); + fill_dev_proc(dev, begin_typed_image, gx_forward_begin_typed_image); + fill_dev_proc(dev, get_bits_rectangle, gx_forward_get_bits_rectangle); + fill_dev_proc(dev, map_color_rgb_alpha, gx_forward_map_color_rgb_alpha); + fill_dev_proc(dev, create_compositor, gx_no_create_compositor); + fill_dev_proc(dev, get_hardware_params, gx_forward_get_hardware_params); + fill_dev_proc(dev, text_begin, gx_forward_text_begin); + gx_device_fill_in_procs((gx_device *) dev); +} + +/* Forward the color mapping procedures from a device to its target. */ +void +gx_device_forward_color_procs(gx_device_forward * dev) +{ + set_dev_proc(dev, map_rgb_color, gx_forward_map_rgb_color); + set_dev_proc(dev, map_color_rgb, gx_forward_map_color_rgb); + set_dev_proc(dev, map_cmyk_color, gx_forward_map_cmyk_color); + set_dev_proc(dev, map_rgb_alpha_color, gx_forward_map_rgb_alpha_color); + set_dev_proc(dev, map_color_rgb_alpha, gx_forward_map_color_rgb_alpha); +} + +void +gx_forward_get_initial_matrix(gx_device * dev, gs_matrix * pmat) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + if (tdev == 0) + gx_default_get_initial_matrix(dev, pmat); + else + (*dev_proc(tdev, get_initial_matrix)) (tdev, pmat); +} + +int +gx_forward_sync_output(gx_device * dev) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_sync_output(dev) : + (*dev_proc(tdev, sync_output)) (tdev)); +} + +int +gx_forward_output_page(gx_device * dev, int num_copies, int flush) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_output_page(dev, num_copies, flush) : + (*dev_proc(tdev, output_page)) (tdev, num_copies, flush)); +} + +gx_color_index +gx_forward_map_rgb_color(gx_device * dev, gx_color_value r, gx_color_value g, + gx_color_value b) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_map_rgb_color(dev, r, g, b) : + (*dev_proc(tdev, map_rgb_color)) (tdev, r, g, b)); +} + +int +gx_forward_map_color_rgb(gx_device * dev, gx_color_index color, + gx_color_value prgb[3]) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_map_color_rgb(dev, color, prgb) : + (*dev_proc(tdev, map_color_rgb)) (tdev, color, prgb)); +} + +int +gx_forward_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + if (tdev == 0) + return_error(gs_error_Fatal); + return (*dev_proc(tdev, fill_rectangle)) (tdev, x, y, w, h, color); +} + +int +gx_forward_tile_rectangle(gx_device * dev, const gx_tile_bitmap * tile, + int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, + int px, int py) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_tile_rectangle((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_tile_rectangle; + else + proc = dev_proc(tdev, tile_rectangle); + return (*proc) (tdev, tile, x, y, w, h, color0, color1, px, py); +} + +int +gx_forward_copy_mono(gx_device * dev, const byte * data, + int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index zero, gx_color_index one) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + if (tdev == 0) + return_error(gs_error_Fatal); + return (*dev_proc(tdev, copy_mono)) + (tdev, data, dx, raster, id, x, y, w, h, zero, one); +} + +int +gx_forward_copy_color(gx_device * dev, const byte * data, + int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + if (tdev == 0) + return_error(gs_error_Fatal); + return (*dev_proc(tdev, copy_color)) + (tdev, data, dx, raster, id, x, y, w, h); +} + +int +gx_forward_get_bits(gx_device * dev, int y, byte * data, byte ** actual_data) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_get_bits(dev, y, data, actual_data) : + (*dev_proc(tdev, get_bits)) (tdev, y, data, actual_data)); +} + +int +gx_forward_get_params(gx_device * dev, gs_param_list * plist) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_get_params(dev, plist) : + (*dev_proc(tdev, get_params)) (tdev, plist)); +} + +int +gx_forward_put_params(gx_device * dev, gs_param_list * plist) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_put_params(dev, plist) : + (*dev_proc(tdev, put_params)) (tdev, plist)); +} + +gx_color_index +gx_forward_map_cmyk_color(gx_device * dev, gx_color_value c, gx_color_value m, + gx_color_value y, gx_color_value k) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_map_cmyk_color(dev, c, m, y, k) : + (*dev_proc(tdev, map_cmyk_color)) (tdev, c, m, y, k)); +} + +const gx_xfont_procs * +gx_forward_get_xfont_procs(gx_device * dev) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_get_xfont_procs(dev) : + (*dev_proc(tdev, get_xfont_procs)) (tdev)); +} + +gx_device * +gx_forward_get_xfont_device(gx_device * dev) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_get_xfont_device(dev) : + (*dev_proc(tdev, get_xfont_device)) (tdev)); +} + +gx_color_index +gx_forward_map_rgb_alpha_color(gx_device * dev, gx_color_value r, + gx_color_value g, gx_color_value b, gx_color_value alpha) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? + gx_default_map_rgb_alpha_color(dev, r, g, b, alpha) : + (*dev_proc(tdev, map_rgb_alpha_color)) (tdev, r, g, b, alpha)); +} + +gx_device * +gx_forward_get_page_device(gx_device * dev) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + gx_device *pdev; + + if (tdev == 0) + return gx_default_get_page_device(dev); + pdev = (*dev_proc(tdev, get_page_device)) (tdev); + return (pdev == tdev ? dev : pdev); +} + +int +gx_forward_get_alpha_bits(gx_device * dev, graphics_object_type type) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? + gx_default_get_alpha_bits(dev, type) : + (*dev_proc(tdev, get_alpha_bits)) (tdev, type)); +} + +int +gx_forward_get_band(gx_device * dev, int y, int *band_start) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? + gx_default_get_band(dev, y, band_start) : + (*dev_proc(tdev, get_band)) (tdev, y, band_start)); +} + +int +gx_forward_copy_rop(gx_device * dev, + const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index * scolors, + const gx_tile_bitmap * texture, const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_copy_rop((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_copy_rop; + else + proc = dev_proc(tdev, copy_rop); + return (*proc) (tdev, sdata, sourcex, sraster, id, scolors, + texture, tcolors, x, y, width, height, + phase_x, phase_y, lop); +} + +int +gx_forward_fill_path(gx_device * dev, const gs_imager_state * pis, + gx_path * ppath, const gx_fill_params * params, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_fill_path((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_fill_path; + else + proc = dev_proc(tdev, fill_path); + return (*proc) (tdev, pis, ppath, params, pdcolor, pcpath); +} + +int +gx_forward_stroke_path(gx_device * dev, const gs_imager_state * pis, + gx_path * ppath, const gx_stroke_params * params, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_stroke_path((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_stroke_path; + else + proc = dev_proc(tdev, stroke_path); + return (*proc) (tdev, pis, ppath, params, pdcolor, pcpath); +} + +int +gx_forward_fill_mask(gx_device * dev, + const byte * data, int dx, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + const gx_drawing_color * pdcolor, int depth, + gs_logical_operation_t lop, const gx_clip_path * pcpath) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_fill_mask((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_fill_mask; + else + proc = dev_proc(tdev, fill_mask); + return (*proc) (tdev, data, dx, raster, id, x, y, w, h, pdcolor, depth, + lop, pcpath); +} + +int +gx_forward_fill_trapezoid(gx_device * dev, + const gs_fixed_edge * left, const gs_fixed_edge * right, + fixed ybot, fixed ytop, bool swap_axes, + const gx_drawing_color * pdcolor, gs_logical_operation_t lop) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_fill_trapezoid((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_fill_trapezoid; + else + proc = dev_proc(tdev, fill_trapezoid); + return (*proc) (tdev, left, right, ybot, ytop, swap_axes, pdcolor, lop); +} + +int +gx_forward_fill_parallelogram(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color * pdcolor, gs_logical_operation_t lop) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_fill_parallelogram((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_fill_parallelogram; + else + proc = dev_proc(tdev, fill_parallelogram); + return (*proc) (tdev, px, py, ax, ay, bx, by, pdcolor, lop); +} + +int +gx_forward_fill_triangle(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color * pdcolor, gs_logical_operation_t lop) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_fill_triangle((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_fill_triangle; + else + proc = dev_proc(tdev, fill_triangle); + return (*proc) (tdev, px, py, ax, ay, bx, by, pdcolor, lop); +} + +int +gx_forward_draw_thin_line(gx_device * dev, + fixed fx0, fixed fy0, fixed fx1, fixed fy1, + const gx_drawing_color * pdcolor, gs_logical_operation_t lop) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_draw_thin_line((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_draw_thin_line; + else + proc = dev_proc(tdev, draw_thin_line); + return (*proc) (tdev, fx0, fy0, fx1, fy1, pdcolor, lop); +} + +int +gx_forward_begin_image(gx_device * dev, + const gs_imager_state * pis, const gs_image_t * pim, + gs_image_format_t format, const gs_int_rect * prect, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * memory, gx_image_enum_common_t ** pinfo) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_begin_image((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_begin_image; + else + proc = dev_proc(tdev, begin_image); + return (*proc) (tdev, pis, pim, format, prect, pdcolor, pcpath, + memory, pinfo); +} + +int +gx_forward_strip_tile_rectangle(gx_device * dev, const gx_strip_bitmap * tiles, + int x, int y, int w, int h, gx_color_index color0, gx_color_index color1, + int px, int py) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_strip_tile_rectangle((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_strip_tile_rectangle; + else + proc = dev_proc(tdev, strip_tile_rectangle); + return (*proc) (tdev, tiles, x, y, w, h, color0, color1, px, py); +} + +int +gx_forward_strip_copy_rop(gx_device * dev, + const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index * scolors, + const gx_strip_bitmap * textures, const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_strip_copy_rop((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_strip_copy_rop; + else + proc = dev_proc(tdev, strip_copy_rop); + return (*proc) (tdev, sdata, sourcex, sraster, id, scolors, + textures, tcolors, x, y, width, height, + phase_x, phase_y, lop); +} + +void +gx_forward_get_clipping_box(gx_device * dev, gs_fixed_rect * pbox) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + if (tdev == 0) + gx_default_get_clipping_box(dev, pbox); + else + (*dev_proc(tdev, get_clipping_box)) (tdev, pbox); +} + +int +gx_forward_begin_typed_image(gx_device * dev, + const gs_imager_state * pis, const gs_matrix * pmat, + const gs_image_common_t * pim, const gs_int_rect * prect, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * memory, gx_image_enum_common_t ** pinfo) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_begin_typed_image((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_begin_typed_image; + else + proc = dev_proc(tdev, begin_typed_image); + return (*proc) (tdev, pis, pmat, pim, prect, pdcolor, pcpath, + memory, pinfo); +} + +int +gx_forward_get_bits_rectangle(gx_device * dev, const gs_int_rect * prect, + gs_get_bits_params_t * params, gs_int_rect ** unread) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_get_bits_rectangle((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_get_bits_rectangle; + else + proc = dev_proc(tdev, get_bits_rectangle); + return (*proc) (tdev, prect, params, unread); +} + +int +gx_forward_map_color_rgb_alpha(gx_device * dev, gx_color_index color, + gx_color_value prgba[4]) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_map_color_rgb_alpha(dev, color, prgba) : + (*dev_proc(tdev, map_color_rgb_alpha)) (tdev, color, prgba)); +} + +int +gx_forward_get_hardware_params(gx_device * dev, gs_param_list * plist) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + return (tdev == 0 ? gx_default_get_hardware_params(dev, plist) : + (*dev_proc(tdev, get_hardware_params)) (tdev, plist)); +} + +int +gx_forward_text_begin(gx_device * dev, gs_imager_state * pis, + const gs_text_params_t * text, const gs_font * font, +gx_path * path, const gx_device_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * memory, gs_text_enum_t ** ppenum) +{ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + + dev_proc_text_begin((*proc)); + + if (tdev == 0) + tdev = dev, proc = gx_default_text_begin; + else + proc = dev_proc(tdev, text_begin); + return (*proc) (tdev, pis, text, font, path, pdcolor, pcpath, + memory, ppenum); +} + +/* ---------------- The null device(s) ---------------- */ + +private dev_proc_fill_rectangle(null_fill_rectangle); +private dev_proc_copy_mono(null_copy_mono); +private dev_proc_copy_color(null_copy_color); +private dev_proc_put_params(null_put_params); +private dev_proc_copy_alpha(null_copy_alpha); +private dev_proc_copy_rop(null_copy_rop); +private dev_proc_fill_path(null_fill_path); +private dev_proc_stroke_path(null_stroke_path); +private dev_proc_fill_trapezoid(null_fill_trapezoid); +private dev_proc_fill_parallelogram(null_fill_parallelogram); +private dev_proc_fill_triangle(null_fill_triangle); +private dev_proc_draw_thin_line(null_draw_thin_line); + +/* We would like to have null implementations of begin/data/end image, */ +/* but we can't do this, because image_data must keep track of the */ +/* Y position so it can return 1 when done. */ +private dev_proc_strip_copy_rop(null_strip_copy_rop); + +#define null_procs(get_page_device) {\ + gx_default_open_device,\ + gx_forward_get_initial_matrix,\ + gx_default_sync_output,\ + gx_default_output_page,\ + gx_default_close_device,\ + gx_forward_map_rgb_color,\ + gx_forward_map_color_rgb,\ + null_fill_rectangle,\ + gx_default_tile_rectangle,\ + null_copy_mono,\ + null_copy_color,\ + gx_default_draw_line,\ + gx_default_get_bits,\ + gx_forward_get_params,\ + null_put_params,\ + gx_forward_map_cmyk_color,\ + gx_forward_get_xfont_procs,\ + gx_forward_get_xfont_device,\ + gx_forward_map_rgb_alpha_color,\ + get_page_device, /* differs */\ + gx_forward_get_alpha_bits,\ + null_copy_alpha,\ + gx_forward_get_band,\ + null_copy_rop,\ + null_fill_path,\ + null_stroke_path,\ + gx_default_fill_mask,\ + null_fill_trapezoid,\ + null_fill_parallelogram,\ + null_fill_triangle,\ + null_draw_thin_line,\ + gx_default_begin_image,\ + gx_default_image_data,\ + gx_default_end_image,\ + gx_default_strip_tile_rectangle,\ + null_strip_copy_rop,\ + gx_default_get_clipping_box,\ + gx_default_begin_typed_image,\ + gx_default_get_bits_rectangle,\ + gx_forward_map_color_rgb_alpha,\ + gx_non_imaging_create_compositor,\ + gx_forward_get_hardware_params,\ + gx_default_text_begin\ +} + +const gx_device_null gs_null_device = +{ + std_device_std_body_type_open(gx_device_null, 0, "null", &st_device_null, + 0, 0, 72, 72), + null_procs(gx_default_get_page_device /* not a page device */ ), + 0 /* target */ +}; + +const gx_device_null gs_nullpage_device = +{ +std_device_std_body_type_open(gx_device_null, 0, "nullpage", &st_device_null, + 72 /*nominal */ , 72 /*nominal */ , 72, 72), + null_procs(gx_page_device_get_page_device /* a page device */ ), + 0 /* target */ +}; + +private int +null_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + return 0; +} +private int +null_copy_mono(gx_device * dev, const byte * data, + int dx, int raster, gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index zero, gx_color_index one) +{ + return 0; +} +private int +null_copy_color(gx_device * dev, const byte * data, + int data_x, int raster, gx_bitmap_id id, + int x, int y, int width, int height) +{ + return 0; +} +private int +null_put_params(gx_device * dev, gs_param_list * plist) +{ + /* + * If this is not a page device, we must defeat attempts to reset + * the size; otherwise this is equivalent to gx_forward_put_params. + */ + gx_device_forward * const fdev = (gx_device_forward *)dev; + gx_device *tdev = fdev->target; + int code; + + if (tdev != 0) + return (*dev_proc(tdev, put_params)) (tdev, plist); + code = gx_default_put_params(dev, plist); + if (code < 0 || (*dev_proc(dev, get_page_device)) (dev) == dev) + return code; + dev->width = dev->height = 0; + return code; +} +private int +null_copy_alpha(gx_device * dev, const byte * data, int data_x, + int raster, gx_bitmap_id id, int x, int y, int width, int height, + gx_color_index color, int depth) +{ + return 0; +} +private int +null_copy_rop(gx_device * dev, + const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index * scolors, + const gx_tile_bitmap * texture, const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + return 0; +} +private int +null_fill_path(gx_device * dev, const gs_imager_state * pis, + gx_path * ppath, const gx_fill_params * params, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) +{ + return 0; +} +private int +null_stroke_path(gx_device * dev, const gs_imager_state * pis, + gx_path * ppath, const gx_stroke_params * params, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) +{ + return 0; +} +private int +null_fill_trapezoid(gx_device * dev, + const gs_fixed_edge * left, const gs_fixed_edge * right, + fixed ybot, fixed ytop, bool swap_axes, + const gx_drawing_color * pdcolor, gs_logical_operation_t lop) +{ + return 0; +} +private int +null_fill_parallelogram(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color * pdcolor, gs_logical_operation_t lop) +{ + return 0; +} +private int +null_fill_triangle(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_drawing_color * pdcolor, gs_logical_operation_t lop) +{ + return 0; +} +private int +null_draw_thin_line(gx_device * dev, + fixed fx0, fixed fy0, fixed fx1, fixed fy1, + const gx_drawing_color * pdcolor, gs_logical_operation_t lop) +{ + return 0; +} +private int +null_strip_copy_rop(gx_device * dev, + const byte * sdata, int sourcex, uint sraster, gx_bitmap_id id, + const gx_color_index * scolors, + const gx_strip_bitmap * textures, const gx_color_index * tcolors, + int x, int y, int width, int height, + int phase_x, int phase_y, gs_logical_operation_t lop) +{ + return 0; +} diff --git a/pstoraster/gdevpccm.h b/pstoraster/gdevpccm.h new file mode 100644 index 0000000000..1322594d24 --- /dev/null +++ b/pstoraster/gdevpccm.h @@ -0,0 +1,44 @@ +/* Copyright (C) 1992 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Requires gxdevice.h */ + +#ifndef gdevpccm_INCLUDED +# define gdevpccm_INCLUDED + +/* Color mapping routines for EGA/VGA-style color. */ +dev_proc_map_rgb_color(pc_4bit_map_rgb_color); +dev_proc_map_color_rgb(pc_4bit_map_color_rgb); +#define dci_pc_4bit { 3, 4, 3, 2, 4, 3 } + +/* Color mapping routines for 8-bit color (with a fixed palette). */ +dev_proc_map_rgb_color(pc_8bit_map_rgb_color); +dev_proc_map_color_rgb(pc_8bit_map_color_rgb); +#define dci_pc_8bit { 3, 8, 6, 6, 7, 7 } + +/* Write the palette on a file. */ +int pc_write_palette(P3(gx_device *, uint, FILE *)); + +#endif /* gdevpccm_INCLUDED */ diff --git a/pstoraster/gdevpcfb.h b/pstoraster/gdevpcfb.h new file mode 100644 index 0000000000..21bde1bb9a --- /dev/null +++ b/pstoraster/gdevpcfb.h @@ -0,0 +1,209 @@ +/* Copyright (C) 1989, 1995 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* IBM PC frame buffer definitions */ + +#ifndef gdevpcfb_INCLUDED +# define gdevpcfb_INCLUDED + +#ifdef __MSDOS__ +# include "dos_.h" +typedef union REGS registers; + +#endif + +/* For testing, the 16-color display may be defined as a monochrome, */ +/* 8-color, or 16-color device. */ +#define ega_bits_of_color 2 /* 0, 1, or 2 */ +#define rgb_max ega_bits_of_color + +/* Define the short (integer) version of "transparent" color. */ +/* ****** Depends on gx_no_color_index being all 1's. ***** */ +#define no_color ((int)gx_no_color_index) + +/* Procedures */ + + /* See gxdevice.h for the definitions of the procedures. */ + +dev_proc_open_device(ega_open); +dev_proc_close_device(ega_close); +dev_proc_fill_rectangle(ega_fill_rectangle); +dev_proc_tile_rectangle(ega_tile_rectangle); +dev_proc_copy_mono(ega_copy_mono); +dev_proc_copy_color(ega_copy_color); +dev_proc_get_bits(ega_get_bits); + +/* Structure for saving state of BIOS variables. */ +typedef struct pcfb_bios_state_s { + int display_mode; /* must be first, see pcfb_save_state */ + /* in gdevpcfb.c */ + byte text_page; + uint text_cursor_mode; + uint text_font; + byte text_attribute; + byte border_color; +} pcfb_bios_state; + +/* Procedures used by gdevpcfb.c */ +void pcfb_set_signals(P1(gx_device *)); +void pcfb_get_state(P1(pcfb_bios_state *)); +void pcfb_set_mode(P1(int)); +void pcfb_set_state(P1(const pcfb_bios_state *)); + +/* Types for frame buffer pointers. */ +typedef byte *fb_ptr; +typedef volatile byte *volatile_fb_ptr; + +/* Define the nominal page height in inches. */ +#ifdef A4 +# define PAGE_HEIGHT_INCHES 11.69 +#else +# define PAGE_HEIGHT_INCHES 11.0 +#endif + +/* The device descriptor */ +typedef struct gx_device_ega_s gx_device_ega; +struct gx_device_ega_s { + gx_device_common; + int raster; /* frame buffer bytes per line */ + int fb_seg_mult; /* multiplier for segment part */ + /* of frame buffer pointer */ + int fb_byte_mult; /* multiplier for word part ditto */ +#define mk_fb_ptr(x, y)\ + (fb_dev->fb_byte_mult == 0 ?\ + (fb_ptr)MK_PTR(regen + (y) * (fb_dev->fb_seg_mult), (x) >> 3) :\ + (fb_ptr)MK_PTR(regen + ((y) >> 4) * (fb_dev->fb_seg_mult),\ + (((y) & 15) * fb_dev->fb_byte_mult) + ((x) >> 3))) + int video_mode; +}; + +/* Macro for creating instances */ +/* The initial parameters map an appropriate fraction of */ +/* the screen to a full-page coordinate space. */ +/* This may or may not be what is desired! */ +#define ega_device(dev_name, procs, fb_raster, screen_height, aspect_ratio, video_mode)\ + { std_device_dci_body(gx_device_ega, &procs, dev_name,\ + fb_raster * 8, screen_height,\ + (screen_height * (aspect_ratio)) / PAGE_HEIGHT_INCHES, /* x dpi */\ + screen_height / PAGE_HEIGHT_INCHES, /* y dpi */\ + (rgb_max ? 3 : 1), /* num_components */\ + 4, /* depth */\ + (rgb_max ? rgb_max : 1), /* max_gray */\ + rgb_max,\ + (rgb_max ? rgb_max + 1 : 2), /* dither_grays */\ + (rgb_max ? rgb_max + 1 : 0) /* dither_colors */\ + ),\ + { 0 }, /* std_procs */\ + fb_raster,\ + (fb_raster & 15 ? fb_raster : fb_raster >> 4),\ + (fb_raster & 15 ? fb_raster : 0),\ + video_mode\ + } + +/* Define the device port and register numbers, and the regen map base */ +#define seq_addr 0x3c4 +#define s_map 2 +#define set_s_map(mask) outport2(seq_addr, s_map, mask) +#define graph_addr 0x3ce +#define g_const 0 /* set/reset */ +#define set_g_const(color) outport2(graph_addr, g_const, color) +#define g_const_map 1 /* enable set/reset */ +#define set_g_const_map(map) outport2(graph_addr, g_const_map, map) +#define g_function 3 +# define gf_WRITE 0 +# define gf_AND 8 +# define gf_OR 0x10 +# define gf_XOR 0x18 +#define set_g_function(func) outport2(graph_addr, g_function, func) +#define g_read_plane 4 +#define set_g_read_plane(plane) outport2(graph_addr, g_read_plane, plane) +#define g_mode 5 +# define gm_DATA 0 +# define gm_FILL 2 +#define set_g_mode(mode) outport2(graph_addr, g_mode, mode) +#define g_mask 8 +#define set_g_mask(mask) outport2(graph_addr, g_mask, mask) +#define select_g_mask() outportb(graph_addr, g_mask) +#define out_g_mask(mask) outportb(graph_addr+1, mask) +#define regen 0xa000 + +/* Define access to the frame buffer and the video registers */ +/* according to whether we are on a DOS system or a Unix system. */ + +#if defined(M_UNIX) || defined(M_XENIX) || defined(UNIX) || defined(SYSV) || defined(__linux__) + + /* SCO Unix/Xenix, AT&T SVR4, or Linux. */ + +#undef outportb + +#if defined(__GNUC__) + /* Inline assembly version for gcc */ + /* Under SCO, requires installing the gnu assembler as "as" */ +static inline void +outportb(int port, int data) +{ + __asm__ volatile ("outb %0,%1":: + "a" ((unsigned char)data), + "d" ((unsigned short)port)); +} +static inline void +outport2(int port, int index, int data) +{ + __asm__ volatile ("movb %0,%%ah; movb %1,%%al; outw %%ax,%2":: + "qmi" ((unsigned char)data), + "qmi" ((unsigned char)index), + "d" ((unsigned short)port): + "eax"); +} +#else +void outportb(P2(uint, byte)); +void outport2(P3(uint, byte, byte)); + +#endif + +/* Redefine mk_fb_ptr -- no segmented addressing. */ + +#undef mk_fb_ptr +extern fb_ptr fb_addr; + +#define mk_fb_ptr(x, y) (fb_addr + (y) * (fb_dev->raster) + ((x) >> 3)) + +#else + + /* MS-DOS */ + +/* outportb is defined in dos_.h */ +#define outport2(port, index, data)\ + (outportb(port, index), outportb((port)+1, data)) + +#endif + +/* Fetch and discard a byte. Prevent the compiler from */ +/* optimizing this away. */ +static unsigned char byte_discard_; + +#define byte_discard(expr) byte_discard_ = (expr) + +#endif /* gdevpcfb_INCLUDED */ diff --git a/pstoraster/gdevpcl.h b/pstoraster/gdevpcl.h new file mode 100644 index 0000000000..b6954f159a --- /dev/null +++ b/pstoraster/gdevpcl.h @@ -0,0 +1,52 @@ +/* Copyright (C) 1992, 1994 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Requires gdevprn.h */ + +#ifndef gdevpcl_INCLUDED +# define gdevpcl_INCLUDED + +/* Define the PCL paper size codes. */ +#define PAPER_SIZE_LETTER 2 +#define PAPER_SIZE_LEGAL 3 +#define PAPER_SIZE_A4 26 +#define PAPER_SIZE_A3 27 +#define PAPER_SIZE_A2 28 +#define PAPER_SIZE_A1 29 +#define PAPER_SIZE_A0 30 + +/* Get the paper size code, based on width and height. */ +int gdev_pcl_paper_size(P1(gx_device *)); + +/* Color mapping procedures for 3-bit-per-pixel RGB printers */ +dev_proc_map_rgb_color(gdev_pcl_3bit_map_rgb_color); +dev_proc_map_color_rgb(gdev_pcl_3bit_map_color_rgb); + +/* Row compression routines */ +typedef ulong word; +int gdev_pcl_mode2compress(P3(const word * row, const word * end_row, byte * compressed)), + gdev_pcl_mode3compress(P4(int bytecount, const byte * current, byte * previous, byte * compressed)); + +#endif /* gdevpcl_INCLUDED */ diff --git a/pstoraster/gdevpipe.c b/pstoraster/gdevpipe.c new file mode 100644 index 0000000000..03909db6a7 --- /dev/null +++ b/pstoraster/gdevpipe.c @@ -0,0 +1,72 @@ +/* Copyright (C) 1993, 1994, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* %pipe% IODevice */ +#include "errno_.h" +#include "pipe_.h" +#include "stdio_.h" +#include "string_.h" +#include "gserror.h" +#include "gstypes.h" +#include "gsmemory.h" /* for gxiodev.h */ +#include "stream.h" +#include "gxiodev.h" + +/* The pipe IODevice */ +private iodev_proc_fopen(pipe_fopen); +private iodev_proc_fclose(pipe_fclose); +const gx_io_device gs_iodev_pipe = +{ + "%pipe%", "FileSystem", + {iodev_no_init, iodev_no_open_device, + NULL /*iodev_os_open_file */ , pipe_fopen, pipe_fclose, + iodev_no_delete_file, iodev_no_rename_file, iodev_no_file_status, + iodev_no_enumerate_files, NULL, NULL, + iodev_no_get_params, iodev_no_put_params + } +}; + +/* The file device procedures */ + +private int +pipe_fopen(gx_io_device * iodev, const char *fname, const char *access, + FILE ** pfile, char *rfname, uint rnamelen) +{ /* The OSF/1 1.3 library doesn't include const in the */ + /* prototype for popen.... */ + errno = 0; + *pfile = popen((char *)fname, (char *)access); + if (*pfile == NULL) + return_error(gs_fopen_errno_to_code(errno)); + if (rfname != NULL) + strcpy(rfname, fname); + return 0; +} + +private int +pipe_fclose(gx_io_device * iodev, FILE * file) +{ + pclose(file); + return 0; +} diff --git a/pstoraster/gdevpm.h b/pstoraster/gdevpm.h new file mode 100644 index 0000000000..f1f7b3cd88 --- /dev/null +++ b/pstoraster/gdevpm.h @@ -0,0 +1,46 @@ +/* Copyright (C) 1992, 1993 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Defines common to gdevpm.c, gspmdrv.c and PM GSview */ + +#ifndef gdevpm_INCLUDED +# define gdevpm_INCLUDED + +#define SHARED_NAME "\\SHAREMEM\\%s" +#define SYNC_NAME "\\SEM32\\SYNC_%s" +#define NEXT_NAME "\\SEM32\\NEXT_%s" +#define MUTEX_NAME "\\SEM32\\MUTEX_%s" +#define QUEUE_NAME "\\QUEUES\\%s" + +#define GS_UPDATING 1 +#define GS_SYNC 2 +#define GS_PAGE 3 +#define GS_CLOSE 4 +#define GS_ERROR 5 +#define GS_PALCHANGE 6 +#define GS_BEGIN 7 +#define GS_END 8 + +#endif /* gdevpm_INCLUDED */ diff --git a/pstoraster/gdevprn.c b/pstoraster/gdevprn.c new file mode 100644 index 0000000000..c5a57657ef --- /dev/null +++ b/pstoraster/gdevprn.c @@ -0,0 +1,837 @@ +/* + Copyright 1993-2000 by Easy Software Products. + Copyright 1990, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Generic printer driver support */ +#include "ctype_.h" +#include "gdevprn.h" +#include "gp.h" +#include "gsparam.h" +#include "gxclio.h" +#include + +/* ---------------- Standard device procedures ---------------- */ + +/* Define the standard printer procedure vector. */ +const gx_device_procs prn_std_procs = + prn_procs(gdev_prn_open, gdev_prn_output_page, gdev_prn_close); + +/* Forward references */ +int gdev_prn_maybe_reallocate_memory(P4(gx_device_printer *pdev, + gdev_prn_space_params *old_space, + int old_width, int old_height)); + +/* ------ Open/close ------ */ + +/* Open a generic printer device. */ +/* Specific devices may wish to extend this. */ +int +gdev_prn_open(gx_device * pdev) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + int code; + + ppdev->file = NULL; + code = gdev_prn_allocate_memory(pdev, NULL, 0, 0); + if (code < 0) + return code; + if (ppdev->OpenOutputFile) + code = gdev_prn_open_printer(pdev, 1); + return code; +} + +/* Generic closing for the printer device. */ +/* Specific devices may wish to extend this. */ +int +gdev_prn_close(gx_device * pdev) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + + gdev_prn_free_memory(pdev); + if (ppdev->file != NULL) { + if (ppdev->file != stdout) + gp_close_printer(ppdev->file, ppdev->fname); + ppdev->file = NULL; + } + return 0; +} + +private int /* returns 0 ok, else -ve error cde */ +gdev_prn_setup_as_command_list(gx_device *pdev, gs_memory_t *buffer_memory, + byte **the_memory, + const gdev_prn_space_params *space_params, + bool bufferSpace_is_exact) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + uint space; + int code; + gx_device_clist *const pclist_dev = (gx_device_clist *)pdev; + gx_device_clist_common * const pcldev = &pclist_dev->common; + bool reallocate = *the_memory != 0; + byte *base; + + /* Try to allocate based simply on param-requested buffer size */ + for ( space = space_params->BufferSpace; ; ) { + base = (reallocate ? + gs_resize_object(buffer_memory, *the_memory, space, + "cmd list buffer") : + gs_alloc_bytes(buffer_memory, space, + "cmd list buffer")); + if (base != 0) + break; + if (bufferSpace_is_exact || (space >>= 1) < PRN_MIN_BUFFER_SPACE) + break; + } + if (base == 0) + return_error(gs_error_VMerror); + *the_memory = base; + + /* Try opening the command list, to see if we allocated */ + /* enough buffer space. */ +open_c: + ppdev->buf = base; + ppdev->buffer_space = space; + clist_init_params(pclist_dev, base, space, pdev, + ppdev->printer_procs.make_buffer_device, + space_params->band, ppdev->is_async_renderer, + (ppdev->bandlist_memory == 0 ? &gs_memory_default : + ppdev->bandlist_memory), + ppdev->free_up_bandlist_memory, + ppdev->clist_disable_mask); + code = (*gs_clist_device_procs.open_device)( (gx_device *)pcldev ); + if (code < 0) { + /* If there wasn't enough room, and we haven't */ + /* already shrunk the buffer, try enlarging it. */ + if ( code == gs_error_limitcheck && + space >= space_params->BufferSpace && + !bufferSpace_is_exact + ) { + space <<= 1; + if (reallocate) { + base = gs_resize_object(buffer_memory, + *the_memory, space, + "cmd list buf(retry open)"); + if (base != 0) + *the_memory = base; + } else { + gs_free_object(buffer_memory, base, + "cmd list buf(retry open)"); + *the_memory = base = + gs_alloc_bytes(buffer_memory, space, + "cmd list buf(retry open)"); + } + ppdev->buf = *the_memory; + if (base != 0) + goto open_c; + } + /* Failure. */ + if (!reallocate) { + gs_free_object(buffer_memory, base, "cmd list buf"); + ppdev->buffer_space = 0; + *the_memory = 0; + } + } + return code; +} + +private bool /* ret true if device was cmd list, else false */ +gdev_prn_tear_down(gx_device *pdev, byte **the_memory) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + gx_device_memory * const pmemdev = (gx_device_memory *)pdev; + gx_device_clist *const pclist_dev = (gx_device_clist *)pdev; + gx_device_clist_common * const pcldev = &pclist_dev->common; + bool is_command_list; + + if (ppdev->buffer_space != 0) { + /* Close cmd list device & point to the storage */ + (*gs_clist_device_procs.close_device)( (gx_device *)pcldev ); + *the_memory = ppdev->buf; + ppdev->buf = 0; + ppdev->buffer_space = 0; + is_command_list = true; + } else { + /* point at the device bitmap, no need to close mem dev */ + *the_memory = pmemdev->base; + pmemdev->base = 0; + is_command_list = false; + } + + /* Reset device proc vector to default */ + if (ppdev->orig_procs.open_device != 0) + pdev->procs = ppdev->orig_procs; + ppdev->orig_procs.open_device = 0; /* prevent uninit'd restore of procs */ + + return is_command_list; +} + +private int +gdev_prn_allocate(gx_device *pdev, gdev_prn_space_params *new_space_params, + int new_width, int new_height, bool reallocate) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + gx_device_memory * const pmemdev = (gx_device_memory *)pdev; + byte *the_memory = 0; + gdev_prn_space_params save_params; + int save_width, save_height; + bool is_command_list; + bool save_is_command_list; + int ecode = 0; + int pass; + gs_memory_t *buffer_memory = + (ppdev->buffer_memory == 0 ? &gs_memory_default : + ppdev->buffer_memory); + + /* If reallocate, find allocated memory & tear down buffer device */ + if (reallocate) + save_is_command_list = gdev_prn_tear_down(pdev, &the_memory); + + /* Re/allocate memory */ + ppdev->orig_procs = pdev->procs; + for ( pass = 1; pass <= (reallocate ? 2 : 1); ++pass ) { + ulong mem_space; + byte *base = 0; + bool bufferSpace_is_default = false; + gdev_prn_space_params space_params = ppdev->space_params; + + if (reallocate) + switch (pass) + { + case 1: + /* Setup device to get reallocated */ + save_params = ppdev->space_params; + ppdev->space_params = *new_space_params; + save_width = ppdev->width; + ppdev->width = new_width; + save_height = ppdev->height; + ppdev->height = new_height; + break; + case 2: /* only comes here if reallocate */ + /* Restore device to previous contents */ + ppdev->space_params = save_params; + ppdev->width = save_width; + ppdev->height = save_height; + break; + } + + /* Init clist/mem device-specific fields */ + memset(ppdev->skip, 0, sizeof(ppdev->skip)); + mem_space = gdev_mem_bitmap_size(pmemdev); + + /* Compute desired space params: never use the space_params as-is. */ + /* Rather, give the dev-specific driver a chance to adjust them. */ + space_params.BufferSpace = 0; + (*ppdev->printer_procs.get_space_params)(ppdev, &space_params); + if (ppdev->is_async_renderer && space_params.band.BandBufferSpace != 0) + space_params.BufferSpace = space_params.band.BandBufferSpace; + else if (space_params.BufferSpace == 0) { + if (space_params.band.BandBufferSpace > 0) + space_params.BufferSpace = space_params.band.BandBufferSpace; + else { + space_params.BufferSpace = ppdev->space_params.BufferSpace; + bufferSpace_is_default = true; + } + } + + /* Determine if we can use a full bitmap buffer, or have to use banding */ + if (pass > 1) + is_command_list = save_is_command_list; + else { + is_command_list = space_params.banding_type == BandingAlways || + mem_space >= space_params.MaxBitmap || + mem_space != (uint)mem_space; /* too big to allocate */ + } + if (!is_command_list) { + /* Try to allocate memory for full memory buffer */ + base = reallocate + ? gs_resize_object( buffer_memory, the_memory, + (uint)mem_space, "printer buffer" ) + : gs_alloc_bytes( buffer_memory, (uint)mem_space, + "printer_buffer" ); + if (base == 0) + is_command_list = true; + else + the_memory = base; + } + if (!is_command_list && pass == 1 && PRN_MIN_MEMORY_LEFT != 0 + && buffer_memory == &gs_memory_default) { + /* before using full memory buffer, ensure enough working mem left */ + byte * left = gs_alloc_bytes( buffer_memory, + PRN_MIN_MEMORY_LEFT, "printer mem left"); + if (left == 0) + is_command_list = true; + else + gs_free_object(buffer_memory, left, "printer mem left"); + } + + if (is_command_list) { + /* Buffer the image in a command list. */ + /* Release the buffer if we allocated it. */ + int code; + if (!reallocate) { + gs_free_object(buffer_memory, the_memory, + "printer buffer(open)"); + the_memory = 0; + } + if (space_params.banding_type == BandingNever) { + ecode = gs_note_error(gs_error_VMerror); + continue; + } + code = gdev_prn_setup_as_command_list(pdev, buffer_memory, + &the_memory, &space_params, + !bufferSpace_is_default); + if (ecode == 0) + ecode = code; + + if ( code >= 0 || (reallocate && pass > 1) ) + ppdev->procs = gs_clist_device_procs; + } else { + /* Render entirely in memory. */ + int code; + + ppdev->buffer_space = 0; + code = (*ppdev->printer_procs.make_buffer_device) + (pmemdev, pdev, buffer_memory, false); + if (code < 0) { /* Catastrophic. Shouldn't ever happen */ + gs_free_object(buffer_memory, base, "printer buffer"); + pdev->procs = ppdev->orig_procs; + ppdev->orig_procs.open_device = 0; /* prevent uninit'd restore of procs */ + return_error(code); + } + pmemdev->base = base; + } + if (ecode == 0) + break; + } + + if (ecode >= 0 || reallocate) { /* even if realloc failed */ + /* Synthesize the procedure vector. */ + /* Rendering operations come from the memory or clist device, */ + /* non-rendering come from the printer device. */ +#define COPY_PROC(p) set_dev_proc(ppdev, p, ppdev->orig_procs.p) + COPY_PROC(get_initial_matrix); + COPY_PROC(output_page); + COPY_PROC(close_device); + COPY_PROC(map_rgb_color); + COPY_PROC(map_color_rgb); + COPY_PROC(get_params); + COPY_PROC(put_params); + COPY_PROC(map_cmyk_color); + COPY_PROC(get_xfont_procs); + COPY_PROC(get_xfont_device); + COPY_PROC(map_rgb_alpha_color); + /* All printers are page devices, even if they didn't use the */ + /* standard macros for generating their procedure vectors. */ + set_dev_proc(ppdev, get_page_device, gx_page_device_get_page_device); + COPY_PROC(get_alpha_bits); + COPY_PROC(get_clipping_box); + COPY_PROC(map_color_rgb_alpha); + COPY_PROC(get_hardware_params); +#undef COPY_PROC + /* If using a command list, already opened the device. */ + if (is_command_list) + return ecode; + else + return (*dev_proc(pdev, open_device))(pdev); + } else { + pdev->procs = ppdev->orig_procs; + ppdev->orig_procs.open_device = 0; /* prevent uninit'd restore of procs */ + return ecode; + } +} + +int +gdev_prn_allocate_memory(gx_device *pdev, + gdev_prn_space_params *new_space_params, + int new_width, int new_height) +{ + return gdev_prn_allocate(pdev, new_space_params, + new_width, new_height, false); +} + +int +gdev_prn_reallocate_memory(gx_device *pdev, + gdev_prn_space_params *new_space_params, + int new_width, int new_height) +{ + return gdev_prn_allocate(pdev, new_space_params, + new_width, new_height, true); +} + +int +gdev_prn_free_memory(gx_device *pdev) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + byte *the_memory = 0; + gs_memory_t *buffer_memory = + (ppdev->buffer_memory == 0 ? &gs_memory_default : + ppdev->buffer_memory); + + gdev_prn_tear_down(pdev, &the_memory); + gs_free_object(buffer_memory, the_memory, "gdev_prn_free_memory"); + return 0; +} + +/* ------------- Stubs related only to async rendering ------- */ + +int /* rets 0 ok, -ve error if couldn't start thread */ +gx_default_start_render_thread(gdev_prn_start_render_params *params) +{ + return gs_error_unknownerror; +} + +/* Open the renderer's copy of a device. */ +/* This is overriden in gdevprna.c */ +int +gx_default_open_render_device(gx_device_printer *pdev) +{ + return gs_error_unknownerror; +} + +/* Close the renderer's copy of a device. */ +int +gx_default_close_render_device(gx_device_printer *pdev) +{ + return gdev_prn_close( (gx_device *)pdev ); +} + +/* ------ Get/put parameters ------ */ + +/* Get parameters. Printer devices add several more parameters */ +/* to the default set. */ +int +gdev_prn_get_params(gx_device * pdev, gs_param_list * plist) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + int code = gx_default_get_params(pdev, plist); + + if (code < 0 || + (ppdev->Duplex_set >= 0 && + (code = (ppdev->Duplex_set ? + param_write_bool(plist, "Duplex", &ppdev->Duplex) : + param_write_null(plist, "Duplex"))) < 0) + ) + return code; + + return 0; +} + +/* Put parameters. */ +int +gdev_prn_put_params(gx_device * pdev, gs_param_list * plist) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + int ecode = 0; + int code; + const char *param_name; + bool is_open = pdev->is_open; + bool oof = ppdev->OpenOutputFile; + bool rpp = ppdev->ReopenPerPage; + bool duplex; + int duplex_set = -1; + int width = pdev->width; + int height = pdev->height; + gdev_prn_space_params sp, save_sp; + gs_param_dict mdict; + + sp = ppdev->space_params; + save_sp = sp; + + switch (code = param_read_bool(plist, (param_name = "OpenOutputFile"), &oof)) { + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 0: + case 1: + break; + } + + switch (code = param_read_bool(plist, (param_name = "ReopenPerPage"), &rpp)) { + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 0: + case 1: + break; + } + + if (ppdev->Duplex_set >= 0) /* i.e., Duplex is supported */ + switch (code = param_read_bool(plist, (param_name = "Duplex"), + &duplex)) { + case 0: + duplex_set = 1; + break; + default: + if ((code = param_read_null(plist, param_name)) == 0) { + duplex_set = 0; + break; + } + ecode = code; + param_signal_error(plist, param_name, ecode); + case 1: + ; + } +#define CHECK_PARAM_CASES(member, bad, label)\ + case 0:\ + if ((sp.params_are_read_only ? sp.member != save_sp.member : bad))\ + ecode = gs_error_rangecheck;\ + else\ + break;\ + goto label;\ + default:\ + ecode = code;\ +label:\ + param_signal_error(plist, param_name, ecode);\ + case 1:\ + break + + /* Read InputAttributes and OutputAttributes just for the type */ + /* check and to indicate that they aren't undefined. */ +#define read_media(pname)\ + switch ( code = param_begin_read_dict(plist, (param_name = pname), &mdict, true) )\ + {\ + case 0:\ + param_end_read_dict(plist, pname, &mdict);\ + break;\ + default:\ + ecode = code;\ + param_signal_error(plist, param_name, ecode);\ + case 1:\ + ;\ + } + + read_media("InputAttributes"); + read_media("OutputAttributes"); + + if (ecode < 0) + return ecode; + /* Prevent gx_default_put_params from closing the printer. */ + pdev->is_open = false; + code = gx_default_put_params(pdev, plist); + pdev->is_open = is_open; + if (code < 0) + return code; + + ppdev->OpenOutputFile = oof; + ppdev->ReopenPerPage = rpp; + if (duplex_set >= 0) { + ppdev->Duplex = duplex; + ppdev->Duplex_set = duplex_set; + } + ppdev->space_params = sp; + + /* If necessary, free and reallocate the printer memory. */ + /* Formerly, would not reallocate if device is not open: */ + /* we had to patch this out (see News for 5.50). */ + code = gdev_prn_maybe_reallocate_memory(ppdev, &save_sp, width, height); + if (code < 0) + return code; + + return 0; +} + +/* ------ Others ------ */ + +#define TILE_SIZE 256 + +/* Default routine to override current space_params. */ +void +gdev_prn_default_get_space_params(const gx_device_printer *printer_dev, + gdev_prn_space_params *space_params) +{ + int cache_size; /* Size of tile cache in bytes */ + char *cache_env, /* Cache size environment variable */ + cache_units[255]; /* Cache size units */ + + + if ((cache_env = getenv("RIP_MAX_CACHE")) != NULL) + { + switch (sscanf(cache_env, "%d%254s", &cache_size, cache_units)) + { + case 0 : + cache_size = 32 * 1024 * 1024; + break; + case 1 : + cache_size *= 4 * TILE_SIZE * TILE_SIZE; + break; + case 2 : + if (tolower(cache_units[0]) == 'g') + cache_size *= 1024 * 1024 * 1024; + else if (tolower(cache_units[0]) == 'm') + cache_size *= 1024 * 1024; + else if (tolower(cache_units[0]) == 'k') + cache_size *= 1024; + else if (tolower(cache_units[0]) == 't') + cache_size *= 4 * TILE_SIZE * TILE_SIZE; + break; + } + } + else + cache_size = 32 * 1024 * 1024; + + space_params->MaxBitmap = cache_size; +} + +/* Generic routine to send the page to the printer. */ +int /* 0 ok, -ve error, or 1 if successfully upgraded to buffer_page */ +gdev_prn_output_page(gx_device * pdev, int num_copies, int flush) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + int outcode = 0, closecode = 0, errcode = 0, endcode; + bool upgraded_copypage = false; + + if (num_copies > 0 || !flush) { + int code = gdev_prn_open_printer(pdev, 1); + + if (code < 0) + return code; + + /* If copypage request, try to do it using buffer_page */ + if ( !flush && + (*ppdev->printer_procs.buffer_page) + (ppdev, ppdev->file, num_copies) >= 0 + ) { + upgraded_copypage = true; + flush = true; + } + else if (num_copies > 0) + /* Print the accumulated page description. */ + outcode = + (*ppdev->printer_procs.print_page_copies)(ppdev, ppdev->file, + num_copies); + if (ppdev->file) + { + fflush(ppdev->file); + errcode = + (ferror(ppdev->file) ? gs_note_error(gs_error_ioerror) : 0); + } + else + errcode = 0; + + if (!upgraded_copypage) + closecode = gdev_prn_close_printer(pdev); + } + endcode = (ppdev->buffer_space ? clist_finish_page(pdev, flush) : 0); + + if (outcode < 0) + return outcode; + if (errcode < 0) + return errcode; + if (closecode < 0) + return closecode; + if (endcode < 0) + return endcode; + return (upgraded_copypage ? 1 : 0); +} + +/* Print multiple copies of a page by calling print_page multiple times. */ +int +gx_default_print_page_copies(gx_device_printer * pdev, FILE * prn_stream, + int num_copies) +{ + int i = num_copies; + int code = 0; + + while (code >= 0 && i-- > 0) + code = (*pdev->printer_procs.print_page) (pdev, prn_stream); + return code; +} + +/* + * Buffer a (partial) rasterized page & optionally print result multiple times. + * The default implementation returns error, since the driver needs to override + * this (in procedure vector) in configurations where this call may occur. + */ +int +gx_default_buffer_page(gx_device_printer *pdev, FILE *prn_stream, + int num_copies) +{ + return gs_error_unknownerror; +} + +/* ---------------- Driver services ---------------- */ + +/* Return the number of scan lines that should actually be passed */ +/* to the device. */ +int +gdev_prn_print_scan_lines(gx_device * pdev) +{ + int height = pdev->height; + gs_matrix imat; + float yscale; + int top, bottom, offset, end; + + (*dev_proc(pdev, get_initial_matrix)) (pdev, &imat); + yscale = imat.yy * 72.0; /* Y dpi, may be negative */ + top = (int)(dev_t_margin(pdev) * yscale); + bottom = (int)(dev_b_margin(pdev) * yscale); + offset = (int)(dev_y_offset(pdev) * yscale); + if (yscale < 0) { /* Y=0 is top of page */ + end = -offset + height + bottom; + } else { /* Y=0 is bottom of page */ + end = offset + height - top; + } + return min(height, end); +} + +/* Open the current page for printing. */ +int +gdev_prn_open_printer_positionable(gx_device *pdev, bool binary_mode, + bool positionable) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + + if (ppdev->file != 0) { + ppdev->file_is_new = false; + return 0; + } + { + int code = gx_device_open_output_file(pdev, ppdev->fname, + binary_mode, positionable, + &ppdev->file); + if (code < 0) + return code; + } + ppdev->file_is_new = true; + return 0; +} +int +gdev_prn_open_printer(gx_device *pdev, bool binary_mode) +{ + return gdev_prn_open_printer_positionable(pdev, binary_mode, false); +} + +/* Copy a scan line from the buffer to the printer. */ +int +gdev_prn_get_bits(gx_device_printer * pdev, int y, byte * str, byte ** actual_data) +{ + int code = (*dev_proc(pdev, get_bits)) ((gx_device *) pdev, y, str, actual_data); + uint line_size = gdev_prn_raster(pdev); + int last_bits = -(pdev->width * pdev->color_info.depth) & 7; + + if (code < 0) + return code; + if (last_bits != 0) { + byte *dest = (actual_data != 0 ? *actual_data : str); + + dest[line_size - 1] &= 0xff << last_bits; + } + return 0; +} +/* Copy scan lines to a buffer. Return the number of scan lines, */ +/* or <0 if error. */ +int +gdev_prn_copy_scan_lines(gx_device_printer * pdev, int y, byte * str, uint size) +{ + uint line_size = gdev_prn_raster(pdev); + int count = size / line_size; + int i; + byte *dest = str; + + count = min(count, pdev->height - y); + for (i = 0; i < count; i++, dest += line_size) { + int code = gdev_prn_get_bits(pdev, y + i, dest, NULL); + + if (code < 0) + return code; + } + return count; +} + +/* Like get_bits, but accepts initial raster contents */ +int +gdev_prn_get_overlay_bits(gx_device_printer *pdev, int y, int lineCount, + byte *data) +{ + if (pdev->buffer_space) { + /* Command lists have built-in support for this function */ + return clist_get_overlay_bits(pdev, y, lineCount, data); + } else { + /* Memory devices cannot support this function. */ + return_error(gs_error_unknownerror); + } +} + +/* Find out where the band buffer for a given line is going to fall on the */ +/* next call to get_bits. */ +int /* rets # lines from y till end of buffer, or -ve error code */ +gdev_prn_locate_overlay_buffer(gx_device_printer *pdev, int y, byte **data) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + + if (ppdev->buffer_space) { + /* Command lists have built-in support for this function */ + return clist_locate_overlay_buffer(pdev, y, data); + } else { + /* Memory devices cannot support this function. */ + return_error(gs_error_unknownerror); + } +} + +/* Close the current page. */ +int +gdev_prn_close_printer(gx_device * pdev) +{ + gx_device_printer * const ppdev = (gx_device_printer *)pdev; + + if (strchr(ppdev->fname, '%') /* file per page */ || + ppdev->ReopenPerPage /* close and reopen for each page */ + ) { + gp_close_printer(ppdev->file, ppdev->fname); + ppdev->file = NULL; + } + return 0; +} + +/* If necessary, free and reallocate the printer memory after changing params */ +int +gdev_prn_maybe_reallocate_memory(gx_device_printer *prdev, + gdev_prn_space_params *old_sp, + int old_width, int old_height) +{ + int code = 0; + gx_device *const pdev = (gx_device *)prdev; + gx_device_memory * const mdev = (gx_device_memory *)prdev; + + /* The first test here used to be prdev->open. See News for 5.50. */ + if (mdev->base != 0 && + (memcmp(&prdev->space_params, old_sp, sizeof(*old_sp)) != 0 || + prdev->width != old_width || prdev->height != old_height ) + ) { + int new_width = prdev->width; + int new_height = prdev->height; + gdev_prn_space_params new_sp = prdev->space_params; + + prdev->width = old_width; + prdev->height = old_height; + prdev->space_params = *old_sp; + code = gdev_prn_reallocate_memory(pdev, &new_sp, + new_width, new_height); + /* If this fails, device should be usable w/old params, but */ + /* band files may not be open. */ + } + return code; +} diff --git a/pstoraster/gdevprn.h b/pstoraster/gdevprn.h new file mode 100644 index 0000000000..68c09d6b5e --- /dev/null +++ b/pstoraster/gdevprn.h @@ -0,0 +1,560 @@ +/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Common header file for memory-buffered printers */ + +#ifndef gdevprn_INCLUDED +# define gdevprn_INCLUDED + +#include "memory_.h" +#include "string_.h" +#include "gx.h" +#include "gp.h" /* for gp_file_name_sizeof */ +#include "gserrors.h" +#include "gsmatrix.h" /* for gxdevice.h */ +#include "gsutil.h" /* for memflip8x8 */ +#include "gxdevice.h" +#include "gxdevmem.h" +#include "gxclist.h" +#include "gsparam.h" + +/* + * Define the parameters for the printer rendering method. + * If the entire bitmap fits in PRN_MAX_BITMAP, and there is at least + * PRN_MIN_MEMORY_LEFT memory left after allocating it, render in RAM, + * otherwise use a command list with a size of PRN_BUFFER_SPACE. + * (These are parameters that can be changed by a client program.) + */ +/* Define parameters for machines with little dinky RAMs.... */ +#define PRN_MAX_BITMAP_SMALL 32000 +#define PRN_BUFFER_SPACE_SMALL 25000 +#define PRN_MIN_MEMORY_LEFT_SMALL 32000 +/* Define parameters for machines with great big hulking RAMs.... */ +#define PRN_MAX_BITMAP_LARGE 10000000L +#define PRN_BUFFER_SPACE_LARGE 1000000L +#define PRN_MIN_MEMORY_LEFT_LARGE 500000L +/* Define parameters valid on all machines. */ +#define PRN_MIN_BUFFER_SPACE 10000 /* give up if less than this */ +/* Now define conditional parameters. */ +#if arch_small_memory +# define PRN_MAX_BITMAP PRN_MAX_BITMAP_SMALL +# define PRN_BUFFER_SPACE PRN_BUFFER_SPACE_SMALL +# define PRN_MIN_MEMORY_LEFT PRN_MIN_MEMORY_LEFT_SMALL +#else +/****** These should really be conditional on gs_debug_c('.') if + ****** DEBUG is defined, but they're used in static initializers, + ****** so we can't do it. + ******/ +# if 0 /****** # ifdef DEBUG ***** */ +# define PRN_MAX_BITMAP\ + (gs_debug_c('.') ? PRN_MAX_BITMAP_SMALL : PRN_MAX_BITMAP_LARGE) +# define PRN_BUFFER_SPACE\ + (gs_debug_c('.') ? PRN_BUFFER_SPACE_SMALL : PRN_BUFFER_SPACE_LARGE) +# define PRN_MIN_MEMORY_LEFT\ + (gs_debug_c('.') ? PRN_MIN_MEMORY_LEFT_SMALL : PRN_MIN_MEMORY_LEFT_LARGE) +# else +# define PRN_MAX_BITMAP PRN_MAX_BITMAP_LARGE +# define PRN_BUFFER_SPACE PRN_BUFFER_SPACE_LARGE +# define PRN_MIN_MEMORY_LEFT PRN_MIN_MEMORY_LEFT_LARGE +# endif +#endif + +/* Define the abstract type for a printer device. */ +#ifndef gx_device_printer_DEFINED +# define gx_device_printer_DEFINED +typedef struct gx_device_printer_s gx_device_printer; +#endif + +/* Define the abstract type for some band device procedures' arguments. */ +typedef struct gdev_prn_start_render_params_s gdev_prn_start_render_params; + +/* Define the abstract type for a page queue for async rendering. */ +#ifndef gx_page_queue_DEFINED +# define gx_page_queue_DEFINED +typedef struct gx_page_queue_s gx_page_queue; +#endif + +/* Define the abstract type for parameters describing buffer space. */ +#ifndef gdev_prn_space_params_DEFINED +# define gdev_prn_space_params_DEFINED +typedef struct gdev_prn_space_params_s gdev_prn_space_params; +#endif + +/* + * Define the special procedures for band devices. + */ +typedef struct gx_printer_device_procs_s { + + /* + * Print the page on the output file. Required only for devices + * where output_page is gdev_prn_output_page; ignored for other + * devices. + */ + +#define prn_dev_proc_print_page(proc)\ + int proc(P2(gx_device_printer *, FILE *)) + prn_dev_proc_print_page((*print_page)); +/* BACKWARD COMPATIBILITY */ +#define dev_proc_print_page(proc) prn_dev_proc_print_page(proc) + + /* Print the page on the output file, with a given # of copies. */ + +#define prn_dev_proc_print_page_copies(proc)\ + int proc(P3(gx_device_printer *, FILE *, int)) + prn_dev_proc_print_page_copies((*print_page_copies)); +/* BACKWARD COMPATIBILITY */ +#define dev_proc_print_page_copies(proc) prn_dev_proc_print_page_copies(proc) + + /* Initialize the memory device for a page or a band. */ + /* (The macro definition is in gxdevcli.h.) */ + + dev_proc_make_buffer_device((*make_buffer_device)); + + /* + * Compute effective space params. These results effectively override + * the space_params in the device, but does not replace them; that is to + * say that computed space params are temps used for computation. + * Procedure must fill in only those space_params that it wishes to + * override, using curr width, height, margins, etc. + * + * Caller is gdevprn.open & gdevprn.put_params, calls driver or + * default. + */ + +#define prn_dev_proc_get_space_params(proc)\ + void proc(P2(const gx_device_printer *, gdev_prn_space_params *)) + prn_dev_proc_get_space_params((*get_space_params)); + + /* + * Only for gx_device_printer devices that overlap interpreting and + * rasterizing. Since there are 2 instances of the device (1 for writing + * the cmd list & 1 for rasterizing it), and each device is associated + * with an different thread, this function is called to start the + * rasterizer's thread. Once started, the rasterizer thread must call + * down to gdev_prn_asnyc_render_thread, which will only return after + * device closes. + * + * Caller is gdevprna.open, calls driver implementation or default. + */ + +#define prn_dev_proc_start_render_thread(proc)\ + int proc(P1(gdev_prn_start_render_params *)) + prn_dev_proc_start_render_thread((*start_render_thread)); + + /* + * Only for gx_device_printer devices that overlap interpreting and + * rasterizing. Since there are 2 instances of the device (1 for writing + * the cmd list & 1 for rasterizing it), these fns are called to + * open/close the rasterizer's instance, once the writer's instance has + * been created & init'd. These procs must cascade down to + * gdev_prn_async_render_open/close. + * + * Caller is gdevprna, calls driver implementation or default. + */ + +#define prn_dev_proc_open_render_device(proc)\ + int proc(P1(gx_device_printer *)) + prn_dev_proc_open_render_device((*open_render_device)); + +#define prn_dev_proc_close_render_device(proc)\ + int proc(P1(gx_device_printer *)) + prn_dev_proc_close_render_device((*close_render_device)); + + /* + * Buffer a page on the output device. A page may or may not have been + * fully rendered, but the rasterizer needs to realize the page to free + * up resources or support copypage. Printing a page may involve zero or + * more buffer_pages. All buffer_page output is overlaid in the buffer + * until a terminating print_page or print_page_copies clears the + * buffer. Note that, after the first buffer_page, the driver must use + * the get_overlay_bits function instead of get_bits. The difference is + * that get_overlay_bits requires the caller to supply the same buffered + * bitmap that was computed as a result of a previous buffer_page, so + * that get_overlay_bits can add further marks to the existing buffered + * image. NB that output must be accumulated in buffer even if + * num_copies == 0. + * + * Caller is expected to be gdevprn, calls driver implementation or + * default. + */ + +#define prn_dev_proc_buffer_page(proc)\ + int proc(P3(gx_device_printer *, FILE *, int)) + prn_dev_proc_buffer_page((*buffer_page)); + + /* + * Transform a given set of bits by marking it per the current page + * description. This is a different version of get_bits, where this + * procedure accepts a bitmap and merely adds further marks, without + * clearing the bits. + * + * Driver implementation is expected to be the caller. + */ + +#define prn_dev_proc_get_overlay_bits(proc)\ + int proc(P4(gx_device_printer *, int, int, byte *)) + prn_dev_proc_get_overlay_bits((*get_overlay_bits)); + + /* + * Find out where the band buffer for a given line is going to fall on + * the next call to get_bits. This is an alternative to get_overlay_bits + * in cases where the client doesn't own a suitably formatted buffer to + * deposit bits into. When using this function, do a + * locate_overlay_buffer, copy the background data into the returned + * buffer, then do get_bits to get the transformed data. IMPORTANT: the + * locate_overlay_buffer for a specific range of lines must immediately + * be followed by one or more get_bits for the same line range with no + * other intervening driver calls. If this condition is violated, + * results are undefined. + */ + +#define prn_dev_proc_locate_overlay_buffer(proc)\ + int proc(P3(gx_device_printer *, int, byte **)) + prn_dev_proc_locate_overlay_buffer((*locate_overlay_buffer)); + +} gx_printer_device_procs; + +/* ------ Printer device definition ------ */ + +/* Structure for generic printer devices. */ +/* This must be preceded by gx_device_common. */ +/* Printer devices are actually a union of a memory device */ +/* and a clist device, plus some additional state. */ +#define prn_fname_sizeof gp_file_name_sizeof +typedef enum { + BandingAuto = 0, + BandingAlways, + BandingNever +} gdev_prn_banding_type; +struct gdev_prn_space_params_s { + long MaxBitmap; /* max size of non-buffered bitmap */ + long BufferSpace; /* space to use for buffer */ + gx_band_params band; /* see gxclist.h */ + bool params_are_read_only; /* true if put_params may not modify this struct */ + gdev_prn_banding_type banding_type; /* used to force banding or bitmap */ +}; + +#define gx_prn_device_common\ + byte skip[max(sizeof(gx_device_memory), sizeof(gx_device_clist)) -\ + sizeof(gx_device) + sizeof(double) /* padding */];\ + gx_printer_device_procs printer_procs;\ + /* ------ Device parameters that must be set ------ */\ + /* ------ before calling the device open routine. ------ */\ + gdev_prn_space_params space_params;\ + char fname[prn_fname_sizeof]; /* OutputFile */\ + /* ------ Other device parameters ------ */\ + bool OpenOutputFile;\ + bool ReopenPerPage;\ + bool Duplex;\ + int Duplex_set; /* -1 = not supported */\ + /* ------ End of parameters ------ */\ + bool file_is_new; /* true iff file just opened */\ + FILE *file; /* output file */\ + long buffer_space; /* amount of space for clist buffer, */\ + /* 0 means not using clist */\ + byte *buf; /* buffer for rendering */\ + /* ---- Begin async rendering support --- */\ + gs_memory_t *buffer_memory; /* allocator for command list */\ + gs_memory_t *bandlist_memory; /* allocator for bandlist files */\ + proc_free_up_bandlist_memory((*free_up_bandlist_memory)); /* if nz, proc to free some bandlist memory */\ + gx_page_queue *page_queue; /* if <> 0,page queue for gdevprna NOT GC'd */\ + bool is_async_renderer; /* device is only the rendering part of async device */\ + gx_device_printer *async_renderer; /* in async writer, pointer to async renderer */\ + uint clist_disable_mask; /* mask of clist options to disable */\ + /* ---- End async rendering support --- */\ + gx_device_procs orig_procs /* original (std_)procs */ + +/* The device descriptor */ +struct gx_device_printer_s { + gx_device_common; + gx_prn_device_common; +}; + +/* Define a typedef for the sake of ansi2knr. */ +typedef dev_proc_print_page((*dev_proc_print_page_t)); + +/* Standard device procedures for printers */ +dev_proc_open_device(gdev_prn_open); +dev_proc_output_page(gdev_prn_output_page); +dev_proc_close_device(gdev_prn_close); +#define gdev_prn_map_rgb_color gx_default_b_w_map_rgb_color +#define gdev_prn_map_color_rgb gx_default_b_w_map_color_rgb +dev_proc_get_params(gdev_prn_get_params); +dev_proc_put_params(gdev_prn_put_params); + +/* Default printer-specific procedures */ +prn_dev_proc_get_space_params(gdev_prn_default_get_space_params); +prn_dev_proc_start_render_thread(gx_default_start_render_thread); /* for async rendering only, see gdevprna.c */ +prn_dev_proc_open_render_device(gx_default_open_render_device); +prn_dev_proc_close_render_device(gx_default_close_render_device); +prn_dev_proc_buffer_page(gx_default_buffer_page); /* returns an error */ +prn_dev_proc_get_overlay_bits(gdev_prn_get_overlay_bits); +prn_dev_proc_locate_overlay_buffer(gdev_prn_locate_overlay_buffer); + +/* Macro for generating procedure table */ +#define prn_procs(p_open, p_output_page, p_close)\ + prn_color_procs(p_open, p_output_page, p_close, gdev_prn_map_rgb_color, gdev_prn_map_color_rgb) +#define prn_params_procs(p_open, p_output_page, p_close, p_get_params, p_put_params)\ + prn_color_params_procs(p_open, p_output_page, p_close, gdev_prn_map_rgb_color, gdev_prn_map_color_rgb, p_get_params, p_put_params) +#define prn_color_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb)\ + prn_color_params_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, gdev_prn_get_params, gdev_prn_put_params) +/* See gdev_prn_open for explanation of the NULLs below. */ +#define prn_color_params_procs(p_open, p_output_page, p_close, p_map_rgb_color, p_map_color_rgb, p_get_params, p_put_params) {\ + p_open,\ + NULL, /* get_initial_matrix */\ + NULL, /* sync_output */\ + p_output_page,\ + p_close,\ + p_map_rgb_color,\ + p_map_color_rgb,\ + NULL, /* fill_rectangle */\ + NULL, /* tile_rectangle */\ + NULL, /* copy_mono */\ + NULL, /* copy_color */\ + NULL, /* draw_line */\ + NULL, /* get_bits */\ + p_get_params,\ + p_put_params,\ + NULL, /* map_cmyk_color */\ + NULL, /* get_xfont_procs */\ + NULL, /* get_xfont_device */\ + NULL, /* map_rgb_alpha_color */\ + gx_page_device_get_page_device,\ + NULL, /* get_alpha_bits */\ + NULL, /* copy_alpha */\ + NULL, /* get_band */\ + NULL, /* copy_rop */\ + NULL, /* fill_path */\ + NULL, /* stroke_path */\ + NULL, /* fill_mask */\ + NULL, /* fill_trapezoid */\ + NULL, /* fill_parallelogram */\ + NULL, /* fill_triangle */\ + NULL, /* draw_thin_line */\ + NULL, /* begin_image */\ + NULL, /* image_data */\ + NULL, /* end_image */\ + NULL, /* strip_tile_rectangle */\ + NULL, /* strip_copy_rop, */\ + NULL, /* get_clipping_box */\ + NULL, /* begin_typed_image */\ + NULL, /* map_color_rgb_alpha */\ + NULL, /* create_compositor */\ + NULL, /* get_hardware_params */\ + NULL /* text_begin */\ +} + +/* The standard printer device procedures */ +/* (using gdev_prn_open/output_page/close). */ +extern const gx_device_procs prn_std_procs; + +/* + * Define macros for generating the device structure, + * analogous to the std_device_body macros in gxdevice.h + * Note that the macros are broken up so as to be usable for devices that + * add further initialized state to the printer device. + * + * The 'margin' values provided here specify the unimageable region + * around the edges of the page (in inches), and the left and top margins + * also specify the displacement of the device (0,0) point from the + * upper left corner. We should provide macros that allow specifying + * all 6 values independently, but we don't yet. + */ +#define prn_device_body_rest_(print_page)\ + { 0 }, /* std_procs */\ + { 0 }, /* skip */\ + { print_page,\ + gx_default_print_page_copies,\ + gx_default_make_buffer_device,\ + gdev_prn_default_get_space_params,\ + gx_default_start_render_thread,\ + gx_default_open_render_device,\ + gx_default_close_render_device,\ + gx_default_buffer_page,\ + gdev_prn_get_overlay_bits,\ + gdev_prn_locate_overlay_buffer\ + },\ + { PRN_MAX_BITMAP, PRN_BUFFER_SPACE,\ + { band_params_initial_values },\ + 0/*false*/, /* params_are_read_only */\ + BandingAuto /* banding_type */\ + },\ + { 0 }, /* fname */\ + 0/*false*/, /* OpenOutputFile */\ + 0/*false*/, /* ReopenPerPage */\ + 0/*false*/, -1, /* Duplex[_set] */\ + 0/*false*/, 0, 0, 0, /* file_is_new ... buf */\ + 0, 0, 0, 0, 0/*false*/, 0, 0, /* buffer_memory ... clist_dis'_mask */\ + { 0 } /* ... orig_procs */ + +/* The Sun cc compiler won't allow \ within a macro argument list. */ +/* This accounts for the short parameter names here and below. */ +#define prn_device_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ + std_device_full_body(dtype, &procs, dname,\ + (int)((long)(w10) * (xdpi) / 10),\ + (int)((long)(h10) * (ydpi) / 10),\ + xdpi, ydpi,\ + ncomp, depth, mg, mc, dg, dc,\ + -(lo) * (xdpi), -(to) * (ydpi),\ + (lm) * 72.0, (bm) * 72.0,\ + (rm) * 72.0, (tm) * 72.0\ + ),\ + prn_device_body_rest_(print_page) + +#define prn_device_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page)\ + prn_device_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi,\ + lm, tm, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_page) + +#define prn_device_body_copies(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, ncomp, depth, mg, mc, dg, dc, print_pages)\ + std_device_full_body(dtype, &procs, dname,\ + (int)((long)w10 * xdpi / 10),\ + (int)((long)h10 * ydpi / 10),\ + xdpi, ydpi,\ + ncomp, depth, mg, mc, dg, dc,\ + -(lm) * (xdpi), -(tm) * (ydpi),\ + (lm) * 72.0, (bm) * 72.0,\ + (rm) * 72.0, (tm) * 72.0\ + ),\ + { 0 }, /* std_procs */\ + { 0 }, /* skip */\ + { NULL,\ + print_pages,\ + gx_default_make_buffer_device,\ + gdev_prn_default_get_space_params,\ + gx_default_start_render_thread,\ + gx_default_open_render_device,\ + gx_default_close_render_device,\ + gx_default_buffer_page,\ + gdev_prn_get_overlay_bits,\ + gdev_prn_locate_overlay_buffer\ + },\ + { PRN_MAX_BITMAP, PRN_BUFFER_SPACE,\ + { band_params_initial_values },\ + 0/*false*/, /* params_are_read_only */\ + BandingAuto /* banding_type */\ + },\ + { 0 }, /* fname */\ + 0/*false*/, /* OpenOutputFile */\ + 0/*false*/, /* ReopenPerPage */\ + 0/*false*/, -1, /* Duplex[_set] */\ + 0/*false*/, 0, 0, 0, /* file_is_new ... buf */\ + 0, 0, 0, 0, 0/*false*/, 0, 0, /* buffer_memory ... clist_dis'_mask */\ + { 0 } /* ... orig_procs */ +#define prn_device_std_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\ + std_device_std_color_full_body(dtype, &procs, dname,\ + (int)((long)(w10) * (xdpi) / 10),\ + (int)((long)(h10) * (ydpi) / 10),\ + xdpi, ydpi, color_bits,\ + -(lo) * (xdpi), -(to) * (ydpi),\ + (lm) * 72.0, (bm) * 72.0,\ + (rm) * 72.0, (tm) * 72.0\ + ),\ + prn_device_body_rest_(print_page) + +#define prn_device_std_body(dtype, procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\ + prn_device_std_margins_body(dtype, procs, dname, w10, h10, xdpi, ydpi,\ + lm, tm, lm, bm, rm, tm, color_bits, print_page) + +#define prn_device_margins(procs, dname, w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\ +{ prn_device_std_margins_body(gx_device_printer, procs, dname,\ + w10, h10, xdpi, ydpi, lo, to, lm, bm, rm, tm, color_bits, print_page)\ +} + +#define prn_device(procs, dname, w10, h10, xdpi, ydpi, lm, bm, rm, tm, color_bits, print_page)\ + prn_device_margins(procs, dname, w10, h10, xdpi, ydpi,\ + lm, tm, lm, bm, rm, tm, color_bits, print_page)\ + +/* ------ Utilities ------ */ +/* These are defined in gdevprn.c. */ + +int gdev_prn_open_printer_positionable(P3(gx_device *dev, bool binary_mode, + bool positionable)); +/* open_printer defaults positionable = false */ +int gdev_prn_open_printer(P2(gx_device * dev, bool binary_mode)); +#define gdev_prn_file_is_new(pdev) ((pdev)->file_is_new) +#define gdev_prn_raster(pdev) gx_device_raster((gx_device *)(pdev), 0) +int gdev_prn_get_bits(P4(gx_device_printer *, int, byte *, byte **)); +int gdev_prn_copy_scan_lines(P4(gx_device_printer *, int, byte *, uint)); +int gdev_prn_close_printer(P1(gx_device *)); + +/* The default print_page_copies procedure just calls print_page */ +/* the given number of times. */ +prn_dev_proc_print_page_copies(gx_default_print_page_copies); + +/* Define the number of scan lines that should actually be passed */ +/* to the device. */ +int gdev_prn_print_scan_lines(P1(gx_device *)); + +/* Allocate / reallocate / free printer memory. */ +int gdev_prn_allocate_memory(P4(gx_device *pdev, + gdev_prn_space_params *space, + int new_width, int new_height)); +int gdev_prn_reallocate_memory(P4(gx_device *pdev, + gdev_prn_space_params *space, + int new_width, int new_height)); +int gdev_prn_free_memory(P1(gx_device *pdev)); + +/* BACKWARD COMPATIBILITY */ +#define dev_print_scan_lines(dev)\ + gdev_prn_print_scan_lines((gx_device *)(dev)) +#define gdev_mem_bytes_per_scan_line(dev)\ + gdev_prn_raster((gx_device_printer *)(dev)) +#define gdev_prn_transpose_8x8(inp,ils,outp,ols)\ + memflip8x8(inp,ils,outp,ols) + +/* ------ Printer device types ------ */ +/**************** THE FOLLOWING CODE IS NOT USED YET. ****************/ + +#if 0 /**************** VMS linker gets upset *************** */ +extern_st(st_prn_device); +#endif +int gdev_prn_initialize(P3(gx_device *, const char *, dev_proc_print_page((*)))); +void gdev_prn_init_color(P4(gx_device *, int, dev_proc_map_rgb_color((*)), dev_proc_map_color_rgb((*)))); + +#define prn_device_type(dtname, initproc, pageproc)\ +private dev_proc_print_page(pageproc);\ +device_type(dtname, st_prn_device, initproc) + +/****** FOLLOWING SHOULD CHECK __PROTOTYPES__ ******/ +#define prn_device_type_mono(dtname, dname, initproc, pageproc)\ +private dev_proc_print_page(pageproc);\ +private int \ +initproc(gx_device *dev)\ +{ return gdev_prn_initialize(dev, dname, pageproc);\ +}\ +device_type(dtname, st_prn_device, initproc) + +/****** DITTO ******/ +#define prn_device_type_color(dtname, dname, depth, initproc, pageproc, rcproc, crproc)\ +private dev_proc_print_page(pageproc);\ +private int \ +initproc(gx_device *dev)\ +{ int code = gdev_prn_initialize(dev, dname, pageproc);\ + gdev_prn_init_color(dev, depth, rcproc, crproc);\ + return code;\ +}\ +device_type(dtname, st_prn_device, initproc) + +#endif /* gdevprn_INCLUDED */ diff --git a/pstoraster/gdevprna.h b/pstoraster/gdevprna.h new file mode 100644 index 0000000000..799a8dc12d --- /dev/null +++ b/pstoraster/gdevprna.h @@ -0,0 +1,190 @@ +/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Generic asynchronous printer driver support */ + +/* Initial version 2/1/1998 by John Desrosiers (soho@crl.com) */ +/* 7/28/98 ghost@aladdin.com - Updated to Ghostscript coding standards. */ + +#ifndef gdevprna_INCLUDED +# define gdevprna_INCLUDED + +# include "gdevprn.h" +# include "gxsync.h" + +/* + * General + * ------- + * Async drivers actually create two separate instances of the device at + * the same time. The first (the writer instance) is only used in the + * interpretation operation; it feeds rendering commands into the command + * lists. The second device instance is used only for rendering the + * commands placed into the command list by the writer. + + * The writer builds a command list for an entire page; the command list + * is only queued for rendering once a page's command list is completely + * built. The only exception to this rule is when the interpreter runs + * out of memory, or when no free command list memory is available. In + * such cases, the interpreter queues a "partial page" consisting of all + * command list data written so far, plus a command indicating that the + * page description is not complete. After queuing the partial page, the + * interpereter waits until the rendering process has freed enough + * command list memory to enable the interpreter to proceed. + + * To avoid deadlocks when the system runs out of memory, special + * memory allocation provisions are made on both the writer and + * renderer sides. On the writer side, enough "reserve" bandlist + * memory is set aside at startup time to cover the needs of queuing a + * partial page to the renderer. The renderer operates out of a fixed + * memory space; that way, it can always complete rendering pages with + * the memory it has. To this end, the writer protects the renderer + * from consuming unbounded amounts of memory by a) never putting + * complex paths into the command list, b) pre-clipping any output + * unless the clip path consists of a single rectangle, c) never putting + * high-level images into the clip path unless the image in question + * meets some very stringent requirements, such as only being rotated by + * even multiples of 90 degrees and having source-image data rows which + * fit into the command buffer in one piece. These restrictions are what + * dictate the "restricted bandlist format." + + * Note that the renderer's instance of the device driver uses the + * renderer's memory. That implies that it must also operate in a small, + * fixed amount of memory, and must do all memory allocation using the + * memory allocator pointed to by the render device's ->memory member. + + * Opening the Device + * ------------------ + * The writer instance is opened first. This occurs when the system + * calls the "standard" open procedure via the device's procedure + * vector. The driver must implement the open function, but must call + * down to gdev_prn_async_write_open instead of calling down to + * gdev_prn_open. Before calling down to gdev_prn_async_write_open, the + * driver must: + * a - init several procedure vectors, to wit: start_render_thread, + * buffer_page, print_page_copies, + * b - init space_params.band.BandWidth, space_params.band.BandHeight, + * space_params.BufferSpace (see extended comments in gdevasyn.c + * for details on computing appropriate values). + * c - if it implements those functions, the driver must init the + * procedure vectors for: put_params, get_hardware_params, + * output_page, open_render_device. + * Notice that there are two procedure vectors: the usual std_procs, and + * the printer-specific printer_procs. + + * Since partial page support imposes extra requirements on drivers, + * such support can be disabled by zeroing out (in the async writer open + * routine, after calling down to gdev_prn_async_write_open) the + * free_up_bandlist_memory member of the driver structure. Doing so + * will, of course, cause interpretation to fail if memory runs out. + + * Once the driver calls down to gdev_prn_async_write_open, the async + * support logic will create a second instance of the driver for + * rendering, but will not open it just yet. Instead, the async logic + * will attempt to synchronize the two device instances. + + * Synchrnonizing the instances + * ---------------------------- + * While still in the gdev_prn_async_write_open routine, the async logic + * will call printer_procs.start_render_thread (which the driver is + * required to implement). start_render_thread must somehow either start a new + * thread or rendez-vous with an existing thread for use in rendering, + * then return. start_render_thread must also have caused the render thread + * to call gdev_prn_async_render_thread, passing it as an argument a magic + * cookie passed to start_render_thread. start_render_thread will only + * return once the device has been closed and all renering has been + * completed. + + * The render device will be opened on the render device's thread, by + * calling printer_procs.open_render_device. + + * Rendering Operation + * ------------------- + * During rendering, the device will not see rendering operations -- the + * first "rendering" operations the driver will see is when the renderer + * instance's print_page_copies or buffer_page routines get called. In + * both cases, the appropriate routine must then perform get_bits calls + * on the async logic in order to retrieve rendered bits, then transmit + * them to the appropriate device buffers. + + * The complication that is introduced is that which is related to + * partial pages: A buffer_page call instructs the driver to grab the + * rendered bits, but to keep the rendered bits available for later + * instead of marking on media. This implies that a buffer_page call + * opens a context where subsequent buffer_page's and print_page_copies' + * must first initialize the rendering buffers with the previous + * rendering results before calling get_bits. Drivers use the + * locate_overlay_buffer function to initialize the driver's rendering + * buffers. The first print_page_copies closes the context that was + * opened by the initial buffer_page -- the driver must go back to + * normal rendering until a new buffer_page comes along. + */ + +/* -------------- Type declarations --------------- */ + +/* typedef is in gdevprn.h */ +/* typedef struct gdev_prn_start_render_params_s gdev_prn_start_render_params;*/ +struct gdev_prn_start_render_params_s { + gx_device_printer *writer_device;/* writer dev that points to render dev */ + gx_semaphore_t *open_semaphore; /* signal this once open_code is set */ + int open_code; /* RETURNS status of open of reader device */ +}; + +/* -------- Macros used to initialize render-specific structures ------ */ + +#define init_async_render_procs(xpdev, xstart_render_thread,\ + xbuffer_page, xprint_page_copies)\ + BEGIN\ + (xpdev)->printer_procs.start_render_thread = (xstart_render_thread);\ + (xpdev)->printer_procs.buffer_page = (xbuffer_page);\ + (xpdev)->printer_procs.print_page_copies = (xprint_page_copies);\ + END + +/* -------------- Global procedure declarations --------- */ + +/* Open this printer device in ASYNC (overlapped) mode. + * + * This routine is always called by the concrete device's xx_open routine + * in lieu of gdev_prn_open. + */ +int gdev_prn_async_write_open(P4(gx_device_printer *pdev, int max_raster, + int min_band_height, int max_src_image_row)); + +/* Open the render portion of a printer device in ASYNC (overlapped) mode. + * + * This routine is always called by concrete device's xx_open_render_device + * in lieu of gdev_prn_open. + */ +int gdev_prn_async_render_open(P1(gx_device_printer *prdev)); + +/* + * Must be called by async device driver implementation (see + * gdevprna.h under "Synchronizing the Instances"). This is the + * rendering loop, which requires its own thread for as long as + * the device is open. This proc only returns after the device is closed. + */ +int /* rets 0 ok, -ve error code */ +gdev_prn_async_render_thread(P1(gdev_prn_start_render_params *)); + +#endif /* gdevprna_INCLUDED */ diff --git a/pstoraster/gdevps.c b/pstoraster/gdevps.c new file mode 100644 index 0000000000..dfb4d28486 --- /dev/null +++ b/pstoraster/gdevps.c @@ -0,0 +1,1151 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* PostScript-writing driver */ +#include "math_.h" +#include "memory_.h" +#include "time_.h" +#include "gx.h" +#include "gserrors.h" +#include "gscdefs.h" +#include "gsmatrix.h" /* for gsiparam.h */ +#include "gsiparam.h" +#include "gsline.h" +#include "gsparam.h" +#include "gxdevice.h" +#include "gscspace.h" +#include "gxdcolor.h" +#include "gzpath.h" +#include "gdevpsdf.h" +#include "gdevpstr.h" +#include "strimpl.h" +#include "sa85x.h" + +/**************************************************************** + * Notes: + * ASCII85EncodePages should use ASCIIHexEncode if LanguageLevel < 2. + * Images are never compressed; in fact, none of the other + * Distiller parameters do anything. + ****************************************************************/ + +/* ---------------- Device definition ---------------- */ + +/* Device procedures */ +private dev_proc_open_device(psw_open); +private dev_proc_output_page(psw_output_page); +private dev_proc_close_device(psw_close); +private dev_proc_copy_mono(psw_copy_mono); +private dev_proc_copy_color(psw_copy_color); +private dev_proc_put_params(psw_put_params); +private dev_proc_get_params(psw_get_params); +private dev_proc_fill_path(psw_fill_path); +private dev_proc_stroke_path(psw_stroke_path); +private dev_proc_fill_mask(psw_fill_mask); +private dev_proc_begin_image(psw_begin_image); + +#define X_DPI 720 +#define Y_DPI 720 + +typedef struct psw_path_state_s { + int num_points; /* # of points since last non-lineto */ + bool move; /* true iff last non-lineto was moveto */ + gs_point dprev[2]; /* line deltas before previous point, */ + /* if num_points - move >= 2 */ +} psw_path_state_t; + +typedef struct psw_image_params_s { + gx_bitmap_id id; + ushort width, height; +} psw_image_params_t; + +typedef struct gx_device_pswrite_s { + gx_device_psdf_common; + /* Settable parameters */ +#define LanguageLevel_default 2.0 +#define psdf_version_default psdf_version_level2 + float LanguageLevel; + /* End of parameters */ + bool ProduceEPS; + bool first_page; + long bbox_position; + psdf_binary_writer image_writer; +#define image_stream image_writer.strm +#define image_cache_size 197 +#define image_cache_reprobe_step 121 + psw_image_params_t image_cache[image_cache_size]; + bool cache_toggle; + /* Temporary state while writing a path */ + psw_path_state_t path_state; +} gx_device_pswrite; + +gs_private_st_suffix_add1_final(st_device_pswrite, gx_device_pswrite, + "gx_device_pswrite", device_pswrite_enum_ptrs, device_pswrite_reloc_ptrs, + gx_device_finalize, st_device_psdf, image_stream); + +#define psw_procs\ + { psw_open,\ + gx_upright_get_initial_matrix,\ + NULL, /* sync_output */\ + psw_output_page,\ + psw_close,\ + gx_default_rgb_map_rgb_color,\ + gx_default_rgb_map_color_rgb,\ + gdev_vector_fill_rectangle,\ + NULL, /* tile_rectangle */\ + psw_copy_mono,\ + psw_copy_color,\ + NULL, /* draw_line */\ + NULL, /* get_bits */\ + psw_get_params,\ + psw_put_params,\ + NULL, /* map_cmyk_color */\ + NULL, /* get_xfont_procs */\ + NULL, /* get_xfont_device */\ + NULL, /* map_rgb_alpha_color */\ + gx_page_device_get_page_device,\ + NULL, /* get_alpha_bits */\ + NULL, /* copy_alpha */\ + NULL, /* get_band */\ + NULL, /* copy_rop */\ + psw_fill_path,\ + psw_stroke_path,\ + psw_fill_mask,\ + gdev_vector_fill_trapezoid,\ + gdev_vector_fill_parallelogram,\ + gdev_vector_fill_triangle,\ + NULL /****** WRONG ******/, /* draw_thin_line */\ + psw_begin_image,\ + NULL, /* image_data */\ + NULL, /* end_image */\ + NULL, /* strip_tile_rectangle */\ + NULL/******psw_strip_copy_rop******/\ + } + +const gx_device_pswrite gs_pswrite_device = +{std_device_dci_type_body(gx_device_pswrite, 0, "pswrite", + &st_device_pswrite, + DEFAULT_WIDTH_10THS * X_DPI / 10, DEFAULT_HEIGHT_10THS * Y_DPI / 10, + X_DPI, Y_DPI, 3, 24, 255, 255, 256, 256), + psw_procs, + psdf_initial_values(psdf_version_default, 1 /*true */ ), /* (ASCII85EncodePages) */ + LanguageLevel_default, /* LanguageLevel */ + 0 /*false *//* ProduceEPS */ +}; + +const gx_device_pswrite gs_epswrite_device = +{std_device_dci_type_body(gx_device_pswrite, 0, "epswrite", + &st_device_pswrite, + DEFAULT_WIDTH_10THS * X_DPI / 10, DEFAULT_HEIGHT_10THS * Y_DPI / 10, + X_DPI, Y_DPI, 3, 24, 255, 255, 256, 256), + psw_procs, + psdf_initial_values(psdf_version_default, 1 /*true */ ), /* (ASCII85EncodePages) */ + LanguageLevel_default, /* LanguageLevel */ + 1 /*true *//* ProduceEPS */ +}; + +/* Vector device implementation */ +private int + psw_beginpage(P1(gx_device_vector * vdev)), psw_setlinewidth(P2(gx_device_vector * vdev, floatp width)), + psw_setcolors(P2(gx_device_vector * vdev, const gx_drawing_color * pdc)), + psw_dorect(P6(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, fixed y1, + gx_path_type_t type)), psw_beginpath(P2(gx_device_vector * vdev, gx_path_type_t type)), + psw_moveto(P6(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x, floatp y, gx_path_type_t type)), psw_lineto(P6(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x, floatp y, gx_path_type_t type)), + psw_curveto(P10(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x1, floatp y1, floatp x2, floatp y2, + floatp x3, floatp y3, gx_path_type_t type)), psw_closepath(P6(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x_start, floatp y_start, gx_path_type_t type)), + psw_endpath(P2(gx_device_vector * vdev, gx_path_type_t type)); +private const gx_device_vector_procs psw_vector_procs = +{ + /* Page management */ + psw_beginpage, + /* Imager state */ + psw_setlinewidth, + psdf_setlinecap, + psdf_setlinejoin, + psdf_setmiterlimit, + psdf_setdash, + psdf_setflat, + psdf_setlogop, + /* Other state */ + psw_setcolors, /* fill & stroke colors are the same */ + psw_setcolors, + /* Paths */ + psdf_dopath, + psw_dorect, + psw_beginpath, + psw_moveto, + psw_lineto, + psw_curveto, + psw_closepath, + psw_endpath +}; + +/* ---------------- File header ---------------- */ + +private const char *const psw_ps_header[] = +{ + "%!PS-Adobe-3.0", + "%%Pages: (atend)", + 0 +}; + +private const char *const psw_eps_header[] = +{ + "%!PS-Adobe-3.0 EPSF-3.0", + 0 +}; + +private const char *const psw_header[] = +{ + "%%EndComments", + "%%BeginProlog", + 0 +}; + +private const char *const psw_prolog[] = +{ + "%%BeginResource: procset GS_pswrite_ProcSet", + "/GS_pswrite_ProcSet 40 dict dup begin", + "/!{bind def}bind def/#{load def}!", + /* rG - */ + /* G - */ + "/rG{3{3 -1 roll 255 div}repeat setrgbcolor}!/G{255 div setgray}!/K{0 G}!", + /* r6 - */ + /* r5 - */ + /* r3 - */ + "/r6{dup 3 -1 roll rG}!/r5{dup 3 1 roll rG}!/r3{dup rG}!", + "/w/setlinewidth #/J/setlinecap #", + "/j/setlinejoin #/M/setmiterlimit #/d/setdash #/i/setflat #", + "/m/moveto #/l/lineto #/c/rcurveto #/h{p closepath}!/H{P closepath}!", + /* lx - */ + /* ly - */ + /* v - */ + /* y - */ + "/lx{0 rlineto}!/ly{0 exch rlineto}!/v{0 0 6 2 roll c}!/y{2 copy c}!", + /* re - */ + "/re{4 -2 roll m exch dup lx exch ly neg lx h}!", + /* ^ <-a> <-y> */ + "/^{3 index neg 3 index neg}!", + /* ... P - */ + "/P{count 0 gt{count -2 roll moveto p}if}!", + /* ... p - */ + "/p{count 2 idiv{count -2 roll rlineto}repeat}!", +"/f{P fill}!/f*{P eofill}!/S{P stroke}!/q/gsave #/Q/grestore #/rf{re fill}!", + "/Y{initclip P clip newpath}!/Y*{initclip P eoclip newpath}!/rY{re Y}!", + /* | */ + "/|{exch string readstring pop exch 4 1 roll 3 packedarray cvx exch 1 index def exec}!", + /* (|) + */ + "/+{dup type/nametype eq{2 index 7 add -3 bitshift 2 index mul}if}!", + /* (|) $ */ + "/@/currentfile #/${+ @ |}!", + /* Ix */ + "/Ix{[1 0 0 1 11 -2 roll exch neg exch neg]exch}!", + /* , - */ + /* If - */ + /* I - */ +"/,{true exch Ix imagemask}!/If{false exch Ix imagemask}!/I{exch Ix image}!", + 0 +}; + +private const char *const psw_1_prolog[] = +{ + 0 +}; + +private const char *const psw_1_5_prolog[] = +{ + "/Ic{exch Ix false 3 colorimage}!", + 0 +}; + +private const char *const psw_2_prolog[] = +{ + /* F */ + "/F{<>/CCITTFaxDecode filter}!", + /* X */ + /* - @X */ + /* +F */ + /* +F */ + /* @F */ + /* @C */ + "/X{/ASCII85Decode filter}!/@X{@ X}!/+F{2 index 2 index F}!/@F{@ +F}!/@C{@X +F}!", + /* (|) $X */ + /* -F */ + /* (|) $F */ + /* (|) $C */ + "/$X{+ @X |}!/-F{4 index 4 index F}!/$F{+ @ -F |}!/$C{+ @X -F |}!", + 0 +}; + +private const char *const psw_end_prolog[] = +{ + "end def", + "%%EndResource", + "%%EndProlog", + 0 +}; + +private void +psw_put_lines(stream * s, const char *const lines[]) +{ + int i; + + for (i = 0; lines[i] != 0; ++i) + pprints1(s, "%s\n", lines[i]); +} + +/* ---------------- Utilities ---------------- */ + +/* Reset the image cache. */ +private void +image_cache_reset(gx_device_pswrite * pdev) +{ + int i; + + for (i = 0; i < image_cache_size; ++i) + pdev->image_cache[i].id = gx_no_bitmap_id; + pdev->cache_toggle = false; +} + +/* Look up or enter image parameters in the cache. */ +/* Return -1 if the key is not in the cache, or its index. */ +/* If id is gx_no_bitmap_id or enter is false, do not enter it. */ +private int +image_cache_lookup(gx_device_pswrite * pdev, gx_bitmap_id id, + int width, int height, bool enter) +{ + int i1, i2; + psw_image_params_t *pip1; + psw_image_params_t *pip2; + + if (id == gx_no_bitmap_id) + return -1; + i1 = id % image_cache_size; + pip1 = &pdev->image_cache[i1]; + if (pip1->id == id && pip1->width == width && pip1->height == height) { + return i1; + } + i2 = (i1 + image_cache_reprobe_step) % image_cache_size; + pip2 = &pdev->image_cache[i2]; + if (pip2->id == id && pip2->width == width && pip2->height == height) { + return i2; + } + if (enter) { + int i = ((pdev->cache_toggle = !pdev->cache_toggle) ? i2 : i1); + psw_image_params_t *pip = &pdev->image_cache[i]; + + pip->id = id, pip->width = width, pip->height = height; + return i; + } + return -1; +} + +/* Prepare the encoding stream for image data. */ +/* Return 1 if we are using ASCII85 encoding. */ +private int +psw_image_stream_setup(gx_device_pswrite * pdev) +{ + int code = + psdf_begin_binary((gx_device_psdf *) pdev, &pdev->image_writer); + + return + (code < 0 ? code : + pdev->image_stream->state->template == &s_A85E_template ? 1 : 0); +} + +/* Clean up after writing an image. */ +private void +psw_image_cleanup(gx_device_pswrite * pdev) +{ + if (pdev->image_stream != 0) { + psdf_end_binary(&pdev->image_writer); + pdev->image_stream = 0; + } +} + +/* Write data for an image. Assumes width > 0, height > 0. */ +/****** IGNORES data_x ******/ +private void +psw_put_bits(stream * s, const byte * data, int data_x_bit, uint raster, + uint width_bits, int height) +{ + int y; + + for (y = 0; y < height; ++y) + pwrite(s, data + (data_x_bit >> 3) + y * raster, + (width_bits + 7) >> 3); +} +private int +psw_image_write(gx_device_pswrite * pdev, const char *imagestr, + const byte * data, int data_x, uint raster, gx_bitmap_id id, + int x, int y, int width, int height, int depth) +{ + stream *s = gdev_vector_stream((gx_device_vector *) pdev); + uint width_bits = width * depth; + int data_x_bit = data_x * depth; + int index = image_cache_lookup(pdev, id, width_bits, height, false); + char str[40]; + int code, encode; + + if (index >= 0) { + sprintf(str, "%d%c", index / 26, index % 26 + 'A'); + pprintd2(s, "%d %d ", x, y); + pprints2(s, "%s %s\n", str, imagestr); + return 0; + } + pprintd4(s, "%d %d %d %d ", x, y, width, height); + encode = code = psw_image_stream_setup(pdev); + if (code < 0) + return code; + if (depth == 1 && width > 16) { + /* + * We should really look at the statistics of the image before + * committing to using G4 encoding.... + */ + code = psdf_CFE_binary(&pdev->image_writer, width, height, false); + if (code < 0) + return code; + encode += 2; + } + if (id == gx_no_bitmap_id || width_bits * (ulong) height > 8000) { + const char *const uncached[4] = + { + "@", "@X", "@F", "@C" + }; + + pprints2(s, "%s %s\n", uncached[encode], imagestr); + psw_put_bits(pdev->image_stream, data, data_x_bit, raster, + width_bits, height); + psw_image_cleanup(pdev); + spputc(s, '\n'); + } else { + const char *const cached[4] = + { + "$", "$X", "$F", "$C" + }; + + index = image_cache_lookup(pdev, id, width_bits, height, true); + sprintf(str, "/%d%c ", index / 26, index % 26 + 'A'); + pputs(s, str); + if (depth != 1) + pprintld1(s, "%ld ", ((width_bits + 7) >> 3) * (ulong) height); + pprints1(s, "%s\n", cached[encode]); + psw_put_bits(pdev->image_stream, data, data_x_bit, raster, + width_bits, height); + psw_image_cleanup(pdev); + pprints1(s, "\n%s\n", imagestr); + } + return 0; +} + +/* Print a matrix. */ +private void +psw_put_matrix(stream * s, const gs_matrix * pmat) +{ + pprintg6(s, "[%g %g %g %g %g %g]", + pmat->xx, pmat->xy, pmat->yx, pmat->yy, pmat->tx, pmat->ty); +} + +/* ---------------- Vector device implementation ---------------- */ + +#define pdev ((gx_device_pswrite *)vdev) + +private int +psw_beginpage(gx_device_vector * vdev) +{ + stream *s = vdev->strm; + long page = vdev->PageCount + 1; + + if (pdev->first_page) { + psw_put_lines(s, + (pdev->ProduceEPS ? psw_eps_header : psw_ps_header)); + if (ftell(vdev->file) < 0) { /* File is not seekable. */ + pdev->bbox_position = -1; + pputs(s, "%%BoundingBox: (atend)\n"); + pputs(s, "%%HiResBoundingBox: (atend)\n"); + } else { /* File is seekable, leave room to rewrite bbox. */ + pdev->bbox_position = stell(s); + pputs(s, "%...............................................................\n"); + pputs(s, "%...............................................................\n"); + } + pprints1(s, "%%%%Creator: %s ", gs_product); + pprintld1(s, "%ld ", (long)gs_revision); + pprints1(s, "(%s)\n", vdev->dname); + { + struct tm tms; + time_t t; + char date_str[25]; + + time(&t); + tms = *localtime(&t); + sprintf(date_str, "%d/%02d/%02d %02d:%02d:%02d", + tms.tm_year + 1900, tms.tm_mon + 1, tms.tm_mday, + tms.tm_hour, tms.tm_min, tms.tm_sec); + pprints1(s, "%%%%CreationDate: %s\n", date_str); + } + if (pdev->params.ASCII85EncodePages) + pputs(s, "%%DocumentData: Clean7Bit\n"); + if (pdev->LanguageLevel == 2.0) + pputs(s, "%%LanguageLevel: 2\n"); + else if (pdev->LanguageLevel == 1.5) + pputs(s, "%%Extensions: CMYK\n"); + psw_put_lines(s, psw_header); + psw_put_lines(s, psw_prolog); + if (pdev->LanguageLevel < 1.5) + psw_put_lines(s, psw_1_prolog); + else { + psw_put_lines(s, psw_1_5_prolog); + if (pdev->LanguageLevel > 1.5) + psw_put_lines(s, psw_2_prolog); + } + psw_put_lines(s, psw_end_prolog); + } + pprintld2(s, "%%%%Page: %ld %ld\n%%%%BeginPageSetup\n", page, page); + pputs(s, "/pagesave save def GS_pswrite_ProcSet begin\n"); + if (!pdev->ProduceEPS) { + int width = (int)(vdev->width * 72.0 / vdev->HWResolution[0] + 0.5); + int height = (int)(vdev->height * 72.0 / vdev->HWResolution[1] + 0.5); + + if (pdev->LanguageLevel > 1.5) + pprintd2(s, "<< /PageSize [%d %d] >> setpagedevice\n", + width, height); + else { + typedef struct ps_ { + const char *size_name; + int width, height; + } page_size; + static const page_size sizes[] = { + {"/11x17", 792, 1224}, + {"/a3", 842, 1190}, + {"/a4", 595, 842}, + {"/b5", 501, 709}, + {"/ledger", 1224, 792}, + {"/legal", 612, 1008}, + {"/letter", 612, 792}, + {"null", 0, 0} + }; + const page_size *p = sizes; + + while (p->size_name[0] == '/' && + (p->width != width || p->height != height)) + ++p; + pprintd2(s, "%d %d ", width, height); + pprints1(s, "%s PS\n", p->size_name); + } + } + pprintg2(s, "%g %g scale\n%%%%EndPageSetup\n", + 72.0 / vdev->HWResolution[0], 72.0 / vdev->HWResolution[1]); + return 0; +} + +private int +psw_setlinewidth(gx_device_vector * vdev, floatp width) +{ /* + * The vector scale is 1, but we have to rescale the line width + * (which is given in device pixels) to account for the actual + * page scaling in effect. + */ + return psdf_setlinewidth(vdev, width * 72.0 / vdev->HWResolution[1]); +} + +private int +psw_setcolors(gx_device_vector * vdev, const gx_drawing_color * pdc) +{ + if (!gx_dc_is_pure(pdc)) + return_error(gs_error_rangecheck); + /* PostScript only keeps track of a single color. */ + vdev->fill_color = *pdc; + vdev->stroke_color = *pdc; + { + stream *s = gdev_vector_stream(vdev); + gx_color_index color = gx_dc_pure_color(pdc); + int r = color >> 16; + int g = (color >> 8) & 0xff; + int b = color & 0xff; + + if (r == g && g == b) { + if (r == 0) + pputs(s, "K\n"); + else + pprintd1(s, "%d G\n", r); + } else if (r == g) + pprintd2(s, "%d %d r6\n", b, r); + else if (g == b) + pprintd2(s, "%d %d r3\n", r, g); + else if (r == b) + pprintd2(s, "%d %d r5\n", g, b); + else + pprintd3(s, "%d %d %d rG\n", r, g, b); + } + return 0; +} + +/* Redefine dorect to recognize rectangle fills. */ +private int +psw_dorect(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, fixed y1, + gx_path_type_t type) +{ + if ((type & ~gx_path_type_rule) != gx_path_type_fill) + return psdf_dorect(vdev, x0, y0, x1, y1, type); + pprintg4(gdev_vector_stream(vdev), "%g %g %g %g rf\n", + fixed2float(x0), fixed2float(y0), + fixed2float(x1 - x0), fixed2float(y1 - y0)); + return 0; +} + +/* + * We redefine path tracing to use a compact form for polygons; also, + * we only need to write coordinates with 2 decimals of precision, + * since this is 10 times more precise than any existing output device. + */ +#define round_coord(v) (floor((v) * 100 + 0.5) / 100.0) +private void +print_coord2(stream * s, floatp x, floatp y, const char *str) +{ + pprintg2(s, "%g %g ", round_coord(x), round_coord(y)); + if (str != 0) + pputs(s, str); +} +#undef round_coord + +private int +psw_beginpath(gx_device_vector * vdev, gx_path_type_t type) +{ + pdev->path_state.num_points = 0; + pdev->path_state.move = false; + return 0; +} + +private int +psw_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y, + gx_path_type_t type) +{ + stream *s = gdev_vector_stream(vdev); + + if (pdev->path_state.num_points > pdev->path_state.move) + pputs(s, (pdev->path_state.move ? "P\n" : "p\n")); + print_coord2(s, x, y, NULL); + pdev->path_state.num_points = 1; + pdev->path_state.move = true; + return 0; +} + +private int +psw_lineto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y, + gx_path_type_t type) +{ + double dx = x - x0, dy = y - y0; + + /* + * Omit null lines when filling. + ****** MAYBE WRONG IF PATH CONSISTS ONLY OF NULL LINES. ****** + */ + if (dx != 0 || dy != 0) { + stream *s = gdev_vector_stream(vdev); + + if (pdev->path_state.num_points - pdev->path_state.move >= 2 && + dx == -pdev->path_state.dprev[1].x && + dy == -pdev->path_state.dprev[1].y + ) + pputs(s, "^ "); + else + print_coord2(s, dx, dy, NULL); + pdev->path_state.num_points++; + pdev->path_state.dprev[1] = pdev->path_state.dprev[0]; + pdev->path_state.dprev[0].x = dx; + pdev->path_state.dprev[0].y = dy; + } + return 0; +} + +private int +psw_curveto(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3, + gx_path_type_t type) +{ + stream *s = gdev_vector_stream(vdev); + double dx1 = x1 - x0, dy1 = y1 - y0; + double dx2 = x2 - x0, dy2 = y2 - y0; + double dx3 = x3 - x0, dy3 = y3 - y0; + + if (pdev->path_state.num_points > 0) + pputs(s, (pdev->path_state.move ? + (pdev->path_state.num_points == 1 ? "m\n" : "P\n") : + "p\n")); + if (dx1 == 0 && dy1 == 0) { + print_coord2(s, dx2, dy2, NULL); + print_coord2(s, dx3, dy3, "v\n"); + } else if (x3 == x2 && y3 == y2) { + print_coord2(s, dx1, dy1, NULL); + print_coord2(s, dx2, dy2, "y\n"); + } else { + print_coord2(s, dx1, dy1, NULL); + print_coord2(s, dx2, dy2, NULL); + print_coord2(s, dx3, dy3, "c\n"); + } + pdev->path_state.num_points = 0; + pdev->path_state.move = false; + return 0; +} + +private int +psw_closepath(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x_start, floatp y_start, gx_path_type_t type) +{ + pputs(gdev_vector_stream(vdev), + (pdev->path_state.num_points > 0 && pdev->path_state.move ? + "H\n" : "h\n")); + pdev->path_state.num_points = 0; + pdev->path_state.move = false; + return 0; +} + +private int +psw_endpath(gx_device_vector * vdev, gx_path_type_t type) +{ + stream *s = vdev->strm; + const char *star = (type & gx_path_type_even_odd ? "*" : ""); + + if (pdev->path_state.num_points > 0 && !pdev->path_state.move) + pputs(s, "p "); + if (type & gx_path_type_fill) { + if (type & (gx_path_type_stroke | gx_path_type_clip)) + pprints1(s, "q f%s Q ", star); + else + pprints1(s, "f%s\n", star); + } + if (type & gx_path_type_stroke) { + if (type & gx_path_type_clip) + pputs(s, "q S Q "); + else + pputs(s, "S\n"); + } + if (type & gx_path_type_clip) + pprints1(s, "Y%s\n", star); + return 0; +} + +#undef pdev + +/* ---------------- Driver procedures ---------------- */ + +#define vdev ((gx_device_vector *)dev) +#define pdev ((gx_device_pswrite *)dev) + +/* ------ Open/close/page ------ */ + +/* Open the device. */ +private int +psw_open(gx_device * dev) +{ + vdev->v_memory = dev->memory; +/****** WRONG ******/ + vdev->vec_procs = &psw_vector_procs; + { + int code = gdev_vector_open_file_bbox(vdev, 512, true); + + if (code < 0) + return code; + } + gdev_vector_init(vdev); + pdev->first_page = true; + pdev->binary_ok = !pdev->params.ASCII85EncodePages; + image_cache_reset(pdev); + return 0; +} + +/* Wrap up ("output") a page. */ +private int +psw_output_page(gx_device * dev, int num_copies, int flush) +{ + stream *s = gdev_vector_stream(vdev); + + if (num_copies != 1) + pprintd1(s, "userdict /#copies %d put\n", num_copies); + pprints1(s, "end %s pagesave restore\n%%%%PageTrailer\n", + (flush ? "showpage" : "copypage")); + sflush(s); + vdev->in_page = false; + pdev->first_page = false; + gdev_vector_reset(vdev); + image_cache_reset(pdev); + return 0; +} + +/* Close the device. */ +/* Note that if this is being called as a result of finalization, */ +/* the stream may no longer exist; but the file will still be open. */ +private int +psw_close(gx_device * dev) +{ + FILE *f = vdev->file; + + fprintf(f, "%%%%Trailer\n%%%%Pages: %ld\n", dev->PageCount); + { + gs_rect bbox; + long save_pos; + + gx_device_bbox_bbox(vdev->bbox_device, &bbox); + if (pdev->bbox_position >= 0) { + save_pos = ftell(f); + fseek(f, pdev->bbox_position, SEEK_SET); + } + fprintf(f, "%%%%BoundingBox: %d %d %d %d\n", + (int)floor(bbox.p.x), (int)floor(bbox.p.y), + (int)ceil(bbox.q.x), (int)ceil(bbox.q.y)); + fprintf(f, "%%%%HiResBoundingBox: %f %f %f %f\n", + bbox.p.x, bbox.p.y, bbox.q.x, bbox.q.y); + if (pdev->bbox_position >= 0) { + fputc('%', f); + fseek(f, save_pos, SEEK_SET); + } + } + if (!pdev->ProduceEPS) + fputs("%%EOF\n", f); + gdev_vector_close_file(vdev); + return 0; +} + +/* ---------------- Get/put parameters ---------------- */ + +/* Get parameters. */ +private int +psw_get_params(gx_device * dev, gs_param_list * plist) +{ + int code = gdev_psdf_get_params(dev, plist); + int ecode; + + if (code < 0) + return code; + if ((ecode = param_write_float(plist, "LanguageLevel", &pdev->LanguageLevel)) < 0) + return ecode; + return code; +} + +/* Put parameters. */ +private int +psw_put_params(gx_device * dev, gs_param_list * plist) +{ + int ecode = 0; + int code; + gs_param_name param_name; + float ll = pdev->LanguageLevel; + psdf_version save_version = pdev->version; + + switch (code = param_read_float(plist, (param_name = "LanguageLevel"), &ll)) { + case 0: + if (ll == 1.0 || ll == 1.5 || ll == 2.0) + break; + code = gs_error_rangecheck; + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 1: + ; + } + + if (ecode < 0) + return ecode; + /* + * We have to set version to the new value, because the set of + * legal parameter values for psdf_put_params varies according to + * the version. + */ + { + static const psdf_version vv[3] = + { + psdf_version_level1, psdf_version_level1_color, + psdf_version_level2 + }; + + pdev->version = vv[(int)(ll * 2) - 2]; + } + code = gdev_psdf_put_params(dev, plist); + if (code < 0) { + pdev->version = save_version; + return code; + } + pdev->LanguageLevel = ll; + return code; +} + +/* ---------------- Images ---------------- */ + +/* Copy a monochrome bitmap. */ +private int +psw_copy_mono(gx_device * dev, const byte * data, + int data_x, int raster, gx_bitmap_id id, int x, int y, int w, int h, + gx_color_index zero, gx_color_index one) +{ + gx_drawing_color color; + const char *op; + int code = 0; + + if (w <= 0 || h <= 0) + return 0; + (*dev_proc(vdev->bbox_device, copy_mono)) + ((gx_device *) vdev->bbox_device, data, data_x, raster, id, + x, y, w, h, zero, one); + if (one == gx_no_color_index) { + color_set_pure(&color, zero); + code = gdev_vector_update_fill_color((gx_device_vector *) pdev, + &color); + op = "If"; + } else if (zero == vdev->black && one == vdev->white) + op = "1 I"; + else { + if (zero != gx_no_color_index) { + code = (*dev_proc(dev, fill_rectangle)) (dev, x, y, w, h, zero); + if (code < 0) + return code; + } + color_set_pure(&color, one); + code = gdev_vector_update_fill_color((gx_device_vector *) pdev, + &color); + op = ","; + } + if (code < 0) + return 0; + return psw_image_write(pdev, op, data, data_x, raster, id, + x, y, w, h, 1); +} + +/* Copy a color bitmap. */ +private int +psw_copy_color(gx_device * dev, + const byte * data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int w, int h) +{ + int depth = dev->color_info.depth; + const byte *bits = data + data_x * 3; + char op[6]; + + if (w <= 0 || h <= 0) + return 0; + (*dev_proc(vdev->bbox_device, copy_color)) + ((gx_device *) vdev->bbox_device, data, data_x, raster, id, + x, y, w, h); + /* + * If this is a 1-pixel-high image, check for it being all the + * same color, and if so, fill it as a rectangle. + */ + if (h == 1 && !memcmp(bits, bits + 3, (w - 1) * 3)) { + return (*dev_proc(dev, fill_rectangle)) + (dev, x, y, w, h, (bits[0] << 16) + (bits[1] << 8) + bits[2]); + } + sprintf(op, "%d Ic", depth / 3); /* RGB */ + return psw_image_write(pdev, op, data, data_x, raster, id, + x, y, w, h, depth); +} + +/* Fill or stroke a path. */ +/* We redefine these to skip empty paths. */ +private int +psw_fill_path(gx_device * dev, const gs_imager_state * pis, + gx_path * ppath, const gx_fill_params * params, + const gx_device_color * pdevc, const gx_clip_path * pcpath) +{ + if (gx_path_is_void(ppath)) + return 0; + return gdev_vector_fill_path(dev, pis, ppath, params, pdevc, pcpath); +} +private int +psw_stroke_path(gx_device * dev, const gs_imager_state * pis, + gx_path * ppath, const gx_stroke_params * params, + const gx_device_color * pdevc, const gx_clip_path * pcpath) +{ + if (gx_path_is_void(ppath) && + (gx_path_is_null(ppath) || + gs_currentlinecap((const gs_state *)pis) != gs_cap_round) + ) + return 0; + return gdev_vector_stroke_path(dev, pis, ppath, params, pdevc, pcpath); +} + +/* Fill a mask. */ +private int +psw_fill_mask(gx_device * dev, + const byte * data, int data_x, int raster, gx_bitmap_id id, + int x, int y, int w, int h, + const gx_drawing_color * pdcolor, int depth, + gs_logical_operation_t lop, const gx_clip_path * pcpath) +{ + if (w <= 0 || h <= 0) + return 0; + if (depth > 1 || + gdev_vector_update_fill_color(vdev, pdcolor) < 0 || + gdev_vector_update_clip_path(vdev, pcpath) < 0 || + gdev_vector_update_log_op(vdev, lop) < 0 + ) + return gx_default_fill_mask(dev, data, data_x, raster, id, + x, y, w, h, pdcolor, depth, lop, pcpath); + (*dev_proc(vdev->bbox_device, fill_mask)) + ((gx_device *) vdev->bbox_device, data, data_x, raster, id, + x, y, w, h, pdcolor, depth, lop, pcpath); + return psw_image_write(pdev, ",", data, data_x, raster, id, + x, y, w, h, 1); +} + +/* ---------------- High-level images ---------------- */ + +private image_enum_proc_plane_data(psw_image_plane_data); +private image_enum_proc_end_image(psw_image_end_image); +private const gx_image_enum_procs_t psw_image_enum_procs = +{ + psw_image_plane_data, psw_image_end_image +}; + +/* Start processing an image. */ +private int +psw_begin_image(gx_device * dev, + const gs_imager_state * pis, const gs_image_t * pim, + gs_image_format_t format, const gs_int_rect * prect, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * mem, gx_image_enum_common_t ** pinfo) +{ + gdev_vector_image_enum_t *pie = + gs_alloc_struct(mem, gdev_vector_image_enum_t, + &st_vector_image_enum, "psw_begin_image"); + const gs_color_space *pcs = pim->ColorSpace; + gs_color_space_index index; + int num_components; + bool can_do = prect == 0; + int code; + + if (pie == 0) + return_error(gs_error_VMerror); + pie->memory = mem; + *pinfo = (gx_image_enum_common_t *) pie; + if (!pim->ImageMask) { + index = gs_color_space_get_index(pcs); + num_components = gs_color_space_num_components(pcs); + } + if (pdev->LanguageLevel < 2 && !pim->ImageMask) { /* + * Restrict ourselves to Level 1 images: device color spaces, [0 + * 1] decode, bits per component <= 8, no CombineWithColor. + */ + if (pim->BitsPerComponent > 8 || pim->CombineWithColor) + can_do = false; + else { + int i; + + switch (index) { + case gs_color_space_index_DeviceGray: + case gs_color_space_index_DeviceRGB: + case gs_color_space_index_DeviceCMYK: + for (i = 0; i < num_components * 2; ++i) + if (pim->Decode[i] != (i & 1)) + can_do = false; + break; + default: + can_do = false; + } + } + } + if (!can_do || + gdev_vector_begin_image(vdev, pis, pim, format, prect, pdcolor, + pcpath, mem, &psw_image_enum_procs, pie) < 0 || + (code = psw_image_stream_setup(pdev)) < 0 + ) + return gx_default_begin_image(dev, pis, pim, format, prect, + pdcolor, pcpath, mem, + &pie->default_info); + /* Write the image/colorimage/imagemask preamble. */ + { + stream *s = gdev_vector_stream((gx_device_vector *) pdev); + const char *source = (code ? "@X" : "@"); + gs_matrix imat; + + pputs(s, "q"); + (*dev_proc(dev, get_initial_matrix)) (dev, &imat); + gs_matrix_scale(&imat, 72.0 / dev->HWResolution[0], + 72.0 / dev->HWResolution[1], &imat); + gs_matrix_invert(&imat, &imat); + gs_matrix_multiply(&ctm_only(pis), &imat, &imat); + psw_put_matrix(s, &imat); + pprintd2(s, "concat\n%d %d ", pie->width, pie->height); + if (pim->ImageMask) { + pputs(s, (pim->Decode[0] == 0 ? "false" : "true")); + psw_put_matrix(s, &pim->ImageMatrix); + pprints1(s, "%s imagemask\n", source); + } else { + pprintd1(s, "%d", pim->BitsPerComponent); + psw_put_matrix(s, &pim->ImageMatrix); + if (index == gs_color_space_index_DeviceGray) + pprints1(s, "%s image\n", source); + else { + if (format == gs_image_format_chunky) + pprints1(s, "%s false", source); + else + pprints2(s, "%s %strue", source, + "dup dup dup " + (16 - num_components * 4)); + pprintd1(s, " %d colorimage\n", num_components); + } + } + } + return 0; +} + +/* Process the next piece of an image. */ +private int +psw_image_plane_data(gx_device * dev, + gx_image_enum_common_t * info, const gx_image_plane_t * planes, int height) +{ + gdev_vector_image_enum_t *pie = (gdev_vector_image_enum_t *) info; + + if (pie->default_info) + return gx_image_plane_data(pie->default_info, planes, height); + gx_image_plane_data(pie->bbox_info, planes, height); + { + int pi; + + for (pi = 0; pi < pie->num_planes; ++pi) + psw_put_bits(pdev->image_stream, planes[pi].data, + planes[pi].data_x * info->plane_depths[pi], + planes[pi].raster, + pie->width * info->plane_depths[pi], + height); + } + return (pie->y += height) >= pie->height; +} + +/* Clean up by releasing the buffers. */ +private int +psw_image_end_image(gx_device * dev, gx_image_enum_common_t * info, + bool draw_last) +{ + gdev_vector_image_enum_t *pie = (gdev_vector_image_enum_t *) info; + int code; + + code = gdev_vector_end_image(vdev, pie, draw_last, pdev->white); + if (code > 0) { + psw_image_cleanup(pdev); + pputs(pdev->strm, "\nQ\n"); + } + return code; +} diff --git a/pstoraster/gdevpsde.c b/pstoraster/gdevpsde.c new file mode 100644 index 0000000000..9389b60ab2 --- /dev/null +++ b/pstoraster/gdevpsde.c @@ -0,0 +1,282 @@ +/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Embedded font writing */ +#include "memory_.h" +#include "gx.h" +#include "gserrors.h" +#include "gsccode.h" +#include "gsmatrix.h" +#include "gxfixed.h" +#include "gxfont.h" +#include "gxfont1.h" +#include "stream.h" +#include "gdevpstr.h" +#include "gdevpsdf.h" + +private int +embed_table(gs_param_list * plist, const char *key, const float *values, + int count) +{ + if (count != 0) { + gs_param_float_array fa; + + fa.size = count; + fa.data = values; + return param_write_float_array(plist, key, &fa); + } + return 0; +} + +private void +embed_uid(stream * s, const gs_uid * puid) +{ + if (uid_is_UniqueID(puid)) + pprintld1(s, "/UniqueID %ld def\n", puid->id); + else if (uid_is_XUID(puid)) { + uint i, n = uid_XUID_size(puid); + + pputs(s, "/XUID ["); + for (i = 0; i < n; ++i) + pprintld1(s, "%ld ", uid_XUID_values(puid)[i]); + pputs(s, "] def\n"); + } +} + +/* Write an embedded Type 1 font. */ +int +psdf_embed_type1_font(stream * s, gs_font_type1 * pfont) +{ + const gs_type1_data *const pdata = &pfont->data; + gs_param_list *plist; + param_printer_params_t ppp; + int code; + + ppp = param_printer_params_default; + ppp.item_suffix = " def\n"; + code = psdf_alloc_param_printer(&plist, &ppp, s, + print_binary_ok, s->memory); + if (code < 0) + return 0; + + /* Write the font header. */ + + pputs(s, "%!PS-AdobeFont-1.0: "); + pwrite(s, pfont->font_name.chars, pfont->font_name.size); + pputs(s, "\n11 dict begin\n"); + + /* Write FontInfo. Currently we don't write anything there. */ + + pputs(s, "/FontInfo 1 dict dup begin\n"); + pputs(s, "end readonly def\n"); + + /* Write the main font dictionary. */ + + pputs(s, "/FontName /"); + pwrite(s, pfont->font_name.chars, pfont->font_name.size); + pputs(s, " def\n"); + pputs(s, "/Encoding "); + switch (pfont->encoding_index) { + case 0: + pputs(s, "StandardEncoding"); + break; + case 1: + pputs(s, "ISOLatin1Encoding"); + break; + default:{ + gs_char i; + + pputs(s, "256 array\n"); + pputs(s, "0 1 255 {1 index exch /.notdef put} for\n"); + for (i = 0; i < 256; ++i) { + gs_glyph glyph = + (*pfont->procs.encode_char) (NULL, (gs_font *) pfont, &i); + const char *namestr; + uint namelen; + + if (glyph != gs_no_glyph && + (namestr = (*pfont->procs.callbacks.glyph_name) (glyph, &namelen)) != 0 && + !(namelen == 7 && !memcmp(namestr, ".notdef", 7)) + ) { + pprintd1(s, "dup %d /", (int)i); + pwrite(s, namestr, namelen); + pputs(s, " put\n"); + } + } + pputs(s, "readonly"); + } + } + pputs(s, " def\n"); + pprintg6(s, "/FontMatrix [%g %g %g %g %g %g] readonly def\n", + pfont->FontMatrix.xx, pfont->FontMatrix.xy, + pfont->FontMatrix.yx, pfont->FontMatrix.yy, + pfont->FontMatrix.tx, pfont->FontMatrix.ty); + embed_uid(s, &pfont->UID); + pprintg4(s, "/FontBBox {%g %g %g %g} readonly def\n", + pfont->FontBBox.p.x, pfont->FontBBox.p.y, + pfont->FontBBox.q.x, pfont->FontBBox.q.y); + { + private const gs_param_item_t font_items[] = + { + {"FontType", gs_param_type_int, + offset_of(gs_font_type1, FontType)}, + {"PaintType", gs_param_type_int, + offset_of(gs_font_type1, PaintType)}, + {"StrokeWidth", gs_param_type_float, + offset_of(gs_font_type1, StrokeWidth)}, + gs_param_item_end + }; + + code = gs_param_write_items(plist, pfont, NULL, font_items); + if (code < 0) + return code; + } + pputs(s, "currentdict end\n"); + + /* Write the Private dictionary. */ + + pputs(s, "dup /Private 17 dict dup begin\n"); + pputs(s, "/-|{string currentfile exch readstring pop}executeonly def\n"); + pputs(s, "/|-{noaccess def}executeonly def\n"); + pputs(s, "/|{noaccess put}executeonly def\n"); + { + private const gs_param_item_t private_items[] = + { + {"lenIV", gs_param_type_int, + offset_of(gs_type1_data, lenIV)}, + {"BlueFuzz", gs_param_type_int, + offset_of(gs_type1_data, BlueFuzz)}, + {"BlueScale", gs_param_type_float, + offset_of(gs_type1_data, BlueScale)}, + {"BlueShift", gs_param_type_float, + offset_of(gs_type1_data, BlueShift)}, + {"ExpansionFactor", gs_param_type_float, + offset_of(gs_type1_data, ExpansionFactor)}, + {"ForceBold", gs_param_type_bool, + offset_of(gs_type1_data, ForceBold)}, + {"LanguageGroup", gs_param_type_int, + offset_of(gs_type1_data, LanguageGroup)}, + {"RndStemUp", gs_param_type_bool, + offset_of(gs_type1_data, RndStemUp)}, + gs_param_item_end + }; + gs_type1_data defaults; + + defaults.lenIV = 4; + defaults.BlueFuzz = 1; + defaults.BlueScale = 0.039625; + defaults.BlueShift = 7.0; + defaults.ExpansionFactor = 0.06; + defaults.ForceBold = false; + defaults.LanguageGroup = 0; + defaults.RndStemUp = true; + code = gs_param_write_items(plist, pdata, &defaults, private_items); + if (code < 0) + return code; + embed_table(plist, "BlueValues", pdata->BlueValues.values, + pdata->BlueValues.count); + embed_table(plist, "OtherBlues", pdata->OtherBlues.values, + pdata->OtherBlues.count); + embed_table(plist, "FamilyBlues", pdata->FamilyBlues.values, + pdata->FamilyBlues.count); + embed_table(plist, "FamilyOtherBlues", pdata->FamilyOtherBlues.values, + pdata->FamilyOtherBlues.count); + embed_table(plist, "StdHW", pdata->StdHW.values, + pdata->StdHW.count); + embed_table(plist, "StemSnapH", pdata->StemSnapH.values, + pdata->StemSnapH.count); + embed_table(plist, "StemSnapV", pdata->StemSnapV.values, + pdata->StemSnapV.count); + } + embed_uid(s, &pfont->UID); + pputs(s, "/MinFeature{16 16} |-\n"); + pputs(s, "/password 5839 def\n"); + + /* Write the Subrs. */ + + { + int n, i; + gs_const_string str; + + for (n = 0; + (*pdata->procs->subr_data) (pfont, n, false, &str) != + gs_error_rangecheck; + ) + ++n; + pprintd1(s, "/Subrs %d array\n", n); + for (i = 0; i < n; ++i) + if ((*pdata->procs->subr_data) (pfont, i, false, &str) >= 0) { + char buf[50]; + + sprintf(buf, "dup %d %u -| ", i, str.size); + pputs(s, buf); + pwrite(s, str.data, str.size); + pputs(s, " |\n"); + } + pputs(s, "|-\n"); + } + + /* We don't write OtherSubrs -- there had better not be any! */ + + /* Write the CharStrings. */ + + { + int num_chars = 0; + gs_glyph glyph; + int index = 0; + gs_const_string gdata; + int code; + + for (glyph = gs_no_glyph, index = 0; + code = (*pdata->procs->next_glyph) (pfont, &index, &glyph), + index != 0; + ) + if (code == 0 && (*pdata->procs->glyph_data) (pfont, glyph, &gdata) >= 0) + ++num_chars; + pprintd1(s, "2 index /CharStrings %d dict dup begin\n", num_chars); + for (glyph = gs_no_glyph, index = 0; + code = (*pdata->procs->next_glyph) (pfont, &index, &glyph), + index != 0; + ) + if (code == 0 && (*pdata->procs->glyph_data) (pfont, glyph, &gdata) >= 0) { + uint gssize; + const char *gstr = + (*pfont->procs.callbacks.glyph_name) (glyph, &gssize); + + pputs(s, "/"); + pwrite(s, gstr, gssize); + pprintd1(s, " %d -| ", gdata.size); + pwrite(s, gdata.data, gdata.size); + pputs(s, " |-\n"); + } + } + + /* Wrap up. */ + + pputs(s, "end\nend\nreadonly put\nnoaccess put\n"); + pputs(s, "dup/FontName get exch definefont pop\n"); + psdf_free_param_printer(plist); + return 0; +} diff --git a/pstoraster/gdevpsdf.c b/pstoraster/gdevpsdf.c new file mode 100644 index 0000000000..38e5f40983 --- /dev/null +++ b/pstoraster/gdevpsdf.c @@ -0,0 +1,514 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Common utilities for PostScript and PDF writers */ +#include "string_.h" +#include "gx.h" +#include "gserrors.h" +#include "gdevpsdf.h" +#include "gdevpstr.h" +#include "scanchar.h" +#include "strimpl.h" +#include "sa85x.h" +#include "scfx.h" +#include "sstring.h" + +/* Structure descriptor */ +public_st_device_psdf(); + +/* ---------------- Vector implementation procedures ---------------- */ + +int +psdf_setlinewidth(gx_device_vector * vdev, floatp width) +{ + pprintg1(gdev_vector_stream(vdev), "%g w\n", width); + return 0; +} + +int +psdf_setlinecap(gx_device_vector * vdev, gs_line_cap cap) +{ + pprintd1(gdev_vector_stream(vdev), "%d J\n", cap); + return 0; +} + +int +psdf_setlinejoin(gx_device_vector * vdev, gs_line_join join) +{ + pprintd1(gdev_vector_stream(vdev), "%d j\n", join); + return 0; +} + +int +psdf_setmiterlimit(gx_device_vector * vdev, floatp limit) +{ + pprintg1(gdev_vector_stream(vdev), "%g M\n", limit); + return 0; +} + +int +psdf_setdash(gx_device_vector * vdev, const float *pattern, uint count, + floatp offset) +{ + stream *s = gdev_vector_stream(vdev); + int i; + + pputs(s, "[ "); + for (i = 0; i < count; ++i) + pprintg1(s, "%g ", pattern[i]); + pprintg1(s, "] %g d\n", offset); + return 0; +} + +int +psdf_setflat(gx_device_vector * vdev, floatp flatness) +{ + pprintg1(gdev_vector_stream(vdev), "%g i\n", flatness); + return 0; +} + +int +psdf_setlogop(gx_device_vector * vdev, gs_logical_operation_t lop, + gs_logical_operation_t diff) +{ +/****** SHOULD AT LEAST DETECT SET-0 & SET-1 ******/ + return 0; +} + +int +psdf_setfillcolor(gx_device_vector * vdev, const gx_drawing_color * pdc) +{ + return psdf_set_color(vdev, pdc, "rg"); +} + +int +psdf_setstrokecolor(gx_device_vector * vdev, const gx_drawing_color * pdc) +{ + return psdf_set_color(vdev, pdc, "RG"); +} + +int +psdf_dorect(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, fixed y1, + gx_path_type_t type) +{ + int code = (*vdev_proc(vdev, beginpath)) (vdev, type); + + if (code < 0) + return code; + pprintg4(gdev_vector_stream(vdev), "%g %g %g %g re\n", + fixed2float(x0), fixed2float(y0), + fixed2float(x1 - x0), fixed2float(y1 - y0)); + return (*vdev_proc(vdev, endpath)) (vdev, type); +} + +int +psdf_beginpath(gx_device_vector * vdev, gx_path_type_t type) +{ + return 0; +} + +int +psdf_moveto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y, + bool first, gx_path_type_t type) +{ + pprintg2(gdev_vector_stream(vdev), "%g %g m\n", x, y); + return 0; +} + +int +psdf_lineto(gx_device_vector * vdev, floatp x0, floatp y0, floatp x, floatp y, + gx_path_type_t type) +{ + pprintg2(gdev_vector_stream(vdev), "%g %g l\n", x, y); + return 0; +} + +int +psdf_curveto(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x1, floatp y1, floatp x2, floatp y2, floatp x3, floatp y3, + gx_path_type_t type) +{ + if (x1 == x0 && y1 == y0) + pprintg4(gdev_vector_stream(vdev), "%g %g %g %g v\n", + x2, y2, x3, y3); + else if (x3 == x2 && y3 == y2) + pprintg4(gdev_vector_stream(vdev), "%g %g %g %g y\n", + x1, y1, x2, y2); + else + pprintg6(gdev_vector_stream(vdev), "%g %g %g %g %g %g c\n", + x1, y1, x2, y2, x3, y3); + return 0; +} + +int +psdf_closepath(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x_start, floatp y_start, gx_path_type_t type) +{ + pputs(gdev_vector_stream(vdev), "h\n"); + return 0; +} + +/* endpath is deliberately omitted. */ + +/* ---------------- Utilities ---------------- */ + +int +psdf_set_color(gx_device_vector * vdev, const gx_drawing_color * pdc, + const char *rgs) +{ + if (!gx_dc_is_pure(pdc)) + return_error(gs_error_rangecheck); + { + stream *s = gdev_vector_stream(vdev); + gx_color_index color = gx_dc_pure_color(pdc); + float r = (color >> 16) / 255.0; + float g = ((color >> 8) & 0xff) / 255.0; + float b = (color & 0xff) / 255.0; + + if (r == g && g == b) + pprintg1(s, "%g", r), pprints1(s, " %s\n", rgs + 1); + else + pprintg3(s, "%g %g %g", r, g, b), pprints1(s, " %s\n", rgs); + } + return 0; +} + +/* ---------------- Binary data writing ---------------- */ + +/* Begin writing binary data. */ +int +psdf_begin_binary(gx_device_psdf * pdev, psdf_binary_writer * pbw) +{ + pbw->strm = pdev->strm; + pbw->dev = pdev; + /* If not binary, set up the encoding stream. */ + if (!pdev->binary_ok) + psdf_encode_binary(pbw, &s_A85E_template, NULL); + return 0; +} + +/* Add an encoding filter. The client must have allocated the stream state, */ +/* if any, using pdev->v_memory. */ +int +psdf_encode_binary(psdf_binary_writer * pbw, const stream_template * template, + stream_state * ss) +{ + gx_device_psdf *pdev = pbw->dev; + gs_memory_t *mem = pdev->v_memory; + stream *es = s_alloc(mem, "psdf_encode_binary(stream)"); + stream_state *ess = (ss == 0 ? (stream_state *) es : ss); + uint bsize = max(template->min_out_size, 256); /* arbitrary */ + byte *buf = gs_alloc_bytes(mem, bsize, "psdf_encode_binary(buf)"); + + if (es == 0 || buf == 0) { + gs_free_object(mem, buf, "psdf_encode_binary(buf)"); + gs_free_object(mem, es, "psdf_encode_binary(stream)"); + return_error(gs_error_VMerror); + } + if (ess == 0) + ess = (stream_state *) es; + s_std_init(es, buf, bsize, &s_filter_write_procs, s_mode_write); + ess->template = template; + ess->memory = mem; + es->procs.process = template->process; + es->memory = mem; + es->state = ess; + if (template->init) + (*template->init) (ess); + es->strm = pbw->strm; + pbw->strm = es; + return 0; +} + +/* Add a 2-D CCITTFax encoding filter. */ +int +psdf_CFE_binary(psdf_binary_writer * pbw, int w, int h, bool invert) +{ + gx_device_psdf *pdev = pbw->dev; + gs_memory_t *mem = pdev->v_memory; + const stream_template *template = &s_CFE_template; + stream_CFE_state *st = + gs_alloc_struct(mem, stream_CFE_state, template->stype, + "psdf_CFE_binary"); + int code; + + if (st == 0) + return_error(gs_error_VMerror); + (*template->set_defaults) ((stream_state *) st); + st->K = -1; + st->Columns = w; + st->Rows = h; + st->BlackIs1 = !invert; + code = psdf_encode_binary(pbw, template, (stream_state *) st); + if (code < 0) + gs_free_object(mem, st, "psdf_CFE_binary"); + return code; +} + +/* Finish writing binary data. */ +int +psdf_end_binary(psdf_binary_writer * pbw) +{ + gx_device_psdf *pdev = pbw->dev; + + /* Close the filters in reverse order. */ + /* Stop before we try to close the file stream. */ + while (pbw->strm != pdev->strm) { + stream *next = pbw->strm->strm; + + sclose(pbw->strm); + pbw->strm = next; + } + return 0; +} + +/* + * Write a string in its shortest form ( () or <> ). Note that + * this form is different depending on whether binary data are allowed. + * Currently we don't support ASCII85 strings ( <~ ~> ). + */ +void +psdf_write_string(stream * s, const byte * str, uint size, int print_ok) +{ + uint added = 0; + uint i; + const stream_template *template; + stream_AXE_state state; + stream_state *st = NULL; + + if (print_ok & print_binary_ok) { /* Only need to escape (, ), \, CR, EOL. */ + pputc(s, '('); + for (i = 0; i < size; ++i) { + byte ch = str[i]; + + switch (ch) { + case char_CR: + pputs(s, "\\r"); + continue; + case char_EOL: + pputs(s, "\\n"); + continue; + case '(': + case ')': + case '\\': + pputc(s, '\\'); + } + pputc(s, ch); + } + pputc(s, ')'); + return; + } + for (i = 0; i < size; ++i) { + byte ch = str[i]; + + if (ch == 0 || ch >= 127) + added += 3; + else if (strchr("()\\\n\r\t\b\f", ch) != 0) + ++added; + else if (ch < 32) + added += 3; + } + + if (added < size) { /* More efficient to represent as PostScript string. */ + template = &s_PSSE_template; + pputc(s, '('); + } else { /* More efficient to represent as hex string. */ + template = &s_AXE_template; + st = (stream_state *) & state; + s_AXE_init_inline(&state); + pputc(s, '<'); + } + + { + byte buf[100]; /* size is arbitrary */ + stream_cursor_read r; + stream_cursor_write w; + int status; + + r.ptr = str - 1; + r.limit = r.ptr + size; + w.limit = buf + sizeof(buf) - 1; + do { + w.ptr = buf - 1; + status = (*template->process) (st, &r, &w, true); + pwrite(s, buf, (uint) (w.ptr + 1 - buf)); + } + while (status == 1); + } +} + +/* Set up a write stream that just keeps track of the position. */ +int +psdf_alloc_position_stream(stream ** ps, gs_memory_t * mem) +{ + stream *s = *ps = s_alloc(mem, "psdf_alloc_position_stream"); + + if (s == 0) + return_error(gs_error_VMerror); + swrite_position_only(s); + return 0; +} + +/* ---------------- Parameter printing ---------------- */ + +typedef struct printer_param_list_s { + gs_param_list_common; + stream *strm; + param_printer_params_t params; + int print_ok; + bool any; +} printer_param_list_t; + +gs_private_st_ptrs1(st_printer_param_list, printer_param_list_t, + "printer_param_list_t", printer_plist_enum_ptrs, printer_plist_reloc_ptrs, + strm); +const param_printer_params_t param_printer_params_default = +{ + param_printer_params_default_values +}; + +/* We'll implement the other printers later if we have to. */ +private param_proc_xmit_typed(param_print_typed); +/*private param_proc_begin_xmit_collection(param_print_begin_collection); */ +/*private param_proc_end_xmit_collection(param_print_end_collection); */ +private const gs_param_list_procs printer_param_list_procs = { + param_print_typed, + NULL /* begin_collection */ , + NULL /* end_collection */ , + NULL /* get_next_key */ , + gs_param_request_default, + gs_param_requested_default +}; + +int +psdf_alloc_param_printer(gs_param_list ** pplist, + const param_printer_params_t * ppp, stream * s, + int print_ok, gs_memory_t * mem) +{ + printer_param_list_t *prlist = + gs_alloc_struct(mem, printer_param_list_t, &st_printer_param_list, + "psdf_alloc_param_printer"); + + *pplist = (gs_param_list *) prlist; + if (prlist == 0) + return_error(gs_error_VMerror); + prlist->procs = &printer_param_list_procs; + prlist->memory = mem; + prlist->strm = s; + prlist->params = *ppp; + prlist->print_ok = print_ok; + prlist->any = false; + return 0; +} + +void +psdf_free_param_printer(gs_param_list * plist) +{ + if (plist) { + printer_param_list_t *prlist = (printer_param_list_t *) plist; + + if (prlist->any && prlist->params.suffix) + pputs(prlist->strm, prlist->params.suffix); + gs_free_object(prlist->memory, plist, "psdf_free_param_printer"); + } +} + +#define prlist ((printer_param_list_t *)plist) +private int +param_print_typed(gs_param_list * plist, gs_param_name pkey, + gs_param_typed_value * pvalue) +{ + stream *s = prlist->strm; + + if (!prlist->any) { + if (prlist->params.prefix) + pputs(s, prlist->params.prefix); + prlist->any = true; + } + if (prlist->params.item_prefix) + pputs(s, prlist->params.item_prefix); + pprints1(s, "/%s", pkey); + switch (pvalue->type) { + case gs_param_type_null: + pputs(s, " null"); + break; + case gs_param_type_bool: + pputs(s, (pvalue->value.b ? " true" : " false")); + break; + case gs_param_type_int: + pprintd1(s, " %d", pvalue->value.i); + break; + case gs_param_type_long: + pprintld1(s, " %l", pvalue->value.l); + break; + case gs_param_type_float: + pprintg1(s, " %g", pvalue->value.f); + break; + case gs_param_type_string: + psdf_write_string(s, pvalue->value.s.data, pvalue->value.s.size, + prlist->print_ok); + break; + case gs_param_type_name: +/****** SHOULD USE #-ESCAPES FOR PDF ******/ + pputc(s, '/'); + pwrite(s, pvalue->value.n.data, pvalue->value.n.size); + break; + case gs_param_type_int_array: + { + uint i; + char sepr = (pvalue->value.ia.size <= 10 ? ' ' : '\n'); + + pputc(s, '['); + for (i = 0; i < pvalue->value.ia.size; ++i) { + pprintd1(s, "%d", pvalue->value.ia.data[i]); + pputc(s, sepr); + } + pputc(s, ']'); + } + break; + case gs_param_type_float_array: + { + uint i; + char sepr = (pvalue->value.fa.size <= 10 ? ' ' : '\n'); + + pputc(s, '['); + for (i = 0; i < pvalue->value.fa.size; ++i) { + pprintg1(s, "%g", pvalue->value.fa.data[i]); + pputc(s, sepr); + } + pputc(s, ']'); + } + break; + /*case gs_param_type_string_array: */ + /*case gs_param_type_name_array: */ + default: + return_error(gs_error_typecheck); + } + if (prlist->params.item_suffix) + pputs(s, prlist->params.item_suffix); + return 0; +} + +#undef prlist diff --git a/pstoraster/gdevpsdf.h b/pstoraster/gdevpsdf.h new file mode 100644 index 0000000000..1e814a52ff --- /dev/null +++ b/pstoraster/gdevpsdf.h @@ -0,0 +1,292 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Common output syntax and parameters for PostScript and PDF writers */ + +#ifndef gdevpsdf_INCLUDED +# define gdevpsdf_INCLUDED + +#include "gdevvec.h" +#include "gsparam.h" +#include "strimpl.h" +#include "scfx.h" + +/* ---------------- Distiller parameters ---------------- */ + +/* Parameters for controlling distillation of images. */ +typedef struct psdf_image_params_s { + stream_state *ACSDict; /* JPEG */ + bool AntiAlias; + bool AutoFilter; + int Depth; + stream_state *Dict; /* JPEG or CCITTFax */ + bool Downsample; + enum psdf_downsample_type { + ds_Average, + ds_Subsample + } DownsampleType; + bool Encode; + const char *Filter; + int Resolution; + const stream_template *filter_template; +} psdf_image_params; + +#define psdf_image_param_defaults(af, res, f, ft)\ + NULL/*ACSDict*/, 0/*false*/, af, -1, NULL/*Dict*/, 0/*false*/,\ + ds_Subsample, 1/*true*/, f, res, ft + +/* Declare templates for default image compression filters. */ +extern const stream_template s_CFE_template; + +/* Complete distiller parameters. */ +typedef struct psdf_distiller_params_s { + + /* General parameters */ + + bool ASCII85EncodePages; + enum psdf_auto_rotate_pages { + arp_None, + arp_All, + arp_PageByPage + } AutoRotatePages; + bool CompressPages; + long ImageMemory; + bool LZWEncodePages; + bool PreserveHalftoneInfo; + bool PreserveOPIComments; + bool PreserveOverprintSettings; + enum psdf_transfer_function_info { + tfi_Preserve, + tfi_Apply, + tfi_Remove + } TransferFunctionInfo; + enum psdf_ucr_and_bg_info { + ucrbg_Preserve, + ucrbg_Remove + } UCRandBGInfo; + bool UseFlateCompression; +#define psdf_general_param_defaults(ascii)\ + ascii, arp_None, 1/*true*/, 250000, 0/*false*/,\ + 0/*false*/, 0/*false*/, 0/*false*/, tfi_Apply, ucrbg_Remove, 1 /*true */ + + /* Color sampled image parameters */ + + psdf_image_params ColorImage; + enum psdf_color_conversion_strategy { + ccs_LeaveColorUnchanged, + ccs_UseDeviceDependentColor, + ccs_UseDeviceIndependentColor + } ColorConversionStrategy; + bool ConvertCMYKImagesToRGB; + bool ConvertImagesToIndexed; +#define psdf_color_image_param_defaults\ + { psdf_image_param_defaults(1/*true*/, 72, 0, 0) },\ + ccs_LeaveColorUnchanged, 1/*true*/, 0 /*false */ + + /* Grayscale sampled image parameters */ + + psdf_image_params GrayImage; +#define psdf_gray_image_param_defaults\ + { psdf_image_param_defaults(1/*true*/, 72, 0, 0) } + + /* Monochrome sampled image parameters */ + + psdf_image_params MonoImage; +#define psdf_mono_image_param_defaults\ + { psdf_image_param_defaults(0/*false*/, 300, "CCITTFaxEncode", &s_CFE_template) } + + /* Font embedding parameters */ + + gs_param_string_array AlwaysEmbed; + gs_param_string_array NeverEmbed; + bool EmbedAllFonts; + bool SubsetFonts; + int MaxSubsetPct; +#define psdf_font_param_defaults\ + { 0, 0, 1/*true*/ }, { 0, 0, 1/*true*/ },\ + 1/*true*/, 1/*true*/, 20 + +} psdf_distiller_params; + +/* Define PostScript/PDF versions, corresponding roughly to Adobe versions. */ +typedef enum { + psdf_version_level1 = 1000, /* Red Book Level 1 */ + psdf_version_level1_color = 1100, /* Level 1 + colorimage + CMYK color */ + psdf_version_level2 = 2000, /* Red Book Level 2 */ + psdf_version_level2_plus = 2017, /* Adobe release 2017 */ + psdf_version_ll3 = 3010 /* LanguageLevel 3, release 3010 */ +} psdf_version; + +/* Define the extended device structure. */ +#define gx_device_psdf_common\ + gx_device_vector_common;\ + psdf_version version;\ + bool binary_ok; /* derived from ASCII85EncodePages */\ + psdf_distiller_params params +typedef struct gx_device_psdf_s { + gx_device_psdf_common; +} gx_device_psdf; + +#define psdf_initial_values(version, ascii)\ + vector_initial_values,\ + version,\ + !(ascii),\ + { psdf_general_param_defaults(ascii),\ + psdf_color_image_param_defaults,\ + psdf_gray_image_param_defaults,\ + psdf_mono_image_param_defaults,\ + psdf_font_param_defaults\ + } + +/* st_device_psdf is never instantiated per se, but we still need to */ +/* extern its descriptor for the sake of subclasses. */ +extern_st(st_device_psdf); +#define public_st_device_psdf() /* in gdevpsdf.c */\ + gs_public_st_suffix_add0_final(st_device_psdf, gx_device_psdf,\ + "gx_device_psdf", device_psdf_enum_ptrs,\ + device_psdf_reloc_ptrs, gx_device_finalize, st_device_vector) +#define st_device_psdf_max_ptrs (st_device_vector_max_ptrs) + +/* Get/put parameters. */ +dev_proc_get_params(gdev_psdf_get_params); +dev_proc_put_params(gdev_psdf_put_params); + +/* Put a Boolean or integer parameter. */ +int psdf_put_bool_param(P4(gs_param_list * plist, gs_param_name param_name, + bool * pval, int ecode)); +int psdf_put_int_param(P4(gs_param_list * plist, gs_param_name param_name, + int *pval, int ecode)); + +/* ---------------- Vector implementation procedures ---------------- */ + + /* Imager state */ +int psdf_setlinewidth(P2(gx_device_vector * vdev, floatp width)); +int psdf_setlinecap(P2(gx_device_vector * vdev, gs_line_cap cap)); +int psdf_setlinejoin(P2(gx_device_vector * vdev, gs_line_join join)); +int psdf_setmiterlimit(P2(gx_device_vector * vdev, floatp limit)); +int psdf_setdash(P4(gx_device_vector * vdev, const float *pattern, + uint count, floatp offset)); +int psdf_setflat(P2(gx_device_vector * vdev, floatp flatness)); +int psdf_setlogop(P3(gx_device_vector * vdev, gs_logical_operation_t lop, + gs_logical_operation_t diff)); + + /* Other state */ +int psdf_setfillcolor(P2(gx_device_vector * vdev, const gx_drawing_color * pdc)); +int psdf_setstrokecolor(P2(gx_device_vector * vdev, const gx_drawing_color * pdc)); + + /* Paths */ +#define psdf_dopath gdev_vector_dopath +int psdf_dorect(P6(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, + fixed y1, gx_path_type_t type)); +int psdf_beginpath(P2(gx_device_vector * vdev, gx_path_type_t type)); +int psdf_moveto(P7(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x, floatp y, bool first, gx_path_type_t type)); +int psdf_lineto(P6(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x, floatp y, gx_path_type_t type)); +int psdf_curveto(P10(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x1, floatp y1, floatp x2, + floatp y2, floatp x3, floatp y3, gx_path_type_t type)); +int psdf_closepath(P6(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x_start, floatp y_start, gx_path_type_t type)); + +/* ---------------- Binary (image) data procedures ---------------- */ + +/* Define the structure for writing binary data. */ +typedef struct psdf_binary_writer_s { + stream *strm; + gx_device_psdf *dev; +} psdf_binary_writer; + +/* Begin writing binary data. */ +int psdf_begin_binary(P2(gx_device_psdf * pdev, psdf_binary_writer * pbw)); + +/* Add an encoding filter. The client must have allocated the stream state, */ +/* if any, using pdev->v_memory. */ +int psdf_encode_binary(P3(psdf_binary_writer * pbw, + const stream_template * template, stream_state * ss)); + +/* Add a 2-D CCITTFax encoding filter. */ +int psdf_CFE_binary(P4(psdf_binary_writer * pbw, int w, int h, bool invert)); + +/* Set up compression and downsampling filters for an image. */ +/* Note that this may modify the image parameters. */ +/* If pctm is NULL, downsampling is not used. */ +/* pis only provides UCR and BG information for CMYK => RGB conversion. */ +int psdf_setup_image_filters(P5(gx_device_psdf * pdev, psdf_binary_writer * pbw, + gs_image_t * pim, const gs_matrix * pctm, + const gs_imager_state * pis)); + +/* Finish writing binary data. */ +int psdf_end_binary(P1(psdf_binary_writer * pbw)); + +/* ------ Symbolic data printing ------ */ + +/* Print a PostScript string in the most efficient form. */ +#define print_binary_ok 1 +#define print_ASCII85_ok 2 +void psdf_write_string(P4(stream * s, const byte * str, uint size, + int print_ok)); + +/* + * Create a stream that just keeps track of how much has been written + * to it. We use this for measuring data that will be stored rather + * than written to an actual stream. This too should probably migrate + * to stream.c.... + */ +int psdf_alloc_position_stream(P2(stream ** ps, gs_memory_t * mem)); + +/* + * Create/release a parameter list for printing (non-default) filter + * parameters. This should probably migrate to a lower level.... + */ +typedef struct param_printer_params_s { + const char *prefix; /* before entire object, if any params */ + const char *suffix; /* after entire object, if any params */ + const char *item_prefix; /* before each param */ + const char *item_suffix; /* after each param */ +} param_printer_params_t; + +#define param_printer_params_default_values 0, 0, 0, "\n" +extern const param_printer_params_t param_printer_params_default; +int psdf_alloc_param_printer(P5(gs_param_list ** pplist, + const param_printer_params_t * ppp, stream * s, + int print_ok, gs_memory_t * mem)); +void psdf_free_param_printer(P1(gs_param_list * plist)); + +/* Write out a Type 1 font definition. */ +#ifndef gs_font_type1_DEFINED +# define gs_font_type1_DEFINED +typedef struct gs_font_type1_s gs_font_type1; + +#endif +int psdf_embed_type1_font(P2(stream * s, gs_font_type1 * pfont)); + +/* ---------------- Other procedures ---------------- */ + +/* Set the fill or stroke color. rgs is "rg" or "RG". */ +int psdf_set_color(P3(gx_device_vector * vdev, const gx_drawing_color * pdc, + const char *rgs)); + +#endif /* gdevpsdf_INCLUDED */ diff --git a/pstoraster/gdevpsdi.c b/pstoraster/gdevpsdi.c new file mode 100644 index 0000000000..9ba6c16149 --- /dev/null +++ b/pstoraster/gdevpsdi.c @@ -0,0 +1,349 @@ +/* + Copyright 1993-2000 by Easy Software Products. + Copyright 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Image compression for PostScript and PDF writers */ +#include "math_.h" +#include "gx.h" +#include "gserrors.h" +#include "gscspace.h" +#include "gdevpsdf.h" +#include "gdevpsds.h" +#include "strimpl.h" +#include "scfx.h" +#include +#ifdef HAVE_LIBJPEG +#include "jpeglib.h" /* for sdct.h */ +#include "sdct.h" +#endif /* HAVE_LIBJPEG */ +#include "slzwx.h" +#include "spngpx.h" +#include "srlx.h" +#ifdef HAVE_LIBZ +#include "szlibx.h" +#endif /* HAVE_LIBZ */ + +/* ---------------- Image compression ---------------- */ + +/* Add a filter to expand or reduce the pixel width if needed. */ +/* At least one of bpc_in and bpc_out is 8; the other is 1, 2, 4, or 8. */ +private int +pixel_resize(psdf_binary_writer * pbw, int width, int num_components, + int bpc_in, int bpc_out) +{ + gs_memory_t *mem = pbw->dev->v_memory; + const stream_template *template; + stream_1248_state *st; + int code; + + if (bpc_out == bpc_in) + return 0; + if (bpc_in < 8) { + static const stream_template *const exts[5] = + { + 0, &s_1_8_template, &s_2_8_template, 0, &s_4_8_template + }; + + template = exts[bpc_in]; + } else { + static const stream_template *const rets[5] = + { + 0, &s_8_1_template, &s_8_2_template, 0, &s_8_4_template + }; + + template = rets[bpc_out]; + } + st = (stream_1248_state *) + s_alloc_state(mem, template->stype, "pixel_resize state"); + if (st == 0) + return_error(gs_error_VMerror); + code = psdf_encode_binary(pbw, template, (stream_state *) st); + if (code < 0) { + gs_free_object(mem, st, "pixel_resize state"); + return code; + } + s_1248_init(st, width, num_components); + return 0; +} + +/* Add the appropriate image compression filter, if any. */ +private int +setup_image_compression(psdf_binary_writer * pbw, const psdf_image_params * pdip, + const gs_image_t * pim) +{ + gx_device_psdf *pdev = pbw->dev; + const stream_template *template = pdip->filter_template; + stream_state *st; + + if (pdip->AutoFilter) { + /****** AutoFilter IS NYI ******/ + /* + * Even though this isn't obvious from the Adobe Tech Note, + * it appears that if UseFlateCompression is true, the default + * compressor for AutoFilter is FlateEncode, not LZWEncode. + */ +#ifdef HAVE_LIBZ + template = + (pdev->params.UseFlateCompression && + pdev->version >= psdf_version_ll3 ? + &s_zlibE_template : &s_LZWE_template); +#else + template = &s_LZWE_template; +#endif /* HAVE_LIBZ */ + } + if (!pdip->Encode || template == 0) /* no compression */ + return 0; +#ifdef HAVE_LIBJPEG + /* Only use DCTE for 8-bit data. */ + if (template == &s_DCTE_template && + !(pdip->Downsample ? + pdip->Depth == 8 || + (pdip->Depth == -1 && pim->BitsPerComponent == 8) : + pim->BitsPerComponent == 8) + ) { + /* Use LZW instead. */ + template = &s_LZWE_template; + } +#endif /* HAVE_LIBJPEG */ + st = s_alloc_state(pdev->v_memory, template->stype, + "setup_image_compression"); + if (st == 0) + return_error(gs_error_VMerror); + if (template->set_defaults) + (*template->set_defaults) (st); + if (template == &s_CFE_template) { + stream_CFE_state *const ss = (stream_CFE_state *) st; + + if (pdip->Dict != 0 && pdip->Dict->template == &s_CFE_template) { + stream_state common; + + common = *st; /* save generic info */ + *ss = *(const stream_CFE_state *)pdip->Dict; + *st = common; + } else { + ss->K = -1; + ss->BlackIs1 = true; + } + ss->Columns = pim->Width; + ss->Rows = (ss->EndOfBlock ? 0 : pim->Height); +#ifdef HAVE_LIBZ + } else if (template == &s_LZWE_template || + template == &s_zlibE_template) { +#else + } else if (template == &s_LZWE_template) { +#endif /* HAVE_LIBZ */ + /* Add a PNGPredictor filter. */ + int code = psdf_encode_binary(pbw, template, st); + + if (code < 0) { + gs_free_object(pdev->v_memory, st, "setup_image_compression"); + return code; + } + template = &s_PNGPE_template; + st = s_alloc_state(pdev->v_memory, template->stype, + "setup_image_compression"); + if (st == 0) + return_error(gs_error_VMerror); + if (template->set_defaults) + (*template->set_defaults) (st); + { + stream_PNGP_state *const ss = (stream_PNGP_state *) st; + + ss->Colors = gs_color_space_num_components(pim->ColorSpace); + ss->Columns = pim->Width; + } +#ifdef HAVE_LIBJPEG + } else if (template == &s_DCTE_template) { + /****** ADD PARAMETERS FROM pdip->Dict ******/ +#endif /* HAVE_LIBJPEG */ + } { + int code = psdf_encode_binary(pbw, template, st); + + if (code < 0) { + gs_free_object(pdev->v_memory, st, "setup_image_compression"); + return code; + } + } + return 0; +} + +/* Add downsampling, antialiasing, and compression filters. */ +/* Uses AntiAlias, Depth, DownsampleType, Resolution. */ +private int +setup_downsampling(psdf_binary_writer * pbw, const psdf_image_params * pdip, + gs_image_t * pim, floatp resolution) +{ + gx_device_psdf *pdev = pbw->dev; + const stream_template *template = + (pdip->DownsampleType == ds_Average ? + &s_Average_template : &s_Subsample_template); + int factor = (int)(resolution / pdip->Resolution); + int orig_bpc = pim->BitsPerComponent; + int orig_width = pim->Width; + int orig_height = pim->Height; + stream_state *st; + int code; + + if (factor <= 1 || pim->Width < factor || pim->Height < factor) + return setup_image_compression(pbw, pdip, pim); /* no downsampling */ + st = s_alloc_state(pdev->v_memory, template->stype, + "setup_downsampling"); + if (st == 0) + return_error(gs_error_VMerror); + if (template->set_defaults) + (*template->set_defaults) (st); + { + stream_Downsample_state *const ss = (stream_Downsample_state *) st; + + ss->Colors = gs_color_space_num_components(pim->ColorSpace); + ss->Columns = pim->Width; + ss->XFactor = ss->YFactor = factor; + ss->AntiAlias = pdip->AntiAlias; + if (template->init) + (*template->init) (st); + pim->Width /= factor; + pim->Height /= factor; + pim->BitsPerComponent = pdip->Depth; + gs_matrix_scale(&pim->ImageMatrix, (double)pim->Width / orig_width, + (double)pim->Height / orig_height, + &pim->ImageMatrix); + /****** NO ANTI-ALIASING YET ******/ + if ((code = setup_image_compression(pbw, pdip, pim)) < 0 || + (code = pixel_resize(pbw, pim->Width, ss->Colors, + 8, pdip->Depth)) < 0 || + (code = psdf_encode_binary(pbw, template, st)) < 0 || + (code = pixel_resize(pbw, orig_width, ss->Colors, + orig_bpc, 8)) < 0 + ) { + gs_free_object(pdev->v_memory, st, "setup_image_compression"); + return code; + } + } + return 0; +} + +/* Set up compression and downsampling filters for an image. */ +/* Note that this may modify the image parameters. */ +int +psdf_setup_image_filters(gx_device_psdf * pdev, psdf_binary_writer * pbw, + gs_image_t * pim, const gs_matrix * pctm, + const gs_imager_state * pis) +{ /* + * The following algorithms are per Adobe Tech Note # 5151, + * "Acrobat Distiller Parameters", revised 16 September 1996 + * for Acrobat(TM) Distiller(TM) 3.0. + * + * The control structure is a little tricky, because filter + * pipelines must be constructed back-to-front. + */ + int code = 0; + psdf_image_params params; + + if (pim->ImageMask) { + params = pdev->params.MonoImage; + params.Depth = 1; + } else { + int ncomp = gs_color_space_num_components(pim->ColorSpace); + int bpc = pim->BitsPerComponent; + + /* + * We can compute the image resolution by: + * W / (W * ImageMatrix^-1 * CTM / HWResolution). + * We can replace W by 1 to simplify the computation. + */ + double resolution; + + if (pctm == 0) + resolution = -1; + else { + gs_point pt; + + /* We could do both X and Y, but why bother? */ + gs_distance_transform_inverse(1.0, 0.0, &pim->ImageMatrix, &pt); + gs_distance_transform(pt.x, pt.y, pctm, &pt); + resolution = 1.0 / hypot(pt.x / pdev->HWResolution[0], + pt.y / pdev->HWResolution[1]); + } + if (ncomp == 1) { + /* Monochrome or gray */ + if (bpc == 1) + params = pdev->params.MonoImage; + else + params = pdev->params.GrayImage; + if (params.Depth == -1) + params.Depth = bpc; + /* Check for downsampling. */ + if (params.Downsample && params.Resolution <= resolution / 2) { + /* Use the downsampled depth, not the original data depth. */ + if (params.Depth == 1) { + params.Filter = pdev->params.MonoImage.Filter; + params.filter_template = pdev->params.MonoImage.filter_template; + params.Dict = pdev->params.MonoImage.Dict; + } else { + params.Filter = pdev->params.GrayImage.Filter; + params.filter_template = pdev->params.GrayImage.filter_template; + params.Dict = pdev->params.GrayImage.Dict; + } + code = setup_downsampling(pbw, ¶ms, pim, resolution); + } else { + code = setup_image_compression(pbw, ¶ms, pim); + } + } else { + /* Color */ + bool cmyk_to_rgb = + pdev->params.ConvertCMYKImagesToRGB && + pis != 0 && + gs_color_space_get_index(pim->ColorSpace) == + gs_color_space_index_DeviceCMYK; + + if (cmyk_to_rgb) + pim->ColorSpace = gs_cspace_DeviceRGB(pis); + params = pdev->params.ColorImage; + if (params.Depth == -1) + params.Depth = (cmyk_to_rgb ? 8 : bpc); + if (params.Downsample && params.Resolution <= resolution / 2) { + code = setup_downsampling(pbw, ¶ms, pim, resolution); + } else { + code = setup_image_compression(pbw, ¶ms, pim); + } + if (cmyk_to_rgb) { + gs_memory_t *mem = pdev->v_memory; + stream_C2R_state *ss = (stream_C2R_state *) + s_alloc_state(mem, s_C2R_template.stype, "C2R state"); + int code = pixel_resize(pbw, pim->Width, 3, 8, bpc); + + if (code < 0 || + (code = psdf_encode_binary(pbw, &s_C2R_template, + (stream_state *) ss)) < 0 || + (code = pixel_resize(pbw, pim->Width, 4, bpc, 8)) < 0 + ) + return code; + s_C2R_init(ss, pis); + } + } + } + return code; +} diff --git a/pstoraster/gdevpsdp.c b/pstoraster/gdevpsdp.c new file mode 100644 index 0000000000..cad5e1d8ab --- /dev/null +++ b/pstoraster/gdevpsdp.c @@ -0,0 +1,705 @@ +/* + Copyright 1993-2000 by Easy Software Products. + Copyright 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* (Distiller) parameter handling for PostScript and PDF writers */ +#include "string_.h" +#include "gx.h" +#include "gserrors.h" +#include "gxdevice.h" +#include "gdevpsdf.h" +#include "gdevpstr.h" +#include "strimpl.h" /* for short-sighted compilers */ +#include "scfx.h" +#include +#ifdef HAVE_LIBJPEG +#include "jpeglib.h" /* for sdct.h */ +#include "sdct.h" +#endif /* HAVE_LIBJPEG */ +#include "slzwx.h" +#include "srlx.h" +#ifdef HAVE_LIBZ +#include "szlibx.h" +#endif /* HAVE_LIBZ */ + +/* ---------------- Get/put Distiller parameters ---------------- */ + +/* + * This code handles all the Distiller parameters except the *ACSDict and + * *ImageDict parameter dictionaries. (It doesn't cause any of the + * parameters actually to have any effect.) + */ + +typedef struct psdf_image_filter_name_s { + const char *pname; + const stream_template *template; + psdf_version min_version; +} psdf_image_filter_name; +typedef struct psdf_image_param_names_s { + const char *ACSDict; /* not used for mono */ + const char *AntiAlias; + const char *AutoFilter; /* not used for mono */ + const char *Depth; + const char *Dict; + const char *Downsample; + const char *DownsampleType; + const char *Encode; + const char *Filter; + const char *Resolution; +} psdf_image_param_names; +private const psdf_image_param_names Color_names = +{ + "ColorACSImageDict", "AntiAliasColorImages", "AutoFilterColorImages", + "ColorImageDepth", "ColorImageDict", + "DownsampleColorImages", "ColorImageDownsampleType", "EncodeColorImages", + "ColorImageFilter", "ColorImageResolution" +}; +private const psdf_image_filter_name Poly_filters[] = +{ +#ifdef HAVE_LIBJPEG + {"DCTEncode", &s_DCTE_template}, +#endif /* HAVE_LIBJPEG */ +#ifdef HAVE_LIBZ + {"FlateEncode", &s_zlibE_template, psdf_version_ll3}, +#endif /* HAVE_LIBZ */ + {"LZWEncode", &s_LZWE_template}, + {0, 0} +}; +private const psdf_image_param_names Gray_names = +{ + "GrayACSImageDict", "AntiAliasGrayImages", "AutoFilterGrayImages", + "GrayImageDepth", "GrayImageDict", + "DownsampleGrayImages", "GrayImageDownsampleType", "EncodeGrayImages", + "GrayImageFilter", "GrayImageResolution" +}; +private const psdf_image_param_names Mono_names = +{ + 0, "AntiAliasMonoImages", 0, + "MonoImageDepth", "MonoImageDict", + "DownsampleMonoImages", "MonoImageDownsampleType", "EncodeMonoImages", + "MonoImageFilter", "MonoImageResolution" +}; +private const psdf_image_filter_name Mono_filters[] = +{ + {"CCITTFaxEncode", &s_CFE_template}, +#ifdef HAVE_LIBZ + {"FlateEncode", &s_zlibE_template, psdf_version_ll3}, +#endif /* HAVE_LIBZ */ + {"LZWEncode", &s_LZWE_template}, + {"RunLengthEncode", &s_RLE_template}, + {0, 0} +}; +private const char *const AutoRotatePages_names[] = +{ + "None", "All", "PageByPage", 0 +}; +private const char *const ColorConversionStrategy_names[] = +{ + "LeaveColorUnchanged", "UseDeviceDependentColor", + "UseDeviceIndependentColor", 0 +}; +private const char *const DownsampleType_names[] = +{ + "Average", "Subsample", 0 +}; +private const char *const TransferFunctionInfo_names[] = +{ + "Preserve", "Apply", "Remove", 0 +}; +private const char *const UCRandBGInfo_names[] = +{ + "Preserve", "Remove", 0 +}; + +/* -------- Get parameters -------- */ + +#ifdef HAVE_LIBJPEG +extern stream_state_proc_get_params(s_DCTE_get_params, stream_DCT_state); +#endif /* HAVE_LIBJPEG */ +extern stream_state_proc_get_params(s_CF_get_params, stream_CF_state); +typedef stream_state_proc_get_params((*ss_get_params_t), stream_state); + +private int +psdf_CF_get_params(gs_param_list * plist, const stream_state * ss, bool all) +{ + return (ss == 0 ? 0 : + s_CF_get_params(plist, (const stream_CF_state *)ss, all)); +} +#ifdef HAVE_LIBJPEG +private int +psdf_DCT_get_params(gs_param_list * plist, const stream_state * ss, bool all) +{ + int code = (ss == 0 ? 0 : + s_DCTE_get_params(plist, (const stream_DCT_state *)ss, all)); + /* + * Add dummy Columns, Rows, and Colors parameters so that put_params + * won't complain. + */ + int dummy_size = 8, dummy_colors = 3; + + if (code < 0 || + (code = param_write_int(plist, "Columns", &dummy_size)) < 0 || + (code = param_write_int(plist, "Rows", &dummy_size)) < 0 || + (code = param_write_int(plist, "Colors", &dummy_colors)) < 0 + ) + return code; + return 0; +} +#endif /* HAVE_LIBJPEG */ + +/* + * Get an image Dict parameter. Note that we return a default (usually + * empty) dictionary if the parameter has never been set. + */ +private int +psdf_get_image_dict_param(gs_param_list * plist, const gs_param_name pname, + stream_state * ss, ss_get_params_t get_params) +{ + gs_param_dict dict; + int code; + + if (pname == 0) + return 0; + dict.size = 12; /* enough for all param dicts we know about */ + if ((code = param_begin_write_dict(plist, pname, &dict, false)) < 0) + return code; + code = (*get_params)(dict.list, ss, false); + param_end_write_dict(plist, pname, &dict); + return code; +} + +/* Get a set of image-related parameters. */ +private int +psdf_get_image_params(gs_param_list * plist, + const psdf_image_param_names * pnames, psdf_image_params * params) +{ + int code; + gs_param_string dsts, fs; + + param_string_from_string(dsts, + DownsampleType_names[params->DownsampleType]); + if ( +#ifdef HAVE_LIBJPEG + (code = psdf_get_image_dict_param(plist, pnames->ACSDict, + params->ACSDict, + psdf_DCT_get_params)) < 0 || +#endif /* HAVE_LIBJPEG */ + (code = param_write_bool(plist, pnames->AntiAlias, + ¶ms->AntiAlias)) < 0 || + (pnames->AutoFilter != 0 && + (code = param_write_bool(plist, pnames->AutoFilter, + ¶ms->AutoFilter)) < 0) || + (code = param_write_int(plist, pnames->Depth, + ¶ms->Depth)) < 0 || + (code = psdf_get_image_dict_param(plist, pnames->Dict, + params->Dict, +#ifdef HAVE_LIBJPEG + (params->Dict == 0 || + params->Dict->template == + &s_CFE_template ? + psdf_CF_get_params : + psdf_DCT_get_params))) < 0 || +#else + psdf_CF_get_params)) < 0 || +#endif /* HAVE_LIBJPEG */ + (code = param_write_bool(plist, pnames->Downsample, + ¶ms->Downsample)) < 0 || + (code = param_write_name(plist, pnames->DownsampleType, + &dsts)) < 0 || + (code = param_write_bool(plist, pnames->Encode, + ¶ms->Encode)) < 0 || + (code = (params->Filter == 0 ? 0 : + (param_string_from_string(fs, params->Filter), + param_write_name(plist, pnames->Filter, &fs)))) < 0 || + (code = param_write_int(plist, pnames->Resolution, + ¶ms->Resolution)) < 0 + ) + DO_NOTHING; + return code; +} + +/* Get parameters. */ +int +gdev_psdf_get_params(gx_device * dev, gs_param_list * plist) +{ + gx_device_psdf *pdev = (gx_device_psdf *) dev; + int code = gdev_vector_get_params(dev, plist); + gs_param_string arps, ccss, tfis, ucrbgis; + + if (code < 0) + return code; + param_string_from_string(arps, + AutoRotatePages_names[(int)pdev->params.AutoRotatePages]); + param_string_from_string(ccss, + ColorConversionStrategy_names[(int)pdev->params.ColorConversionStrategy]); + param_string_from_string(tfis, + TransferFunctionInfo_names[(int)pdev->params.TransferFunctionInfo]); + param_string_from_string(ucrbgis, + UCRandBGInfo_names[(int)pdev->params.UCRandBGInfo]); + if ( + /* General parameters */ + + (code = param_write_bool(plist, "ASCII85EncodePages", + &pdev->params.ASCII85EncodePages)) < 0 || + (code = param_write_name(plist, "AutoRotatePages", + &arps)) < 0 || + (code = param_write_bool(plist, "CompressPages", + &pdev->params.CompressPages)) < 0 || + (code = param_write_long(plist, "ImageMemory", + &pdev->params.ImageMemory)) < 0 || + (code = param_write_bool(plist, "LZWEncodePages", + &pdev->params.LZWEncodePages)) < 0 || + (code = param_write_bool(plist, "PreserveHalftoneInfo", + &pdev->params.PreserveHalftoneInfo)) < 0 || + (code = param_write_bool(plist, "PreserveOPIComments", + &pdev->params.PreserveOPIComments)) < 0 || + (code = param_write_bool(plist, "PreserveOverprintSettings", + &pdev->params.PreserveOverprintSettings)) < 0 || + (code = param_write_name(plist, "TransferFunctionInfo", &tfis)) < 0 || + (code = param_write_name(plist, "UCRandBGInfo", &ucrbgis)) < 0 || + (code = param_write_bool(plist, "UseFlateCompression", + &pdev->params.UseFlateCompression)) < 0 || + + /* Color sampled image parameters */ + + (code = psdf_get_image_params(plist, &Color_names, &pdev->params.ColorImage)) < 0 || + (code = param_write_name(plist, "ColorConversionStrategy", + &ccss)) < 0 || + (code = param_write_bool(plist, "ConvertCMYKImagesToRGB", + &pdev->params.ConvertCMYKImagesToRGB)) < 0 || + (code = param_write_bool(plist, "ConvertImagesToIndexed", + &pdev->params.ConvertImagesToIndexed)) < 0 || + + /* Gray sampled image parameters */ + + (code = psdf_get_image_params(plist, &Gray_names, &pdev->params.GrayImage)) < 0 || + + /* Mono sampled image parameters */ + + (code = psdf_get_image_params(plist, &Mono_names, &pdev->params.MonoImage)) < 0 || + + /* Font embedding parameters */ + + (code = param_write_name_array(plist, "AlwaysEmbed", &pdev->params.AlwaysEmbed)) < 0 || + (code = param_write_name_array(plist, "NeverEmbed", &pdev->params.NeverEmbed)) < 0 || + (code = param_write_bool(plist, "EmbedAllFonts", &pdev->params.EmbedAllFonts)) < 0 || + (code = param_write_bool(plist, "SubsetFonts", &pdev->params.SubsetFonts)) < 0 || + (code = param_write_int(plist, "MaxSubsetPct", &pdev->params.MaxSubsetPct)) < 0 + ); + return code; +} + +/* -------- Put parameters -------- */ + +#ifdef HAVE_LIBJPEG +extern stream_state_proc_put_params(s_DCTE_put_params, stream_DCT_state); +#endif /* HAVE_LIBJPEG */ +extern stream_state_proc_put_params(s_CF_put_params, stream_CF_state); +typedef stream_state_proc_put_params((*ss_put_params_t), stream_state); + +private int +psdf_CF_put_params(gs_param_list * plist, stream_state * st) +{ + stream_CFE_state *const ss = (stream_CFE_state *) st; + + (*s_CFE_template.set_defaults) (st); + ss->K = -1; + ss->BlackIs1 = true; + return s_CF_put_params(plist, (stream_CF_state *) ss); +} +#ifdef HAVE_LIBJPEG +private int +psdf_DCT_put_params(gs_param_list * plist, stream_state * ss) +{ + return s_DCTE_put_params(plist, (stream_DCT_state *) ss); +} +#endif /* HAVE_LIBJPEG */ + +/* Compare a C string and a gs_param_string. */ +bool +psdf_key_eq(const gs_param_string * pcs, const char *str) +{ + return (strlen(str) == pcs->size && + !strncmp(str, (const char *)pcs->data, pcs->size)); +} + +/* Put an enumerated value. */ +private int +psdf_put_enum_param(gs_param_list * plist, gs_param_name param_name, + int *pvalue, const char *const pnames[], int ecode) +{ + gs_param_string ens; + int code = param_read_name(plist, param_name, &ens); + + switch (code) { + case 1: + return ecode; + case 0: + { + int i; + + for (i = 0; pnames[i] != 0; ++i) + if (psdf_key_eq(&ens, pnames[i])) { + *pvalue = i; + return 0; + } + } + code = gs_error_rangecheck; + default: + ecode = code; + param_signal_error(plist, param_name, code); + } + return code; +} + +/* Put a Boolean or integer parameter. */ +int +psdf_put_bool_param(gs_param_list * plist, gs_param_name param_name, + bool * pval, int ecode) +{ + int code; + + switch (code = param_read_bool(plist, param_name, pval)) { + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 0: + case 1: + break; + } + return ecode; +} +int +psdf_put_int_param(gs_param_list * plist, gs_param_name param_name, + int *pval, int ecode) +{ + int code; + + switch (code = param_read_int(plist, param_name, pval)) { + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 0: + case 1: + break; + } + return ecode; +} + +/* Put [~](Always|Never)Embed parameters. */ +private int +psdf_put_embed_param(gs_param_list * plist, gs_param_name notpname, + gs_param_string_array * psa, int ecode) +{ + gs_param_name pname = notpname + 1; + int code; + gs_param_string_array nsa; + +/***** Storage management is incomplete ******/ +/***** Doesn't do incremental add/delete ******/ + switch (code = param_read_name_array(plist, pname, psa)) { + default: + ecode = code; + param_signal_error(plist, pname, ecode); + case 0: + case 1: + break; + } + switch (code = param_read_name_array(plist, notpname, &nsa)) { + default: + ecode = code; + param_signal_error(plist, notpname, ecode); + case 0: + case 1: + break; + } + return ecode; +} + +/* Put an image Dict parameter. */ +private int +psdf_put_image_dict_param(gs_param_list * plist, const gs_param_name pname, + stream_state ** pss, const stream_template * template, + ss_put_params_t put_params, gs_memory_t * mem) +{ + gs_param_dict dict; + stream_state *ss = *pss; + int code; + + switch (code = param_begin_read_dict(plist, pname, &dict, false)) { + default: + param_signal_error(plist, pname, code); + return code; + case 1: + ss = 0; + break; + case 0:{ + /****** + ****** THIS CAUSES A SEGV FOR DCT FILTERS, BECAUSE + ****** THEY DON'T INTIALIZE PROPERLY. + ******/ +#ifdef HAVE_LIBJPEG + if (template != &s_DCTE_template) +#endif /* HAVE_LIBJPEG */ + { + stream_state *ss_new = + s_alloc_state(mem, template->stype, pname); + + if (ss_new == 0) + return_error(gs_error_VMerror); + ss_new->template = template; + if (template->set_defaults) + (*template->set_defaults)(ss_new); + code = (*put_params)(dict.list, ss_new); + if (code < 0) { + param_signal_error(plist, pname, code); + /* Make sure we free the new state. */ + *pss = ss_new; + } else + ss = ss_new; + } + } + param_end_read_dict(plist, pname, &dict); + } + if (*pss != ss) { + if (ss) { + /****** FREE SUBSIDIARY OBJECTS -- HOW? ******/ + gs_free_object(mem, *pss, pname); + } + *pss = ss; + } + return code; +} + +/* Put a set of image-related parameters. */ +private int +psdf_put_image_params(const gx_device_psdf * pdev, gs_param_list * plist, + const psdf_image_param_names * pnames, const psdf_image_filter_name * pifn, + psdf_image_params * params, int ecode) +{ + gs_param_string fs; + + /* + * Since this procedure can be called before the device is open, + * we must use pdev->memory rather than pdev->v_memory. + */ + gs_memory_t *mem = pdev->memory; + gs_param_name pname; + int dsti = params->DownsampleType; + int code; + +#ifdef HAVE_LIBJPEG + if ((pname = pnames->ACSDict) != 0) { + code = psdf_put_image_dict_param(plist, pname, ¶ms->ACSDict, + &s_DCTE_template, + psdf_DCT_put_params, mem); + if (code < 0) + ecode = code; + } +#endif /* HAVE_LIBJPEG */ + ecode = psdf_put_bool_param(plist, pnames->AntiAlias, + ¶ms->AntiAlias, ecode); + if (pnames->AutoFilter) + ecode = psdf_put_bool_param(plist, pnames->AutoFilter, + ¶ms->AutoFilter, ecode); + ecode = psdf_put_int_param(plist, pnames->Depth, + ¶ms->Depth, ecode); + if ((pname = pnames->Dict) != 0) { + const stream_template *template; + ss_put_params_t put_params; + + /* Hack to determine what kind of a Dict we want: */ + if (pnames->Dict[0] == 'M') + template = &s_CFE_template, + put_params = psdf_CF_put_params; +#ifdef HAVE_LIBJPEG + else + template = &s_DCTE_template, + put_params = psdf_DCT_put_params; +#endif /* HAVE_LIBJPEG */ + code = psdf_put_image_dict_param(plist, pname, ¶ms->Dict, + template, put_params, mem); + if (code < 0) + ecode = code; + } + ecode = psdf_put_bool_param(plist, pnames->Downsample, + ¶ms->Downsample, ecode); + if ((ecode = psdf_put_enum_param(plist, pnames->DownsampleType, + &dsti, DownsampleType_names, + ecode)) >= 0 + ) + params->DownsampleType = (enum psdf_downsample_type)dsti; + ecode = psdf_put_bool_param(plist, pnames->Encode, + ¶ms->Encode, ecode); + switch (code = param_read_string(plist, pnames->Filter, &fs)) { + case 0: + { + const psdf_image_filter_name *pn = pifn; + + while (pn->pname != 0 && !psdf_key_eq(&fs, pn->pname)) + pn++; + if (pn->pname == 0 || pn->min_version > pdev->version) { + ecode = gs_error_rangecheck; + goto ipe; + } + params->Filter = pn->pname; + params->filter_template = pn->template; + break; + } + default: + ecode = code; + ipe:param_signal_error(plist, pnames->Filter, ecode); + case 1: + break; + } + ecode = psdf_put_int_param(plist, pnames->Resolution, + ¶ms->Resolution, ecode); + if (ecode >= 0) { /* Force parameters to acceptable values. */ + if (params->Resolution < 1) + params->Resolution = 1; + switch (params->Depth) { + default: + params->Depth = -1; + case 1: + case 2: + case 4: + case 8: + case -1: + break; + } + } + return ecode; +} + +/* Put parameters. */ +int +gdev_psdf_put_params(gx_device * dev, gs_param_list * plist) +{ + gx_device_psdf *pdev = (gx_device_psdf *) dev; + int ecode = 0; + int code; + gs_param_name param_name; + psdf_distiller_params params; + + /* General parameters. */ + + params = pdev->params; + + ecode = psdf_put_bool_param(plist, "ASCII85EncodePages", + ¶ms.ASCII85EncodePages, ecode); + { + int arpi = params.AutoRotatePages; + + ecode = psdf_put_enum_param(plist, "AutoRotatePages", &arpi, + AutoRotatePages_names, ecode); + params.AutoRotatePages = (enum psdf_auto_rotate_pages)arpi; + } + ecode = psdf_put_bool_param(plist, "CompressPages", + ¶ms.CompressPages, ecode); + switch (code = param_read_long(plist, (param_name = "ImageMemory"), ¶ms.ImageMemory)) { + default: + ecode = code; + param_signal_error(plist, param_name, ecode); + case 0: + case 1: + break; + } + ecode = psdf_put_bool_param(plist, "LZWEncodePages", + ¶ms.LZWEncodePages, ecode); + ecode = psdf_put_bool_param(plist, "PreserveHalftoneInfo", + ¶ms.PreserveHalftoneInfo, ecode); + ecode = psdf_put_bool_param(plist, "PreserveOPIComments", + ¶ms.PreserveOPIComments, ecode); + ecode = psdf_put_bool_param(plist, "PreserveOverprintSettings", + ¶ms.PreserveOverprintSettings, ecode); + { + int tfii = params.TransferFunctionInfo; + + ecode = psdf_put_enum_param(plist, "TransferFunctionInfo", &tfii, + TransferFunctionInfo_names, ecode); + params.TransferFunctionInfo = (enum psdf_transfer_function_info)tfii; + } + { + int ucrbgi = params.UCRandBGInfo; + + ecode = psdf_put_enum_param(plist, "UCRandBGInfo", &ucrbgi, + UCRandBGInfo_names, ecode); + params.UCRandBGInfo = (enum psdf_ucr_and_bg_info)ucrbgi; + } +#ifdef HAVE_LIBZ + ecode = psdf_put_bool_param(plist, "UseFlateCompression", + ¶ms.UseFlateCompression, ecode); +#endif /* HAVE_LIBZ */ + + /* Color sampled image parameters */ + + ecode = psdf_put_image_params(pdev, plist, &Color_names, Poly_filters, + ¶ms.ColorImage, ecode); + { + int ccsi = params.ColorConversionStrategy; + + ecode = psdf_put_enum_param(plist, "ColorConversionStrategy", &ccsi, + ColorConversionStrategy_names, ecode); + params.ColorConversionStrategy = + (enum psdf_color_conversion_strategy)ccsi; + } + ecode = psdf_put_bool_param(plist, "ConvertCMYKImagesToRGB", + ¶ms.ConvertCMYKImagesToRGB, ecode); + ecode = psdf_put_bool_param(plist, "ConvertImagesToIndexed", + ¶ms.ConvertImagesToIndexed, ecode); + + /* Gray sampled image parameters */ + + ecode = psdf_put_image_params(pdev, plist, &Gray_names, Poly_filters, + ¶ms.GrayImage, ecode); + + /* Mono sampled image parameters */ + + ecode = psdf_put_image_params(pdev, plist, &Mono_names, Mono_filters, + ¶ms.MonoImage, ecode); + + /* Font embedding parameters */ + + ecode = psdf_put_embed_param(plist, "~AlwaysEmbed", + ¶ms.AlwaysEmbed, ecode); + ecode = psdf_put_embed_param(plist, "~NeverEmbed", + ¶ms.NeverEmbed, ecode); + ecode = psdf_put_bool_param(plist, "EmbedAllFonts", + ¶ms.EmbedAllFonts, ecode); + ecode = psdf_put_bool_param(plist, "SubsetFonts", + ¶ms.SubsetFonts, ecode); + ecode = psdf_put_int_param(plist, "MaxSubsetPct", + ¶ms.MaxSubsetPct, ecode); + + if (ecode < 0) + return ecode; + code = gdev_vector_put_params(dev, plist); + if (code < 0) + return code; + + pdev->params = params; /* OK to update now */ + return 0; +} diff --git a/pstoraster/gdevpsds.c b/pstoraster/gdevpsds.c new file mode 100644 index 0000000000..da128b5b7d --- /dev/null +++ b/pstoraster/gdevpsds.c @@ -0,0 +1,470 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Image processing streams for PostScript and PDF writers */ +#include "gx.h" +#include "memory_.h" +#include "gserrors.h" +#include "gxdcconv.h" +#include "gdevpsds.h" + +/* ---------------- Convert between 1/2/4 and 8 bits ---------------- */ +gs_private_st_simple(st_1248_state, stream_1248_state, "stream_1248_state"); + +/* Initialize the state. */ +private int +s_1_init(stream_state * st) +{ + stream_1248_state *const ss = (stream_1248_state *) st; + + ss->left = ss->samples_per_row; + ss->bits_per_sample = 1; + return 0; +} +private int +s_2_init(stream_state * st) +{ + stream_1248_state *const ss = (stream_1248_state *) st; + + ss->left = ss->samples_per_row; + ss->bits_per_sample = 2; + return 0; +} +private int +s_4_init(stream_state * st) +{ + stream_1248_state *const ss = (stream_1248_state *) st; + + ss->left = ss->samples_per_row; + ss->bits_per_sample = 4; + return 0; +} + +/* Process one buffer. */ +#define BEGIN_1248\ + stream_1248_state * const ss = (stream_1248_state *)st;\ + const byte *p = pr->ptr;\ + const byte *rlimit = pr->limit;\ + byte *q = pw->ptr;\ + byte *wlimit = pw->limit;\ + uint left = ss->left;\ + int status;\ + int n +#define END_1248\ + pr->ptr = p;\ + pw->ptr = q;\ + ss->left = left;\ + return status + +/* N-to-8 expansion */ +#define FOREACH_N_8(in, nout)\ + status = 0;\ + for ( ; p < rlimit; left -= n, q += n, ++p ) {\ + byte in = p[1];\ + n = min(left, nout);\ + if ( wlimit - q < n ) {\ + status = 1;\ + break;\ + }\ + switch ( n ) {\ + case 0: left = ss->samples_per_row; --p; continue; +#define END_FOREACH_N_8\ + }\ + } +private int +s_N_8_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * pw, bool last) +{ + BEGIN_1248; + + switch (ss->bits_per_sample) { + + case 1:{ + FOREACH_N_8(in, 8) + case 8: + q[8] = (byte) - (in & 1); + case 7: + q[7] = (byte) - ((in >> 1) & 1); + case 6: + q[6] = (byte) - ((in >> 2) & 1); + case 5: + q[5] = (byte) - ((in >> 3) & 1); + case 4: + q[4] = (byte) - ((in >> 4) & 1); + case 3: + q[3] = (byte) - ((in >> 5) & 1); + case 2: + q[2] = (byte) - ((in >> 6) & 1); + case 1: + q[1] = (byte) - (in >> 7); + END_FOREACH_N_8; + } + break; + + case 2:{ + static const byte b2[4] = + {0x00, 0x55, 0xaa, 0xff}; + + FOREACH_N_8(in, 4) + case 4: + q[4] = b2[in & 3]; + case 3: + q[3] = b2[(in >> 2) & 3]; + case 2: + q[2] = b2[(in >> 4) & 3]; + case 1: + q[1] = b2[in >> 6]; + END_FOREACH_N_8; + } + break; + + case 4:{ + static const byte b4[16] = + { + 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, + 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff + }; + + FOREACH_N_8(in, 2) + case 2: + q[2] = b4[in & 0xf]; + case 1: + q[1] = b4[in >> 4]; + END_FOREACH_N_8; + } + break; + + default: + return ERRC; + } + + END_1248; +} + +/* 8-to-N reduction */ +#define FOREACH_8_N(out, nin)\ + byte out;\ + status = 1;\ + for ( ; q < wlimit; left -= n, p += n, ++q ) {\ + n = min(left, nin);\ + if ( rlimit - p < n ) {\ + status = 0;\ + break;\ + }\ + out = 0;\ + switch ( n ) {\ + case 0: left = ss->samples_per_row; --q; continue; +#define END_FOREACH_8_N\ + q[1] = out;\ + }\ + } +private int +s_8_N_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * pw, bool last) +{ + BEGIN_1248; + + switch (ss->bits_per_sample) { + + case 1:{ + FOREACH_8_N(out, 8) + case 8: + out = p[8] >> 7; + case 7: + out |= (p[7] >> 7) << 1; + case 6: + out |= (p[6] >> 7) << 2; + case 5: + out |= (p[5] >> 7) << 3; + case 4: + out |= (p[4] >> 7) << 4; + case 3: + out |= (p[3] >> 7) << 5; + case 2: + out |= (p[2] >> 7) << 6; + case 1: + out |= p[1] & 0x80; + END_FOREACH_8_N; + } + break; + + case 2:{ + FOREACH_8_N(out, 4) + case 4: + out |= p[4] >> 6; + case 3: + out |= (p[3] >> 6) << 2; + case 2: + out |= (p[2] >> 6) << 4; + case 1: + out |= p[1] & 0xc0; + END_FOREACH_8_N; + } + break; + + case 4:{ + FOREACH_8_N(out, 2) + case 2: + out |= p[2] >> 4; + case 1: + out |= p[1] & 0xf0; + END_FOREACH_8_N; + } + break; + + default: + return ERRC; + } + + END_1248; +} + +const stream_template s_1_8_template = +{ + &st_1248_state, s_1_init, s_N_8_process, 1, 8 +}; +const stream_template s_2_8_template = +{ + &st_1248_state, s_2_init, s_N_8_process, 1, 4 +}; +const stream_template s_4_8_template = +{ + &st_1248_state, s_4_init, s_N_8_process, 1, 2 +}; + +const stream_template s_8_1_template = +{ + &st_1248_state, s_1_init, s_8_N_process, 8, 1 +}; +const stream_template s_8_2_template = +{ + &st_1248_state, s_2_init, s_8_N_process, 4, 1 +}; +const stream_template s_8_4_template = +{ + &st_1248_state, s_4_init, s_8_N_process, 2, 1 +}; + +/* ---------------- CMYK => RGB conversion ---------------- */ + +private_st_C2R_state(); + +/* Process one buffer. */ +private int +s_C2R_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * pw, bool last) +{ + stream_C2R_state *const ss = (stream_C2R_state *) st; + const byte *p = pr->ptr; + const byte *rlimit = pr->limit; + byte *q = pw->ptr; + byte *wlimit = pw->limit; + + for (; rlimit - p >= 4 && wlimit - q >= 3; p += 4, q += 3) { + byte bc = p[1], bm = p[2], by = p[3], bk = p[4]; + frac rgb[3]; + + color_cmyk_to_rgb(byte2frac(bc), byte2frac(bm), byte2frac(by), + byte2frac(bk), ss->pis, rgb); + q[1] = frac2byte(rgb[0]); + q[2] = frac2byte(rgb[1]); + q[3] = frac2byte(rgb[2]); + } + pr->ptr = p; + pw->ptr = q; + return (rlimit - p < 4 ? 0 : 1); +} + +const stream_template s_C2R_template = +{ + &st_C2R_state, 0 /*NULL */ , s_C2R_process, 4, 3 +}; + +/* ---------------- Downsampling ---------------- */ + +private void +s_Downsample_set_defaults(register stream_state * st) +{ + stream_Downsample_state *const ss = + (stream_Downsample_state *) st; + + s_Downsample_set_defaults_inline(ss); +} + +/* Subsample */ +/****** DOESN'T IMPLEMENT padY YET ******/ + +gs_private_st_simple(st_Subsample_state, stream_Subsample_state, + "stream_Subsample_state"); + +/* Initialize the state. */ +private int +s_Subsample_init(stream_state * st) +{ + stream_Subsample_state *const ss = (stream_Subsample_state *) st; + + ss->x = ss->y = 0; + return 0; +} + +/* Process one buffer. */ +private int +s_Subsample_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * pw, bool last) +{ + stream_Subsample_state *const ss = (stream_Subsample_state *) st; + const byte *p = pr->ptr; + const byte *rlimit = pr->limit; + byte *q = pw->ptr; + byte *wlimit = pw->limit; + int spp = ss->Colors; + int width = ss->Columns; + int xf = ss->XFactor, yf = ss->YFactor; + int xf2 = xf / 2, yf2 = yf / 2; + int xlimit = (width / xf) * xf; + int xlast = (ss->padX && xlimit < width ? xlimit + (width % xf) / 2 : -1); + int x = ss->x, y = ss->y; + int status = 0; + + for (; rlimit - p >= spp; p += spp) { + if (y == yf2 && ((x % xf == xf2 && x < xlimit) || x == xlast)) { + if (wlimit - q < spp) { + status = 1; + break; + } + memcpy(q + 1, p + 1, spp); + q += spp; + } + if (++x == width) { + x = 0; + if (++y == yf) { + y = 0; + } + } + } + pr->ptr = p; + pw->ptr = q; + ss->x = x, ss->y = y; + return status; +} + +const stream_template s_Subsample_template = +{ + &st_Subsample_state, s_Subsample_init, s_Subsample_process, 4, 4, + 0 /* NULL */, s_Downsample_set_defaults +}; + +/* Average */ + +private_st_Average_state(); + +/* Initialize the state. */ +private int +s_Average_init(stream_state * st) +{ + stream_Average_state *const ss = (stream_Average_state *) st; + + ss->sum_size = + ss->Colors * ((ss->Columns + ss->XFactor - 1) / ss->XFactor); + ss->copy_size = ss->sum_size - + (ss->padX || (ss->Columns % ss->XFactor == 0) ? 0 : ss->Colors); + ss->sums = + (uint *)gs_alloc_byte_array(st->memory, ss->sum_size, + sizeof(uint), "Average sums"); + if (ss->sums == 0) + return ERRC; /****** WRONG ******/ + memset(ss->sums, 0, ss->sum_size * sizeof(uint)); + return s_Subsample_init(st); +} + +/* Release the state. */ +private void +s_Average_release(stream_state * st) +{ + stream_Average_state *const ss = (stream_Average_state *) st; + + gs_free_object(st->memory, ss->sums, "Average sums"); +} + +/* Process one buffer. */ +private int +s_Average_process(stream_state * st, stream_cursor_read * pr, + stream_cursor_write * pw, bool last) +{ + stream_Average_state *const ss = (stream_Average_state *) st; + const byte *p = pr->ptr; + const byte *rlimit = pr->limit; + byte *q = pw->ptr; + byte *wlimit = pw->limit; + int spp = ss->Colors; + int width = ss->Columns; + int xf = ss->XFactor, yf = ss->YFactor; + int x = ss->x, y = ss->y; + uint *sums = ss->sums; + int status = 0; + +top: + if (y == yf || (last && p >= rlimit && ss->padY && y != 0)) { + /* We're copying averaged values to the output. */ + int ncopy = min(ss->copy_size - x, wlimit - q); + + if (ncopy) { + int scale = xf * y; + + while (--ncopy >= 0) + *++q = (byte) (sums[x++] / scale); + } + if (x < ss->copy_size) { + status = 1; + goto out; + } + /* Done copying. */ + x = y = 0; + memset(sums, 0, ss->sum_size * sizeof(uint)); + } + while (rlimit - p >= spp) { + uint *bp = sums + x / xf * spp; + int i; + + for (i = spp; --i >= 0;) + *bp++ += *++p; + if (++x == width) { + x = 0; + ++y; + goto top; + } + } +out: + pr->ptr = p; + pw->ptr = q; + ss->x = x, ss->y = y; + return status; +} + +const stream_template s_Average_template = +{ + &st_Average_state, s_Average_init, s_Average_process, 4, 4, + s_Average_release, s_Downsample_set_defaults +}; diff --git a/pstoraster/gdevpsds.h b/pstoraster/gdevpsds.h new file mode 100644 index 0000000000..772c1ff535 --- /dev/null +++ b/pstoraster/gdevpsds.h @@ -0,0 +1,110 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Image processing stream interface for PostScript and PDF writers */ + +#ifndef gdevpsds_INCLUDED +# define gdevpsds_INCLUDED + +#include "strimpl.h" + +/* Convert between 1/2/4 bits and 8 bits. */ +typedef struct stream_1248_state_s { + stream_state_common; + /* The following are set at initialization time. */ + uint samples_per_row; /* >0 */ + int bits_per_sample; /* 1, 2, 4 */ + /* The following are updated dynamically. */ + uint left; /* # of samples left in current row */ +} stream_1248_state; + +/* Expand N (1, 2, 4) bits to 8. */ +extern const stream_template s_1_8_template; +extern const stream_template s_2_8_template; +extern const stream_template s_4_8_template; + +/* Reduce 8 bits to N (1, 2, 4) */ +extern const stream_template s_8_1_template; +extern const stream_template s_8_2_template; +extern const stream_template s_8_4_template; + +/* Initialize an expansion or reduction stream. */ +#define s_1248_init(ss, Columns, samples_per_pixel)\ + ((ss)->samples_per_row = (Columns) * (samples_per_pixel),\ + (*(ss)->template->init)((stream_state *)(ss))) + +/* Convert (8-bit) CMYK to RGB. */ +typedef struct stream_C2R_state_s { + stream_state_common; + /* The following are set at initialization time. */ + const gs_imager_state *pis; /* for UCR & BG */ +} stream_C2R_state; + +#define private_st_C2R_state() /* in gdevpsds.c */\ + gs_private_st_ptrs1(st_C2R_state, stream_C2R_state, "stream_C2R_state",\ + c2r_enum_ptrs, c2r_reloc_ptrs, pis) +extern const stream_template s_C2R_template; + +#define s_C2R_init(ss, pisv)\ + ((ss)->pis = (pisv), 0) + +/* Downsample, possibly with anti-aliasing. */ +#define stream_Downsample_state_common\ + stream_state_common;\ + /* The client sets the following before initialization. */\ + int Colors;\ + int Columns; /* # of input columns */\ + int XFactor, YFactor;\ + bool AntiAlias;\ + bool padX, padY; /* keep excess samples */\ + /* The following are updated dynamically. */\ + int x, y /* position within input image */ +#define s_Downsample_set_defaults_inline(ss)\ + ((ss)->AntiAlias = (ss)->padX = (ss)->padY = false) +typedef struct stream_Downsample_state_s { + stream_Downsample_state_common; +} stream_Downsample_state; + +/* Subsample */ +/****** Subsample DOESN'T IMPLEMENT padY YET ******/ +typedef struct stream_Subsample_state_s { + stream_Downsample_state_common; +} stream_Subsample_state; +extern const stream_template s_Subsample_template; + +/* Average */ +typedef struct stream_Average_state_s { + stream_Downsample_state_common; + uint sum_size; + uint copy_size; + uint *sums; /* accumulated sums for average */ +} stream_Average_state; + +#define private_st_Average_state() /* in gdevpsds.c */\ + gs_private_st_ptrs1(st_Average_state, stream_Average_state,\ + "stream_Average_state", avg_enum_ptrs, avg_reloc_ptrs, sums) +extern const stream_template s_Average_template; + +#endif /* gdevpsds_INCLUDED */ diff --git a/pstoraster/gdevpstr.h b/pstoraster/gdevpstr.h new file mode 100644 index 0000000000..12156c39ad --- /dev/null +++ b/pstoraster/gdevpstr.h @@ -0,0 +1,90 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Stream output for PostScript- and PDF-writing drivers. */ + +#ifndef gdevpstr_INCLUDED +# define gdevpstr_INCLUDED + +/* Define an opaque type for streams. */ +#ifndef stream_DEFINED +# define stream_DEFINED +typedef struct stream_s stream; + +#endif + +/* Put a character on a stream. */ +#define pputc(s, c) spputc(s, c) + +/* Put a byte array on a stream. */ +int pwrite(P3(stream * s, const void *ptr, uint count)); + +/* Put a string on a stream. */ +int pputs(P2(stream * s, const char *str)); + +/* + * Print (a) floating point number(s) using a format. This is needed + * because %f format always prints a fixed number of digits after the + * decimal point, and %g format may use %e format, which PDF disallows. + * These functions return a pointer to the next %-element of the format, or + * to the terminating 0. + */ +const char *pprintg1(P3(stream * s, const char *format, floatp v)); +const char *pprintg2(P4(stream * s, const char *format, floatp v1, floatp v2)); +const char *pprintg3(P5(stream * s, const char *format, + floatp v1, floatp v2, floatp v3)); +const char *pprintg4(P6(stream * s, const char *format, + floatp v1, floatp v2, floatp v3, floatp v4)); +const char *pprintg6(P8(stream * s, const char *format, + floatp v1, floatp v2, floatp v3, floatp v4, + floatp v5, floatp v6)); + +/* + * The rest of these printing functions exist solely because the ANSI C + * "standard" for functions with a variable number of arguments is not + * implemented properly or consistently across compilers. + */ +/* Print (an) int value(s) using a format. */ +const char *pprintd1(P3(stream * s, const char *format, int v)); +const char *pprintd2(P4(stream * s, const char *format, int v1, int v2)); +const char *pprintd3(P5(stream * s, const char *format, + int v1, int v2, int v3)); +const char *pprintd4(P6(stream * s, const char *format, + int v1, int v2, int v3, int v4)); + +/* Print a long value using a format. */ +const char *pprintld1(P3(stream * s, const char *format, long v)); +const char *pprintld2(P4(stream * s, const char *format, long v1, long v2)); +const char *pprintld3(P5(stream * s, const char *format, + long v1, long v2, long v3)); + +/* Print (a) string(s) using a format. */ +const char *pprints1(P3(stream * s, const char *format, const char *str)); +const char *pprints2(P4(stream * s, const char *format, + const char *str1, const char *str2)); +const char *pprints3(P5(stream * s, const char *format, + const char *str1, const char *str2, const char *str3)); + +#endif /* gdevpstr_INCLUDED */ diff --git a/pstoraster/gdevpxen.h b/pstoraster/gdevpxen.h new file mode 100644 index 0000000000..25eb1e30cc --- /dev/null +++ b/pstoraster/gdevpxen.h @@ -0,0 +1,269 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Enumerated attribute value definitions for PCL XL */ + +#ifndef gdevpxen_INCLUDED +# define gdevpxen_INCLUDED + +typedef enum { + eClockWise = 0, + eCounterClockWise, + pxeArcDirection_next +} pxeArcDirection_t; + +typedef enum { + eNoSubstitution = 0, + eVerticalSubstitution, + pxeCharSubModeArray_next +} pxeCharSubModeArray_t; + +typedef enum { + eNonZeroWinding = 0, + eEvenOdd, + pxeClipMode_next, + pxeFillMode_next = pxeClipMode_next /* see pxeFillMode_t below */ +} pxeClipMode_t; + +typedef enum { + eInterior = 0, + eExterior, + pxeClipRegion_next +} pxeClipRegion_t; + +typedef enum { + e1Bit = 0, + e4Bit, + e8Bit, + pxeColorDepth_next +} pxeColorDepth_t; + +typedef enum { + eCRGB = 5, /* Note: for this enumeration, 0 is not a valid value */ + pxeColorimetricColorSpace_next +} pxeColorimetricColorSpace_t; /* 2.0 */ + +typedef enum { + eDirectPixel = 0, + eIndexedPixel, + pxeColorMapping_next +} pxeColorMapping_t; + +typedef enum { + eNoColorSpace = 0, /* Note: for this enumeration, 0 is not a valid value */ + eGray, + eRGB, + eSRGB, /* 2.0 */ + pxeColorSpace_next +} pxeColorSpace_t; + +typedef enum { + eNoCompression = 0, + eRLECompression, + eJPEGCompression, /* 2.0 */ + pxeCompressMode_next +} pxeCompressMode_t; + +typedef enum { + eBinaryHighByteFirst = 0, + eBinaryLowByteFirst, + pxeDataOrg_next /* is this DataOrg or DataOrganization? */ +} pxeDataOrg_t; + +typedef enum { + eDefault = 0, /* bad choice of name! */ + pxeDataSource_next +} pxeDataSource_t; + +typedef enum { + eUByte = 0, + eSByte, + eUInt16, + eSInt16, + pxeDataType_next +} pxeDataType_t; + +typedef enum { + eDownloaded = -1, /* Not a real value, indicates a downloaded matrix */ + eDeviceBest = 0, + pxeDitherMatrix_next +} pxeDitherMatrix_t; + +typedef enum { + eDuplexHorizontalBinding = 0, + eDuplexVerticalBinding, + pxeDuplexPageMode_next +} pxeDuplexPageMode_t; + +typedef enum { + eFrontMediaSide = 0, + eBackMediaSide, + pxeDuplexPageSide_next +} pxeDuplexPageSide_t; + +typedef enum { + /* Several pieces of code know that this is a bit mask. */ + eNoReporting = 0, + eBackChannel, + eErrorPage, + eBackChAndErrPage, + eNWBackChannel, /* 2.0 */ + eNWErrorPage, /* 2.0 */ + eNWBackChAndErrPage, /* 2.0 */ + pxeErrorReport_next +} pxeErrorReport_t; + +typedef pxeClipMode_t pxeFillMode_t; + +typedef enum { + eButtCap = 0, + eRoundCap, + eSquareCap, + eTriangleCap, + pxeLineCap_next +} pxeLineCap_t; + +#define pxeLineCap_to_library\ + { gs_cap_butt, gs_cap_round, gs_cap_square, gs_cap_triangle } + +typedef enum { + eMiterJoin = 0, + eRoundJoin, + eBevelJoin, + eNoJoin, + pxeLineJoin_next +} pxeLineJoin_t; + +#define pxeLineJoin_to_library\ + { gs_join_miter, gs_join_round, gs_join_bevel, gs_join_none } + +typedef enum { + eInch = 0, + eMillimeter, + eTenthsOfAMillimeter, + pxeMeasure_next +} pxeMeasure_t; + +#define pxeMeasure_to_points { 72.0, 72.0 / 25.4, 72.0 / 254.0 } + +typedef enum { + eDefaultDestination = 0, + eFaceDownBin, /* 2.0 */ + eFaceUpBin, /* 2.0 */ + eJobOffsetBin, /* 2.0 */ + pxeMediaDestination_next +} pxeMediaDestination_t; + +typedef enum { + eLetterPaper = 0, + eLegalPaper, + eA4Paper, + eExecPaper, + eLedgerPaper, + eA3Paper, + eCOM10Envelope, + eMonarchEnvelope, + eC5Envelope, + eDLEnvelope, + eJB4Paper, + eJB5Paper, + eB5Envelope, + eJPostcard, + eJDoublePostcard, + eA5Paper, + eA6Paper, /* 2.0 */ + eJB6Paper, /* 2.0 */ + pxeMediaSize_next +} pxeMediaSize_t; + +/* + * Apply a macro (or procedure) to all known paper sizes. + * The arguments are: + * media size code, resolution for width/height, width, height. + */ +#define px_enumerate_media(m)\ + m(eLetterPaper, 300, 2550, 3300)\ + m(eLegalPaper, 300, 2550, 5300)\ + m(eA4Paper, 300, 2480, 3507)\ + m(eExecPaper, 300, 2175, 3150)\ + m(eLedgerPaper, 300, 3300, 5100)\ + m(eA3Paper, 300, 3507, 4960)\ + m(eCOM10Envelope, 300, 1237, 2850)\ + m(eMonarchEnvelope, 300, 1162, 2250)\ + m(eC5Envelope, 300, 1913, 2704)\ + m(eDLEnvelope, 300, 1299, 2598)\ + m(eB5Envelope, 300, 2078, 2952) + +typedef enum { + eDefaultSource = 0, + eAutoSelect, + eManualFeed, + eMultiPurposeTray, + eUpperCassette, + eLowerCassette, + eEnvelopeTray, + eThirdCassette, /* 2.0 */ + pxeMediaSource_next +} pxeMediaSource_t; + +/**** MediaType is not documented. ****/ +typedef enum { + eDefaultType = 0, + pxeMediaType_next +} pxeMediaType_t; + +typedef enum { + ePortraitOrientation = 0, + eLandscapeOrientation, + eReversePortrait, + eReverseLandscape, + pxeOrientation_next +} pxeOrientation_t; + +typedef enum { + eTempPattern = 0, + ePagePattern, + eSessionPattern, + pxePatternPersistence_next +} pxePatternPersistence_t; + +typedef enum { + eSimplexFrontSide = 0, + pxeSimplexPageMode_next +} pxeSimplexPageMode_t; + +typedef enum { + eOpaque = 0, + eTransparent, + pxeTxMode_next +} pxeTxMode_t; + +typedef enum { + eHorizontal = 0, + eVertical, + pxeWritingMode_next +} pxeWritingMode_t; /* 2.0 */ + +#endif /* gdevpxen_INCLUDED */ diff --git a/pstoraster/gdevpxop.h b/pstoraster/gdevpxop.h new file mode 100644 index 0000000000..9b61a01e0a --- /dev/null +++ b/pstoraster/gdevpxop.h @@ -0,0 +1,114 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Operator and other tag definitions for PCL XL */ + +#ifndef gdevpxop_INCLUDED +# define gdevpxop_INCLUDED + +typedef enum { +/*0x */ + pxtNull = 0x00, pxt01, pxt02, pxt03, + pxt04, pxt05, pxt06, pxt07, + pxt08, pxtHT, pxtLF, pxtVT, + pxtFF, pxtCR, pxt0e, pxt0f, +/*1x */ + pxt10, pxt11, pxt12, pxt13, + pxt14, pxt15, pxt16, pxt17, + pxt18, pxt19, pxt1a, pxt1b, + pxt1c, pxt1d, pxt1e, pxt1f, +/*2x */ + pxtSpace, pxt21, pxt22, pxt23, + pxt24, pxt25, pxt26, pxt_beginASCII, + pxt_beginBinaryMSB, pxt_beginBinaryLSB, pxt2a, pxt2b, + pxt2c, pxt2d, pxt2e, pxt2f, +/*3x */ + pxt30, pxt31, pxt32, pxt33, + pxt34, pxt35, pxt36, pxt37, + pxt38, pxt39, pxt3a, pxt3b, + pxt3c, pxt3d, pxt3e, pxt3f, +/*4x */ + pxt40, pxtBeginSession, pxtEndSession, pxtBeginPage, + pxtEndPage, pxt45, pxt46, pxtComment, + pxtOpenDataSource, pxtCloseDataSource, pxt4a, pxt4b, + pxt4c, pxt4d, pxt4e, pxtBeginFontHeader, +/*5x */ + pxtReadFontHeader, pxtEndFontHeader, pxtBeginChar, pxtReadChar, + pxtEndChar, pxtRemoveFont, pxtSetCharAttributes /*2.0 */ , pxt57, + pxt58, pxt59, pxt5a, pxtBeginStream, + pxtReadStream, pxtEndStream, pxtExecStream, pxtRemoveStream /*2.0 */ , +/*6x */ + pxtPopGS, pxtPushGS, pxtSetClipReplace, pxtSetBrushSource, + pxtSetCharAngle, pxtSetCharScale, pxtSetCharShear, pxtSetClipIntersect, + pxtSetClipRectangle, pxtSetClipToPage, pxtSetColorSpace, pxtSetCursor, + pxtSetCursorRel, pxtSetHalftoneMethod, pxtSetFillMode, pxtSetFont, +/*7x */ + pxtSetLineDash, pxtSetLineCap, pxtSetLineJoin, pxtSetMiterLimit, + pxtSetPageDefaultCTM, pxtSetPageOrigin, pxtSetPageRotation, pxtSetPageScale, + pxtSetPaintTxMode, pxtSetPenSource, pxtSetPenWidth, pxtSetROP, + pxtSetSourceTxMode, pxtSetCharBoldValue, pxt7e, pxtSetClipMode, +/*8x */ + pxtSetPathToClip, pxtSetCharSubMode, pxt82, pxt83, + pxtCloseSubPath, pxtNewPath, pxtPaintPath, pxt87, + pxt88, pxt89, pxt8a, pxt8b, + pxt8c, pxt8d, pxt8e, pxt8f, +/*9x */ + pxt90, pxtArcPath, pxt92, pxtBezierPath, + pxt94, pxtBezierRelPath, pxtChord, pxtChordPath, + pxtEllipse, pxtEllipsePath, pxt9a, pxtLinePath, + pxt9c, pxtLineRelPath, pxtPie, pxtPiePath, +/*ax */ + pxtRectangle, pxtRectanglePath, pxtRoundRectangle, pxtRoundRectanglePath, + pxta4, pxta5, pxta6, pxta7, + pxtText, pxtTextPath, pxtaa, pxtab, + pxtac, pxtad, pxtae, pxtaf, +/*bx */ + pxtBeginImage, pxtReadImage, pxtEndImage, pxtBeginRastPattern, + pxtReadRastPattern, pxtEndRastPattern, pxtBeginScan, pxtb7, + pxtEndScan, pxtScanLineRel, pxtba, pxtbb, + pxtbc, pxtbd, pxtbe, pxtbf, +/*cx */ + pxt_ubyte, pxt_uint16, pxt_uint32, pxt_sint16, + pxt_sint32, pxt_real32, pxtc6, pxtc7, + pxt_ubyte_array, pxt_uint16_array, pxt_uint32_array, pxt_sint16_array, + pxt_sint32_array, pxt_real32_array, pxtce, pxtcf, +/*dx */ + pxt_ubyte_xy, pxt_uint16_xy, pxt_uint32_xy, pxt_sint16_xy, + pxt_sint32_xy, pxt_real32_xy, pxtd6, pxtd7, + pxtd8, pxtd9, pxtda, pxtdb, + pxtdc, pxtdd, pxtde, pxtdf, +/*ex */ + pxt_ubyte_box, pxt_uint16_box, pxt_uint32_box, pxt_sint16_box, + pxt_sint32_box, pxt_real32_box, pxte6, pxte7, + pxte8, pxte9, pxtea, pxteb, + pxtec, pxted, pxtee, pxtef, +/*fx */ + pxtf0, pxtf1, pxtf2, pxtf3, + pxtf4, pxtf5, pxtf6, pxtf7, + pxt_attr_ubyte, pxt_attr_uint16, pxt_dataLength, pxt_dataLengthByte, + pxtfc, pxtfd, pxtfe, pxtff +} px_tag_t; + +#endif /* gdevpxop_INCLUDED */ diff --git a/pstoraster/gdevvec.c b/pstoraster/gdevvec.c new file mode 100644 index 0000000000..80adbb7e84 --- /dev/null +++ b/pstoraster/gdevvec.c @@ -0,0 +1,905 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Utilities for "vector" devices */ +#include "math_.h" +#include "memory_.h" +#include "string_.h" +#include "gx.h" +#include "gp.h" +#include "gserrors.h" +#include "gsparam.h" +#include "gsutil.h" +#include "gxfixed.h" +#include "gdevvec.h" +#include "gscspace.h" +#include "gxdcolor.h" +#include "gxpaint.h" /* requires gx_path, ... */ +#include "gzpath.h" +#include "gzcpath.h" + +/****** + ****** NOTE: EVERYTHING IN THIS FILE IS SUBJECT TO CHANGE WITHOUT NOTICE. + ****** USE AT YOUR OWN RISK. + ******/ + +/* Structure descriptors */ +public_st_device_vector(); +public_st_vector_image_enum(); + +/* ================ Default implementations of vector procs ================ */ + +int +gdev_vector_setflat(gx_device_vector * vdev, floatp flatness) +{ + return 0; +} + +int +gdev_vector_dopath(gx_device_vector * vdev, const gx_path * ppath, + gx_path_type_t type) +{ + bool do_close = (type & gx_path_type_stroke) != 0; + gs_fixed_rect rect; + gs_point scale; + double x_start = 0, y_start = 0, x_prev, y_prev; + bool first = true; + gs_path_enum cenum; + int code; + + if (gx_path_is_rectangle(ppath, &rect)) + return (*vdev_proc(vdev, dorect)) (vdev, rect.p.x, rect.p.y, rect.q.x, + rect.q.y, type); + scale = vdev->scale; + code = (*vdev_proc(vdev, beginpath)) (vdev, type); + gx_path_enum_init(&cenum, ppath); + for (;;) { + fixed vs[6]; + int pe_op = gx_path_enum_next(&cenum, (gs_fixed_point *) vs); + double x, y; + + sw:switch (pe_op) { + case 0: /* done */ + return (*vdev_proc(vdev, endpath)) (vdev, type); + case gs_pe_moveto: + code = (*vdev_proc(vdev, moveto)) + (vdev, x_prev, y_prev, (x = fixed2float(vs[0]) / scale.x), + (y = fixed2float(vs[1]) / scale.y), type); + if (first) + x_start = x, y_start = y, first = false; + break; + case gs_pe_lineto: + code = (*vdev_proc(vdev, lineto)) + (vdev, x_prev, y_prev, (x = fixed2float(vs[0]) / scale.x), + (y = fixed2float(vs[1]) / scale.y), type); + break; + case gs_pe_curveto: + code = (*vdev_proc(vdev, curveto)) + (vdev, x_prev, y_prev, + fixed2float(vs[0]) / scale.x, + fixed2float(vs[1]) / scale.y, + fixed2float(vs[2]) / scale.x, + fixed2float(vs[3]) / scale.y, + (x = fixed2float(vs[4]) / scale.x), + (y = fixed2float(vs[5]) / scale.y), + type); + break; + case gs_pe_closepath: + x = x_start, y = y_start; + if (do_close) { + code = (*vdev_proc(vdev, closepath)) + (vdev, x_prev, y_prev, x_start, y_start, type); + break; + } + pe_op = gx_path_enum_next(&cenum, (gs_fixed_point *) vs); + if (pe_op != 0) { + code = (*vdev_proc(vdev, closepath)) + (vdev, x_prev, y_prev, x_start, y_start, type); + if (code < 0) + return code; + goto sw; + } + return (*vdev_proc(vdev, endpath)) (vdev, type); + default: /* can't happen */ + return_error(gs_error_unknownerror); + } + if (code < 0) + return code; + x_prev = x, y_prev = y; + } +} + +int +gdev_vector_dorect(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, + fixed y1, gx_path_type_t type) +{ + int code = (*vdev_proc(vdev, beginpath)) (vdev, type); + + if (code < 0) + return code; + code = gdev_vector_write_rectangle(vdev, x0, y0, x1, y1, + (type & gx_path_type_stroke) != 0, + gx_rect_x_first); + if (code < 0) + return code; + return (*vdev_proc(vdev, endpath)) (vdev, type); +} + +/* ================ Utility procedures ================ */ + +/* Recompute the cached color values. */ +private void +gdev_vector_load_cache(gx_device_vector * vdev) +{ + vdev->black = gx_device_black((gx_device *)vdev); + vdev->white = gx_device_white((gx_device *)vdev); +} + +/* Initialize the state. */ +void +gdev_vector_init(gx_device_vector * vdev) +{ + gdev_vector_reset(vdev); + vdev->scale.x = vdev->scale.y = 1.0; + vdev->in_page = false; + gdev_vector_load_cache(vdev); +} + +/* Reset the remembered graphics state. */ +void +gdev_vector_reset(gx_device_vector * vdev) +{ + static const gs_imager_state state_initial = + {gs_imager_state_initial(1)}; + + vdev->state = state_initial; + color_unset(&vdev->fill_color); + color_unset(&vdev->stroke_color); + vdev->clip_path_id = + vdev->no_clip_path_id = gs_next_ids(1); +} + +/* Open the output file and stream. */ +int +gdev_vector_open_file_bbox(gx_device_vector * vdev, uint strmbuf_size, + bool bbox) +{ /* Open the file as positionable if possible. */ + int code = gx_device_open_output_file((gx_device *) vdev, vdev->fname, + true, true, &vdev->file); + + if (code < 0) + return code; + if ((vdev->strmbuf = gs_alloc_bytes(vdev->v_memory, strmbuf_size, + "vector_open(strmbuf)")) == 0 || + (vdev->strm = s_alloc(vdev->v_memory, + "vector_open(strm)")) == 0 || + (bbox && + (vdev->bbox_device = + gs_alloc_struct_immovable(vdev->v_memory, + gx_device_bbox, &st_device_bbox, + "vector_open(bbox_device)")) == 0) + ) { + if (vdev->bbox_device) + gs_free_object(vdev->v_memory, vdev->bbox_device, + "vector_open(bbox_device)"); + vdev->bbox_device = 0; + if (vdev->strm) + gs_free_object(vdev->v_memory, vdev->strm, + "vector_open(strm)"); + vdev->strm = 0; + if (vdev->strmbuf) + gs_free_object(vdev->v_memory, vdev->strmbuf, + "vector_open(strmbuf)"); + vdev->strmbuf = 0; + fclose(vdev->file); + vdev->file = 0; + return_error(gs_error_VMerror); + } + vdev->strmbuf_size = strmbuf_size; + swrite_file(vdev->strm, vdev->file, vdev->strmbuf, strmbuf_size); + /* + * We don't want finalization to close the file, but we do want it + * to flush the stream buffer. + */ + vdev->strm->procs.close = vdev->strm->procs.flush; + if (vdev->bbox_device) { + gx_device_bbox_init(vdev->bbox_device, NULL); + gx_device_set_resolution((gx_device *) vdev->bbox_device, + vdev->HWResolution[0], + vdev->HWResolution[1]); + /* Do the right thing about upright vs. inverted. */ + /* (This is dangerous in general, since the procedure */ + /* might reference non-standard elements.) */ + set_dev_proc(vdev->bbox_device, get_initial_matrix, + dev_proc(vdev, get_initial_matrix)); + (*dev_proc(vdev->bbox_device, open_device)) + ((gx_device *) vdev->bbox_device); + } + return 0; +} + +/* Get the current stream, calling beginpage if in_page is false. */ +stream * +gdev_vector_stream(gx_device_vector * vdev) +{ + if (!vdev->in_page) { + (*vdev_proc(vdev, beginpage)) (vdev); + vdev->in_page = true; + } + return vdev->strm; +} + +/* Compare two drawing colors. */ +/* Right now we don't attempt to handle non-pure colors. */ +private bool +drawing_color_eq(const gx_drawing_color * pdc1, const gx_drawing_color * pdc2) +{ + return (gx_dc_is_pure(pdc1) ? + gx_dc_is_pure(pdc2) && + gx_dc_pure_color(pdc1) == gx_dc_pure_color(pdc2) : + gx_dc_is_null(pdc1) ? + gx_dc_is_null(pdc2) : + false); +} + +/* Update the logical operation. */ +int +gdev_vector_update_log_op(gx_device_vector * vdev, gs_logical_operation_t lop) +{ + gs_logical_operation_t diff = lop ^ vdev->state.log_op; + + if (diff != 0) { + int code = (*vdev_proc(vdev, setlogop)) (vdev, lop, diff); + + if (code < 0) + return code; + vdev->state.log_op = lop; + } + return 0; +} + +/* Update the fill color. */ +int +gdev_vector_update_fill_color(gx_device_vector * vdev, + const gx_drawing_color * pdcolor) +{ + if (!drawing_color_eq(pdcolor, &vdev->fill_color)) { + int code = (*vdev_proc(vdev, setfillcolor)) (vdev, pdcolor); + + if (code < 0) + return code; + vdev->fill_color = *pdcolor; + } + return 0; +} + +/* Update the state for filling a region. */ +private int +update_fill(gx_device_vector * vdev, const gx_drawing_color * pdcolor, + gs_logical_operation_t lop) +{ + int code = gdev_vector_update_fill_color(vdev, pdcolor); + + if (code < 0) + return code; + return gdev_vector_update_log_op(vdev, lop); +} + +/* Bring state up to date for filling. */ +int +gdev_vector_prepare_fill(gx_device_vector * vdev, const gs_imager_state * pis, + const gx_fill_params * params, const gx_drawing_color * pdcolor) +{ + if (params->flatness != vdev->state.flatness) { + int code = (*vdev_proc(vdev, setflat)) (vdev, params->flatness); + + if (code < 0) + return code; + vdev->state.flatness = params->flatness; + } + return update_fill(vdev, pdcolor, pis->log_op); +} + +/* Compare two dash patterns. */ +private bool +dash_pattern_eq(const float *stored, const gx_dash_params * set, floatp scale) +{ + int i; + + for (i = 0; i < set->pattern_size; ++i) + if (stored[i] != (float)(set->pattern[i] * scale)) + return false; + return true; +} + +/* Bring state up to date for stroking. */ +int +gdev_vector_prepare_stroke(gx_device_vector * vdev, const gs_imager_state * pis, + const gx_stroke_params * params, const gx_drawing_color * pdcolor, + floatp scale) +{ + int pattern_size = pis->line_params.dash.pattern_size; + float dash_offset = pis->line_params.dash.offset * scale; + float half_width = pis->line_params.half_width * scale; + + if (pattern_size > max_dash) + return_error(gs_error_limitcheck); + if (dash_offset != vdev->state.line_params.dash.offset || + pattern_size != vdev->state.line_params.dash.pattern_size || + (pattern_size != 0 && + !dash_pattern_eq(vdev->dash_pattern, &pis->line_params.dash, + scale)) + ) { + float pattern[max_dash]; + int i, code; + + for (i = 0; i < pattern_size; ++i) + pattern[i] = pis->line_params.dash.pattern[i] * scale; + code = (*vdev_proc(vdev, setdash)) + (vdev, pattern, pattern_size, dash_offset); + if (code < 0) + return code; + memcpy(vdev->dash_pattern, pattern, pattern_size * sizeof(float)); + + vdev->state.line_params.dash.pattern_size = pattern_size; + vdev->state.line_params.dash.offset = dash_offset; + } + if (params->flatness != vdev->state.flatness) { + int code = (*vdev_proc(vdev, setflat)) (vdev, params->flatness); + + if (code < 0) + return code; + vdev->state.flatness = params->flatness; + } + if (half_width != vdev->state.line_params.half_width) { + int code = (*vdev_proc(vdev, setlinewidth)) + (vdev, pis->line_params.half_width * 2); + + if (code < 0) + return code; + vdev->state.line_params.half_width = half_width; + } + if (pis->line_params.miter_limit != vdev->state.line_params.miter_limit) { + int code = (*vdev_proc(vdev, setmiterlimit)) + (vdev, pis->line_params.miter_limit); + + if (code < 0) + return code; + gx_set_miter_limit(&vdev->state.line_params, + pis->line_params.miter_limit); + } + if (pis->line_params.cap != vdev->state.line_params.cap) { + int code = (*vdev_proc(vdev, setlinecap)) + (vdev, pis->line_params.cap); + + if (code < 0) + return code; + vdev->state.line_params.cap = pis->line_params.cap; + } + if (pis->line_params.join != vdev->state.line_params.join) { + int code = (*vdev_proc(vdev, setlinejoin)) + (vdev, pis->line_params.join); + + if (code < 0) + return code; + vdev->state.line_params.join = pis->line_params.join; + } { + int code = gdev_vector_update_log_op(vdev, pis->log_op); + + if (code < 0) + return code; + } + if (!drawing_color_eq(pdcolor, &vdev->stroke_color)) { + int code = (*vdev_proc(vdev, setstrokecolor)) (vdev, pdcolor); + + if (code < 0) + return code; + vdev->stroke_color = *pdcolor; + } + return 0; +} + +/* Write a polygon as part of a path. */ +/* May call beginpath, moveto, lineto, closepath, endpath. */ +int +gdev_vector_write_polygon(gx_device_vector * vdev, const gs_fixed_point * points, + uint count, bool close, gx_path_type_t type) +{ + int code = 0; + + if (type != gx_path_type_none && + (code = (*vdev_proc(vdev, beginpath)) (vdev, type)) < 0 + ) + return code; + if (count > 0) { + double x = fixed2float(points[0].x) / vdev->scale.x, y = fixed2float(points[0].y) / vdev->scale.y; + double x_start = x, y_start = y, x_prev, y_prev; + uint i; + + code = (*vdev_proc(vdev, moveto)) + (vdev, 0.0, 0.0, x, y, type); + if (code >= 0) + for (i = 1; i < count && code >= 0; ++i) { + x_prev = x, y_prev = y; + code = (*vdev_proc(vdev, lineto)) + (vdev, x_prev, y_prev, + (x = fixed2float(points[i].x) / vdev->scale.x), + (y = fixed2float(points[i].y) / vdev->scale.y), + type); + } + if (code >= 0 && close) + code = (*vdev_proc(vdev, closepath)) + (vdev, x, y, x_start, y_start, type); + } + return (code >= 0 && type != gx_path_type_none ? + (*vdev_proc(vdev, endpath)) (vdev, type) : code); +} + +/* Write a rectangle as part of a path. */ +/* May call moveto, lineto, closepath. */ +int +gdev_vector_write_rectangle(gx_device_vector * vdev, fixed x0, fixed y0, + fixed x1, fixed y1, bool close, gx_rect_direction_t direction) +{ + gs_fixed_point points[4]; + + points[0].x = x0, points[0].y = y0; + points[2].x = x1, points[2].y = y1; + if (direction == gx_rect_x_first) + points[1].x = x1, points[1].y = y0, + points[3].x = x0, points[3].y = y1; + else + points[1].x = x0, points[1].y = y1, + points[3].x = x1, points[3].y = y0; + return gdev_vector_write_polygon(vdev, points, 4, close, + gx_path_type_none); +} + +/* Write a clipping path by calling the path procedures. */ +int +gdev_vector_write_clip_path(gx_device_vector * vdev, const gx_clip_path * pcpath) +{ + const gx_clip_rect *prect; + gx_clip_rect page_rect; + int code; + + if (pcpath == 0) { /* There's no special provision for initclip. */ + /* Write a rectangle that covers the entire page. */ + page_rect.xmin = page_rect.ymin = 0; + page_rect.xmax = vdev->width; + page_rect.ymax = vdev->height; + page_rect.next = 0; + prect = &page_rect; + } else if (pcpath->path_valid) + return (*vdev_proc(vdev, dopath)) (vdev, &pcpath->path, + gx_path_type_clip); + else { + const gx_clip_list *list = gx_cpath_list(pcpath); + + prect = list->head; + if (prect == 0) + prect = &list->single; + } + /* Write out the rectangles. */ + code = (*vdev_proc(vdev, beginpath)) (vdev, gx_path_type_clip); + for (; code >= 0 && prect != 0; prect = prect->next) + if (prect->xmax > prect->xmin && prect->ymax > prect->ymin) + code = gdev_vector_write_rectangle + (vdev, int2fixed(prect->xmin), int2fixed(prect->ymin), + int2fixed(prect->xmax), int2fixed(prect->ymax), + false, gx_rect_x_first); + if (code >= 0) + code = (*vdev_proc(vdev, endpath)) (vdev, gx_path_type_clip); + return code; +} + +/* Update the clipping path if needed. */ +int +gdev_vector_update_clip_path(gx_device_vector * vdev, + const gx_clip_path * pcpath) +{ + if (pcpath) { + if (pcpath->id != vdev->clip_path_id) { + int code = gdev_vector_write_clip_path(vdev, pcpath); + + if (code < 0) + return code; + vdev->clip_path_id = pcpath->id; + } + } else { + if (vdev->clip_path_id != vdev->no_clip_path_id) { + int code = gdev_vector_write_clip_path(vdev, NULL); + + if (code < 0) + return code; + vdev->clip_path_id = vdev->no_clip_path_id; + } + } + return 0; +} + +/* Close the output file and stream. */ +void +gdev_vector_close_file(gx_device_vector * vdev) +{ + gs_free_object(vdev->v_memory, vdev->bbox_device, + "vector_close(bbox_device)"); + vdev->bbox_device = 0; + sclose(vdev->strm); + gs_free_object(vdev->v_memory, vdev->strm, "vector_close(strm)"); + vdev->strm = 0; + gs_free_object(vdev->v_memory, vdev->strmbuf, "vector_close(strmbuf)"); + vdev->strmbuf = 0; + fclose(vdev->file); /* we prevented sclose from doing this */ + vdev->file = 0; +} + +/* ---------------- Image enumeration ---------------- */ + +/* Initialize for enumerating an image. */ +int +gdev_vector_begin_image(gx_device_vector * vdev, + const gs_imager_state * pis, const gs_image_t * pim, + gs_image_format_t format, const gs_int_rect * prect, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * mem, const gx_image_enum_procs_t * pprocs, + gdev_vector_image_enum_t * pie) +{ + const gs_color_space *pcs = pim->ColorSpace; + int num_components; + int bits_per_pixel; + int code; + + if (pim->ImageMask) + bits_per_pixel = num_components = 1; + else + num_components = gs_color_space_num_components(pcs), + bits_per_pixel = pim->BitsPerComponent; + code = gx_image_enum_common_init((gx_image_enum_common_t *) pie, + (const gs_image_common_t *)pim, + pprocs, (gx_device *) vdev, + bits_per_pixel, num_components, + format); + if (code < 0) + return code; + pie->bits_per_pixel = bits_per_pixel * num_components / + pie->num_planes; + pie->default_info = 0; + pie->bbox_info = 0; + if ((code = gdev_vector_update_log_op(vdev, pis->log_op)) < 0 || + (code = gdev_vector_update_clip_path(vdev, pcpath)) < 0 || + ((pim->ImageMask || + (pim->CombineWithColor && rop3_uses_T(pis->log_op))) && + (code = gdev_vector_update_fill_color(vdev, pdcolor)) < 0) || + (vdev->bbox_device && + (code = (*dev_proc(vdev->bbox_device, begin_image)) + ((gx_device *) vdev->bbox_device, pis, pim, format, prect, + pdcolor, pcpath, mem, &pie->bbox_info)) < 0) + ) + return code; + pie->memory = mem; + if (prect) + pie->width = prect->q.x - prect->p.x, + pie->height = prect->q.y - prect->p.y; + else + pie->width = pim->Width, pie->height = pim->Height; + pie->bits_per_row = pie->width * pie->bits_per_pixel; + pie->y = 0; + return 0; +} + +/* End an image, optionally supplying any necessary blank padding rows. */ +/* Return 0 if we used the default implementation, 1 if not. */ +int +gdev_vector_end_image(gx_device_vector * vdev, + gdev_vector_image_enum_t * pie, bool draw_last, gx_color_index pad) +{ + int code; + + if (pie->default_info) { + code = gx_default_end_image((gx_device *) vdev, pie->default_info, + draw_last); + if (code >= 0) + code = 0; + } else { /* Fill out to the full image height. */ + if (pie->y < pie->height && pad != gx_no_color_index) { + uint bytes_per_row = (pie->bits_per_row + 7) >> 3; + byte *row = gs_alloc_bytes(pie->memory, bytes_per_row, + "gdev_vector_end_image(fill)"); + + if (row == 0) + return_error(gs_error_VMerror); +/****** FILL VALUE IS WRONG ******/ + memset(row, (byte) pad, bytes_per_row); + for (; pie->y < pie->height; pie->y++) + gx_image_data((gx_image_enum_common_t *) pie, + (const byte **)&row, 0, + bytes_per_row, 1); + gs_free_object(pie->memory, row, + "gdev_vector_end_image(fill)"); + } + code = 1; + } + if (vdev->bbox_device) { + int bcode = gx_image_end(pie->bbox_info, draw_last); + + if (bcode < 0) + code = bcode; + } + gs_free_object(pie->memory, pie, "gdev_vector_end_image"); + return code; +} + +/* ================ Device procedures ================ */ + +#define vdev ((gx_device_vector *)dev) + +/* Get parameters. */ +int +gdev_vector_get_params(gx_device * dev, gs_param_list * plist) +{ + int code = gx_default_get_params(dev, plist); + int ecode; + gs_param_string ofns; + + if (code < 0) + return code; + ofns.data = (const byte *)vdev->fname, + ofns.size = strlen(vdev->fname), + ofns.persistent = false; + if ((ecode = param_write_string(plist, "OutputFile", &ofns)) < 0) + return ecode; + return code; +} + +/* Put parameters. */ +int +gdev_vector_put_params(gx_device * dev, gs_param_list * plist) +{ + int ecode = 0; + int code; + gs_param_name param_name; + gs_param_string ofns; + + switch (code = param_read_string(plist, (param_name = "OutputFile"), &ofns)) { + case 0: + if (ofns.size > fname_size) + ecode = gs_error_limitcheck; + else + break; + goto ofe; + default: + ecode = code; + ofe:param_signal_error(plist, param_name, ecode); + case 1: + ofns.data = 0; + break; + } + + if (ecode < 0) + return ecode; + { + bool open = dev->is_open; + + /* Don't let gx_default_put_params close the device. */ + dev->is_open = false; + code = gx_default_put_params(dev, plist); + dev->is_open = open; + } + if (code < 0) + return code; + + if (ofns.data != 0 && + bytes_compare(ofns.data, ofns.size, + (const byte *)vdev->fname, strlen(vdev->fname)) + ) { + memcpy(vdev->fname, ofns.data, ofns.size); + vdev->fname[ofns.size] = 0; + if (vdev->file != 0) { + gdev_vector_close_file(vdev); + return gdev_vector_open_file(vdev, vdev->strmbuf_size); + } + } + gdev_vector_load_cache(vdev); /* in case color mapping changed */ + return 0; +} + +/* ---------------- Defaults ---------------- */ + +int +gdev_vector_fill_rectangle(gx_device * dev, int x, int y, int w, int h, + gx_color_index color) +{ + gx_drawing_color dcolor; + + /* Ignore the initial fill with white. */ + if (!vdev->in_page && color == vdev->white) + return 0; + color_set_pure(&dcolor, color); + { + int code = update_fill(vdev, &dcolor, rop3_T); + + if (code < 0) + return code; + } + if (vdev->bbox_device) { + int code = (*dev_proc(vdev->bbox_device, fill_rectangle)) + ((gx_device *) vdev->bbox_device, x, y, w, h, color); + + if (code < 0) + return code; + } + return (*vdev_proc(vdev, dorect)) (vdev, int2fixed(x), int2fixed(y), + int2fixed(x + w), int2fixed(y + h), + gx_path_type_fill); +} + +int +gdev_vector_fill_path(gx_device * dev, const gs_imager_state * pis, + gx_path * ppath, const gx_fill_params * params, + const gx_device_color * pdevc, const gx_clip_path * pcpath) +{ + int code; + + if ((code = gdev_vector_prepare_fill(vdev, pis, params, pdevc)) < 0 || + (code = gdev_vector_update_clip_path(vdev, pcpath)) < 0 || + (vdev->bbox_device && + (code = (*dev_proc(vdev->bbox_device, fill_path)) + ((gx_device *) vdev->bbox_device, pis, ppath, params, + pdevc, pcpath)) < 0) || + (code = (*vdev_proc(vdev, dopath)) + (vdev, ppath, + (params->rule > 0 ? gx_path_type_even_odd : + gx_path_type_winding_number) | gx_path_type_fill)) < 0 + ) + return gx_default_fill_path(dev, pis, ppath, params, pdevc, pcpath); + return code; +} + +int +gdev_vector_stroke_path(gx_device * dev, const gs_imager_state * pis, + gx_path * ppath, const gx_stroke_params * params, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath) +{ + int code; + +/****** HANDLE SCALE ******/ + if ((code = gdev_vector_prepare_stroke(vdev, pis, params, pdcolor, + dev->HWResolution[0])) < 0 || + (code = gdev_vector_update_clip_path(vdev, pcpath)) < 0 || + (vdev->bbox_device && + (code = (*dev_proc(vdev->bbox_device, stroke_path)) + ((gx_device *) vdev->bbox_device, pis, ppath, params, + pdcolor, pcpath)) < 0) || + (code = (*vdev_proc(vdev, dopath)) + (vdev, ppath, gx_path_type_stroke)) < 0 + ) + return gx_default_stroke_path(dev, pis, ppath, params, pdcolor, pcpath); + return code; +} + +int +gdev_vector_fill_trapezoid(gx_device * dev, const gs_fixed_edge * left, + const gs_fixed_edge * right, fixed ybot, fixed ytop, bool swap_axes, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + fixed xl = left->start.x; + fixed wl = left->end.x - xl; + fixed yl = left->start.y; + fixed hl = left->end.y - yl; + fixed xr = right->start.x; + fixed wr = right->end.x - xr; + fixed yr = right->start.y; + fixed hr = right->end.y - yr; + fixed x0l = xl + fixed_mult_quo(wl, ybot - yl, hl); + fixed x1l = xl + fixed_mult_quo(wl, ytop - yl, hl); + fixed x0r = xr + fixed_mult_quo(wr, ybot - yr, hr); + fixed x1r = xr + fixed_mult_quo(wr, ytop - yr, hr); + +#define y0 ybot +#define y1 ytop + int code = update_fill(vdev, pdevc, lop); + gs_fixed_point points[4]; + + if (code < 0) + return gx_default_fill_trapezoid(dev, left, right, ybot, ytop, + swap_axes, pdevc, lop); + if (swap_axes) + points[0].y = x0l, points[1].y = x0r, + points[0].x = points[1].x = y0, + points[2].y = x1r, points[3].y = x1l, + points[2].x = points[3].x = y1; + else + points[0].x = x0l, points[1].x = x0r, + points[0].y = points[1].y = y0, + points[2].x = x1r, points[3].x = x1l, + points[2].y = points[3].y = y1; +#undef y0 +#undef y1 + if (vdev->bbox_device) { + int code = (*dev_proc(vdev->bbox_device, fill_trapezoid)) + ((gx_device *) vdev->bbox_device, left, right, ybot, ytop, + swap_axes, pdevc, lop); + + if (code < 0) + return code; + } + return gdev_vector_write_polygon(vdev, points, 4, true, + gx_path_type_fill); +} + +int +gdev_vector_fill_parallelogram(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + fixed pax = px + ax, pay = py + ay; + int code = update_fill(vdev, pdevc, lop); + gs_fixed_point points[4]; + + if (code < 0) + return gx_default_fill_parallelogram(dev, px, py, ax, ay, bx, by, + pdevc, lop); + if (vdev->bbox_device) { + code = (*dev_proc(vdev->bbox_device, fill_parallelogram)) + ((gx_device *) vdev->bbox_device, px, py, ax, ay, bx, by, + pdevc, lop); + if (code < 0) + return code; + } + points[0].x = px, points[0].y = py; + points[1].x = pax, points[0].y = pay; + points[2].x = pax + bx, points[2].y = pay + by; + points[3].x = px + bx, points[3].y = py + by; + return gdev_vector_write_polygon(vdev, points, 4, true, + gx_path_type_fill); +} + +int +gdev_vector_fill_triangle(gx_device * dev, + fixed px, fixed py, fixed ax, fixed ay, fixed bx, fixed by, + const gx_device_color * pdevc, gs_logical_operation_t lop) +{ + int code = update_fill(vdev, pdevc, lop); + gs_fixed_point points[3]; + + if (code < 0) + return gx_default_fill_triangle(dev, px, py, ax, ay, bx, by, + pdevc, lop); + if (vdev->bbox_device) { + code = (*dev_proc(vdev->bbox_device, fill_triangle)) + ((gx_device *) vdev->bbox_device, px, py, ax, ay, bx, by, + pdevc, lop); + if (code < 0) + return code; + } + points[0].x = px, points[0].y = py; + points[1].x = px + ax, points[1].y = py + ay; + points[2].x = px + bx, points[2].y = py + by; + return gdev_vector_write_polygon(vdev, points, 3, true, + gx_path_type_fill); +} + +#undef vdev diff --git a/pstoraster/gdevvec.h b/pstoraster/gdevvec.h new file mode 100644 index 0000000000..f4a2aebb47 --- /dev/null +++ b/pstoraster/gdevvec.h @@ -0,0 +1,349 @@ +/* Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Common definitions for "vector" devices */ + +#ifndef gdevvec_INCLUDED +# define gdevvec_INCLUDED + +#include "gp.h" /* for gp_file_name_sizeof */ +#include "gsropt.h" +#include "gxdevice.h" +#include "gdevbbox.h" +#include "gxiparam.h" +#include "gxistate.h" +#include "stream.h" + +/****** + ****** NOTE: EVERYTHING IN THIS FILE IS SUBJECT TO CHANGE WITHOUT NOTICE. + ****** USE AT YOUR OWN RISK. + ******/ + +/* + * "Vector" devices produce a stream of higher-level drawing commands rather + * than a raster image. (We don't like the term "vector", since the command + * vocabulary typically includes text and raster images as well as actual + * vectors, but it's widely used in the industry, and we weren't able to + * find one that read better.) Some examples of "vector" formats are PDF, + * PostScript, PCL XL, HP-GL/2 + RTL, CGM, Windows Metafile, and Macintosh + * PICT. + * + * This file extends the basic driver structure with elements likely to be + * useful to vector devices. These include: + * + * - Tracking whether any marks have been made on the page; + * + * - Keeping track of the page bounding box; + * + * - A copy of the most recently written current graphics state + * parameters; + * + * - An output stream (for drivers that compress or otherwise filter + * their output); + * + * - A vector of procedures for writing changes to the graphics state. + * + * - The ability to work with scaled output coordinate systems. + * + * We expect to add more elements and procedures as we gain more experience + * with this kind of driver. + */ + +/* ================ Types and structures ================ */ + +/* Define the abstract type for a vector device. */ +typedef struct gx_device_vector_s gx_device_vector; + +/* Define the maximum size of the output file name. */ +#define fname_size (gp_file_name_sizeof - 1) + +/* Define the longest dash pattern we can remember. */ +#define max_dash 11 + +/* + * Define procedures for writing common output elements. Not all devices + * will support all of these elements. Note that these procedures normally + * only write out commands, and don't update the driver state itself. All + * of them are optional, called only as indicated under the utility + * procedures below. + */ +typedef enum { + gx_path_type_none = 0, + /* + * All combinations of flags are legal. Multiple commands are + * executed in the order fill, stroke, clip. + */ + gx_path_type_fill = 1, + gx_path_type_stroke = 2, + gx_path_type_clip = 4, + gx_path_type_winding_number = 0, + gx_path_type_even_odd = 8, + gx_path_type_rule = gx_path_type_winding_number | gx_path_type_even_odd +} gx_path_type_t; +typedef enum { + gx_rect_x_first, + gx_rect_y_first +} gx_rect_direction_t; +typedef struct gx_device_vector_procs_s { + /* Page management */ + int (*beginpage) (P1(gx_device_vector * vdev)); + /* Imager state */ + int (*setlinewidth) (P2(gx_device_vector * vdev, floatp width)); + int (*setlinecap) (P2(gx_device_vector * vdev, gs_line_cap cap)); + int (*setlinejoin) (P2(gx_device_vector * vdev, gs_line_join join)); + int (*setmiterlimit) (P2(gx_device_vector * vdev, floatp limit)); + int (*setdash) (P4(gx_device_vector * vdev, const float *pattern, + uint count, floatp offset)); + int (*setflat) (P2(gx_device_vector * vdev, floatp flatness)); + int (*setlogop) (P3(gx_device_vector * vdev, gs_logical_operation_t lop, + gs_logical_operation_t diff)); + /* Other state */ + int (*setfillcolor) (P2(gx_device_vector * vdev, const gx_drawing_color * pdc)); + int (*setstrokecolor) (P2(gx_device_vector * vdev, const gx_drawing_color * pdc)); + /* Paths */ + /* dopath and dorect are normally defaulted */ + int (*dopath) (P3(gx_device_vector * vdev, const gx_path * ppath, + gx_path_type_t type)); + int (*dorect) (P6(gx_device_vector * vdev, fixed x0, fixed y0, fixed x1, + fixed y1, gx_path_type_t type)); + int (*beginpath) (P2(gx_device_vector * vdev, gx_path_type_t type)); + int (*moveto) (P6(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x, floatp y, gx_path_type_t type)); + int (*lineto) (P6(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x, floatp y, gx_path_type_t type)); + int (*curveto) (P10(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x1, floatp y1, floatp x2, floatp y2, + floatp x3, floatp y3, gx_path_type_t type)); + int (*closepath) (P6(gx_device_vector * vdev, floatp x0, floatp y0, + floatp x_start, floatp y_start, gx_path_type_t type)); + int (*endpath) (P2(gx_device_vector * vdev, gx_path_type_t type)); +} gx_device_vector_procs; + +/* Default implementations of procedures */ +/* setflat does nothing */ +int gdev_vector_setflat(P2(gx_device_vector * vdev, floatp flatness)); + +/* dopath may call dorect, beginpath, moveto/lineto/curveto/closepath, */ +/* endpath */ +int gdev_vector_dopath(P3(gx_device_vector * vdev, const gx_path * ppath, + gx_path_type_t type)); + +/* dorect may call beginpath, moveto, lineto, closepath */ +int gdev_vector_dorect(P6(gx_device_vector * vdev, fixed x0, fixed y0, + fixed x1, fixed y1, gx_path_type_t type)); + +/* Finally, define the extended device structure. */ +#define gx_device_vector_common\ + gx_device_common;\ + gs_memory_t *v_memory;\ + /* Output element writing procedures */\ + const gx_device_vector_procs *vec_procs;\ + /* Output file */\ + char fname[fname_size + 1];\ + FILE *file;\ + stream *strm;\ + byte *strmbuf;\ + uint strmbuf_size;\ + /* Graphics state */\ + gs_imager_state state;\ + float dash_pattern[max_dash];\ + gx_drawing_color fill_color, stroke_color;\ + gs_id no_clip_path_id; /* indicates no clipping */\ + gs_id clip_path_id;\ + /* Other state */\ + gs_point scale; /* device coords / scale => output coords */\ + bool in_page; /* true if any marks on this page */\ + gx_device_bbox *bbox_device; /* for tracking bounding box */\ + /* Cached values */\ + gx_color_index black, white +#define vdev_proc(vdev, p) ((vdev)->vec_procs->p) + +#define vector_initial_values\ + 0, /* v_memory */\ + 0, /* vec_procs */\ + { 0 }, /* fname */\ + 0, /* file */\ + 0, /* strm */\ + 0, /* strmbuf */\ + 0, /* strmbuf_size */\ + { 0 }, /* state */\ + { 0 }, /* dash_pattern */\ + { 0 }, /* fill_color ****** WRONG ****** */\ + { 0 }, /* stroke_color ****** WRONG ****** */\ + gs_no_id, /* clip_path_id */\ + gs_no_id, /* no_clip_path_id */\ + { X_DPI/72.0, Y_DPI/72.0 }, /* scale */\ + 0/*false*/, /* in_page */\ + 0, /* bbox_device */\ + gx_no_color_index, /* black */\ + gx_no_color_index /* white */ + +struct gx_device_vector_s { + gx_device_vector_common; +}; + +/* st_device_vector is never instantiated per se, but we still need to */ +/* extern its descriptor for the sake of subclasses. */ +extern_st(st_device_vector); +#define public_st_device_vector() /* in gdevvec.c */\ + gs_public_st_suffix_add3_final(st_device_vector, gx_device_vector,\ + "gx_device_vector", device_vector_enum_ptrs,\ + device_vector_reloc_ptrs, gx_device_finalize, st_device, strm, strmbuf,\ + bbox_device) +#define st_device_vector_max_ptrs (st_device_max_ptrs + 3) + +/* ================ Utility procedures ================ */ + +/* Initialize the state. */ +void gdev_vector_init(P1(gx_device_vector * vdev)); + +/* Reset the remembered graphics state. */ +void gdev_vector_reset(P1(gx_device_vector * vdev)); + +/* Open the output file and stream, with optional bbox tracking. */ +int gdev_vector_open_file_bbox(P3(gx_device_vector * vdev, uint strmbuf_size, + bool bbox)); + +#define gdev_vector_open_file(vdev, strmbuf_size)\ + gdev_vector_open_file_bbox(vdev, strmbuf_size, false) + +/* Get the current stream, calling beginpage if in_page is false. */ +stream *gdev_vector_stream(P1(gx_device_vector * vdev)); + +/* Bring the logical operation up to date. */ +/* May call setlogop. */ +int gdev_vector_update_log_op(P2(gx_device_vector * vdev, + gs_logical_operation_t lop)); + +/* Bring the fill color up to date. */ +/* May call setfillcolor. */ +int gdev_vector_update_fill_color(P2(gx_device_vector * vdev, + const gx_drawing_color * pdcolor)); + +/* Bring state up to date for filling. */ +/* May call setflat, setfillcolor, setlogop. */ +int gdev_vector_prepare_fill(P4(gx_device_vector * vdev, + const gs_imager_state * pis, + const gx_fill_params * params, + const gx_drawing_color * pdcolor)); + +/* Bring state up to date for stroking. Note that we pass the scale */ +/* for the line width and dash offset explicitly. */ +/* May call setlinewidth, setlinecap, setlinejoin, setmiterlimit, */ +/* setdash, setflat, setstrokecolor, setlogop. */ +int gdev_vector_prepare_stroke(P5(gx_device_vector * vdev, + const gs_imager_state * pis, + const gx_stroke_params * params, + const gx_drawing_color * pdcolor, + floatp scale)); + +/* Write a polygon as part of a path (type = gx_path_type_none) */ +/* or as a path. */ +/* May call moveto, lineto, closepath (if close); */ +/* may call beginpath & endpath if type != none. */ +int gdev_vector_write_polygon(P5(gx_device_vector * vdev, + const gs_fixed_point * points, uint count, + bool close, gx_path_type_t type)); + +/* Write a rectangle. This is just a special case of write_polygon. */ +int gdev_vector_write_rectangle(P7(gx_device_vector * vdev, + fixed x0, fixed y0, fixed x1, fixed y1, + bool close, gx_rect_direction_t dir)); + +/* Write a clipping path by calling the path procedures. */ +/* May call the same procedures as writepath. */ +int gdev_vector_write_clip_path(P2(gx_device_vector * vdev, + const gx_clip_path * pcpath)); + +/* Bring the clipping state up to date. */ +/* May call write_rectangle (q.v.), write_clip_path (q.v.). */ +int gdev_vector_update_clip_path(P2(gx_device_vector * vdev, + const gx_clip_path * pcpath)); + +/* Close the output file and stream. */ +void gdev_vector_close_file(P1(gx_device_vector * vdev)); + +/* ---------------- Image enumeration ---------------- */ + +/* Define a common set of state parameters for enumerating images. */ +#define gdev_vector_image_enum_common\ + gx_image_enum_common;\ + /* Set by begin_image */\ + gs_memory_t *memory; /* from begin_image */\ + gx_image_enum_common_t *default_info; /* non-0 iff using default implementation */\ + gx_image_enum_common_t *bbox_info; /* non-0 iff passing image data to bbox dev */\ + int width, height;\ + int bits_per_pixel; /* (per plane) */\ + uint bits_per_row; /* (per plane) */\ + /* Updated dynamically by image_data */\ + int y /* 0 <= y < height */ +typedef struct gdev_vector_image_enum_s { + gdev_vector_image_enum_common; +} gdev_vector_image_enum_t; + +extern_st(st_vector_image_enum); +#define public_st_vector_image_enum() /* in gdevvec.c */\ + gs_public_st_ptrs2(st_vector_image_enum, gdev_vector_image_enum_t,\ + "gdev_vector_image_enum_t", vector_image_enum_enum_ptrs,\ + vector_image_enum_reloc_ptrs, default_info, bbox_info) + +/* + * Initialize for enumerating an image. Note that the last argument is an + * already-allocated enumerator, not a pointer to the place to store the + * enumerator. + */ +int gdev_vector_begin_image(P10(gx_device_vector * vdev, + const gs_imager_state * pis, const gs_image_t * pim, + gs_image_format_t format, const gs_int_rect * prect, + const gx_drawing_color * pdcolor, const gx_clip_path * pcpath, + gs_memory_t * mem, const gx_image_enum_procs_t * pprocs, + gdev_vector_image_enum_t * pie)); + +/* End an image, optionally supplying any necessary blank padding rows. */ +/* Return 0 if we used the default implementation, 1 if not. */ +int gdev_vector_end_image(P4(gx_device_vector * vdev, + gdev_vector_image_enum_t * pie, bool draw_last, gx_color_index pad)); + +/* ================ Device procedures ================ */ + +/* Redefine get/put_params to handle OutputFile. */ +dev_proc_put_params(gdev_vector_put_params); +dev_proc_get_params(gdev_vector_get_params); + +/* ---------------- Defaults ---------------- */ + +/* fill_rectangle may call setfillcolor, dorect. */ +dev_proc_fill_rectangle(gdev_vector_fill_rectangle); +/* fill_path may call prepare_fill, writepath, write_clip_path. */ +dev_proc_fill_path(gdev_vector_fill_path); +/* stroke_path may call prepare_stroke, write_path, write_clip_path. */ +dev_proc_stroke_path(gdev_vector_stroke_path); +/* fill_trapezoid, fill_parallelogram, and fill_triangle may call */ +/* setfillcolor, setlogop, beginpath, moveto, lineto, endpath. */ +dev_proc_fill_trapezoid(gdev_vector_fill_trapezoid); +dev_proc_fill_parallelogram(gdev_vector_fill_parallelogram); +dev_proc_fill_triangle(gdev_vector_fill_triangle); + +#endif /* gdevvec_INCLUDED */ diff --git a/pstoraster/genarch.c b/pstoraster/genarch.c new file mode 100644 index 0000000000..a8f308bffc --- /dev/null +++ b/pstoraster/genarch.c @@ -0,0 +1,163 @@ +/* Copyright (C) 1989, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Generate a header file (arch.h) with parameters */ +/* reflecting the machine architecture and compiler characteristics. */ + +#include "stdpre.h" +#include + +/* We should write the result on stdout, but the original Turbo C 'make' */ +/* can't handle output redirection (sigh). */ + +private void +section(FILE * f, char *str) +{ + fprintf(f, "\n\t /* ---------------- %s ---------------- */\n\n", str); +} + +int +main(int argc, char *argv[]) +{ + char *fname = argv[1]; + long one = 1; + char *ffs = "ffffffffffffffff"; /* 8 bytes */ + int ffs_strlen = strlen(ffs); + struct { + char c; + short s; + } ss; + struct { + char c; + int i; + } si; + struct { + char c; + long l; + } sl; + struct { + char c; + char *p; + } sp; + struct { + char c; + float f; + } sf; + struct { + char c; + double d; + } sd; + static int log2s[17] = + {0, 0, 1, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 4}; + long lm1 = -1; + long lr1 = lm1 >> 1, lr2 = lm1 >> 2; + unsigned long um1 = ~(unsigned long)0; + int im1 = -1; + int ir1 = im1 >> 1, ir2 = im1 >> 2; + union { + long l; + char *p; + } pl0, pl1; + int ars; + int lwidth = size_of(long) * 8; + union { + float f; + int i; + long l; + } f0 , f1, fm1; + FILE *f = fopen(fname, "w"); + + if (f == NULL) { + fprintf(stderr, "genarch.c: can't open %s for writing\n", fname); + return exit_FAILED; + } + fprintf(f, "/* Parameters derived from machine and compiler architecture */\n"); + + section(f, "Scalar alignments"); + +#define OFFSET_IN(s, e) (int)((char *)&s.e - (char *)&s) + fprintf(f, "#define arch_align_short_mod %d\n", OFFSET_IN(ss, s)); + fprintf(f, "#define arch_align_int_mod %d\n", OFFSET_IN(si, i)); + fprintf(f, "#define arch_align_long_mod %d\n", OFFSET_IN(sl, l)); + fprintf(f, "#define arch_align_ptr_mod %d\n", OFFSET_IN(sp, p)); + fprintf(f, "#define arch_align_float_mod %d\n", OFFSET_IN(sf, f)); + fprintf(f, "#define arch_align_double_mod %d\n", OFFSET_IN(sd, d)); +#undef OFFSET_IN + + section(f, "Scalar sizes"); + + fprintf(f, "#define arch_log2_sizeof_short %d\n", log2s[size_of(short)]); + fprintf(f, "#define arch_log2_sizeof_int %d\n", log2s[size_of(int)]); + fprintf(f, "#define arch_log2_sizeof_long %d\n", log2s[size_of(long)]); + fprintf(f, "#define arch_sizeof_ptr %d\n", size_of(char *)); + fprintf(f, "#define arch_sizeof_float %d\n", size_of(float)); + fprintf(f, "#define arch_sizeof_double %d\n", size_of(double)); + + section(f, "Unsigned max values"); + +#define PRINT_MAX(str, typ, tstr, l)\ + fprintf(f, "#define arch_max_%s ((%s)0x%s%s + (%s)0)\n",\ + str, tstr, ffs + ffs_strlen - size_of(typ) * 2, l, tstr) + PRINT_MAX("uchar", unsigned char, "unsigned char", ""); + PRINT_MAX("ushort", unsigned short, "unsigned short", ""); + PRINT_MAX("uint", unsigned int, "unsigned int", ""); + PRINT_MAX("ulong", unsigned long, "unsigned long", "L"); + +#undef PRINT_MAX + + section(f, "Miscellaneous"); + + fprintf(f, "#define arch_is_big_endian %d\n", 1 - *(char *)&one); + pl0.l = 0; + pl1.l = -1; + fprintf(f, "#define arch_ptrs_are_signed %d\n", + (pl1.p < pl0.p)); + f0.f = 0.0, f1.f = 1.0, fm1.f = -1.0; + /* We have to test the size dynamically here, */ + /* because the preprocessor can't evaluate sizeof. */ + fprintf(f, "#define arch_floats_are_IEEE %d\n", + ((size_of(float) == size_of(int) ? + f0.i == 0 && f1.i == (int)0x3f800000 && fm1.i == (int)0xbf800000 : + f0.l == 0 && f1.l == 0x3f800000L && fm1.l == 0xbf800000L) + ? 1 : 0)); + + /* There are three cases for arithmetic right shift: */ + /* always correct, correct except for right-shifting a long by 1 */ + /* (a bug in some versions of the Turbo C compiler), and */ + /* never correct. */ + ars = (lr2 != -1 || ir1 != -1 || ir2 != -1 ? 0 : + lr1 != -1 ? 1 : /* Turbo C problem */ + 2); + fprintf(f, "#define arch_arith_rshift %d\n", ars); + /* Some machines can't handle a variable shift by */ + /* the full width of a long. */ + fprintf(f, "#define arch_can_shift_full_long %d\n", + um1 >> lwidth == 0); + +/* ---------------- Done. ---------------- */ + + fclose(f); + return exit_OK; +} diff --git a/pstoraster/ghost.h b/pstoraster/ghost.h new file mode 100644 index 0000000000..5df931e78e --- /dev/null +++ b/pstoraster/ghost.h @@ -0,0 +1,34 @@ +/* Copyright (C) 1989, 1992 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Common definitions for interpreter */ + +#ifndef ghost_INCLUDED +# define ghost_INCLUDED + +#include "gx.h" +#include "iref.h" + +#endif /* ghost_INCLUDED */ diff --git a/pstoraster/gp.h b/pstoraster/gp.h new file mode 100644 index 0000000000..39aa8c4aa4 --- /dev/null +++ b/pstoraster/gp.h @@ -0,0 +1,233 @@ +/* Copyright (C) 1991, 1995, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Interface to platform-specific routines */ +/* Requires gsmemory.h, gstypes.h */ + +#ifndef gp_INCLUDED +# define gp_INCLUDED + +/* + * This file defines the interface to ***ALL*** platform-specific routines, + * with the exception of the thread/synchronization interface (gpsync.h). + * The routines are implemented in a gp_*.c file specific to each platform. + * We try very hard to keep this list short! + */ +/* + * gp_getenv is declared in a separate file, because a few places need it + * and don't want to include any of the other gs definitions. + */ +#include "gpgetenv.h" + +/* ------ Initialization/termination ------ */ + +/* + * This routine is called early in the initialization. + * It should do as little as possible. In particular, it should not + * do things like open display connections: that is the responsibility + * of the display device driver. + */ +void gp_init(P0()); + +/* + * This routine is called just before the program exits (normally or + * abnormally). It too should do as little as possible. + */ +void gp_exit(P2(int exit_status, int code)); + +/* + * Exit the program. Normally this just calls the `exit' library procedure, + * but it does something different on a few platforms. + */ +void gp_do_exit(P1(int exit_status)); + +/* ------ Miscellaneous ------ */ + +/* + * Get the string corresponding to an OS error number. + * If no string is available, return NULL. The caller may assume + * the string is allocated statically and permanently. + */ +const char *gp_strerror(P1(int)); + +/* ------ Date and time ------ */ + +/* + * Read the current time (in seconds since an implementation-defined epoch) + * into ptm[0], and fraction (in nanoseconds) into ptm[1]. + */ +void gp_get_realtime(P1(long ptm[2])); + +/* + * Read the current user CPU time (in seconds) into ptm[0], + * and fraction (in nanoseconds) into ptm[1]. + */ +void gp_get_usertime(P1(long ptm[2])); + +/* ------ Screen management ------ */ + +/* + * The following routines are only relevant in a single-window environment + * such as a PC; on platforms with window systems, the 'make current' + * routines do nothing. + */ + +#ifndef gx_device_DEFINED +# define gx_device_DEFINED +typedef struct gx_device_s gx_device; + +#endif + +/* Initialize the console. */ +void gp_init_console(P0()); + +/* Write a string to the console. */ +void gp_console_puts(P2(const char *, uint)); + +/* Make the console current on the screen. */ +int gp_make_console_current(P1(gx_device *)); + +/* Make the graphics current on the screen. */ +int gp_make_graphics_current(P1(gx_device *)); + +/* + * The following are only relevant for X Windows. + */ + +/* Get the environment variable that specifies the display to use. */ +const char *gp_getenv_display(P0()); + +/* ------ File naming and accessing ------ */ + +/* + * Define the maximum size of a file name returned by gp_open_scratch_file + * or gp_open_printer. (This should really be passed as an additional + * parameter, but it would break too many clients to make this change now.) + * Note that this is the size of the buffer, not the maximum number of + * characters: the latter is one less, because of the terminating \0. + */ +#define gp_file_name_sizeof 128 + +/* Define the character used for separating file names in a list. */ +extern const char gp_file_name_list_separator; + +/* Define the default scratch file name prefix. */ +extern const char gp_scratch_file_name_prefix[]; + +/* Define the name of the null output file. */ +extern const char gp_null_file_name[]; + +/* Define the name that designates the current directory. */ +extern const char gp_current_directory_name[]; + +/* Define the string to be concatenated with the file mode */ +/* for opening files without end-of-line conversion. */ +/* This is always either "" or "b". */ +extern const char gp_fmode_binary_suffix[]; + +/* Define the file modes for binary reading or writing. */ +/* (This is just a convenience: they are "r" or "w" + the suffix.) */ +extern const char gp_fmode_rb[]; +extern const char gp_fmode_wb[]; + +/* Create and open a scratch file with a given name prefix. */ +/* Write the actual file name at fname. */ +FILE *gp_open_scratch_file(P3(const char *prefix, + char fname[gp_file_name_sizeof], + const char *mode)); + +/* Open a file with the given name, as a stream of uninterpreted bytes. */ +FILE *gp_fopen(P2(const char *fname, const char *mode)); + +/* Force given file into binary mode (no eol translations, etc) */ +/* if 2nd param true, text mode if 2nd param false */ +bool gp_setmode_binary(P2(FILE * pfile, bool mode)); + +/* Answer whether a file name contains a directory/device specification, */ +/* i.e. is absolute (not directory- or device-relative). */ +bool gp_file_name_is_absolute(P2(const char *fname, uint len)); + +/* Answer the string to be used for combining a directory/device prefix */ +/* with a base file name. The file name is known to not be absolute. */ +const char *gp_file_name_concat_string(P4(const char *prefix, uint plen, + const char *fname, uint len)); + +/* ------ Printer accessing ------ */ + +/* + * Open a connection to a printer. A null file name means use the + * standard printer connected to the machine, if any. + * If possible, support "|command" for opening an output pipe. + * Return NULL if the connection could not be opened. + * + * Note that if the file name is null (0-length), it may be replaced with + * the name of a scratch file. + */ +FILE *gp_open_printer(P2(char fname[gp_file_name_sizeof], int binary_mode)); + +/* Close the connection to the printer. */ +void gp_close_printer(P2(FILE * pfile, const char *fname)); + +/* ------ File enumeration ------ */ + +#ifndef file_enum_DEFINED /* also defined in iodev.h */ +# define file_enum_DEFINED +struct file_enum_s; /* opaque to client, defined by implementor */ +typedef struct file_enum_s file_enum; + +#endif + +/* + * Begin an enumeration. pat is a C string that may contain *s or ?s. + * The implementor should copy the string to a safe place. + * If the operating system doesn't support correct, arbitrarily placed + * *s and ?s, the implementation should modify the string so that it + * will return a conservative superset of the request, and then use + * the string_match procedure to select the desired subset. E.g., if the + * OS doesn't implement ? (single-character wild card), any consecutive + * string of ?s should be interpreted as *. Note that \ can appear in + * the pattern also, as a quoting character. + */ +file_enum *gp_enumerate_files_init(P3(const char *pat, uint patlen, + gs_memory_t * memory)); + +/* + * Return the next file name in the enumeration. The client passes in + * a scratch string and a max length. If the name of the next file fits, + * the procedure returns the length. If it doesn't fit, the procedure + * returns max length +1. If there are no more files, the procedure + * returns -1. + */ +uint gp_enumerate_files_next(P3(file_enum * pfen, char *ptr, uint maxlen)); + +/* + * Clean up a file enumeration. This is only called to abandon + * an enumeration partway through: ...next should do it if there are + * no more files to enumerate. This should deallocate the file_enum + * structure and any subsidiary structures, strings, buffers, etc. + */ +void gp_enumerate_files_close(P1(file_enum * pfen)); + +#endif /* gp_INCLUDED */ diff --git a/pstoraster/gp_getnv.c b/pstoraster/gp_getnv.c new file mode 100644 index 0000000000..fbf997f32a --- /dev/null +++ b/pstoraster/gp_getnv.c @@ -0,0 +1,60 @@ +/* Copyright (C) 1997 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Standard implementation of gp_getenv */ +#include "stdio_.h" +#include "string_.h" +#include "gsmemory.h" +#include "gstypes.h" +#include "gp.h" + +/* Import the C getenv function. */ +extern char *getenv(P1(const char *)); + +/* Get the value of an environment variable. See gp.h for details. */ +int +gp_getenv(const char *key, char *ptr, int *plen) +{ + const char *str = getenv(key); + + if (str) { + int len = strlen(str); + + if (len < *plen) { + /* string fits */ + strcpy(ptr, str); + *plen = len + 1; + return 0; + } + /* string doesn't fit */ + *plen = len + 1; + return -1; + } + /* missing key */ + if (*plen > 0) + *ptr = 0; + *plen = 1; + return 1; +} diff --git a/pstoraster/gp_nofb.c b/pstoraster/gp_nofb.c new file mode 100644 index 0000000000..49c50ae8a5 --- /dev/null +++ b/pstoraster/gp_nofb.c @@ -0,0 +1,58 @@ +/* Copyright (C) 1993 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Dummy routines for Ghostscript platforms with no frame buffer management */ +#include "gx.h" +#include "gp.h" +#include "gxdevice.h" + +/* ------ Screen management ------ */ + +/* Initialize the console. */ +void +gp_init_console(void) +{ +} + +/* Write a string to the console. */ +void +gp_console_puts(const char *str, uint size) +{ + fwrite(str, 1, size, stdout); +} + +/* Make the console current on the screen. */ +int +gp_make_console_current(gx_device * dev) +{ + return 0; +} + +/* Make the graphics current on the screen. */ +int +gp_make_graphics_current(gx_device * dev) +{ + return 0; +} diff --git a/pstoraster/gp_nsync.c b/pstoraster/gp_nsync.c new file mode 100644 index 0000000000..0163cf5a23 --- /dev/null +++ b/pstoraster/gp_nsync.c @@ -0,0 +1,120 @@ +/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Dummy thread / semaphore / monitor implementation */ +#include "std.h" +#include "gserror.h" +#include "gserrors.h" +#include "gpsync.h" + +/* ------- Synchronization primitives -------- */ + +/* Semaphores */ + +uint +gp_semaphore_sizeof(void) +{ + return sizeof(gp_semaphore); +} + +int +gp_semaphore_open(gp_semaphore * sema) +{ + if (sema) + *(int *)sema = 0; + return 0; +} + +int +gp_semaphore_close(gp_semaphore * sema) +{ + return 0; +} + +int +gp_semaphore_wait(gp_semaphore * sema) +{ + if (*(int *)sema == 0) + return_error(gs_error_unknownerror); + --(*(int *)sema); + return 0; +} + +int +gp_semaphore_signal(gp_semaphore * sema) +{ + ++(*(int *)sema); + return 0; +} + +/* Monitors */ + +uint +gp_monitor_sizeof(void) +{ + return sizeof(gp_monitor); +} + +int +gp_monitor_open(gp_monitor * mon) +{ + if (mon) + mon->dummy_ = 0; + return 0; +} + +int +gp_monitor_close(gp_monitor * mon) +{ + return 0; +} + +int +gp_monitor_enter(gp_monitor * mon) +{ + if (mon->dummy_ != 0) + return_error(gs_error_unknownerror); + mon->dummy_ = &mon; + return 0; +} + +int +gp_monitor_leave(gp_monitor * mon) +{ + if (mon->dummy_ != &mon) + return_error(gs_error_unknownerror); + mon->dummy_ = 0; + return 0; +} + +/* Thread creation */ + +int +gp_create_thread(gp_thread_creation_callback_t proc, void *proc_data) +{ + /* Just call the procedure now. */ + (*proc)(proc_data); + return 0; +} diff --git a/pstoraster/gp_unifn.c b/pstoraster/gp_unifn.c new file mode 100644 index 0000000000..aa128faaba --- /dev/null +++ b/pstoraster/gp_unifn.c @@ -0,0 +1,61 @@ +/* Copyright (C) 1994, 1996 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Unix-like file name syntax platform routines for Ghostscript */ +#include "gx.h" +#include "gp.h" + +/* Define the character used for separating file names in a list. */ +const char gp_file_name_list_separator = ':'; + +/* Define the string to be concatenated with the file mode */ +/* for opening files without end-of-line conversion. */ +const char gp_fmode_binary_suffix[] = ""; + +/* Define the file modes for binary reading or writing. */ +const char gp_fmode_rb[] = "r"; +const char gp_fmode_wb[] = "w"; + +/* Answer whether a file name contains a directory/device specification, */ +/* i.e. is absolute (not directory- or device-relative). */ +bool +gp_file_name_is_absolute(const char *fname, unsigned len) +{ /* A file name is absolute if it starts with a 0 or more .s */ + /* followed by a /. */ + while (len && *fname == '.') + ++fname, --len; + return (len && *fname == '/'); +} + +/* Answer the string to be used for combining a directory/device prefix */ +/* with a base file name. The file name is known to not be absolute. */ +const char * +gp_file_name_concat_string(const char *prefix, unsigned plen, + const char *fname, unsigned len) +{ + if (plen > 0 && prefix[plen - 1] == '/') + return ""; + return "/"; +} diff --git a/pstoraster/gp_unifs.c b/pstoraster/gp_unifs.c new file mode 100644 index 0000000000..7d6bf0ba82 --- /dev/null +++ b/pstoraster/gp_unifs.c @@ -0,0 +1,440 @@ +/*Copyright 1993-2000 by Easy Software Products. + Copyright 1993, 1995, 1996, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* "Unix-like" file system platform routines for Ghostscript */ +#include "memory_.h" +#include "string_.h" +#include "gx.h" +#include "gp.h" +#include "gsstruct.h" +#include "gsutil.h" /* for string_match */ +#include "stat_.h" +#include "dirent_.h" +#include /* for MAXPATHLEN */ + +/* Some systems (Interactive for example) don't define MAXPATHLEN, + * so we define it here. (This probably should be done via a Config-Script.) + */ + +#ifndef MAXPATHLEN +# define MAXPATHLEN 1024 +#endif + +/* Library routines not declared in a standard header */ +extern char *mktemp(P1(char *)); + +/* ------ File naming and accessing ------ */ + +/* Define the default scratch file name prefix. */ +const char gp_scratch_file_name_prefix[] = "gs_"; + +/* Define the name of the null output file. */ +const char gp_null_file_name[] = "/dev/null"; + +/* Define the name that designates the current directory. */ +const char gp_current_directory_name[] = "."; + +/* Create and open a scratch file with a given name prefix. */ +/* Write the actual file name at fname. */ +FILE * +gp_open_scratch_file(const char *prefix, char fname[gp_file_name_sizeof], + const char *mode) +{ /* The -8 is for XXXXXX plus a possible final / and -. */ + int len = gp_file_name_sizeof - strlen(prefix) - 8; + + /* + * MRS - Hello? TEMP is a DOS thing, TMPDIR is the UNIX thing. + * Also, we should default to /var/tmp, since the root + * partition is often small. + */ + + if (gp_getenv("TMPDIR", fname, &len) != 0) + strcpy(fname, "/var/tmp/"); + else { + if (strlen(fname) != 0 && fname[strlen(fname) - 1] != '/') + strcat(fname, "/"); + } + strcat(fname, prefix); + /* Prevent trailing X's in path from being converted by mktemp. */ + if (*fname != 0 && fname[strlen(fname) - 1] == 'X') + strcat(fname, "-"); + strcat(fname, "XXXXXX"); + mktemp(fname); + return fopen(fname, mode); +} + +/* Open a file with the given name, as a stream of uninterpreted bytes. */ +FILE * +gp_fopen(const char *fname, const char *mode) +{ + return fopen(fname, mode); +} + +/* Set a file into binary or text mode. */ +int +gp_setmode_binary(FILE * pfile, bool mode) +{ + return 0; /* Noop under Unix */ +} + +/* ------ File enumeration ------ */ + +/* Thanks to Fritz Elfert (Fritz_Elfert@wue.maus.de) for */ +/* the original version of the following code, and Richard Mlynarik */ +/* (mly@adoc.xerox.com) for an improved version. */ + +typedef struct dirstack_s dirstack; +struct dirstack_s { + dirstack *next; + DIR *entry; +}; + +gs_private_st_ptrs1(st_dirstack, dirstack, "dirstack", + dirstack_enum_ptrs, dirstack_reloc_ptrs, next); + +struct file_enum_s { + DIR *dirp; /* pointer to current open directory */ + char *pattern; /* original pattern */ + char *work; /* current path */ + int worklen; /* strlen (work) */ + dirstack *dstack; /* directory stack */ + int patlen; + int pathead; /* how much of pattern to consider + * when listing files in current directory */ + bool first_time; + gs_memory_t *memory; +}; +gs_private_st_ptrs3(st_file_enum, struct file_enum_s, "file_enum", + file_enum_enum_ptrs, file_enum_reloc_ptrs, pattern, work, dstack); + +/* Private procedures */ + +/* Do a wild-card match. */ +#ifdef DEBUG +private bool +wmatch(const byte * str, uint len, const byte * pstr, uint plen, + const string_match_params * psmp) +{ + bool match = string_match(str, len, pstr, plen, psmp); + + if (gs_debug_c('e')) { + dlputs("[e]string_match(\""); + fwrite(str, 1, len, dstderr); + dputs("\", \""); + fwrite(pstr, 1, plen, dstderr); + dprintf1("\") = %s\n", (match ? "TRUE" : "false")); + } + return match; +} +#define string_match wmatch +#endif + +/* Search a string backward for a character. */ +/* (This substitutes for strrchr, which some systems don't provide.) */ +private char * +rchr(char *str, char ch, int len) +{ + register char *p = str + len; + + while (p > str) + if (*--p == ch) + return p; + return 0; +} + +/* Pop a directory from the enumeration stack. */ +private bool +popdir(file_enum * pfen) +{ + dirstack *d = pfen->dstack; + + if (d == 0) + return false; + pfen->dirp = d->entry; + pfen->dstack = d->next; + gs_free_object(pfen->memory, d, "gp_enumerate_files(popdir)"); + return true; +} + +/* Initialize an enumeration. */ +file_enum * +gp_enumerate_files_init(const char *pat, uint patlen, gs_memory_t * mem) +{ + file_enum *pfen; + char *p; + char *work; + + /* Reject attempts to enumerate paths longer than the */ + /* system-dependent limit. */ + if (patlen > MAXPATHLEN) + return 0; + + /* Reject attempts to enumerate with a pattern containing zeroes. */ + { + const char *p1; + + for (p1 = pat; p1 < pat + patlen; p1++) + if (*p1 == 0) + return 0; + } + /* >>> Should crunch strings of repeated "/"'s in pat to a single "/" + * >>> to match stupid unix filesystem "conventions" */ + + pfen = gs_alloc_struct(mem, file_enum, &st_file_enum, + "gp_enumerate_files"); + if (pfen == 0) + return 0; + + /* pattern and work could be allocated as strings, */ + /* but it's simpler for GC and freeing to allocate them as bytes. */ + + pfen->pattern = + (char *)gs_alloc_bytes(mem, patlen + 1, + "gp_enumerate_files(pattern)"); + if (pfen->pattern == 0) + return 0; + memcpy(pfen->pattern, pat, patlen); + pfen->pattern[patlen] = 0; + + work = (char *)gs_alloc_bytes(mem, MAXPATHLEN + 1, + "gp_enumerate_files(work)"); + if (work == 0) + return 0; + pfen->work = work; + + p = work; + memcpy(p, pat, patlen); + p += patlen; + *p = 0; + + /* Remove directory specifications beyond the first wild card. */ + /* Some systems don't have strpbrk, so we code it open. */ + p = pfen->work; + while (!(*p == '*' || *p == '?' || *p == 0)) + p++; + while (!(*p == '/' || *p == 0)) + p++; + if (*p == '/') + *p = 0; + /* Substring for first wildcard match */ + pfen->pathead = p - work; + + /* Select the next higher directory-level. */ + p = rchr(work, '/', p - work); + if (!p) { /* No directory specification */ + work[0] = 0; + pfen->worklen = 0; + } else { + if (p == work) { /* Root directory -- don't turn "/" into "" */ + p++; + } + *p = 0; + pfen->worklen = p - work; + } + + pfen->memory = mem; + pfen->dstack = 0; + pfen->first_time = true; + pfen->patlen = patlen; + return pfen; +} + +/* Enumerate the next file. */ +uint +gp_enumerate_files_next(file_enum * pfen, char *ptr, uint maxlen) +{ + const dir_entry *de; + char *work = pfen->work; + int worklen = pfen->worklen; + char *pattern = pfen->pattern; + int pathead = pfen->pathead; + int len; + struct stat stbuf; + + if (pfen->first_time) { + pfen->dirp = ((worklen == 0) ? opendir(".") : opendir(work)); + if_debug1('e', "[e]file_enum:First-Open '%s'\n", work); + pfen->first_time = false; + if (pfen->dirp == 0) { /* first opendir failed */ + gp_enumerate_files_close(pfen); + return ~(uint) 0; + } + } + top:de = readdir(pfen->dirp); + if (de == 0) { /* No more entries in this directory */ + char *p; + + if_debug0('e', "[e]file_enum:Closedir\n"); + closedir(pfen->dirp); + /* Back working directory and matching pattern up one level */ + p = rchr(work, '/', worklen); + if (p != 0) { + if (p == work) + p++; + *p = 0; + worklen = p - work; + } else + worklen = 0; + p = rchr(pattern, '/', pathead); + if (p != 0) + pathead = p - pattern; + else + pathead = 0; + + if (popdir(pfen)) { /* Back up the directory tree. */ + if_debug1('e', "[e]file_enum:Dir popped '%s'\n", work); + goto top; + } else { + if_debug0('e', "[e]file_enum:Dirstack empty\n"); + gp_enumerate_files_close(pfen); + return ~(uint) 0; + } + } + /* Skip . and .. */ + len = strlen(de->d_name); + if (len <= 2 && (!strcmp(de->d_name, ".") || !strcmp(de->d_name, ".."))) + goto top; + if (len + worklen + 1 > MAXPATHLEN) + /* Should be an error, I suppose */ + goto top; + if (worklen == 0) { /* "Current" directory (evil un*x kludge) */ + memcpy(work, de->d_name, len + 1); + } else if (worklen == 1 && work[0] == '/') { /* Root directory */ + memcpy(work + 1, de->d_name, len + 1); + len = len + 1; + } else { + work[worklen] = '/'; + memcpy(work + worklen + 1, de->d_name, len + 1); + len = worklen + 1 + len; + } + + /* Test for a match at this directory level */ + if (!string_match((byte *) work, len, (byte *) pattern, pathead, NULL)) + goto top; + + /* Perhaps descend into subdirectories */ + if (pathead < pfen->patlen) { + DIR *dp; + + if (((stat(work, &stbuf) >= 0) + ? !stat_is_dir(stbuf) + /* Couldn't stat it. + * Well, perhaps it's a directory and + * we'll be able to list it anyway. + * If it isn't or we can't, no harm done. */ + : 0)) + goto top; + + if (pfen->patlen == pathead + 1) { /* Listing "foo/?/" -- return this entry */ + /* if it's a directory. */ + if (!stat_is_dir(stbuf)) { /* Do directoryp test the hard way */ + dp = opendir(work); + if (!dp) + goto top; + closedir(dp); + } + work[len++] = '/'; + goto winner; + } + /* >>> Should optimise the case in which the next level */ + /* >>> of directory has no wildcards. */ + dp = opendir(work); +#ifdef DEBUG + { + char save_end = pattern[pathead]; + + pattern[pathead] = 0; + if_debug2('e', "[e]file_enum:fname='%s', p='%s'\n", + work, pattern); + pattern[pathead] = save_end; + } +#endif /* DEBUG */ + if (!dp) + /* Can't list this one */ + goto top; + else { /* Advance to the next directory-delimiter */ + /* in pattern */ + char *p; + dirstack *d; + + for (p = pattern + pathead + 1;; p++) { + if (*p == 0) { /* No more subdirectories to match */ + pathead = pfen->patlen; + break; + } else if (*p == '/') { + pathead = p - pattern; + break; + } + } + + /* Push a directory onto the enumeration stack. */ + d = gs_alloc_struct(pfen->memory, dirstack, + &st_dirstack, + "gp_enumerate_files(pushdir)"); + if (d != 0) { + d->next = pfen->dstack; + d->entry = pfen->dirp; + pfen->dstack = d; + } else + DO_NOTHING; /* >>> e_VMerror!!! */ + + if_debug1('e', "[e]file_enum:Dir pushed '%s'\n", + work); + worklen = len; + pfen->dirp = dp; + goto top; + } + } + winner: + /* We have a winner! */ + pfen->worklen = worklen; + pfen->pathead = pathead; + memcpy(ptr, work, len); + return len; +} + +/* Clean up the file enumeration. */ +void +gp_enumerate_files_close(file_enum * pfen) +{ + gs_memory_t *mem = pfen->memory; + + if_debug0('e', "[e]file_enum:Cleanup\n"); + while (popdir(pfen)) /* clear directory stack */ + DO_NOTHING; + gs_free_object(mem, (byte *) pfen->work, + "gp_enumerate_close(work)"); + gs_free_object(mem, (byte *) pfen->pattern, + "gp_enumerate_files_close(pattern)"); + gs_free_object(mem, pfen, "gp_enumerate_files_close"); +} + +/* Test-cases: + (../?*r*?/?*.ps) {==} 100 string filenameforall + (../?*r*?/?*.ps*) {==} 100 string filenameforall + (../?*r*?/) {==} 100 string filenameforall + (/t*?/?*.ps) {==} 100 string filenameforall + */ diff --git a/pstoraster/gp_unix.c b/pstoraster/gp_unix.c new file mode 100644 index 0000000000..e705af6359 --- /dev/null +++ b/pstoraster/gp_unix.c @@ -0,0 +1,173 @@ +/* Copyright (C) 1989, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Unix-specific routines for Ghostscript */ +#include "pipe_.h" +#include "string_.h" +#include "time_.h" +#include "gx.h" +#include "gsexit.h" +#include "gp.h" + +/* + * This is the only place in Ghostscript that calls 'exit'. Including + * is overkill, but that's where it's declared on ANSI systems. + * We don't have any way of detecting whether we have a standard library + * (some GNU compilers perversely define __STDC__ but don't provide + * an ANSI-compliant library), so we check __PROTOTYPES__ and + * hope for the best. We pick up getenv at the same time. + */ +#ifdef __PROTOTYPES__ +# include /* for exit and getenv */ +#else +extern void exit(P1(int)); +extern char *getenv(P1(const char *)); + +#endif + +/* Do platform-dependent initialization. */ +void +gp_init(void) +{ +} + +/* Do platform-dependent cleanup. */ +void +gp_exit(int exit_status, int code) +{ +} + +/* Exit the program. */ +void +gp_do_exit(int exit_status) +{ + exit(exit_status); +} + +/* ------ Miscellaneous ------ */ + +/* Get the string corresponding to an OS error number. */ +/* Unix systems support this so inconsistently that we don't attempt */ +/* to figure out whether it's available. */ +const char * +gp_strerror(int errnum) +{ + return NULL; +} + +/* ------ Date and time ------ */ + +/* Read the current time (in seconds since Jan. 1, 1970) */ +/* and fraction (in nanoseconds). */ +void +gp_get_realtime(long *pdt) +{ + struct timeval tp; + +#if gettimeofday_no_timezone /* older versions of SVR4 */ + { + if (gettimeofday(&tp) == -1) { + lprintf("Ghostscript: gettimeofday failed!\n"); + gs_exit(1); + } + } +#else /* All other systems */ + { + struct timezone tzp; + + if (gettimeofday(&tp, &tzp) == -1) { + lprintf("Ghostscript: gettimeofday failed!\n"); + gs_exit(1); + } + } +#endif + + /* tp.tv_sec is #secs since Jan 1, 1970 */ + pdt[0] = tp.tv_sec; + + /* Some Unix systems (e.g., Interactive 3.2 r3.0) return garbage */ + /* in tp.tv_usec. Try to filter out the worst of it here. */ + pdt[1] = tp.tv_usec >= 0 && tp.tv_usec < 1000000 ? tp.tv_usec * 1000 : 0; + +#ifdef DEBUG_CLOCK + printf("tp.tv_sec = %d tp.tv_usec = %d pdt[0] = %ld pdt[1] = %ld\n", + tp.tv_sec, tp.tv_usec, pdt[0], pdt[1]); +#endif +} + +/* Read the current user CPU time (in seconds) */ +/* and fraction (in nanoseconds). */ +void +gp_get_usertime(long *pdt) +{ +#if use_times_for_usertime + struct tms tms; + long ticks; + const long ticks_per_sec = CLK_TCK; + + times(&tms); + ticks = tms.tms_utime + tms.tms_stime + tms.tms_cutime + tms.tms_cstime; + pdt[0] = ticks / ticks_per_sec; + pdt[1] = (ticks % ticks_per_sec) * (1000000000 / ticks_per_sec); +#else + gp_get_realtime(pdt); /* Use an approximation on other hosts. */ +#endif +} + +/* ------ Screen management ------ */ + +/* Get the environment variable that specifies the display to use. */ +const char * +gp_getenv_display(void) +{ + return getenv("DISPLAY"); +} + +/* ------ Printer accessing ------ */ + +/* Open a connection to a printer. A null file name means use the */ +/* standard printer connected to the machine, if any. */ +/* "|command" opens an output pipe. */ +/* Return NULL if the connection could not be opened. */ +FILE * +gp_open_printer(char fname[gp_file_name_sizeof], int binary_mode) +{ + return + (strlen(fname) == 0 ? + gp_open_scratch_file(gp_scratch_file_name_prefix, fname, "w") : + fname[0] == '|' ? + popen(fname + 1, "w") : + fopen(fname, "w")); +} + +/* Close the connection to the printer. */ +void +gp_close_printer(FILE * pfile, const char *fname) +{ + if (fname[0] == '|') + pclose(pfile); + else + fclose(pfile); +} diff --git a/pstoraster/gpcheck.h b/pstoraster/gpcheck.h new file mode 100644 index 0000000000..aaaf2b7343 --- /dev/null +++ b/pstoraster/gpcheck.h @@ -0,0 +1,65 @@ +/* Copyright (C) 1992, 1994 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Interrupt check interface */ + +#ifndef gpcheck_INCLUDED +# define gpcheck_INCLUDED + +/* + * On some platforms, the interpreter must check periodically for user- + * initiated actions. (Eventually, this may be extended to all platforms, + * to handle multi-tasking through the 'context' facility.) Routines that + * run for a long time must periodically call gp_check_interrupts(), and + * if it returns true, must clean up whatever they are doing and return an + * e_interrupted (or gs_error_interrupted) exceptional condition. + * The return_if_interrupt macro provides a convenient way to do this. + * + * On platforms that require an interrupt check, the makefile defines + * a symbol CHECK_INTERRUPTS. Currently this is only the Microsoft + * Windows platform. + */ + +#ifdef CHECK_INTERRUPTS +int gp_check_interrupts(P0()); +int gs_return_check_interrupt(P1(int code)); + +# define process_interrupts() discard(gp_check_interrupts()) +# define return_if_interrupt()\ + { int icode_ = gp_check_interrupts();\ + if ( icode_ )\ + return gs_note_error((icode_ > 0 ? gs_error_interrupt : icode_));\ + } +# define return_check_interrupt(code)\ + return gs_return_check_interrupt(code) +#else +# define gp_check_interrupts() 0 +# define process_interrupts() DO_NOTHING +# define return_if_interrupt() DO_NOTHING +# define return_check_interrupt(code)\ + return (code) +#endif + +#endif /* gpcheck_INCLUDED */ diff --git a/pstoraster/gpgetenv.h b/pstoraster/gpgetenv.h new file mode 100644 index 0000000000..61b75c3884 --- /dev/null +++ b/pstoraster/gpgetenv.h @@ -0,0 +1,50 @@ +/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Interface to platform-specific getenv routine */ + +#ifndef gpgetenv_INCLUDED +# define gpgetenv_INCLUDED + +/* + * Get a value from the environment (getenv). + * + * If the key is missing, set *ptr = 0 (if *plen > 0), set *plen = 1, + * and return 1. + * + * If the key is present and the length len of the value (not counting + * the terminating \0) is less than *plen, copy the value to ptr, set + * *plen = len + 1, and return 0. + * + * If the key is present and len >= *plen, set *plen = len + 1, + * don't store anything at ptr, and return -1. + * + * Note that *plen is the size of the buffer, not the length of the string: + * because of the terminating \0, the maximum string length is 1 less than + * the size of the buffer. + */ +int gp_getenv(P3(const char *key, char *ptr, int *plen)); + +#endif /* gpgetenv_INCLUDED */ diff --git a/pstoraster/gpsync.h b/pstoraster/gpsync.h new file mode 100644 index 0000000000..5a16f28d15 --- /dev/null +++ b/pstoraster/gpsync.h @@ -0,0 +1,81 @@ +/* Copyright (C) 1998 Aladdin Enterprises. All rights reserved. + + This file is part of GNU Ghostscript. + + GNU Ghostscript is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY. No author or distributor accepts responsibility + to anyone for the consequences of using it or for whether it serves any + particular purpose or works at all, unless he says so in writing. Refer + to the GNU General Public License for full details. + + Everyone is granted permission to copy, modify and redistribute GNU + Ghostscript, but only under the conditions described in the GNU General + Public License. A copy of this license is supposed to have been given + to you along with GNU Ghostscript so you can know your rights and + responsibilities. It should be in a file named COPYING. Among other + things, the copyright notice and this notice must be preserved on all + copies. + + Aladdin Enterprises supports the work of the GNU Project, but is not + affiliated with the Free Software Foundation or the GNU Project. GNU + Ghostscript, as distributed by Aladdin Enterprises, does not require any + GNU software to build or run it. +*/ + +/*$Id$ */ +/* Interface to platform-dependent synchronization primitives */ + +#if !defined(gpsync_INCLUDED) + #define gpsync_INCLUDED + +/* Initial version 4/1/98 by John Desrosiers (soho@crl.com). */ +/* 8/9/98 L. Peter Deutsch (ghost@aladdin.com) Changed ...sizeof to + procedures, added some comments. */ + +/* -------- Synchronization primitives ------- */ + +/* + * Semaphores support wait/signal semantics: a wait operation will allow + * control to proceed iff the number of signals since semaphore creation + * is greater than the number of waits. + */ +typedef struct { + void *dummy_; +} gp_semaphore; + +uint gp_semaphore_sizeof(P0()); +/* + * Hack: gp_semaphore_open(0) succeeds iff it's OK for the memory manager + * to move a gp_semaphore in memory. + */ +int gp_semaphore_open(P1(gp_semaphore * sema)); +int gp_semaphore_close(P1(gp_semaphore * sema)); +int gp_semaphore_wait(P1(gp_semaphore * sema)); +int gp_semaphore_signal(P1(gp_semaphore * sema)); + +/* + * Monitors support enter/leave semantics: at most one thread can have + * entered and not yet left a given monitor. + */ +typedef struct { + void *dummy_; +} gp_monitor; + +uint gp_monitor_sizeof(P0()); +/* + * Hack: gp_monitor_open(0) succeeds iff it's OK for the memory manager + * to move a gp_monitor in memory. + */ +int gp_monitor_open(P1(gp_monitor * mon)); +int gp_monitor_close(P1(gp_monitor * mon)); +int gp_monitor_enter(P1(gp_monitor * mon)); +int gp_monitor_leave(P1(gp_monitor * mon)); + +/* + * A new thread starts by calling a procedure, passing it a void * that + * allows it to gain access to whatever data it needs. + */ +typedef void (*gp_thread_creation_callback_t) (P1(void *)); +int gp_create_thread(P2(gp_thread_creation_callback_t, void *)); + +#endif /* !defined(gpsync_INCLUDED) */ diff --git a/pstoraster/gs_btokn.ps b/pstoraster/gs_btokn.ps new file mode 100644 index 0000000000..7ad61f8a5a --- /dev/null +++ b/pstoraster/gs_btokn.ps @@ -0,0 +1,313 @@ +% Copyright 1993-2000 by Easy Software Products. +% Copyright 1994, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_btokn.ps 956 2000-03-08 23:15:43Z mike $ +% Initialization file for binary tokens. +% When this is run, systemdict is still writable, +% but everything defined here goes into level2dict. + +% Define whether or not to allow writing dictionaries. +/WRITEDICTS true def + +languagelevel 1 .setlanguagelevel +level2dict begin + +% Initialization for the system name table. + +mark +% 0 + /abs /add /aload /anchorsearch /and + /arc /arcn /arct /arcto /array + /ashow /astore /awidthshow /begin /bind + /bitshift /ceiling /charpath /clear /cleartomark +% 20 + /clip /clippath /closepath /concat /concatmatrix + /copy /count /counttomark /currentcmykcolor /currentdash + /currentdict /currentfile /currentfont /currentgray /currentgstate + /currenthsbcolor /currentlinecap /currentlinejoin /currentlinewidth /currentmatrix +% 40 + /currentpoint /currentrgbcolor /currentshared /curveto /cvi + /cvlit /cvn /cvr /cvrs /cvs + /cvx /def /defineusername /dict /div + /dtransform /dup /end /eoclip /eofill +% 60 + /eoviewclip /eq /exch /exec /exit + /file /fill /findfont /flattenpath /floor + /flush /flushfile /for /forall /ge + /get /getinterval /grestore /gsave /gstate +% 80 + /gt /identmatrix /idiv /idtransform /if + /ifelse /image /imagemask /index /ineofill + /infill /initviewclip /inueofill /inufill /invertmatrix + /itransform /known /le /length /lineto +% 100 + /load /loop /lt /makefont /matrix + /maxlength /mod /moveto /mul /ne + /neg /newpath /not /null /or + /pathbbox /pathforall /pop /print /printobject +% 120 + /put /putinterval /rcurveto /read /readhexstring + /readline /readstring /rectclip /rectfill /rectstroke + /rectviewclip /repeat /restore /rlineto /rmoveto + /roll /rotate /round /save /scale +% 140 + /scalefont /search /selectfont /setbbox /setcachedevice + /setcachedevice2 /setcharwidth /setcmykcolor /setdash /setfont + /setgray /setgstate /sethsbcolor /setlinecap /setlinejoin + /setlinewidth /setmatrix /setrgbcolor /setshared /shareddict +% 160 + /show /showpage /stop /stopped /store + /string /stringwidth /stroke /strokepath /sub + /systemdict /token /transform /translate /truncate + /type /uappend /ucache /ueofill /ufill +% 180 + /undef /upath /userdict /ustroke /viewclip + /viewclippath /where /widthshow /write /writehexstring + /writeobject /writestring /wtranslation /xor /xshow + /xyshow /yshow /FontDirectory /SharedFontDirectory /Courier +% 200 + /Courier-Bold /Courier-BoldOblique /Courier-Oblique /Helvetica /Helvetica-Bold + /Helvetica-BoldOblique /Helvetica-Oblique /Symbol /Times-Bold /Times-BoldItalic + /Times-Italic /Times-Roman /execuserobject /currentcolor /currentcolorspace + /currentglobal /execform /filter /findresource /globaldict +% 220 + /makepattern /setcolor /setcolorspace /setglobal /setpagedevice + /setpattern +% pad to 256 + counttomark 256 exch sub { 0 } repeat +% 256 + /= /== /ISOLatin1Encoding /StandardEncoding +% 260 + ([) cvn (]) cvn /atan /banddevice /bytesavailable + /cachestatus /closefile /colorimage /condition /copypage + /cos /countdictstack /countexecstack /cshow /currentblackgeneration + /currentcacheparams /currentcolorscreen /currentcolortransfer /currentcontext /currentflat +% 280 + /currenthalftone /currenthalftonephase /currentmiterlimit /currentobjectformat /currentpacking + /currentscreen /currentstrokeadjust /currenttransfer /currentundercolorremoval /defaultmatrix + /definefont /deletefile /detach /deviceinfo /dictstack + /echo /erasepage /errordict /execstack /executeonly +% 300 + /exp /false /filenameforall /fileposition /fork + /framedevice /grestoreall /handleerror /initclip /initgraphics + /initmatrix /instroke /inustroke /join /kshow + /ln /lock /log /mark /monitor +% 320 + /noaccess /notify /nulldevice /packedarray /quit + /rand /rcheck /readonly /realtime /renamefile + /renderbands /resetfile /reversepath /rootfont /rrand + /run /scheck /setblackgeneration /setcachelimit /setcacheparams +% 340 + /setcolorscreen /setcolortransfer /setfileposition /setflat /sethalftone + /sethalftonephase /setmiterlimit /setobjectformat /setpacking /setscreen + /setstrokeadjust /settransfer /setucacheparams /setundercolorremoval /sin + /sqrt /srand /stack /status /statusdict +% 360 + /true /ucachestatus /undefinefont /usertime /ustrokepath + /version /vmreclaim /vmstatus /wait /wcheck + /xcheck /yield /defineuserobject /undefineuserobject /UserObjects + /cleardictstack +% 376 + /A /B /C /D /E /F /G /H /I /J /K /L /M + /N /O /P /Q /R /S /T /U /V /W /X /Y /Z + /a /b /c /d /e /f /g /h /i /j /k /l /m + /n /o /p /q /r /s /t /u /v /w /x /y /z +% 428 + /setvmthreshold (<<) cvn + (>>) cvn /currentcolorrendering /currentdevparams /currentoverprint /currentpagedevice + /currentsystemparams /currentuserparams /defineresource /findencoding /gcheck +% 440 + /glyphshow /languagelevel /product /pstack /resourceforall + /resourcestatus /revision /serialnumber /setcolorrendering /setdevparams + /setoverprint /setsystemparams /setuserparams /startjob /undefineresource + /GlobalFontDirectory /ASCII85Decode /ASCII85Encode /ASCIIHexDecode /ASCIIHexEncode +% 460 + /CCITTFaxDecode /CCITTFaxEncode /DCTDecode /DCTEncode /LZWDecode + /LZWEncode /NullEncode /RunLengthDecode /RunLengthEncode /SubFileDecode + /CIEBasedA /CIEBasedABC /DeviceCMYK /DeviceGray /DeviceRGB + /Indexed /Pattern /Separation +% 478 -- end +.packtomark +dup /SystemNames exch def .installsystemnames + +% Define printobject and writeobject. +% These are mostly implemented in PostScript, so that we don't have to +% worry about interrupts or callbacks when writing to the output file. + +% Define procedures for accumulating the space required to represent +% an object in binary form. +/cntdict mark % <#refs> <#chars> -proc- <#refs> <#chars> + /integertype /pop load + /realtype 1 index + /marktype 1 index + /nulltype 1 index + /booleantype 1 index + /nametype { length add } bind + /stringtype 1 index + /arraytype null + WRITEDICTS { /dicttype null } if +.dicttomark def +cntdict /arraytype + { dup dup length 5 -1 roll add 4 2 roll + { dup type //cntdict exch get exec } forall + } bind put +WRITEDICTS + { cntdict /dicttype + { dup dup length 2 mul 5 -1 roll add 4 2 roll + { 4 1 roll dup type //cntdict exch get exec + 3 -1 roll dup type //cntdict exch get exec + } forall + } bind put + } if + +/w2dict mark + /nametype { 2 copy .writecvs pop } bind + /stringtype 1 index +.dicttomark def + +/.bosheader { % .bosheader + % + dup 0 currentobjectformat 127 add put % object format => BOS tag + 2 index 255 le 2 index 65531 le and { + % Use the short header format: tag toplen(1) totlen(2) + exch 4 add exch + 0 4 getinterval + dup 1 5 -1 roll put + } { + % Use the long header format: tag 0(1) toplen(2) totlen(4) + exch 8 add exch + 0 0 4 2 roll .bosobject exch pop exch pop % store with byte swapping + } ifelse % Stack: shortlen str + exch dup -8 bitshift exch 255 and % str hibyte lobyte + currentobjectformat 1 and 0 eq { % lsb first + exch + } if + 2 index 3 3 -1 roll put + 1 index 2 3 -1 roll put +} .bind def + +/.writeobjects % .writeobjects - + { + mark exch + + % Count the space required for refs and strings. + dup length 0 3 -1 roll + % Stack: -mark- <#refs> <#chars> + + dup 4 1 roll + { dup type //cntdict exch get exec + } forall + + % Write the header. + % Stack: -mark- ... <#refs> <#chars> + counttomark 3 add -2 roll 4 1 roll + % Stack: -mark- ... <#refs> <#chars> + dup counttomark 1 sub index length + 4 index 3 bitshift 4 index add + (xxxxxxxx) .bosheader writestring + + % Write the objects per se. + 3 1 roll pop + counttomark 1 sub index length 3 bitshift exch + 3 bitshift + % Stack: -mark- ... + + counttomark 4 sub + { counttomark -1 roll dup 6 1 roll + dup type /dicttype eq % can't be first object + { { 5 1 roll (xxxxxxxx) .bosobject + 3 index exch writestring + 4 -1 roll (xxxxxxxx) .bosobject + 3 index exch writestring + } forall + } + { { (xxxxxxxx) .bosobject + dup 1 6 index put + 3 index exch writestring + 4 -1 roll pop 0 4 1 roll % clear tag + } forall + } + ifelse + } + repeat + + % Write the strings and names. + pop pop exch pop + % Stack: -mark- ... + + counttomark 1 sub + { counttomark -1 roll + { % The counting pass ensured that the keys and values + % of any dictionary must be writable objects. + % Hence, we are processing a dictionary iff + % the next-to-top stack element is not a file. + 1 index type /filetype ne + { exch 2 index exch dup type //w2dict exch .knownget + { exec } { pop } ifelse pop + } + if + dup type //w2dict exch .knownget { exec } { pop } ifelse + } forall + } + repeat + + % Clean up. + % Stack: -mark- + + pop pop + + } odef +currentdict /cntdict .undef +currentdict /w2dict .undef + +%%%% MRS - stderr instead of stdout, which is used for output... +/printobject { % printobject - + (%stderr) (w) file 2 index 2 index writeobject pop pop +} odef +/writeobject { % writeobject - + 3 copy exch + % We must allocate the array in local VM + % to avoid a possible invalidaccess. + .currentglobal false .setglobal exch 1 array astore exch .setglobal + .writeobjects pop pop pop +} odef + +% Implement binary error message output. + /.printerror + { $error /binary get .languagelevel 2 ge and + { currentobjectformat 0 ne + { [ /Error $error /errorname get $error /command get false + ] 250 printobject + } + //.printerror + ifelse + } + //.printerror + ifelse + } bind def + +% End of level2dict + +end +.setlanguagelevel diff --git a/pstoraster/gs_ccfnt.ps b/pstoraster/gs_ccfnt.ps new file mode 100644 index 0000000000..5d4ada0e49 --- /dev/null +++ b/pstoraster/gs_ccfnt.ps @@ -0,0 +1,100 @@ +% Copyright (C) 1994, 1996 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_ccfnt.ps 956 2000-03-08 23:15:43Z mike $ +% Find and register all the precompiled font operators in systemdict. + +/registerfont % registerfont + { DEBUG { (Registering ) print 1 index = } if + dup begin + Encoding type /nametype eq + { Encoding .findencoding /Encoding exch def + } + if + dup /PrefEnc known + { PrefEnc type /nametype eq + { PrefEnc .findencoding /PrefEnc exch def + } + if + } + if + dup /FDepVector known + { /FDepVector [ FDepVector + { .FontDirectory 1 index .knownget + { exch pop } + { ccfonts 1 index .knownget + { registerfont + } + { Fontmap 1 index known + { findfont } + { pop NullFont } + ifelse + } + ifelse + } + ifelse + } + forall ] readonly def + } + if + end + % Use the value of definefont appropriate at run-time, not bind-time + /definefont load exec + } bind odef +% Bind recursive call (bind descends into oparrays: feature!) +/registerfont dup load bind def + +/.loadinitialfonts { + //.loadinitialfonts exec + /ccfonts mark + 0 1 null .getccfont 1 sub { .getccfont dup /FontName get exch } for + .dicttomark def + ccfonts + { .FontDirectory 2 index known { pop pop } { registerfont pop } ifelse } + forall + currentdict /ccfonts .undef +} bind def + +currentdict /registerfont .undef + + +% If we're in a Level 2 system but running in Level 1 mode, +% register the fonts explicitly as resources. +% This is a bit of a hack, but doing better is too much work. + +/level2dict where + { pop /findresource where + { % Level 2 system, Level 2 mode + pop + } + { % Level 2 system, Level 1 mode + /Font /Category level2dict /findresource get exec begin + .FontDirectory + { dup .gcheck { Instances } { LocalInstances } ifelse + 3 1 roll [exch 0 -1] .growput + } + forall end + } + ifelse + } +if diff --git a/pstoraster/gs_cff.ps b/pstoraster/gs_cff.ps new file mode 100644 index 0000000000..515fe5d083 --- /dev/null +++ b/pstoraster/gs_cff.ps @@ -0,0 +1,614 @@ +% Copyright (C) 1997 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_cff.ps 1159 2000-06-26 15:50:18Z mike $ +% Loader for CFF (compressed) fonts. +% The following are not implemented yet: +% Deleted entries in the Name Index +% Embedded PostScript +% Multiple Master fonts +% CIDFonts +% Chameleon fonts +% Synthetic fonts +% Also, Type 2 charstrings are converted into Type 1 fonts with +% CharstringType = 2, which may or may not be supported. + +100 dict begin + +% ---------------- Standard strings (actually names) ---------------- % + +/StandardStrings mark +% 0 + /.notdef /space /exclam /quotedbl /numbersign + /dollar /percent /ampersand /quoteright /parenleft + /parenright /asterisk /plus /comma /hyphen + /period /slash /zero /one /two + /three /four /five /six /seven + /eight /nine /colon /semicolon /less + /equal /greater /question /at /A + /B /C /D /E /F + /G /H /I /J /K + /L /M /N /O /P +% 50 + /Q /R /S /T /U + /V /W /X /Y /Z + /bracketleft /backslash /bracketright /asciicircum /underscore + /quoteleft /a /b /c /d + /e /f /g /h /i + /j /k /l /m /n + /o /p /q /r /s + /t /u /v /w /x + /y /z /braceleft /bar /braceright + /asciitilde /exclamdown /cent /sterling /fraction +% 100 + /yen /florin /section /currency /quotesingle + /quotedblleft /guillemotleft /guilsinglleft /guilsinglright /fi + /fl /endash /dagger /daggerdbl /periodcentered + /paragraph /bullet /quotesinglbase /quotedblbase /quotedblright + /guillemotright /ellipsis /perthousand /questiondown /grave + /acute /circumflex /tilde /macron /breve + /dotaccent /dieresis /ring /cedilla /hungarumlaut + /ogonek /caron /emdash /AE /ordfeminine + /Lslash /Oslash /OE /ordmasculine /ae + /dotlessi /lslash /oslash /oe /germandbls +% 150 + /onesuperior /logicalnot /mu /trademark /Eth + /onehalf /plusminus /Thorn /onequarter /divide + /brokenbar /degree /thorn /threequarters /twosuperior + /registered /minus /eth /multiply /threesuperior + /copyright /Aacute /Acircumflex /Adieresis /Agrave + /Aring /Atilde /Ccedilla /Eacute /Ecircumflex + /Edieresis /Egrave /Iacute /Icircumflex /Idieresis + /Igrave /Ntilde /Oacute /Ocircumflex /Odieresis + /Ograve /Otilde /Scaron /Uacute /Ucircumflex + /Udieresis /Ugrave /Yacute /Ydieresis /Zcaron +% 200 + /aacute /acircumflex /adieresis /agrave /aring + /atilde /ccedilla /eacute /ecircumflex /edieresis + /egrave /iacute /icircumflex /idieresis /igrave + /ntilde /oacute /ocircumflex /odieresis /ograve + /otilde /scaron /uacute /ucircumflex /udieresis + /ugrave /yacute /ydieresis /zcaron /exclamsmall + /Hungarumlautsmall /dollaroldstyle /dollarsuperior /ampersandsmall /Acutesmall + /parenleftsuperior /parenrightsuperior /twodotenleader /onedotenleader /zerooldstyle + /oneoldstyle /twooldstyle /threeoldstyle /fouroldstyle /fiveoldstyle + /sixoldstyle /sevenoldstyle /eightoldstyle /nineoldstyle /commasuperior +% 250 + /threequartersemdash /periodsuperior /questionsmall /asuperior /bsuperior + /centsuperior /dsuperior /esuperior /isuperior /lsuperior + /msuperior /nsuperior /osuperior /rsuperior /ssuperior + /tsuperior /ff /ffi /ffl /parenleftinferior + /parenrightinferior /Circumflexsmall /hyphensuperior /Gravesmall /Asmall + /Bsmall /Csmall /Dsmall /Esmall /Fsmall + /Gsmall /Hsmall /Ismall /Jsmall /Ksmall + /Lsmall /Msmall /Nsmall /Osmall /Psmall + /Qsmall /Rsmall /Ssmall /Tsmall /Usmall + /Vsmall /Wsmall /Xsmall /Ysmall /Zsmall +% 300 + /colonmonetary /onefitted /rupiah /Tildesmall /exclamdownsmall + /centoldstyle /Lslashsmall /Scaronsmall /Zcaronsmall /Dieresissmall + /Brevesmall /Caronsmall /Dotaccentsmall /Macronsmall /figuredash + /hypheninferior /Ogoneksmall /Ringsmall /Cedillasmall /questiondownsmall + /oneeighth /threeeighths /fiveeighths /seveneighths /onethird + /twothirds /zerosuperior /foursuperior /fivesuperior /sixsuperior + /sevensuperior /eightsuperior /ninesuperior /zeroinferior /oneinferior + /twoinferior /threeinferior /fourinferior /fiveinferior /sixinferior + /seveninferior /eightinferior /nineinferior /centinferior /dollarinferior + /periodinferior /commainferior /Agravesmall /Aacutesmall /Acircumflexsmall +% 350 + /Atildesmall /Adieresissmall /Aringsmall /AEsmall /Ccedillasmall + /Egravesmall /Eacutesmall /Ecircumflexsmall /Edieresissmall /Igravesmall + /Iacutesmall /Icircumflexsmall /Idieresissmall /Ethsmall /Ntildesmall + /Ogravesmall /Oacutesmall /Ocircumflexsmall /Otildesmall /Odieresissmall + /OEsmall /Oslashsmall /Ugravesmall /Uacutesmall /Ucircumflexsmall + /Udieresissmall /Yacutesmall /Thornsmall /Ydieresissmall (001.000) + (001.001) (001.002) (001.003) /Black /Bold + /Book /Light /Medium /Regular /Roman + /Semibold +.packtomark def + +% ---------------- Standard encodings ---------------- % + +/StandardEncodings [ + +% StandardEncoding +mark + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 + 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 + 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 + 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 + 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 + 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 + 0 111 112 113 114 0 115 116 117 118 119 120 121 122 0 123 + 0 124 125 126 127 128 129 130 131 0 132 133 0 134 135 136 + 137 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 138 0 139 0 0 0 0 140 141 142 143 0 0 0 0 + 0 144 0 0 0 145 0 0 146 147 148 149 0 0 0 0 +.packtomark + +% ExpertEncoding +mark + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 1 229 230 0 231 232 233 234 235 236 237 238 13 14 15 99 + 239 240 241 242 243 244 245 246 247 248 27 28 249 250 251 252 + 0 253 254 255 256 257 0 0 0 258 0 0 259 260 261 262 + 0 0 263 264 265 0 266 109 110 267 268 269 0 270 271 272 + 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 + 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 + 0 304 305 306 0 0 307 308 309 310 311 0 312 0 0 313 + 0 0 314 315 0 0 316 317 318 0 0 0 158 155 163 319 + 320 321 322 323 324 325 0 0 326 150 164 169 327 328 329 330 + 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 + 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 + 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 +.packtomark + +] readonly def + +% ---------------- Standard Charsets ---------------- % + +% We include an explicit 0 at the beginning of each charset. + +/StandardCharsets [ + +% ISOAdobe +mark + 0 + 1 1 228 { } for +.packtomark + +% Expert +mark + 0 + 1 229 230 231 232 233 234 235 236 237 238 13 14 15 99 239 + 240 241 242 243 244 245 246 247 248 27 28 249 250 251 252 253 + 254 255 256 257 258 259 260 261 262 263 264 265 266 109 110 267 + 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 + 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 + 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 + 316 317 318 158 155 163 319 320 321 322 323 324 325 326 150 164 + 169 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 + 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 + 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 + 374 375 376 377 378 +.packtomark + +% ExpertSubset +mark + 0 + 1 231 232 235 236 237 238 13 14 15 99 239 240 241 242 243 + 244 245 246 247 248 27 28 249 250 251 253 254 255 256 257 258 + 259 260 261 262 263 264 265 266 109 110 267 268 269 270 272 300 + 301 302 305 314 315 158 155 163 320 321 322 323 324 325 326 150 + 164 169 327 328 329 330 331 332 333 334 335 336 337 338 339 340 + 341 342 343 344 345 346 +.packtomark + +] readonly def + +% ---------------- Font loading ---------------- % + +% ------ Utilities ------ % + +/advance { % advance - + f cff eq { /pos pos 3 -1 roll add store } { pop } ifelse +} def +/next { % - next + f read { 1 advance } if +} def +/nextstring { % nextstring + dup 0 eq { + pop () + } { + string f exch readstring pop dup length advance + } ifelse +} def +/card8 % - card8 + /next load +def +/card16 { % - card16 + card8 8 bitshift card8 add +} def +/offset { % offset + 0 exch { 8 bitshift next add } repeat +} def +/sid % - sid + /card16 load +def +/Index { % - Index + mark card16 dup 0 ne { + 1 exch next dup offset pop exch { + dup offset dup 4 -1 roll sub 3 1 roll exch + } repeat pop + } if pop .packtomark + [ exch { nextstring } forall ] readonly +} def +/tokens { % - tokens ... (op# = 12 means EOF) + { + f read not { 12 exit } if + 1 advance + dup 12 eq { pop next 32 add exit } if + dup 28 lt { exit } if + dup 32 lt { + 28 sub { + { card16 32768 xor 32768 sub } + { 4 offset dup 16#7fffffff gt { -1 32 bitshift add } if } + { tokenreal } + { 31 exit } + } exch get exec + } { + dup 247 lt { + 139 sub + } { + 247 sub { + { next 108 add } + { next 364 add } + { next 620 add } + { next 876 add } + { next 108 add neg } + { next 364 add neg } + { next 620 add neg } + { next 876 add neg } + % 255 is deliberately omitted and will cause a rangecheck + } exch get exec + } ifelse + } ifelse + } loop +} def +/tokenbuf 100 string def +/tokenput { % tokenput + tokenbuf 2 index 3 -1 roll put 1 add +} def +/tokenrealarray [ + (0123456789.E) { } forall + [(E) 0 get /tokenput cvx (-) 0 get] cvx + null % will give an error + (-) 0 get + { exit } +] readonly def +/tokenreal { % - tokenreal + 0 { + next exch 1 index -4 bitshift tokenrealarray exch get exec tokenput + % We must leave the byte on the stack temporarily so that + % the exit will see a consistent stack state. + 1 index 15 and tokenrealarray exch get exec tokenput exch pop + } loop + tokenbuf 0 3 -1 roll getinterval cvr exch pop +} def +/Dict { % Dict - + /opdict exch store { + mark tokens opdict exch .knownget { exec } if cleartomark + } loop cleartomark +} def +/idstring { % idstring + dup 391 lt { StandardStrings } { 391 sub strings } ifelse exch get +} def +/idname { % idname + idstring dup type /nametype ne { cvn } if +} def + +% ------ Top dictionary ------ % + +/offput { % offput - + currentdict exch aload length 1 add packedarray cvx + offsets 3 1 roll put +} def +/queueput { % queueput - + 16#7fffffff offsets { pop .min } forall + pos sub nextstring + 3 1 roll aload length 2 add packedarray cvx + [ queued aload pop counttomark 2 add -1 roll ] + /queued exch store +} def +/xxput { % xxput - + 3 1 roll exch put +} def +/putfi { % putfi - + FontInfo xxput +} def +/xdef { % xdef - + exch def +} def +/topdictops mark + 12 { exit } + 0 { idstring /version putfi } + 1 { idstring /Notice putfi } + 32 { idstring /Copyright putfi } + 2 { idstring /FullName putfi } + 3 { idstring /FamilyName putfi } + 4 { idstring /Weight putfi } + 33 { 0 ne /isFixedPitch putfi } + 34 { /ItalicAngle putfi } + 35 { /UnderlinePosition putfi } + 36 { /UnderlineThickness putfi } + 37 { /PaintType xdef } + 38 { /CharstringType xdef } + 39 { counttomark array astore /FontMatrix xdef } + 13 { /UniqueID xdef } + 5 { counttomark array astore /FontBBox xdef } + 40 { /StrokeWidth xdef } + 14 { counttomark array astore /XUID xdef } + 15 { + dup StandardCharsets length lt { + StandardCharsets exch get /charset xdef + } { + { queuecharset } offput + } ifelse + } + 16 { + dup StandardEncodings length lt { + /Encoding xdef + } { + { queueEncoding } offput + } ifelse + } + 17 { { readCharStrings } offput } + 18 { exch /readPrivate cvx 2 packedarray offput } +.dicttomark readonly def + +/readCharStrings { % readCharStrings - + /CharStringArray Index put +} def + +% ------ Charsets and encodings ------ % + +% Note: formats 1 and 2 can overflow the operand stack. +% We'll fix this if it ever becomes necessary. +/charsetformats [ +{ [ 0 CharStringArray length 1 sub { sid } repeat ] +} +{ [ 0 CharStringArray length 1 sub { + dup 0 eq { pop exit } if + sid card8 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop + } loop ] +} +{ [ 0 CharStringArray length 1 sub { + dup 0 eq { pop exit } if + sid card16 1 add 2 index .min { exch 1 sub 1 index 1 add } repeat pop + } loop ] +} +] readonly def +/queuecharset { % queuecharset - + { readcharset } queueput +} def +/readcharset { % readcharset - + begin 0 () /SubFileDecode filter /f exch store + charsetformats next get exec /charset exch def end +} def + +/encodingformats [ +{ 1 1 next { next exch Encoding 3 1 roll put } for +} +{ 1 next { + next next 1 add { + % Stack: gid code + Encoding 1 index 3 index put + exch 1 add exch 1 add + } repeat pop + } repeat pop +} +] readonly def +/queueEncoding { % queueEncoding - + { readEncoding } queueput +} def +/readEncoding { % readEncoding - + begin 0 () /SubFileDecode filter /f exch store + /Encoding [ 256 { /.notdef } repeat ] def + next encodingformats 1 index 127 and get exec + 128 ge { + % Read supplementary encodings. + next { + Encoding next sid idname put + } repeat + } if end +} def + +% ------ Private dictionary ------ % + +/deltarray { % -mark- ... deltarray ... + 0 counttomark 1 sub { counttomark -1 roll add dup } repeat pop + counttomark array astore +} def + +/privatedictops mark + 12 { exit } + 6 { deltarray /BlueValues xdef } + 7 { deltarray /OtherBlues xdef } + 8 { deltarray /FamilyBlues xdef } + 9 { deltarray /FamilyOtherBlues xdef } + 41 { /BlueScale xdef } + 42 { /BlueShift xdef } + 43 { /BlueFuzz xdef } + 10 { 1 array astore /StdHW xdef } + 11 { 1 array astore /StdVW xdef } + 44 { deltarray /StemSnapH xdef } + 45 { deltarray /StemSnapV xdef } + 46 { 0 ne /ForceBold xdef } + 47 { /ForceBoldThreshold xdef } + 48 { /lenIV xdef } + 49 { /LanguageGroup xdef } + 50 { /ExpansionFactor xdef } + 51 { /initialRandomSeed xdef } + 19 { { readSubrs } offput } + 20 { /defaultWidthX xdef } + 21 { /nominalWidthX xdef } + % Multiple Master fonts only + 59 { /NDV xdef } + 60 { /CDV xdef } + 61 { /lenBuildCharArray xdef } +.dicttomark readonly def + +/readPrivate { % readPrivate - + exch 1 index f exch () /SubFileDecode filter /f exch def + /Private get begin //privatedictops Dict end + /f cff def advance +} def + +% ------ Main program ------ % + +% We need to pass the file as a parameter for the sake of the PDF +% interpreter. +/StartData { % StartData - + currentfile exch () /SubFileDecode filter ReadData +} def +/ReadData { % ReadData - + + % Initialize. + + 30 dict begin + /cff exch def + /pos 0 def + /resname exch cvlit def + + % Read the header. + + /f cff def + /vmajor next def + /vminor next def + /hdrsize next def + /aoffsize next def + + % Read the Indexes. + + /names Index def + /topdicts Index def + /strings Index def + /gsubrs Index def + + % Read the top Dicts. + + /offsets 50 dict def + /queued [] def + /opdict null def % reserve a slot + /fonts [ topdicts { + 0 () /SubFileDecode filter /f exch def + 40 dict begin + % Preload defaults that differ from PostScript defaults, + % or that are required. + /FontType 1 def + /PaintType 0 def + /CharstringType 2 def + /FontMatrix [0.001 0 0 0.001 0 0] def + /charset StandardCharsets 0 get def + /Encoding 0 def + /FontInfo 10 dict + dup /UnderlinePosition -100 put + dup /UnderlineThickness 50 put + def + /Private 20 dict + gsubrs length 0 ne { dup /GlobalSubrs gsubrs put } if + def + //topdictops Dict + currentdict end + } forall ] def + + % Read other tables with queued offsets. + + DEBUG { offsets length =only ( offsets) = flush } if + { /f cff def + offsets pos 2 copy .knownget not { pop pop exit } if + 3 1 roll undef exec + } loop + offsets length 0 ne { + (Error: missing tables at ) print [ offsets { pop } forall ] == + (Current position is ) print pos == + flush stop + } if + + % Process out-of-order tables. + + DEBUG { queued length =only ( queued) = flush } if + queued { exec } forall + + % Update Encoding and CharStrings. + + fonts { + begin + % Construct the real Encoding. + % The value of Encoding is either a number, for predefined + % encodings, or an array of mixed GIDs and names. + /Encoding mark Encoding + DEBUG { (Encoding: ) print dup === flush } if + dup type /integertype eq { + StandardEncodings exch get { idname } forall + } { + { + dup type /integertype eq { charset exch get idname } if + } forall + } ifelse .packtomark def + % Construct the CharStrings. + % Note that they may only correspond to an initial + % subset of the charset. + /CharStrings charset length CharStringArray length .min dict def + DEBUG { + charset length =only ( charset ) print + CharStringArray length =only ( CharStringArray) = + charset == flush + } if + 0 1 CharStrings maxlength 1 sub { + dup CharStringArray exch get + exch charset exch get idstring + CharStrings xxput + } for + % Remove unwanted entries. + currentdict /charset undef + currentdict /CharStringArray undef + end + } forall + + % Wrap up. + + resname mark 0 1 fonts length 1 sub { + DEBUG { dup =only ( ) print flush } if + dup names exch get + DEBUG { dup == flush } if + exch fonts exch get + dup /FontName 3 index put + 1 index exch definefont + } for .dicttomark + end % temporary dict + end % FontSetInit ProcSet + /FontSet defineresource pop + +} bind def + +% ---------------- Resource category definition ---------------- % + +currentdict end readonly + +languagelevel exch 2 .setlanguagelevel + +/FontSet /Generic /Category findresource dup length dict .copydict +/Category defineresource pop + +/FontSetInit exch /ProcSet defineresource pop + +.setlanguagelevel diff --git a/pstoraster/gs_cidfn.ps b/pstoraster/gs_cidfn.ps new file mode 100644 index 0000000000..f7f9265021 --- /dev/null +++ b/pstoraster/gs_cidfn.ps @@ -0,0 +1,466 @@ +% Copyright (C) 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_cidfn.ps 956 2000-03-08 23:15:43Z mike $ +% ProcSet for implementing CIDFont and CIDMap resources. +% When this is run, systemdict is still writable. + +% ---------------- Defining CIDFont resources ---------------- % + +% Define a CIDFont resource. This is the defineresource implementation for +% the CIDFont resource category. + +/.cidfonttypes where { pop } { /.cidfonttypes 6 dict def } ifelse +.cidfonttypes begin + +% The key in .cidfonttypes is the CIDFontType value; +% the value is a procedure that takes a font name and the CIDFont dictionary +% and replaces the latter with a real font. + +0 { % CIDFontType 0 = FontType 9 + currentglobal 3 1 roll dup gcheck setglobal + dup /FontType 9 put + dup /FontMatrix known not { + dup /FontMatrix [0.001 0 0 0.001 0 0] put + dup /FDArray get { + /FontMatrix get [1000 0 0 1000 0 0] 1 index concatmatrix pop + } forall + } if + dup /FDArray get mark exch { + % Add pro forma entries + currentglobal exch dup gcheck setglobal + dup /FontType 1 put + dup /CharStrings mark /.notdef () .dicttomark put + dup /Encoding [] put + % Create a dummy Subrs array now, if there isn't one here + % already (which can only happen if we're giving another + % name to an existing font). + dup /Private get dup /Subrs known not { + dup /SubrCount .knownget { + array 1 index /Subrs 3 -1 roll put + } if readonly + } if pop + exch setglobal + dup /FontName .knownget not { () } if exch .buildfont1 exch pop + } forall ] 1 index /FDepVector 3 -1 roll put + 3 -1 roll setglobal + 1 index exch .buildfont9 exch pop +} bind def + +1 { % CIDFontType 1 = FontType 10 + dup /FontType 10 put + 1 index exch .buildfont10 exch pop +} bind def + +2 { % CIDFontType 2 = FontType 11 + dup /FontType 11 put + 1 index exch .buildfont11 exch pop +} bind def + +end % .cidfonttypes + +% ---------------- Reading CIDFontType 0 files ---------------- % + +30 dict begin + +% We add the following entries to the CIDFont dictionary, in addition to +% the ones documented by Adobe: +% ReadString - procedure for reading a string from the binary data +% SubrCache - dictionary for caching Subr arrays +% For CIDFonts where we read the data from disk incrementally: +% DataOffset - starting position of data in file +% (if data are in hex) OffsetMap - map from logical data positions to +% physical positions in file + +/StartData % <(Binary)|(Hex)> StartData - + % (currentdict is CID font dict) +{ % If we're loading a resource file, we can just save a + % pointer to the binary data and load it incrementally. + % Check for this by opening the resource file, + % positioning it to currentfile's position plus the + % data length, and checking for %%EndData. + mark + { currentfile fileposition + CIDFontName 100 string ResourceFileName (r) file + mark + { % Stack: (Binary)|(Hex) length -mark- pos resfile + % -mark- + 5 index (Hex) eq + { 1 index 3 index setfileposition + 1 index 5 index .skiphex + %**************** SKIP > AND WHITESPACE SOMEHOW + } + { 1 index 3 index 6 index add setfileposition + } + ifelse + 1 index 9 string readstring pop (%%EndData) ne { stop } if + } + .internalstopped { cleartomark closefile stop } if + pop % pop the mark + } + .internalstopped + { % File is not positionable, load the data now. + cleartomark exch (Hex) eq + { { currentfile exch readhexstring pop } } + { { currentfile exch readstring pop } } + ifelse /ReadString exch def + dup 65535 le + { string ReadString + } + { mark exch + { dup 0 eq { pop exit } if + dup 65535 min dup string ReadString + 3 1 roll sub + } + loop ] + } + ifelse + /GlyphData exch def + % If we were reading hex data, skip past the >. + /ReadString load 2 get { readhexstring } 0 get eq { + currentfile 0 (>) /SubFileDecode filter dup flushfile closefile + } if + /.vmreadstring cvx + } + { % File is positionable, just save a pointer. + % Stack: (Binary)|(Hex) length -mark- pos file + 4 1 roll + /DataOffset exch def + pop /GlyphData exch def + exch (Hex) eq + { % Hex data, build the offset map. + .buildoffsetmap + /.hexreadstring + } + { % Binary data, just skip over it. + currentfile DataOffset GlyphData add setfileposition + /.binaryreadstring + } + ifelse cvx + 2 packedarray cvx + } + ifelse /ReadString exch def + /SubrCache 10 dict def + CIDFontName currentdict /CIDFont defineresource pop + end % CID font dict + end % resource category dict +} bind def + +% Skip a given distance in an ASCIIHex encoded file. We use this at +% rendering time as well. +/.skiphex % .skiphex - +{ exch /ASCIIHexDecode filter dup 3 -1 roll () /SubFileDecode filter + dup flushfile closefile closefile +} bind def + +% Build the map from logical offsets to physical offsets in ASCIIHex +% encoded data. +/.buildoffsetmap +{ /OffsetMap GlyphData 256 idiv 8000 min array def + 2 dict begin + /block GlyphData OffsetMap length idiv def + 0 1 OffsetMap length 1 sub + { OffsetMap exch currentfile fileposition put + currentfile block .skiphex + } + for + GlyphData block mod dup 0 eq + { pop } + { currentfile exch .skiphex } + ifelse + end % scratch dict +} bind def + +currentdict end + +% ---------------- Rendering ---------------- % + +% ------ Generic ------ % + +% Read a string at a given offset in a "file" (binary file, ASCII hex file, +% or GlyphData in RAM). +/.binaryreadstring % .binaryreadstring + { dup 4 -1 roll DataOffset add setfileposition exch readstring pop + } bind def +/.hexreadstring % .hexreadstring +{ % Use the OffsetMap to get to the block of hex data, + % then skip to the correct position by reading. + GlyphData OffsetMap length idiv + % Stack: pos string file blocklen + 3 index 1 index idiv OffsetMap exch get + 2 index exch setfileposition + % Skip the next (pos % blocklen) hex bytes. + 4 -1 roll exch mod 1 index exch .skiphex + % Stack: string file + exch readhexstring pop +} bind def +/.vmreadstring % .vmreadstring +{ GlyphData .stringsreadstring +} bind def +/.stringsreadstring % .stringsreadstring + % +{ dup type /stringtype eq + { 3 1 roll length getinterval + } + { { % Stack: pos string glyphdata + dup 0 get length dup 4 index gt { exit } if + 4 -1 roll exch sub 3 1 roll + dup length 1 sub 1 exch getinterval + } + loop + % Stack: pos string glyphdata glyphdata[0]length + % We know no request can span more than 2 strings. + 3 index 3 index length add 1 index le + { % Request fits in a single string: just return a substring. + pop 0 get 3 1 roll length getinterval + } + { % Request spans 2 strings. Copy the first part. + 1 index 0 get 4 index 3 -1 roll 1 index sub getinterval + 2 index copy + % Copy the second part. + % Stack: pos str glyphdata str1 + length exch 1 get 0 3 index length + 3 index sub getinterval 2 index 3 1 roll putinterval + exch pop + } + ifelse + } + ifelse +} bind def + +% Interpret a byte string as a (big-endian) integer. +/.cvbsi % .cvbsi +{ 0 exch { exch 8 bitshift add } forall +} bind def + +% Read an integer from binary data. +/.readint % .readint +{ string ReadString .cvbsi +} bind def + +% Read the glyph data for a given CID. The CIDFont is currentdict. +% Note that the data must be read into the same VM as the CharStrings +% dictionary of the selected subfont. +/.readglyphdata { % .readglyphdata + currentdict /GlyphDirectory .knownget { + dup type /arraytype eq { + 1 index exch get + } { + 1 index exch .knownget not { null } if + } ifelse + dup null eq { + FDepVector 0 get exch + } { + FDBytes 0 eq { + FDepVector 0 get exch + } { + % Note: FDBytes > 1 is not supported. + dup 0 get FDepVector exch get + exch dup length 1 sub 1 exch getinterval + } ifelse + } ifelse + } { + FDBytes GDBytes add mul CIDMapOffset add + dup FDBytes .readint exch + FDBytes add dup GDBytes .readint + exch GDBytes add FDBytes add GDBytes .readint + % Stack: fd pos nextpos + 1 index sub dup 0 eq { + pop pop pop FDepVector 0 get null + } { + % Stack: fd pos len + FDepVector 4 -1 roll get + dup /CharStrings get gcheck .currentglobal exch .setglobal + % Stack: pos len subfont global + 4 2 roll string ReadString exch .setglobal + } ifelse + } ifelse +} bind def + +% ------ CIDFontType 0 ------ % + +% Read some Subrs for the current Type 1 subfont. +% The subfont's Private dict is currentdict; the CIDFont itself is the +% next dictionary on the stack. +/.readsubrs { % .readsubrs + 1 SubrCount 1 sub { + dup SDBytes mul SubrMapOffset add + dup SDBytes .readint exch SDBytes add SDBytes .readint + 1 index sub string ReadString 2 index 3 1 roll put + } for +} bind def + +% Ensure that all the Subrs for the current Type 1 subfont are loaded. +% The subfont's Private dict is currentdict; the CIDFont itself is the +% next dictionary on the stack. +/.loadsubrs { + currentdict /SubrMapOffset .knownget { + Subrs 0 get null ne { + pop % We've already loaded the Subrs. + } { + currentglobal exch currentdict gcheck setglobal + SubrCache 1 index .knownget { + % We've already loaded some Subrs at this offset. + % Make sure we've got as many as we need. + dup length SubrCount lt { + % We need to load more. + SubrCount array exch 1 index copy length .readsubrs + SubrCache 3 -1 roll 2 index put + } if + } { + % We haven't loaded any Subrs at this offset yet. + SubrCount array 0 .readsubrs + SubrCache 3 -1 roll 2 index put + } ifelse + Subrs copy pop setglobal + } ifelse + } if +} bind def + +% BuildGlyph procedure for CIDFontType 0. +% ****** WHY NOT USE .type1execchar FOR THIS? ****** +% The name %Type9BuildGlyph is known to the interpreter. +/.cid0buildstring 10 string def +(%Type9BuildGlyph) cvn { % %Type9BuildGlyph - + .currentglobal 3 1 roll 1 index gcheck .setglobal + 1 index begin + dup .readglyphdata dup null eq + { %**** HANDLE NOTDEF **** + } + if + % Stack: cidfont cid subfont charstring +dup null eq { pop pop pop pop } { %**** WRONG **** + 4 -1 roll pop + exch dup /Private get begin .loadsubrs end + 3 -1 roll //.cid0buildstring cvs cvn 3 1 roll + dup /CharStrings get 3 index 4 -1 roll put + setfont + 1000 0 setcharwidth %**** WRONG **** + 0 0 moveto glyphshow +} ifelse %**** WRONG **** + end + .setglobal +} bind def + +% ------ CIDFontType 2 ------ % + +% BuildGlyph procedure for CIDFontType 2. +% ****** ADD THE OUTLINE STRING AS AN ARGUMENT TO .type42execchar. ****** +% The name %Type11BuildGlyph is known to the interpreter. +(%Type11BuildGlyph) cvn { % %Type11BuildGlyph - + .currentglobal 3 1 roll 1 index gcheck .setglobal + 1 index begin + % We must be prepared for out-of-range CIDs. + dup GDBytes mul GDBytes string CIDMap + mark 4 1 roll { .stringsreadstring } .internalstopped { + %**** 0 IS WRONG + cleartomark 0 GDBytes string CIDMap .stringsreadstring + } { + exch pop + } ifelse .cvbsi + % Stack: cidfont cid glyphindex +%**************** GlyphDirectory is not supported yet. +( + currentdict /GlyphDirectory .knownget +) pop false + { dup type /arraytype eq + { 1 index exch get } + { 1 index exch .knownget not { null } if } + ifelse + dup null eq + { %**** HANDLE NOTDEF + } + if + 1 index exch .type42execchar + } + { 1 index exch .type42execchar + } + ifelse + end + .setglobal +} bind def + +% ---------------- Define resources ---------------- % + +languagelevel exch 2 .setlanguagelevel + +% Define the CIDInit ProcSet resource. +% The ProcSet dictionary is still on the stack. + +/CMap /Generic /Category findresource dup length dict .copydict +/Category defineresource pop + % We might have loaded CMap support already. +/CIDInit /ProcSet 2 copy resourcestatus { + pop pop findresource dup length 4 index length add dict .copydict + 4 -1 roll exch .copydict +} { + 3 -1 roll +} ifelse exch defineresource pop + +% Define the CIDFont resource category. +% We break out .buildcidfont because it appears that at least for +% Type 32 (CIDFontType 4) fonts, the font can be registered in the Font +% category with only a CIDFontType and no FontType. +/.buildcidfont { % .buildcidfont + % + dup /CIDFontType get //.cidfonttypes exch get exec +} odef + +/CIDFont /Generic /Category findresource dup length dict .copydict +dup /InstanceType /dicttype put +dup /DefineResource { + .buildcidfont + /Generic /Category findresource /DefineResource get exec +} put +/Category defineresource pop + +% Add the new FontType resources. + +9 1 11 { dup /FontType defineresource pop } for + +% Add the new FMapType resource. + +9 dup /FMapType defineresource pop + +% Define the CIDMap resource category. +% These aren't documented, but it's clear what they are for: +% to give names to CIDMaps for CIDFontType 2 fonts. + +/CIDMap /Generic /Category findresource dup length dict .copydict +dup /.CheckResource { + % Allow either a string or an array of strings. + dup type dup /stringtype eq + { pop true + } + { dup /arraytype eq exch /packedarraytype eq or + { true exch { type /stringtype ne { pop false exit } if } forall + } + { false + } + ifelse + } + ifelse +} bind put +/Category defineresource pop + +.setlanguagelevel diff --git a/pstoraster/gs_cmap.ps b/pstoraster/gs_cmap.ps new file mode 100644 index 0000000000..e2ce96d65f --- /dev/null +++ b/pstoraster/gs_cmap.ps @@ -0,0 +1,256 @@ +% Copyright (C) 1995, 1996, 1997 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_cmap.ps 956 2000-03-08 23:15:43Z mike $ +% ProcSet for implementing CMap resources. +% When this is run, systemdict is still writable. + +% NOTE: Rearranged fonts are not implemented yet. + +% ---------------- Public operators ---------------- % + +% composefont doesn't appear in CMap files -- it's documented in +% the "PostScript Language Reference Manual Supplement". +/composefont { % composefont + 10 dict begin + /CMap 2 index dup type /dicttype ne { /CMap findresource } if def + /Encoding [ 0 1 4 index length 1 sub { } for ] def + /FDepVector [ 2 index { + dup type /dicttype ne { + dup /CIDFont resourcestatus { + pop pop /CIDFont findresource + } { + /Font findresource + } ifelse + } if + } forall ] readonly def + /FMapType 9 def + /FontMatrix matrix def + /FontName 3 index def + /CMap load /WMode .knownget { /WMode exch def } if + /FontType 0 def + pop pop currentdict end /Font defineresource +} bind odef + +% ---------------- CMap operators ---------------- % + +30 dict begin + +% Our internal .CodeMaps structure is an array of two arrays: array 0 +% is the map for defined characters, array 1 is the map for notdefs. +% Both are multi-level arrays indexed by the successive bytes of the +% character code. Each value is either a sub-array, null, a character name, +% a CID (an integer), or a character code (expressed as a byte string). +% All of the arrays are read-only after they have been built. +% +% Note that the code in zfcmap.c that constructs the C structures from +% the PostScript structures has intimate knowledge of the above format. + +/.getmap { .CodeMaps exch get } bind def +/.putmap { .CodeMaps exch 3 -1 roll put } bind def + +% ------ Font-level operators ------ % + +/begincmap % - begincmap - + { /.CodeMaps [256 array 256 array] def + } bind def +/endcmap % - endcmap - + { /.CodeMaps .CodeMaps .endmap def + /CodeMap null def % for .buildcmap + currentdict end .buildcmap begin + } bind def + +/begincodespacerange % begincodespacerange - + { pop mark + } bind def +/endcodespacerange % ... endcodespacerange - + { counttomark 2 idiv + { .CodeMaps { 3 copy .addcodespacerange pop } forall pop pop + } repeat pop + } bind def + +/.addcodespacerange % .addcodespacerange - + { 2 index length 1 eq + { 2 { 3 -1 roll 0 get } repeat 1 exch + { 2 copy 0 put pop } for pop + } + { 2 index 0 get 1 3 index 0 get + 6 -2 roll + 2 { 1 1 index length 1 sub getinterval 6 1 roll } repeat + % Stack: lo hi map lo0 1 hi0 + { 2 copy get null eq { 2 copy 256 array put } if + 4 copy get .addcodespacerange pop + } + for pop pop pop + } + ifelse + } bind def +/.endmap % .endmap + { dup type /arraytype eq { dup { .endmap exch } forall astore readonly } if + } bind def + +/usecmap % usecmap - + { /CMap findresource + dup length dict .copydict + currentdict end exch .copydict begin + } bind def + +% ------ Rearranged font operators ------ % + +/beginrearrangedfont % beginrearrangedfont - + { (NOT IMPLEMENTED YET.\n) print flush + } bind def +/endrearrangedfont % - endrearrangedfont - + { (NOT IMPLEMENTED YET.\n) print flush + } bind def + +/usefont % usefont - + { (NOT IMPLEMENTED YET.\n) print flush + } bind def + +/beginusematrix % beginusematrix - + { (NOT IMPLEMENTED YET.\n) print flush + } bind def +/endusematrix % endusematrix - + { (NOT IMPLEMENTED YET.\n) print flush + } bind def + +% ------ Character name/code selector operators ------ % + +/beginbfchar % beginbfchar - + { pop mark + } bind def +/endbfchar % ... endbfchar + { 0 .getmap .endmapchar 0 .putmap + } bind def + +/beginbfrange % beginbfrange - + { pop mark + } bind def +/endbfrange % ... + % endbfrange - + { 0 .getmap counttomark 3 idiv { .addbfrange } repeat 0 .putmap pop + } bind def + +/.addbfrange % + % .addbfrange + { 1 index type /stringtype eq + { { dup length string copy dup dup length 1 sub 2 copy get 1 add put } + exch .addmaprange + } + { 2 dict begin exch /codes 1 index def 0 get exch + { codes dup length 1 sub 1 exch getinterval /codes 1 index def + dup length 0 gt { 0 get } if + } + exch .addmaprange end + } + ifelse exch pop + } bind def + +% ------ CID selector operators ------ % + +/begincidchar % begincidchar - + { pop mark + } bind def +/endcidchar % ... endcidchar - + { 0 .getmap .endmapchar 0 .putmap + } bind def + +/begincidrange % begincidrange - + { pop mark + } bind def +/endcidrange % ... endcidrange - + { 0 .getmap counttomark 3 idiv { { 1 add } exch .addmaprange exch pop } repeat + 0 .putmap pop + } bind def + +/.endmapchar % -mark- ... .endmapchar - + { counttomark 2 idiv + { 2 index 3 1 roll { } exch .addmaprange exch pop + } repeat exch pop + } bind def + +/.addmaprange % + % .addcidrange + { % We may be updating a (partly) read-only map from another CMap. + % If so, implement copy-on-write. + dup wcheck not { dup length array copy } if + 4 index length 1 eq + { 2 { 5 -1 roll 0 get } repeat 1 exch + { % Stack: value proc map code + 2 copy 5 index put pop + 3 -1 roll 2 index exec 3 1 roll + } for + } + { 4 index 0 get 1 5 index 0 get + 8 -2 roll + 2 { 1 1 index length 1 sub getinterval 8 1 roll } repeat + % Stack: lo hi next proc map lo0 1 hi0 + { 6 copy get .addmaprange + % Stack: lo hi oldnext proc map i next submap + exch 6 1 roll 5 -1 roll pop + % Stack: lo hi next proc map i submap + 3 copy put pop pop + } + for 5 -2 roll pop pop + } + ifelse exch pop + } bind def + +% ------ notdef operators ------ % + +/beginnotdefchar % beginnotdefchar - + { pop mark + } bind def +/endnotdefchar % ... endnotdefchar - + { counttomark 2 idiv { 1 index exch .addnotdefrange } repeat pop + } bind def + +/beginnotdefrange % beginnotdefrange - + { pop mark + } bind def +/endnotdefrange % ... endnotdefrange - + { counttomark 3 idiv { .addnotdefrange } repeat pop + } bind def + +/.addnotdefrange % .addnotdefrange - + { { } 1 .getmap .addmaprange 1 .putmap pop + } bind def + +% ---------------- Resource category definition ---------------- % + +currentdict end + +languagelevel exch 2 .setlanguagelevel + +/CMap /Generic /Category findresource dup length dict .copydict +/Category defineresource pop + % We might have loaded CID font support already. +/CIDInit /ProcSet 2 copy { findresource } .internalstopped + % An interior `stopped' might have reset VM allocation to local. +true .setglobal + { pop pop 3 -1 roll } + { dup length 4 index length add dict .copydict 4 -1 roll exch .copydict } +ifelse exch defineresource pop + +.setlanguagelevel diff --git a/pstoraster/gs_cmdl.ps b/pstoraster/gs_cmdl.ps new file mode 100644 index 0000000000..7293e09232 --- /dev/null +++ b/pstoraster/gs_cmdl.ps @@ -0,0 +1,188 @@ +% Copyright (C) 1994, 1996 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_cmdl.ps 956 2000-03-08 23:15:43Z mike $ +% Parse and execute the command line. +% C code handles the following switches: -h/-? -I -M -v + +/cmddict 50 dict def +cmddict begin + +% ---------------- Utility procedures ---------------- % + +% Get the next argument from the parsed argument list. +/nextarg % - nextarg true + % - nextarg false + { argv length 0 eq + { false } + { argv dup 0 get exch dup length 1 sub 1 exch getinterval /argv exch def } + ifelse + } bind def + +% Run a file, under job control if implemented. +/runjob % runjob - + { end % cmddict + /startjob where { pop false () startjob pop } + run + //cmddict begin + } bind def +/runfilejob % runfilejob - + { findlibfile { exch pop } { (r) file } runjob + } bind def + +% Expand arguments. Free variables: expand@. +/expandarg % expandarg + { dup () eq + { pop + } + { dup dup (--) eq exch (-+) eq or + { pop /expand@ false def + } + { expand@ { (@) anchorsearch } { false } ifelse + { pop findlibfile + { exch pop } + { (r) file } % let the error happen + expandargfile + } + if + } + ifelse + } + } bind def +/expandargfile % expandargfile + { [ exch cvlit + { token not { exit } if + dup type /stringtype ne { =string cvs dup length string copy } if + expandarg + } + /exec cvx + ] cvx loop + } bind def + +% ---------------- Recognized switches ---------------- % + +% Switches with arguments are defined as ; +% switches without arguments are defined as -. + +% Switches without arguments +/-- + { nextarg not + { (-- and -+ require a file name.\n) print flush } + { //systemdict /ARGUMENTS argv put /argv [] def runjob } + ifelse + } bind def +/-+ /-- load def +/-@ /-- load def +/-A { (@) Z } bind def +/-c + { { argv length 0 eq { exit } if + argv 0 get (-) anchorsearch { pop pop exit } if + pop nextarg token + { exch pop % Probably should check for empty. + end exec //cmddict begin + } + if + } + loop + } bind def +/-e { (#) Z } bind def +/-E /-e load def +/-f { } def +/-q { //systemdict /QUIET true put } bind def + +% Switches with arguments +/d + { (=) search not { (#) search not { () exch dup } if } if + exch pop cvn dup where + { pop (Redefining ) print print ( is not allowed.\n) print flush pop } + { exch token + { exch pop } % Probably should check for empty. + { true } + ifelse + //systemdict 3 1 roll put + } + ifelse + } bind def +/D /d load def +/f { dup length 0 ne { runfilejob } if } bind def +/g + { (x) search { cvi pop exch cvi } { cvi dup } ifelse + //systemdict begin /DEVICEHEIGHT exch def /DEVICEWIDTH exch def end + } bind def +/r + { (x) search { cvr pop exch cvr } { cvr dup } ifelse + //systemdict begin /DEVICEYRESOLUTION exch def /DEVICEXRESOLUTION exch def end + } bind def +/s + { (=) search not { (#) search not { () exch dup } if } if + exch pop cvn dup where { pop dup load } { () } ifelse + type /stringtype ne + { (Redefining ) print print ( is not allowed.\n) print flush pop } + { exch //systemdict 3 1 roll put } + ifelse + } bind def +/S /s load def +/Z { true .setdebug } bind def + +% ---------------- Main program ---------------- % + +% We process the command line in two passes. In the first pass, +% we read and expand any @-files as necessary. The second pass +% does the real work. + +/cmdstart + { //cmddict begin + /expand@ true def + [ + % Process the GS_OPTIONS environment variable. + (GS_OPTIONS) getenv { 0 () /SubFileDecode filter expandargfile } if + % Process the actual command line. + .getargv { expandarg } forall + ] readonly /argv exch def + % Now interpret the commands. + { nextarg not { exit } if + dup 0 get (-) 0 get eq + { dup length 1 eq + { pop (%stdin) (r) file runjob + } + { dup length 2 gt + { dup dup length 2 sub 2 exch getinterval exch 1 1 getinterval } + if currentdict .knownget + { exec + } + { (Ignoring unknown switch ) print + dup length 1 eq { (-) print print } if print + (\n) print flush + } + ifelse + } + ifelse + } + { runfilejob + } + ifelse + } + loop end + } bind def + +end % cmddict diff --git a/pstoraster/gs_dbt_e.ps b/pstoraster/gs_dbt_e.ps new file mode 100644 index 0000000000..b31a392281 --- /dev/null +++ b/pstoraster/gs_dbt_e.ps @@ -0,0 +1,67 @@ +% Copyright (C) 1993, 1994 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_dbt_e.ps 956 2000-03-08 23:15:43Z mike $ +% Define the Dingbats encoding vector. +/currentglobal where + { pop currentglobal { setglobal } true setglobal } + { { } } +ifelse +/DingbatsEncoding +% \000 + StandardEncoding 0 32 getinterval aload pop % /.notdef +% \040 + /space /a1 /a2 /a202 /a3 /a4 /a5 /a119 + /a118 /a117 /a11 /a12 /a13 /a14 /a15 /a16 + /a105 /a17 /a18 /a19 /a20 /a21 /a22 /a23 + /a24 /a25 /a26 /a27 /a28 /a6 /a7 /a8 +% \100 + /a9 /a10 /a29 /a30 /a31 /a32 /a33 /a34 + /a35 /a36 /a37 /a38 /a39 /a40 /a41 /a42 + /a43 /a44 /a45 /a46 /a47 /a48 /a49 /a50 + /a51 /a52 /a53 /a54 /a55 /a56 /a57 /a58 +% \140 + /a59 /a60 /a61 /a62 /a63 /a64 /a65 /a66 + /a67 /a68 /a69 /a70 /a71 /a72 /a73 /a74 + /a203 /a75 /a204 /a76 /a77 /a78 /a79 /a81 + /a82 /a83 /a84 /a97 /a98 /a99 /a100 /.notdef +% \200 + StandardEncoding 0 32 getinterval aload pop % /.notdef +% \240 + /.notdef /a101 /a102 /a103 /a104 /a106 /a107 /a108 + /a112 /a111 /a110 /a109 /a120 /a121 /a122 /a123 + /a124 /a125 /a126 /a127 /a128 /a129 /a130 /a131 + /a132 /a133 /a134 /a135 /a136 /a137 /a138 /a139 +% \300 + /a140 /a141 /a142 /a143 /a144 /a145 /a146 /a147 + /a148 /a149 /a150 /a151 /a152 /a153 /a154 /a155 + /a156 /a157 /a158 /a159 /a160 /a161 /a163 /a164 + /a196 /a165 /a192 /a166 /a167 /a168 /a169 /a170 +% \340 + /a171 /a172 /a173 /a162 /a174 /a175 /a176 /a177 + /a178 /a179 /a193 /a180 /a199 /a181 /a200 /a182 + /.notdef /a201 /a183 /a184 /a197 /a185 /a194 /a198 + /a186 /a195 /a187 /a188 /a189 /a190 /a191 /.notdef +256 packedarray .defineencoding +3 DingbatsEncoding .registerencoding +exec diff --git a/pstoraster/gs_diskf.ps b/pstoraster/gs_diskf.ps new file mode 100644 index 0000000000..eedd980826 --- /dev/null +++ b/pstoraster/gs_diskf.ps @@ -0,0 +1,232 @@ +% Copyright (C) 1996 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_diskf.ps 956 2000-03-08 23:15:43Z mike $ +% Support for converting Type 1 fonts without eexec encryption to +% Type 4 fonts that load individual character outlines on demand. + +% If DISKFONTS is true, we load individual CharStrings as they are needed. +% (This is intended primarily for machines with very small memories.) +% Initially, the character definition is the file position of the definition; +% this gets replaced with the actual CharString. +% Note that if we are loading characters lazily, CharStrings is writable. + +% _Cstring must be long enough to hold the longest CharString for +% a character defined using seac. This is lenIV + 4 * 5 (for the operands +% of sbw, assuming div is not used) + 2 (for sbw) + 3 * 5 (for the operands +% of seac other than the character codes) + 2 * 2 (for the character codes) +% + 2 (for seac), i.e., lenIV + 43. + +/_Cstring 60 string def + +% When we initially load the font, we call +% cskip_C +% to skip over each character definition and return the file position instead. +% This substitutes for the procedure +% string currentfile exch read[hex]string pop +% [encrypt] +% What we actually store in the CharString is fileposition * 1000 + length, +% negated if the string is stored in binary form. + +/cskip_C + { exch dup 1000 ge 3 index type /nametype ne or + { % This is a Subrs string, or the string is so long we can't represent + % its length. Load it now. + exch exec + } + { % Record the position and length, and skip the string. + dup currentfile fileposition 1000 mul add + 2 index 3 get /readstring cvx eq { neg } if + 3 1 roll + dup _Cstring length idiv + { currentfile _Cstring 3 index 3 get exec pop pop + } repeat + _Cstring length mod _Cstring exch 0 exch getinterval + currentfile exch 3 -1 roll 3 get exec pop pop + } + ifelse + } bind def + +% Load a CharString from the file. The font is the top entry +% on the dictionary stack. +/load_C % load_C - + { dup abs 1000 idiv FontFile exch setfileposition + CharStrings 3 1 roll + .currentglobal CharStrings .gcheck .setglobal exch + dup 0 lt + { neg 1000 mod string FontFile exch readstring } + { 1000 mod string FontFile exch readhexstring } + ifelse pop + exch .setglobal +% If the CharStrings aren't encrypted on the file, encrypt now. + Private /-| get 0 get + dup type /nametype ne + { dup length 5 sub 5 exch getinterval exec } + { pop } + ifelse dup 4 1 roll put +% If the character is defined with seac, load its components now. + mark exch seac_C + counttomark + { StandardEncoding exch get dup CharStrings exch get + dup type /integertype eq { load_C } { pop pop } ifelse + } repeat + pop % the mark + } bind def + +/seac_C % seac_C ..or nothing.. + { dup length _Cstring length le + { 4330 exch _Cstring .type1decrypt exch pop + dup dup length 2 sub 2 getinterval <0c06> eq % seac + { dup length + Private /lenIV known { Private /lenIV get } { 4 } ifelse + exch 1 index sub getinterval +% Parse the string just enough to extract the seac information. +% We assume that the only possible operators are hsbw, sbw, and seac, +% and that there are no 5-byte numbers. + mark 0 3 -1 roll + { exch + { { dup 32 lt + { pop 0 } + { dup 247 lt + { 139 sub 0 } + { dup 251 lt + { 247 sub 256 mul 108 add 1 1 } + { 251 sub -256 mul -108 add -1 1 } + ifelse + } + ifelse + } + ifelse + } % 0 + { mul add 0 } % 1 + } + exch get exec + } + forall pop + counttomark 1 add 2 roll cleartomark % pop all but achar bchar + } + { pop % not seac + } + ifelse + } + { pop % punt + } + ifelse + } bind def + +% Define replacement procedures for loading fonts. +% If DISKFONTS is true and the body of the font is not encrypted with eexec: +% - Prevent the CharStrings from being made read-only. +% - Substitute a different CharString-reading procedure. +% (eexec disables this because the implicit 'systemdict begin' hides +% the redefinitions that make the scheme work.) +% We assume that: +% - The magic procedures (-|, -!, |-, and |) are defined with +% executeonly or readonly; +% - The contents of the reading procedures are as defined in bdftops.ps; +% - The font includes the code +% /CharStrings readonly put +/.loadfontdict 6 dict def mark + /begin % push this dict after systemdict + { dup begin + //systemdict eq { //.loadfontdict begin } if + } bind + /end % match begin + { currentdict end + //.loadfontdict eq currentdict //systemdict eq and { end } if + } bind + /dict % leave room for FontFile, BuildChar, BuildGlyph + { 3 add dict + } bind + /executeonly % for reading procedures + { readonly + } + /noaccess % for Subrs strings and Private dictionary + { readonly + } + /readonly % for procedures and CharStrings dictionary + { % We want to take the following non-standard actions here: + % - If the operand is the CharStrings dictionary, do nothing; + % - If the operand is a number (a file position replacing the + % actual CharString), do nothing; + % - If the operand is either of the reading procedures (-| or -!), + % substitute a different one. + dup type /dicttype eq % CharStrings or Private + count 2 gt and + { 1 index /CharStrings ne { readonly } if } + { dup type /arraytype eq % procedure or data array + { dup length 5 ge 1 index xcheck and + { dup 0 get /string eq + 1 index 1 get /currentfile eq and + 1 index 2 get /exch eq and + 1 index 3 get dup /readstring eq exch /readhexstring eq or and + 1 index 4 get /pop eq and + { /cskip_C cvx 2 packedarray cvx + } + { readonly + } + ifelse + } + { readonly + } + ifelse + } + { dup type /stringtype eq % must be a Subr string + { readonly } + if + } + ifelse + } + ifelse + } bind + /definefont % to insert BuildChar/Glyph and change FontType + { dup /FontType get 1 eq + { dup /FontType 4 put + dup /BuildChar /build_C load put + dup /BuildGlyph /build_C load put + } + if definefont + } bind +counttomark 2 idiv { .loadfontdict 3 1 roll put } repeat pop +.loadfontdict readonly pop + +% Define the BuildChar and BuildGlyph procedures for modified fonts. +% A single procedure serves for both. +/build_C % build_C - + { 1 index begin + dup dup type /integertype eq { Encoding exch get } if + % Stack: font code|name name + dup CharStrings exch .knownget not + { 2 copy eq { exch pop /.notdef exch } if + QUIET not + { (Substituting .notdef for ) print = flush } + { pop } + ifelse + /.notdef CharStrings /.notdef get + } if + % Stack: font code|name name charstring + dup type /integertype eq + { load_C end build_C } + { end .type1execchar } + ifelse + } bind def diff --git a/pstoraster/gs_dpnxt.ps b/pstoraster/gs_dpnxt.ps new file mode 100644 index 0000000000..2d2573ff7d --- /dev/null +++ b/pstoraster/gs_dpnxt.ps @@ -0,0 +1,120 @@ +% Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_dpnxt.ps 956 2000-03-08 23:15:43Z mike $ +% gs_dpnxt.ps +% NeXT Display PostScript extensions + +% Define the operation values for compositing. These must match the values +% in gsdpnext.h, which also are the ones from the NeXT documentation. +% We put them in systemdict, which seems like as good a place as any. +mark + /Clear /Copy /Sover /Sin /Sout /Satop /Dover /Din /Dout /Datop /Xor + /PlusD /PlusL /Highlight % not sure about Highlight +counttomark { counttomark 1 sub def } repeat pop + +% We implement readimage and sizeimage using the following 3 otherwise +% undocumented lower-level operators: +% +% .sizeimagebox +% +% +% - .sizeimageparams +% +% +% .getbitsrect +% +% NOTE: These operators are subject to change without notice! + +% Implement readimage using .getbitsrect. Experimentation on a NeXT system +% shows that the data is always returned in order of increasing device Y, +% regardless of the CTM. +% +% Note that we can't make stack protection work for this operator, +% because it must remove its operands from the stack before calling +% the supplied procedure(s). + +/readimage { % [... ] + % readimage - + .sizeimageparams exch { + % multiproc = true. If N > 1, store the procedures in an array. + exch pop 1 index { 1 add } if + % Stack: ... string alpha? nprocs + dup 1 eq { + pop false % only 1 procedure, multiproc is irrelevant + } { + dup array 4 1 roll 3 add 2 roll astore 3 1 roll true + } ifelse + } { + % multiproc = false. + pop pop false + } ifelse + % Map the rectangle to device coordinates. + % Stack: x y w h proc(s) str alpha? multi? + 8 -4 roll matrix .sizeimagebox pop 8 4 roll + % Make sure we allocate the operand array in local VM + % to avoid a possible invalidaccess. + .currentglobal false .setglobal 9 1 roll + exch { 1 } { 0 } ifelse exch % alpha is last, if present + exch 4 1 roll 8 array astore exch .setglobal + { % Read out a block of scan lines and pass them to the procedure. + % Stack: [x y w h alpha? proc(s) str multi?] -- we must consume this. + dup 3 get 0 eq { pop exit } if + aload 9 1 roll pop exch pop currentdevice 7 1 roll + % Always read out the data as standard (not native) pixels. + .sizeimageparams pop pop exch .getbitsrect + % Stack: [x y w h alpha? proc(s) str multi?] hread substr + 3 -1 roll + % Stack: hread substr [x y w h alpha? proc(s) str multi?] + dup 1 2 copy get 5 index add put + % Stack: hread substr [x y' w h alpha? proc(s) str multi?] + dup 3 2 copy get 6 -1 roll sub put + % Stack: substr [x y' w h' alpha? proc(s) str multi?] + dup 5 get exch 7 get { + % multiproc = true, pass each plane to a different procedure. + % Stack: substr procs + 0 1 2 index length 1 sub { + % Push 1 plane and its procedure under the top 2 elements. + % Stack: ... substr procs plane# + 2 index length 2 index length idiv % bytes per plane + dup 2 index mul exch + % Stack: ... substr procs plane# start length + 4 index 3 1 roll getinterval 4 1 roll + 2 copy get 4 1 roll pop + } for + exch pop length 2 mul .execn + } { + % multiproc = false, just call the procedure. + exec + } ifelse + } //systemdict /exec get 3 packedarray cvx loop +} bind odef + +% Implement sizeimage using lower-level operators. + +/sizeimage { % sizeimage + % + % + .sizeimagebox 5 -2 roll pop pop + .sizeimageparams 3 -1 roll 4 1 roll +} bind odef diff --git a/pstoraster/gs_dps.ps b/pstoraster/gs_dps.ps new file mode 100644 index 0000000000..354d8155b5 --- /dev/null +++ b/pstoraster/gs_dps.ps @@ -0,0 +1,205 @@ +% Copyright (C) 1997, 1998 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_dps.ps 956 2000-03-08 23:15:43Z mike $ +% Initialization file for Display PostScript functions. + +% ------ Contexts ------ % + +% To create a context with private local VM, we use the .localfork +% operator to actually create the context, the new VM, and an empty +% userdict, and then we call the .initlocaldicts procedure to make +% local copies of the initial contents of the dictionaries in local VM. +% savedlocaldicts in systemdict is a global read-only dictionary whose +% elements are global read-only copies of these initial contents; +% we just copy its elements into local VM and install them in systemdict. +% userdict and internaldict require special handling. + +% Switching between contexts with different local VMs requires +% changing the bindings in systemdict that reference local objects. +% For this purpose, each userdict has an entry called localdicts +% which holds the local copies of the elements of savedlocaldicts, +% plus internaldict. The context switching code in the interpreter +% effectively copies this dictionary into systemdict. +% NOTE: the name localdicts is known to the interpreter. + +% Switching between contexts also requires resetting the user parameters. +% The interpreter records the value of userparams (a local dictionary +% referenced from systemdict) for each context, and uses it for this. +% See gs_lev2.ps for more details. +% NOTE: the name userparams is known to the interpreter. + +% Save copies of local dictionaries at the end of system initialization. +% Also save the initial gstate. +/.savelocalstate { + .currentglobal true .setglobal + //systemdict /savedlocaldicts mark //systemdict { + dup gcheck { + pop pop + } { + dup type /dicttype eq { + % Save a copy of this dictionary in global VM. + dup maxlength dict .copydict readonly + } { + pop pop + } ifelse + } ifelse + } forall .dicttomark readonly .forceput % systemdict is read-only + % Create localdicts for the current context. + false .setglobal + userdict /localdicts mark savedlocaldicts { + pop dup load + } forall /internaldict dup load + .dicttomark readonly put + % Save a copy of the initial gstate. + true .setglobal + //systemdict /savedinitialgstate gstate readonly put + .setglobal +} .bind def + +% Initialize local dictionaries and gstate when creating a new context. +% Note that until this completes, we are in the anomalous situation of +% having systemdict point to dictionaries that are in a non-current +% local VM. Because of this, we turn off garbage collection temporarily. +/.copylocal { % .copylocal + % Copy a dictionary to the current (local) VM, + % and make it read-only if its current definition is. + dup maxlength dict .copydict + 1 index load wcheck not { readonly } if +} .bind def +% When this is called, the dictionary stack is in its initial state, +% and there is (anomalously) only one gstate on the gstate stack. +/.initlocaldicts { % - .initlocaldicts - + -2 vmreclaim + .currentglobal //systemdict begin + false .setglobal + % Since localdicts doesn't exist yet, references from + % systemdict to local objects won't get restored if + % a context switch happens in this code. Therefore, + % until localdicts is defined, we have to keep all our + % state on the operand stack. + + % Acquire userdict. + %****** WRONG IF NON-STANDARD INITIAL DSTACK ****** + countdictstack array dictstack + { dup gcheck not { exit } if pop } forall + % Create localdicts with a local copy of each dictionary, + % except for userdict and userparams, which just need + % to be filled in. + mark savedlocaldicts { + 1 index /userdict eq { + % Stack: userdict mark ... /userdict inituserdict + counttomark 1 add index exch .copydict + } { + 1 index /userparams eq { + % Stack: userparams mark ... /userparams inituserparams + userparams .copydict + } { + .copylocal + } ifelse + } ifelse + } forall /internaldict dup .makeinternaldict .makeoperator + .dicttomark readonly /localdicts exch put + % localdicts is now defined in userdict. + % Copy the definitions into systemdict. + localdicts { .forcedef } forall + % Set the user parameters. + userparams readonly .setuserparams + % Establish the initial gstate(s). + /savedinitialgstate .systemvar setgstate gsave + % Wrap up. + end .setglobal +} odef + +% Create a context with private local VM. +% The .localfork operator does all the work, but we must ensure that +% .initlocaldicts gets called when the new context starts up. +/localfork { % ... + % + % localfork + .currentglobal true .setglobal 3 index + dup dup xcheck + exch type dup /arraytype eq exch /packedarraytype eq or and not { + pop .setglobal /localfork cvx /typecheck signalerror + } if + {exec .initlocaldicts} aload pop + 3 1 roll 3 packedarray cvx + 4 1 roll 5 -1 roll pop .setglobal .localfork +} odef + +% Fork a context that shares VM. We still need to fill in userparams +% when the new context starts up. +/.postfork { % - .postfork - + % Initialize the user parameters. + savedlocaldicts /userparams get userparams .copydict readonly pop +} odef +/fork { % ... fork + .currentglobal false .setglobal 1 index + dup dup xcheck + exch type dup /arraytype eq exch /packedarraytype eq or and not { + pop .setglobal /fork cvx /typecheck signalerror + } if + {exec .postfork} aload pop + 3 1 roll 3 packedarray cvx + 3 1 roll exch pop .setglobal .fork +} odef + +% ------ Halftone phase ------ % + +/sethalftonephase { % sethalftonephase - + -1 2 index 2 index .setscreenphase pop pop +} odef +/currenthalftonephase { % - currenthalftonephase + 0 .currentscreenphase +} odef + +% ------ Device-source images ------ */ + +.imagetypes 2 /.image2 load put + +% ------ Device information ------ % + +/.deviceinfodict mark + /Colors null /GrayValues null /RedValues null /GreenValues null + /BlueValues null /ColorValues null +.dicttomark readonly def +/deviceinfo { % - deviceinfo + currentdevice //.deviceinfodict .getdeviceparams .dicttomark readonly +} odef + +% The current implementation allocates a 2-element array each time. +% Perhaps we should change this to 2 separate parameters for X and Y? +/.wtdict mark + /wtranslation null +.dicttomark readonly def +/wtranslation { % - wtranslation + currentdevice //.wtdict .getdeviceparams exch pop exch pop aload pop +} odef +currentdict /.wtdict .undef + +% ------ View clipping ------ % + +/rectviewclip { % rectviewclip - + % rectviewclip - + newpath .rectappend viewclip +} odef diff --git a/pstoraster/gs_dps1.ps b/pstoraster/gs_dps1.ps new file mode 100644 index 0000000000..f343b571a2 --- /dev/null +++ b/pstoraster/gs_dps1.ps @@ -0,0 +1,147 @@ +% Copyright (C) 1997 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_dps1.ps 956 2000-03-08 23:15:43Z mike $ +% Initialization file for most of the Display PostScript functions +% that are also included in Level 2. + +level2dict begin + +% ------ Virtual memory ------ % + +/currentshared /.currentglobal load def +/scheck /.gcheck load def +%****** FOLLOWING IS WRONG ****** +/shareddict currentdict /globaldict .knownget not { 20 dict } if def + +% Global and LocalFontDirectory must remain in systemdict +% even if we temporarily exit Level 2 mode. + +end % level2dict +systemdict begin + +/SharedFontDirectory .FontDirectory .gcheck + { .currentglobal false .setglobal + /LocalFontDirectory .FontDirectory dup maxlength dict copy + .forcedef % LocalFontDirectory is local, systemdict is global + .setglobal .FontDirectory + } + { /LocalFontDirectory .FontDirectory + .forcedef % LocalFontDirectory is local, systemdict is global + 50 dict + } +ifelse def + +end % systemdict +level2dict begin + +% setshared must rebind FontDirectory to the appropriate one of +% Local or SharedFontDirectory. + +/.setglobal % .setglobal - + { dup .setglobal + //systemdict /FontDirectory .currentglobal + { //SharedFontDirectory } + { /LocalFontDirectory .systemvar } % can't embed ref to local VM + ifelse .forceput pop % LocalFontDirectory is local, systemdict is global + } .bind odef % must bind .forceput and .setglobal + % even if NOBIND in effect +/setshared /.setglobal load def +.currentglobal setshared + +% See below for changes in save and restore. + +% ------ Fonts ------ % + +/selectfont % selectfont - + { 1 index findfont + 1 index dup type /arraytype eq { makefont } { scalefont } ifelse + setfont pop pop + } odef +% undefinefont has to take local/global VM into account. +/undefinefont % undefinefont - + { .FontDirectory 1 index .undef + .currentglobal + { % Current mode is global; delete from local directory too. + //systemdict /LocalFontDirectory .knownget + { 1 index .undef } + if + } + { % Current mode is local; if there was a shadowed global + % definition, copy it into the local directory. + //systemdict /SharedFontDirectory .knownget + { 1 index .knownget + { .FontDirectory 2 index 3 -1 roll put } + if + } + if + } + ifelse pop + } odef + +% If we load a font into global VM within an inner save, the restore +% will delete it from FontDirectory but not from SharedFontDirectory. +% We have to handle this by making restore copy missing entries from +% SharedFontDirectory to FontDirectory. Since this could slow down restore +% considerably, we define a new operator .dictcopynew for this purpose. +% Furthermore, if FAKEFONTS is in effect, we want global real fonts to +% override fake local ones. We handle this by brute force. +/restore % restore - + { dup //restore % bind even if NOBIND + /LocalFontDirectory .systemvar + FAKEFONTS + { mark + % We want to delete a fake font from the local directory + % iff the global directory now has no definition for it, + % or a non-fake definition. + 1 index dup + { % Stack: lfd mark lfd key ... lfd key value + length 1 gt + { % This is a real local definition; don't do anything. + pop + } + { % This is a fake local definition, check for global. + //SharedFontDirectory 1 index .knownget + { % A global definition exists, check for fake. + length 1 eq { pop } { 1 index } ifelse + } + { % No global definition, delete the local one. + 1 index + } + ifelse + } + ifelse + } forall + pop counttomark 2 idiv { .undef } repeat pop + } + if + //SharedFontDirectory exch .dictcopynew pop + .currentglobal .setglobal % Rebind FontDirectory according to current VM. + pop + } bind odef + +% ------ Miscellaneous ------ % + +/undef /.undef load def + +end % level2dict diff --git a/pstoraster/gs_dps2.ps b/pstoraster/gs_dps2.ps new file mode 100644 index 0000000000..e375505ab4 --- /dev/null +++ b/pstoraster/gs_dps2.ps @@ -0,0 +1,200 @@ +% Copyright (C) 1990, 1996, 1997 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_dps2.ps 956 2000-03-08 23:15:43Z mike $ +% Initialization file for basic Display PostScript functions +% that are also included in Level 2. + +level2dict begin + +% ------ Halftones ------ % + +/.makestackdict + { { counttomark -1 roll } forall .dicttomark + } bind def +/currenthalftone % - currenthalftone + { mark .currenthalftone + { { exch pop } % halftone + { /HalftoneType 1 % screen + { /Frequency /Angle /SpotFunction } + .makestackdict + } + { /HalftoneType 2 % colorscreen + { /RedFrequency /RedAngle /RedSpotFunction + /GreenFrequency /GreenAngle /GreenSpotFunction + /BlueFrequency /BlueAngle /BlueSpotFunction + /GrayFrequency /GrayAngle /GraySpotFunction + } + .makestackdict + } + } + exch get exec + } odef +% Define sethalftone so it converts all other types to type 5. +/.sethalftoneRGBV % + { 4 -1 roll exch { 1 index exch get exch } forall 15 1 roll + 14 -2 roll mark 15 1 roll { /Gray /Blue /Green /Red } + { % stack: v0 v1 v2 type keys comp + mark + 2 index 0 get 8 -1 roll + 4 index 1 get 9 -1 roll + 6 index 2 get 10 -1 roll + % stack: type keys comp mark k0 v0 k1 v1 k2 v2 + /HalftoneType 10 index .dicttomark + counttomark 2 roll + } + forall pop pop + /Default 1 index .dicttomark .sethalftone5 + } bind def +/sethalftone { % sethalftone - + % We must create the new dictionary in the same VM as the + % operand; otherwise, invalidaccess errors may occur. + .currentglobal 1 index dup gcheck .setglobal + dup /HalftoneType get 1 sub { + { mark /Default 2 index .dicttomark .sethalftone5 + } + { 1 { /Frequency /Angle /SpotFunction } + { /RedFrequency /RedAngle /RedSpotFunction + /GreenFrequency /GreenAngle /GreenSpotFunction + /BlueFrequency /BlueAngle /BlueSpotFunction + /GrayFrequency /GrayAngle /GraySpotFunction + } .sethalftoneRGBV + } + { mark /Default 2 index .dicttomark .sethalftone5 + } + { 3 { /Width /Height /Thresholds } + { /RedWidth /RedHeight /RedThresholds + /GreenWidth /GreenHeight /GreenThresholds + /BlueWidth /BlueHeight /BlueThresholds + /GrayWidth /GrayHeight /GrayThresholds + } .sethalftoneRGBV + } + { dup .sethalftone5 + } + } exch get exec .setglobal pop +} odef +% Redefine setscreen and setcolorscreen to recognize halftone dictionaries, +% and to insert the Frequency and Angle into Type 1 halftones, per +% Adobe TN 5085. +/.fixsethalftonescreen % .fix...screen + % + { dup dup /HalftoneType get 1 eq + { dup wcheck not { dup length .copydict } if + dup /Frequency 5 index put + dup /Angle 4 index put + } + if + } bind def +/setscreen % setscreen - + { dup type /dicttype eq + { .fixsethalftonescreen sethalftone pop pop pop } + { //setscreen } + ifelse + } odef +/setcolorscreen % setcolorscreen - + { dup type /dicttype eq + { .fixsethalftonescreen sethalftone 12 { pop } repeat } + { //setcolorscreen } + ifelse + } odef +% Redefine currentscreen and currentcolorscreen to extract the Frequency +% and Angle from Type 1 halftones, per Adobe TN 5085. +/.fixcurrenthalftonescreen % .fix... + { dup /HalftoneType get 1 eq + { dup /Frequency get 1 index /Angle get } + { 60 0 } + ifelse 3 2 roll + } bind def +/currentscreen % - currentscreen 60 0 + { .currenthalftone + { { .fixcurrenthalftonescreen } % halftone + { } % screen + { 12 3 roll 9 { pop } repeat % colorscreen + dup type /dicttype eq { .fixcurrenthalftonescreen } if + } + } + exch get exec + } odef +/currentcolorscreen % - currentcolorscreen (60 0 )*4 + { .currenthalftone + { { .fixcurrenthalftonescreen 3 copy 6 copy } % halftone + { 3 copy 6 copy } % screen + { } % colorscreen + } + exch get exec + } odef + +% ------ User objects ------ % + +/.localarray where { + pop +} { + /.localarray { + currentglobal false setglobal + exch array exch setglobal + } bind def +} ifelse +/.UserObjects { + .userdict /UserObjects +} odef +% In order to get proper error recovery behavior, we need to be careful +% not to pop any operands from the stack until we're done. +% The code below faithfully duplicates the apparent array-growing +% behavior of Adobe interpreters. +/defineuserobject { % defineuserobject - + .UserObjects .knownget { + length dup 3 index le { + % Stack: index value len + 2 index eq { 1 index 2 mul } { 1 index 1 add } ifelse + .localarray .UserObjects get + 1 index copy pop + .UserObjects 3 -1 roll put + } { + pop + } ifelse + } { + .UserObjects 3 index 1 add 10 .max .localarray put + } ifelse + .UserObjects get 2 index 2 index put pop pop +} odef +/execuserobject { % execuserobject - + .UserObjects get 1 index get exch pop exec +} odef +/undefineuserobject { % undefineuserobject - + .UserObjects get 1 index null put pop +} odef + +% ------ Cache control ------ % + +% Dummy definitions for cache control operators + +/ucachestatus { % - ucachestatus -mark- ? ? ? ? + mark 0 0 0 0 .userdict /.ucachesize .knownget not { 0 } if +} odef +/setucacheparams { % -mark- ... setucacheparams - + % Provoke an appropriate error if needed. + counttomark 1 lt { () 0 get } if + 0 or .userdict /.ucachesize 2 index 0 .max put cleartomark +} odef + +end % level2dict diff --git a/pstoraster/gs_epsf.ps b/pstoraster/gs_epsf.ps new file mode 100644 index 0000000000..fcccb3e330 --- /dev/null +++ b/pstoraster/gs_epsf.ps @@ -0,0 +1,67 @@ +% Copyright (C) 1989, 1996 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_epsf.ps 956 2000-03-08 23:15:43Z mike $ +% Allow the interpreter to recognize MS-DOS EPSF file headers, and skip to +% the PostScript section of the file. + +/.runnoepsf /run load def +/.epsfheader def +/run + { dup type /filetype ne { (r) file } if + % Check for MS-DOS EPSF file (see Red Book p. 729). + true exch 0 1 3 + { % Stack: true file index + 1 index read dup { pop dup .epsfheader 3 index get eq } if + { pop pop } % if matched, don't need the character + { % unread characters (wasn't EPSF) + 2 index exch unread % unread mismatch character + dup { % loop unreading backwards in .epsfheader + 1 sub dup .epsfheader exch get 2 index exch unread + } repeat pop + exch not exch exit % change true to false + } + ifelse + } + for exch % Stack: file true/false + { % This block is executed if the file is MS-DOS EPSF. + % Build up the little-endian byte offset and length. + 2 + { 1 0 4 + { 2 index read not { pop exit } if % if EOF, let error happen + 2 index mul add exch 256 mul exch + } + repeat exch pop exch + } + repeat + % Stack: offset length file + % Use flushfile to skip quickly to the start of the + % PostScript section. + dup 4 -1 roll 12 sub () /SubFileDecode filter flushfile + % Now interpret the PostScript. + exch () /SubFileDecode filter cvx .runexec + } + { .runnoepsf + } + ifelse + } odef diff --git a/pstoraster/gs_fform.ps b/pstoraster/gs_fform.ps new file mode 100644 index 0000000000..17dfbef74f --- /dev/null +++ b/pstoraster/gs_fform.ps @@ -0,0 +1,100 @@ +% Copyright (C) 1995, 1996, 1998 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_fform.ps 956 2000-03-08 23:15:43Z mike $ +% Form caching implemented in PostScript. + +% This implementation doesn't do the right thing about halftone or +% Pattern phase, but the Pattern cache doesn't either.... + +% The Form cache key is the Form dictionary; the value is an array +% of 2 elements [CTM pattern_instance]. +% +% In order to prevent restore from clearing the cache, we explicitly +% push the cache entries on the stack before a restore and reinstall them. +currentglobal false setglobal +/.formcachedict 20 dict def % must be local +true setglobal +/restore { + mark .formcachedict { } forall + counttomark 1 add index { restore } .internalstopped + { cleartomark restore } + { counttomark 2 idiv { .formcachedict 3 1 roll put } repeat pop pop } + ifelse +} bind odef + +/.execform1 { + dup /Implementation known not { + dup /FormType get 1 ne { /rangecheck signalerror } if + % The Implementation is a Pattern that will draw the form. + currentglobal 1 index gcheck setglobal + % Stack: form global + 10 dict begin + /PatternType 1 def + /PaintType 1 def % colored + /TilingType 1 def % irrelevant + % Copy the BBox to the correct VM. + /BBox 2 index /BBox get 4 array copy exch 1 index def + % Set XStep and YStep to very large numbers, + % so we won't get multiple copies of the form. + /XStep 1 index dup 2 get exch 0 get sub 100 mul def + /YStep exch dup 3 get exch 1 get sub 100 mul def + /PaintProc 2 index /PaintProc get def + currentdict end readonly + % Stack: form global impl + exch setglobal + 1 index /Implementation 3 -1 roll .forceput + } if + .formcachedict 1 index .knownget { + % Check whether we can use the cached value. + % Stack: form cachevalue + matrix currentmatrix true 0 1 3 { + % Stack: form cachevalue curmat true index + 3 index 0 get 1 index get exch 3 index exch get ne { + pop pop false exit + } if + } for exch pop + } { + false + } ifelse not + { % Make a new cache entry. + gsave + matrix currentmatrix dup 4 0 put dup 5 0 put dup setmatrix + % Stack: form mat + 1 index /Implementation get + 2 index /Matrix get + makepattern 2 array astore + .formcachedict 2 index 2 index put + grestore + } if + % Stack: form cachevalue + -1 0 0 transform + 2 { exch round cvi } repeat .setscreenphase + 1 get setpattern + /BBox get aload pop + exch 3 index sub exch 2 index sub rectfill +} .bind odef % must bind .forceput + +.formtypes 1 /.execform1 load put + +setglobal diff --git a/pstoraster/gs_fonts.ps b/pstoraster/gs_fonts.ps new file mode 100644 index 0000000000..c413882ace --- /dev/null +++ b/pstoraster/gs_fonts.ps @@ -0,0 +1,934 @@ +% Copyright (C) 1990, 1995, 1996, 1997, 1998 Aladdin Enterprises. All rights reserved. +% +% This file is part of GNU Ghostscript. +% +% GNU Ghostscript is distributed in the hope that it will be useful, but +% WITHOUT ANY WARRANTY. No author or distributor accepts responsibility +% to anyone for the consequences of using it or for whether it serves any +% particular purpose or works at all, unless he says so in writing. Refer +% to the GNU General Public License for full details. +% +% Everyone is granted permission to copy, modify and redistribute GNU +% Ghostscript, but only under the conditions described in the GNU General +% Public License. A copy of this license is supposed to have been given +% to you along with GNU Ghostscript so you can know your rights and +% responsibilities. It should be in a file named COPYING. Among other +% things, the copyright notice and this notice must be preserved on all +% copies. +% +% Aladdin Enterprises supports the work of the GNU Project, but is not +% affiliated with the Free Software Foundation or the GNU Project. GNU +% Ghostscript, as distributed by Aladdin Enterprises, does not require any +% GNU software to build or run it. + +% $Id: gs_fonts.ps 956 2000-03-08 23:15:43Z mike $ +% Font initialization and management code. + +% Define the default font. +/defaultfontname /Courier def + +% Define the name of the font map file. +/defaultfontmap (Fontmap) def + +% ------ End of editable parameters ------ % + +% If SUBSTFONT is defined, make it the default font. +/SUBSTFONT where { pop /defaultfontname /SUBSTFONT load def } if + +% Define a reliable way of accessing FontDirectory in systemdict. +/.FontDirectory +{ /FontDirectory .systemvar +} .bind odef + +% If DISKFONTS is true, we load individual CharStrings as they are needed. +% (This is intended primarily for machines with very small memories.) +% In this case, we define another dictionary, parallel to FontDirectory, +% that retains an open file for every font loaded. +/FontFileDirectory 10 dict def + +% Define a temporary string for local use, since using =string +% interferes with some PostScript programs. +/.fonttempstring 128 string def + +% Split up a search path into individual directories or files. +/.pathlist % .pathlist ... + { { dup length 0 eq { pop exit } if + .filenamelistseparator search not { exit } if + exch pop exch + } + loop + } bind def + +% Load a font name -> font file name map. +userdict /Fontmap .FontDirectory maxlength dict put +/.loadFontmap % .loadFontmap - + { % We would like to simply execute .definefontmap as we read, + % but we have to maintain backward compatibility with an older + % specification that makes later entries override earlier. + 50 dict exch + { dup token not { closefile exit } if + % stack: fontname + % This is a hack to get around the absurd habit of MS-DOS editors + % of adding an EOF character at the end of the file. + dup (\032) eq { pop closefile exit } if + 1 index token not + { (Fontmap entry for ) print dup =only + ( has no associated file or alias name! Giving up.\n) print flush + {.loadFontmap} 0 get 1 .quit + } if + dup type dup /stringtype eq exch /nametype eq or not + { (Fontmap entry for ) print 1 index =only + ( has an invalid file or alias name! Giving up.\n) print flush + {.loadFontmap} 0 get 1 .quit + } if + % stack: dict file fontname filename|aliasname + % Read and pop tokens until a semicolon. + { 2 index token not + { (Fontmap entry for ) print 1 index =only + ( ends prematurely! Giving up.\n) print flush + {.loadFontmap} 0 get 1 .quit + } if + dup /; eq { pop 3 index 3 1 roll .growput exit } if + pop + } loop + } loop + { .definefontmap } forall + } bind def +% Add an entry in Fontmap. We redefine this if the Level 2 +% resource machinery is loaded. +/.definefontmap % .definefontmap - + { % Since Fontmap is global, make sure the values are storable. + .currentglobal 3 1 roll true .setglobal + dup type /stringtype eq + { dup .gcheck not { dup length string copy } if + } + if + Fontmap 3 -1 roll 2 copy .knownget + { % Add an element to the end of the existing value, + % unless it's the same as the current last element. + mark exch aload pop counttomark 4 add -1 roll + 2 copy eq { cleartomark pop pop } { ] readonly .growput } ifelse + } + { % Make a new entry. + mark 4 -1 roll ] readonly .growput + } + ifelse .setglobal + } bind def + +% Parse a font file just enough to find the FontName or FontType. +/.findfontvalue % .findfontvalue true + % .findfontvalue false + % Closes the file in either case. + { exch dup read not { -1 } if + 2 copy unread 16#80 eq + { dup (xxxxxx) readstring pop pop } % skip .PFB header + if + % Stack: key file + { dup token not { false exit } if % end of file + dup /eexec eq { pop false exit } if % reached eexec section + dup /Subrs eq { pop false exit } if % Subrs without eexec + dup /CharStrings eq { pop false exit } if % CharStrings without eexec + dup 3 index eq + { xcheck not { dup token exit } if } % found key + { pop } + ifelse + } loop + % Stack: key file value true (or) + % Stack: key file false + dup { 4 } { 3 } ifelse -2 roll closefile pop + } bind def +/.findfontname + { /FontName .findfontvalue + } bind def + +% If there is no FONTPATH, try to get one from the environment. +NOFONTPATH { /FONTPATH () def } if +/FONTPATH where + { pop } + { /FONTPATH (GS_FONTPATH) getenv not { () } if def } +ifelse +FONTPATH length 0 eq { (%END FONTPATH) .skipeof } if +/FONTPATH [ FONTPATH .pathlist ] def + +% Scan directories looking for plausible fonts. "Plausible" means that +% the file begins with %!PS-AdobeFont or %!FontType1, or with \200\001 +% followed by four arbitrary bytes and then either of these strings. +% To speed up the search, we skip any file whose name appears in +% the Fontmap (with any extension and upper/lower case variation) already, +% and any file whose extension definitely indicates it is not a font. +% +% NOTE: The current implementation of this procedure is somewhat Unix/DOS- +% specific. It assumes that '/' and '\' are directory separators, and that +% the part of a file name following the last '.' is the extension. +% +/.lowerstring % .lowerstring + { 0 1 2 index length 1 sub + { 2 copy get dup 65 ge exch 90 le and + { 2 copy 2 copy get 32 add put } + if pop + } + for + } bind def +/.splitfilename % .basename + { { (/) search { true } { (\\) search } ifelse + { pop pop } + { exit } + ifelse + } + loop + dup { (.) search { pop pop } { exit } ifelse } loop + 2 copy eq + { pop () } + { exch dup length 2 index length 1 add sub 0 exch getinterval exch } + ifelse +% Following is debugging code. +% (*** Split => ) print 2 copy exch ==only ( ) print ==only +% ( ***\n) print flush + } bind def +/.scanfontdict 1 dict def % establish a binding +/.scanfontbegin + { % Construct the table of all file names already in Fontmap. + currentglobal true setglobal + .scanfontdict dup maxlength Fontmap length 2 add .max .setmaxlength + Fontmap + { exch pop + { dup type /stringtype eq + { .splitfilename pop .fonttempstring copy .lowerstring cvn + .scanfontdict exch true put + } + { pop + } + ifelse + } + forall + } + forall + setglobal + } bind def +/.scanfontskip mark + % Strings are converted to names anyway, so.... + /afm true + /bat true + /c true + /cmd true + /com true + /dir true + /dll true + /doc true + /drv true + /exe true + /fon true + /fot true + /h true + /o true + /obj true + /pfm true + /pss true % Adobe Multiple Master font instances + /txt true +.dicttomark def +/.scan1fontstring 128 string def +/.scanfontheaders [(%!PS-Adobe*) (%!FontType*)] def +0 .scanfontheaders { length max } forall 6 add % extra for PFB header +/.scan1fontfirst exch string def +/.scanfontdir % .scanfontdir - + { currentglobal exch true setglobal + QUIET not { (Scanning ) print dup print ( for fonts...) print flush } if + (*) 2 copy .filenamedirseparator + dup (\\) eq { pop (\\\\) } if % double \ for pattern match + exch concatstrings concatstrings + 0 0 0 4 -1 roll % found scanned files + { % stack: + exch 1 add exch % increment filecount + dup .splitfilename .lowerstring + % stack: + % + .scanfontskip exch known exch .scanfontdict exch known or + { pop + % stack: + } + { 3 -1 roll 1 add 3 1 roll + % stack: + dup (r) { file } .internalstopped + { pop pop null () + % stack: + % null () + } + { + % On some platforms, the file operator will open directories, + % but an error will occur if we try to read from one. + % Handle this possibility here. + dup .scan1fontfirst { readstring } .internalstopped + { pop pop () } + { pop } + ifelse + % stack: + %